Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
abeymg opened this issue Oct 29, 2018 · 65 comments · Fixed by #24394
Closed

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

abeymg opened this issue Oct 29, 2018 · 65 comments · Fixed by #24394
Assignees
Labels
area: cdk/scrolling feature This issue represents a new feature or feature request rather than a bug or bug fix G This is is related to a Google internal issue P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent

Comments

@abeymg
Copy link

abeymg commented Oct 29, 2018

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?

@mmalerba mmalerba added feature This issue represents a new feature or feature request rather than a bug or bug fix G This is is related to a Google internal issue P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent labels Oct 30, 2018
@mmalerba mmalerba self-assigned this Oct 30, 2018
@mmalerba mmalerba added this to To do in Virtual scrolling via automation Oct 30, 2018
@LeParadoxHD
Copy link

That would be very useful!

@vahidvdn

This comment has been minimized.

@flolu
Copy link

flolu commented Jan 3, 2019

This should definitely be implemented soon!

@wunaidage
Copy link

mark to track status. This will be awesome!

rmedaer pushed a commit to rmedaer/material2 that referenced this issue Jan 9, 2019
[POC/WIP] This commit partially implements virtual scrolling within
closest relative parent or using window.
This is indeed not ready for merging but it demonstrates a way to handle
these use-cases with dependency injection and an abstraction of viewport
container.
@rmedaer
Copy link

rmedaer commented Jan 9, 2019

@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
Copy link
Contributor

mmalerba commented Jan 9, 2019

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

@rmedaer
Copy link

rmedaer commented Jan 9, 2019

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
Copy link
Contributor

@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
Copy link
Member

Could you summarize the approach?

@rmedaer
Copy link

rmedaer commented Jan 18, 2019

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:

  • CdkVirtualScrollDefaultViewport: same behavior then current impl; we are scrolling into the viewport.
  • CdkVirtualScrollNestedViewport: use the closest relative parent as container => works well with offsetTop property.
  • CdkVirtualScrollWindowViewport: use window as container. This one cannot use implementation from CdkScrollable.

@hezzyg
Copy link

hezzyg commented Feb 6, 2019

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
Copy link

vahidvdn commented Feb 6, 2019

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

@rmedaer
Copy link

rmedaer commented Feb 6, 2019

@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
Copy link

hezzyg commented Feb 6, 2019

@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
Copy link

hezzyg commented Feb 6, 2019

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

I'll have a look. thanks @vahidvdn

@mmalerba
Copy link
Contributor

mmalerba commented Feb 6, 2019

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

@jeetparikh
Copy link

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
Copy link

@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
Copy link

@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
Copy link

rmedaer commented Apr 9, 2019

@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
Copy link
Contributor

mmalerba commented Apr 9, 2019

@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
Copy link

@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?

@sthan001
Copy link

sthan001 commented May 30, 2021

What i feel is that,

  1. By default if we don't control overflow (overflow: auto) at cdk-virtual-scroll-viewport, that carries to parent element all the way to window.
    Now that is missing in the cdk-virtual-scroll-viewport element. and cdk-virtual-scroll-spacer should accept the element be it window, of element in local component, or element from parent component as scrollable. A attribute possibly?
  2. the cdk-virtual-scroll-viewport should be calculating header and footer size to occupy the cdk-virtual-scroll-spacer. Basically accept the header, footer and any other intermediate element height to be considered to have complete scroll option. Again via attribue.
  3. Either spacer to take care of the complete page available to scroll or we can set height of cdk-virtual-scroll-content-wrapper excluding header/breadcrumb/footer including media query adjustments.
  4. as much as possible the position of cdk-virtual-scroll-viewport should be not fixed, or absolute. because some application may not able to reuse at their component level depth if that is the case.

Angular doing lot, not sure why this feature is on hold for long time. And again, suggesting alternative 3rd party library is another overhead. These all angular can fix and sell itself well among industries.

@ursaciuc-adrian
Copy link

ursaciuc-adrian commented Jul 30, 2021

Until this is merged i found a quick workaround for this. You can create a new custom scrolling strategy which is basically the same as the fixed size scrolling strategy, but for the viewPort height you use the hight of the window and for the scroll offset you use the pageYOffset of the window.
And what is left to do is to listen to the scroll event on the page and update the redered range when this happens.
Here is a basic stackblitz with it. It might not work for every case, but it's good enough for what i need it to do. Maybe it will help others too.

https://stackblitz.com/edit/window-virtual-scroll-strategy

@ghenry22
Copy link

With Ionic Framework deprecating their own virtual-scroll in favour of CDK virtual-scroller the ability to scroll based on a parent element/window is essential in order for the CDK virtual-scroller to work with other common components like pull-to-refresh, infinite-scroll and iOS style auto expanding header styling in mobile apps.

Details from Ionic team:
https://github.com/ionic-team/ionic-docs/blob/liam-v6-docs/src/pages/angular/virtual-scroll.md

I would be really great if we could pass in a scroll element to the virtual-scroller to use in a similar way to how https://github.com/rintoj/ngx-virtual-scroller works.

@vahidvdn
Copy link

@ghenry22 ionic built-in virtual list component was literally useless. Hope it's going to work with the angular CDK virtual-scroller.

@ghenry22
Copy link

