angular / components

Component infrastructure and Material Design components for Angular
https://material.angular.io
MIT License
24.34k stars 6.74k forks source link

cdk-virtual-scroll-viewport - support window scroll #13862

Closed abeymg closed 2 years ago

abeymg commented 5 years ago

Bug, feature request, or proposal:

Feature request

What is the expected behavior?

Allow the scroll of the cdk-virtual-scroll-viewport to be controlled by the top level window scrollbar.

See example at the link below. (Go to that page and click on parent scroll to see desired behavior) https://rintoj.github.io/ngx-virtual-scroller

Another example of window scrolling in the context of virtual scrolling https://bvaughn.github.io/react-virtualized/#/components/WindowScroller

What is the current behavior?

Specifying a parent scroll does not seem to be supported, from what I can tell.

What is the use-case or motivation for changing an existing behavior?

Having a single top level window/page scroll is standard in a lot of SPAs. The virtual-scroll would be a lot more useful in these cases, if it could use the same scroll bar, otherwise often times you end up with two scrollbars (one for the virt-scroll and the other for the page, or else a smaller inset container for the virt-scroll with a scrollbar), which is less than ideal.

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

Angular: 7.0.1 Material: 7.0.2

Is there anything else we should know?

LeParadoxHD commented 5 years ago

That would be very useful!

vahidvdn commented 5 years ago

+1

flolu commented 5 years ago

This should definitely be implemented soon!

wunaidage commented 5 years ago

mark to track status. This will be awesome!

rmedaer commented 5 years ago

@mmalerba I did a small POC to support both window and closest relative parent virtual scrolling.

Actually it's not yet ready for merge. It's still missing tests, examples, and even implementations... But at least it gives a proposal for the implementation. I would be really interested to get your feedback.

In my use-case it fits well. Hope you appreciate.

Here is a demo: demo-virtual-scroll

Kind regards,

mmalerba commented 5 years ago

@rmedaer sure, I can take a look. Can you link me to the branch where you're working?

rmedaer commented 5 years ago

Yeah ! I committed on master branch in my fork. I know it's bad but again my plan was just to do a test and it became probably more ..

The dev-app (demo) contains an example.

mmalerba commented 5 years ago

@rmedaer Overall I like the approach, though parts of the implementation I'm not too sure about. I also think we could make the nested viewport more flexible by either making a directive that can be used to mark the parent, or using an @Input() that lets the user specify the scrolling container (e.g. viewportRoot=".some-ancestor-element"), rather than just assuming it's the direct parent.

@jelbourn Do you have any thoughts about this proposal?

jelbourn commented 5 years ago

Could you summarize the approach?

rmedaer commented 5 years ago

Actually, my approach is to decouple the viewport and its container. Then I provide somehow the container to the viewport which will use its API to calculate scroll offset and so on. Here is the container's interface:

export interface VirtualScrollContainerRef {
  measureScrollOffset(from: 'top' | 'left' | 'right' | 'bottom' | 'start' | 'end'): number;
  measureContainerSize(orientation: 'horizontal' | 'vertical'): number;
  getViewportSize(contentSize: number): string | null;
  scrollTo(options: ExtendedScrollToOptions): any;
  elementScrolled(): Observable<Event>;
}

As you can see this interface is implementing more or less the same then CdkScrollable (there is no need of ElementRef).

In my POC I "provide" the container ref to the viewport using a directive that you have to apply on viewport. But as @mmalerba said, we could also use a DOM reference. We could even create a directive that you apply on parent (container) element which has to scroll.

Currently my prototype has 3 ContainerRef directives:

hezzyg commented 5 years ago

This feature is really needed in order to use the Virtual-scroll in real apps.... We would really appreciate if it would be implemented soon.

vahidvdn commented 5 years ago

@hezzyg You can use this module. It's already supported window scroll.

rmedaer commented 5 years ago

@hezzyg otherwise if @mmalerba and/or @jelbourn are OK with my approach, I can deliver a patch ASAP. But I'm still waiting their (no)go to do it (or not). ;-)

hezzyg commented 5 years ago

@hezzyg otherwise if @mmalerba and/or @jelbourn are OK with my approach, I can deliver a patch ASAP. But I'm still waiting their (no)go to do it (or not). ;-)

