-
Notifications
You must be signed in to change notification settings - Fork 6.8k
feat(overlay): add scroll blocking strategy #4500
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
Conversation
Adds the `BlockScrollStrategy` which, when activated, will prevent the user from scrolling. For now it is only used in the dialog. Relates to angular#4093.
* Strategy that will prevent the user from scrolling while the overlay is visible. | ||
*/ | ||
export class BlockScrollStrategy implements ScrollStrategy { | ||
private _prevHTMLStyles = { top: null, left: null }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_previousHtmlElementStyles
?
let forceScrollElement: HTMLElement; | ||
|
||
beforeEach(async(() => { | ||
TestBed.configureTestingModule({ imports: [OverlayModule] }).compileComponents(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No spaces inside object literals
TestBed.configureTestingModule({ imports: [OverlayModule] }).compileComponents(); | ||
})); | ||
|
||
beforeEach(inject([ViewportRuler], (_viewportRuler: ViewportRuler) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't use _
for function params; for inject
I'm fine with just doing something like vpr
// we have to skip them on iOS. | ||
function skipUnreliableBrowser(spec: Function) { | ||
return () => { | ||
if (!platform.IOS) { spec(); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't want to always skip iOS, since sometimes it does pass (and I think iOS 10 has this problem less frequently than iOS 9).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a fan of skipping tests either, but I couldn't find a decent way to even scroll the page on iOS 10.3. E.g. something as simple as this doesn't work:
it('should scroll down', () => {
forceScrollElement.style.height = '3000px';
window.scroll(0, 100);
viewport._cacheViewportGeometry();
expect(viewport.getViewportScrollPosition().top).toBe(100);
});
This renders the entire test pointless since we can't verify whether we're actually doing anything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case I would call the function skipIOS
and expand the comment to include that code snippet (just the window.scroll(0, 100); expect(viewport.getViewportScrollPosition().top).toBe(100);
part) as reasoning for why it's skipped.
forceScrollElement.style.height = '3000px'; | ||
|
||
setScrollPosition(0, 100); | ||
expect(viewport.getViewportScrollPosition().top).toBe(100, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefer breaking at the higher syntactic level, e.g.
expect(viewport.getViewportScrollPosition().top)
.toBe(100, 'Expected viewport to be scrollable initially.');
src/lib/core/_core.scss
Outdated
// Used when disabling global scrolling. | ||
.cdk-global-scrollblock { | ||
position: fixed; | ||
overflow-y: scroll; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't adding overflow-y: scroll
cause a scrollbar to always appear, even if there wasn't one there already? This could lead to an app suddenly multiple scrollbars when a, e.g., a dialog is opened.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will, but we don't activate the strategy unless there was a scrollbar in the first place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should add a comment mentioning that
viewport._cacheViewportGeometry(); | ||
} | ||
|
||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should have an e2e test w/ screenshots for this as well that actually attempts to scroll the page through user input.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, but wouldn't it be pointless since we only run the e2e tests against Chrome?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's better than not having it; there were issues w/ the AngularJS version that manifested in Chrome.
Added e2e tests and addressed the feedback @jelbourn. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, one minor comment
Also, I'm shocked that webdriver doesn't have anything to make scrolling happen other than window.scrollTo
(just looked it up).
src/lib/core/_core.scss
Outdated
@@ -41,4 +41,17 @@ | |||
.mat-theme-loaded-marker { | |||
display: none; | |||
} | |||
|
|||
// Used when disabling global scrolling. | |||
.cdk-global-scrollblock { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should go into the cdk-overlay
mixin
Hi @jelbourn is this where a user is using a dialog box or sidenav(panel) flyout and the overlay content still scrolls up and down? For now I used a method that alters the body element to position: fixed when opening one of these is opened up. |
How can I use the BlockScrollStrategy on a Select-Dropdown? |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Adds the
BlockScrollStrategy
which, when activated, will prevent the user from scrolling. For now it is only used in the dialog.Relates to #4093.