@vahidvdn I've used the Ionic virtual scroll component successfully in a number of cases. It definitely has some quirks and never got the attention it needed but when you work around it's specific weirdness it does the job.

I agree though I am hoping that the cdk virtual scroller will provide a much more robust and more actively supported solution. Only time will tell!

@syam38
Copy link

syam38 commented Nov 10, 2021

Any update on this feature?

@syam38
Copy link

syam38 commented Nov 10, 2021

Until this is merged i found a quick workaround for this. You can create a new custom scrolling strategy which is basically the same as the fixed size scrolling strategy, but for the viewPort height you use the hight of the window and for the scroll offset you use the pageYOffset of the window. And what is left to do is to listen to the scroll event on the page and update the redered range when this happens. Here is a basic stackblitz with it. It might not work for every case, but it's good enough for what i need it to do. Maybe it will help others too. https://stackblitz.com/edit/window-virtual-scroll-strategy

The stackblitz link is not working, could you please re share it @ursaciuc-adrian

@ursaciuc-adrian
Copy link

ursaciuc-adrian commented Nov 10, 2021

The stackblitz link is not working, could you please re share it @ursaciuc-adrian

Updated the url

@vugar005
Copy link

vugar005 commented Dec 22, 2021

For now, I ended up using Custom Intersection api. Stackblitz url

@spike-rabbit
Copy link
Contributor

@mmalerba Would you still accept a PR adding this feature? I would be happy to provide one following the suggestions by @rmedaer

@mmalerba
Copy link
Contributor

mmalerba commented Feb 4, 2022

@spike-rabbit Yes, I'm happy to look at a PR along the lines of what we discussed above.

@Harpush
Copy link

Harpush commented Feb 4, 2022

Will it allow to have two virtual scroll viewports under the same container and the scroll will be in the container? Thus allowing them both to render only what's shown relative to the shared parent container.

@spike-rabbit
Copy link
Contributor

@mmalerba Great, thanks for the info. I plan to provide one around March.

@Harpush Based on my current knowledge: yes. But I need to dive further into this to provide a reliable answer

@lincolnthree
Copy link

lincolnthree commented Feb 6, 2022

Thanks for all of you effort on this! Really looking forward to seeing it.

This feature is critical for a "native-like" feel in mobile apps with momentum scrolling. When scrolling locks up and you need to scroll again with a new gesture to continue past the virtual scroll viewport, or capture the gesture in the viewport instead of going past, it really interrupts the user experience.

I will be happy to test and contribute if there is a beta build to try!

spike-rabbit added a commit to siemens/components that referenced this issue Feb 10, 2022
…crolling

Decouples the scroller from the virtual-scroll-viewport which allows library consumers
to use any parent element as a scroller. This is especially helpful when building SPAs
with a single global scrollbar.

Closes angular#13862
spike-rabbit added a commit to siemens/components that referenced this issue Feb 10, 2022
…crolling

Decouples the scroller from the virtual-scroll-viewport which allows library consumers
to use any parent element as a scroller. This is especially helpful when building SPAs
with a single global scrollbar.

Closes angular#13862
spike-rabbit added a commit to siemens/components that referenced this issue Feb 10, 2022
…crolling

Decouples the scroller from the virtual-scroll-viewport which allows library consumers
to use any parent element as a scroller. This is especially helpful when building SPAs
with a single global scrollbar.

Closes angular#13862
spike-rabbit added a commit to siemens/components that referenced this issue Feb 10, 2022
…crolling

Decouples the scroller from the virtual-scroll-viewport which allows library consumers
to use any parent element as a scroller. This is especially helpful when building SPAs
with a single global scrollbar.

Closes angular#13862
spike-rabbit added a commit to siemens/components that referenced this issue Feb 21, 2022
…crolling

Decouples the scroller from the virtual-scroll-viewport which allows library consumers
to use any parent element as a scroller. This is especially helpful when building SPAs
with a single global scrollbar.

Closes angular#13862
spike-rabbit added a commit to siemens/components that referenced this issue Apr 14, 2022
…crolling

Decouples the scroller from the virtual-scroll-viewport which allows library consumers
to use any parent element as a scroller. This is especially helpful when building SPAs
with a single global scrollbar.

Closes angular#13862
spike-rabbit added a commit to siemens/components that referenced this issue May 13, 2022
…crolling

Decouples the scroller from the virtual-scroll-viewport which allows library consumers
to use any parent element as a scroller. This is especially helpful when building SPAs
with a single global scrollbar.

Closes angular#13862
spike-rabbit added a commit to siemens/components that referenced this issue May 13, 2022
…crolling

Decouples the scroller from the virtual-scroll-viewport which allows library consumers
to use any parent element as a scroller. This is especially helpful when building SPAs
with a single global scrollbar.

Closes angular#13862
spike-rabbit added a commit to siemens/components that referenced this issue Jun 7, 2022
…crolling

Decouples the scroller from the virtual-scroll-viewport which allows library consumers
to use any parent element as a scroller. This is especially helpful when building SPAs
with a single global scrollbar.

Closes angular#13862
Virtual scrolling automation moved this from To do to Done Jun 8, 2022
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Jul 9, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: cdk/scrolling feature This issue represents a new feature or feature request rather than a bug or bug fix G This is is related to a Google internal issue P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent
Projects
Development

Successfully merging a pull request may close this issue.