Thanks @rmedaer . I do prefer a solution integrated into Angular Material for better support in the future. So I hope your suggestion will get there asap :-)

hezzyg commented 5 years ago

@hezzyg You can use this module. It's already supported window scroll.

I'll have a look. thanks @vahidvdn

mmalerba commented 5 years ago

@rmedaer yes I'd like to do this, please send a PR and mention me on it, thanks!

jeetparikh commented 5 years ago

This would be a really useful feature. We are unable to use this at the moment because we have a scrollbar at a different level.

levitatejay commented 5 years ago

@rmedaer @mmalerba

@hezzyg otherwise if @mmalerba and/or @jelbourn are OK with my approach, I can deliver a patch ASAP. But I'm still waiting their (no)go to do it (or not). ;-)

@rmedaer yes I'd like to do this, please send a PR and mention me on it, thanks!

Is there a pull request for the patch? I really need to implement a window scrolling CDK viewport so I'd be grateful for any help!

jeetparikh commented 5 years ago

@mmalerba the PR #14287 is simply introducing the virtual adapter but is there any PR to support scrolling at parent level or window level for cdk-virtual-scroll-viewport?

rmedaer commented 5 years ago

@jeetparikh if it's really urgent, you can take a look at this commit. It's the POC I made to test virtual scrolling on window. Btw I don't have so much time to do a PR for now but at least you can already play with it !

mmalerba commented 5 years ago

@jeetparikh yeah my bad, I saw that it was linked to this issue but didn't look closely enough, that PR is unrelated. Deleting my previous comment to avoid confusion for people reading this later.

I thought I remember seeing a PR related to this, but it may have just been a proof of concept on someone's branch

jeetparikh commented 5 years ago

@rmedaer thank you for sharing that. Does that work without any tweaks? Also, does it work with cdk-table? or I would have to make amendments?

rmedaer commented 5 years ago

Yes it should work out of the box by adding window to cdk-virtual-scroll-viewport component (see cdk-virtual-scroll-viewport[window] directive).

I don't know about cdk-table... You'll probably have to use CdkVirtualScrollNestedViewport directive to deal with parent relative positioning... but again I don't know much more about that.

jeetparikh commented 5 years ago

thanks @rmedaer .. what exactly does the nested viewport support?

rmedaer commented 5 years ago

Instead of using existing viewport from cdk-virtual-scroll-viewport, it takes the closest relative parent (nativeElement.offsetParent) as reference. Later it uses offsetTop property to measure the scroll offset (c.f. measureScrollOffset method). Because my code is a POC it's currently implemented only to measure from "top".

jeetparikh commented 5 years ago

sounds good.. thanks @rmedaer I l have a look :)

hanishmaram commented 5 years ago

@rmedaer

@jeetparikh if it's really urgent, you can take a look at this commit. It's the POC I made to test virtual scrolling on window. Btw I don't have so much time to do a PR for now but at least you can already play with it !

@rmedaer How can I use this in my project?

hanishmaram commented 5 years ago

This is very feature. We are not able to use virtual scroll as scroll bars are at different levels.

ydang204 commented 5 years ago

Will this feature be implemented soon?

shanehsu commented 5 years ago

@rmedaer Will you be open to fixing your previous #14287 ? It seems to have some suggested changes here I think the idea looks great!

ShakurOo commented 5 years ago

One year later, there is no news about this feature :(

Celtian commented 4 years ago

@rmedaer

@jeetparikh if it's really urgent, you can take a look at this commit. It's the POC I made to test virtual scrolling on window. Btw I don't have so much time to do a PR for now but at least you can already play with it !

@rmedaer How can I use this in my project?

@hanishmaram :

Recipe for you:

  1. Build from source git clone https://github.com/rmedaer/material2 && cd material2 && npm run install && npm run deploy

  2. Then you need content into your repo, just this content material2/dist/packages (just cdk folder is enough)

  3. Installation into your project yarn add ${github_user}/${github_repo}

  4. Import into your project: import { ScrollingModule } from '${github_user}/${github_repo}/cdk/scrolling';

@rmedaer

Hi,

can you provide an example how to use window scroll? For my purpose, I can use "nested" but "window" is more optimal.

Screenshot_20191230-220434

The last small problem is, when you are not using window.scroll, adress bar on anrdoid cannot be hidden automatically when you scroll down.

I hope that this feature will be available soon.

Thanks,

Celtian

pjjroux commented 4 years ago

What is the current status on this? Still being looked at?

limes commented 4 years ago

Guys, don't make me move to React :) Please write, is there a chance to do this task in 2020? Who needs to buy a beer? :D

vahidvdn commented 4 years ago

@limes If you are gonna change your framework just because of a small built-in feature, you will move for your entire life. Just check this module instead if you need this feature.

limes commented 4 years ago

@vahidvdn My adventure with Angular has been going on for several years and sometimes such small nuisance can drive me crazy. I have an application that is designed to be displayed as desktop / mobile / PWA / Electron / Android / iOS. One code base. The last thing I miss is hiding the address bar (while scrolling) in mobile browser. There is no other way but to scroll the window object. I tested the module you're writing about. The problem is that scrolling mode on the window does not work with https://material.angular.io/components/sidenav/overview. Angular Material is very important for me because of the great support for disabled people. That's why I would like to know if scrolling on window support will be available this year or I have to look for completely different solutions having in mind the parallel support of many different platforms.

vahidvdn commented 4 years ago

@limes Good point. But the important thing is that maybe this is a much bigger problem in reactjs. Because that's a library and even a lot of important things like router component is not coming out of the box (but made by the community). So even in react you will gonna use a 3rd party library for your virtual scroll. (You may have some problems or may not)

limes commented 4 years ago

@vahidvdn And that's the reason I use Angular. I like the fact that I have everything in the box and I don't have to look for more libraries and watch out for dependencies. Just this little problem with scroll on the window @ mobile :)

illnr commented 4 years ago

@vahidvdn [...] I tested the module you're writing about. The problem is that scrolling mode on the window does not work with https://material.angular.io/components/sidenav/overview. [...]

I implemented ngx-virtual-scroller with a window scroll and mat-sidenav. It works perfectly now (URL Bar is hiding on iOS and Android), after getting the html and css set correctly (which was a pain).

But still I think supporting scroll on the document.window is essential for mobile for the reasons mentioned.

limes commented 4 years ago

It works perfectly now (URL Bar is hiding on iOS and Android), after getting the html and css set correctly (which was a pain).

@iBaff Can you show me how you fixed it?

dmc31a42 commented 4 years ago

edit: not work for url bar hiding.... @limes please check difference (div native element in sidenav-content) between https://stackblitz.com/edit/angular-virtual-scroll-with-sidenav-work and https://stackblitz.com/edit/angular-virtual-scroll-with-sidenav-not-work

just use edit: has production build error

<mat-sidenav-content #content>
  ...
  <virtual-scroller ... [parentScroll]="content.elementRef.nativeElement">
  ...
dmc31a42 commented 4 years ago

@limes URL bar hiding work https://stackblitz.com/edit/angular-virtual-scroll-with-sidenav-work-with-urlbar-hide

limes commented 4 years ago

@dmc31a42

https://angular-virtual-scroll-with-sidenav-work-with-urlbar-hide.stackblitz.io/ https://angular-virtual-scroll-with-sidenav-work.stackblitz.io/

Maybe I'm doing something wrong, but no pages under the above addresses hide the address bar when I'm scrolling them. I tested on real iPhone/Chrome

dmc31a42 commented 4 years ago

@limes I have checked. I'll tell you when find solution

dmc31a42 commented 4 years ago

@limes I fixed https://angular-virtual-scroll-with-sidenav-work-with-urlbar-hide.stackblitz.io/ work in iOS Key point is,

  1. make 'overflow' of mat-sidenav-container and mat-sidenav-content to 'visible' to fix virtual-scroller does not work in sidenav
    mat-sidenav-container {
    overflow: visible;
    }
    mat-sidenav-content {
    overflow: visible;
    }
  2. use scroll.window to work url hide
limes commented 4 years ago

@dmc31a42 Thank you! 👍

tomasdev commented 4 years ago

@mmalerba is there any update on timeline / prioritization of this feature?

its-dibo commented 4 years ago

I am searching for this approach. nice to see this issue. is there any updates?

jdussouillez commented 3 years ago

Any updates on this ?

Aymeriic commented 3 years ago

An update would be really great