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

feat(overlay): add scroll handling strategies #4293

Merged
merged 5 commits into from
May 2, 2017

Conversation

crisbeto
Copy link
Member

  • Adds the scrollStrategy option to the overlay state, allowing the consumer to specify what scroll handling strategy they'd want to use. Also includes a ScrollStrategy interface that users can utilize to build their own strategies.
  • Adds the RepositionScrollStrategy, CloseScrollStrategy and NoopScrollStrategy as initial, out-of-the-box strategies.
  • Sets the RepositionScrollStrategy by default on all the connected overlays and removes some repetitive logic from the tooltip, autocomplete, menu and select.

Note: I'll add a BlockScrollStrategy in a follow-up PR. I wanted to keep this one shorter.

Relates to #4093.

@googlebot googlebot added the cla: yes PR author has agreed to Google's Contributor License Agreement label Apr 26, 2017
private _scrollSubscription: Subscription|null = null;
private _overlayRef: OverlayRef;

constructor(private _scrollDispatcher, private _scrollThrottle = 0) { }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing type on _scrollDispatcher

private _scrollSubscription: Subscription|null = null;
private _overlayRef: OverlayRef;

constructor(private _scrollDispatcher) { }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing type on _scrollDipstacher?

fakeScrollStrategy = {
attach: jasmine.createSpy('attach spy'),
enable: jasmine.createSpy('enable spy'),
disable: jasmine.createSpy('disable spy')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than having spies, it would be slightly more accurate to just store attachedOverlay and set isEnabled and make assertions against those.

(with a spy technically you could do something like call enabled(); disabled(); and have it still pass)

Copy link
Member Author

@crisbeto crisbeto Apr 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main reason I avoided adding isAttached and isEnabled was that I wanted to keep the ScrollStrategy interface as lean as possible. Also, apart from unit tests, I'm not sure that they provide a lot of value.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant only in the fake implementation for tests

Copy link
Member Author

@crisbeto crisbeto Apr 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, got it. I've updated the tests.

@@ -218,6 +220,7 @@ export class MdMenuTrigger implements AfterViewInit, OnDestroy {
overlayState.hasBackdrop = true;
overlayState.backdropClass = 'cdk-overlay-transparent-backdrop';
overlayState.direction = this.dir;
overlayState.scrollStrategy = new RepositionScrollStrategy(this._scrollDispatcher);
Copy link
Member

@jelbourn jelbourn Apr 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For a follow-up PR: rather than having menu, select, etc. all directly use RepositionScrollStrategy, we should have a provider that can configure the behavior more globally.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, although we'd have to have at least two: one for the global overlays and one for the connected ones.

if (!this._scrollSubscription) {
this._scrollSubscription = this._scrollDispatcher.scrolled(null, () => {
if (this._overlayRef.hasAttached()) {
this._overlayRef.detach();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't look like anything communicates the fact that the overlay detached back to the component, which would make their own state be out of sync.

Copy link
Member Author

@crisbeto crisbeto Apr 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The OverlayRef calls the disable method when it detaches and when it is disposed: https://github.com/angular/material2/pull/4293/files#diff-d4ca44eeaacca5fbb90029f947afc1e0R82

Copy link
Member

@jelbourn jelbourn Apr 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant the other way around- for example, if the overlay for MdMenuTrigger is closed due to scrolling, nothing tells MdMenuTrigger that this has happened and its _menuOpen state will be wrong

Copy link
Member Author

@crisbeto crisbeto Apr 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. We should add a detach observable to the OverlayRef IMO. We already do it on the ConnectedOverlayDirective.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds reasonable to me

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added the observables as discussed. They're not being used anywhere right now since nothing uses the CloseScrollStrategy. Also I initially wanted to have the outputs on the ConnectedOverlayDirective proxy the ones on the overlay ref, but it's not possible since the ref gets created lazily before attaching.

/** Returns an observable that emits when the overlay has been detached. */
onDetach(): Observable<void> {
return this._onDetach.asObservable();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make these getters called attachments and detachments? I kind of want to move away from the onAction-style naming for observables

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Member

@jelbourn jelbourn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jelbourn jelbourn added pr: lgtm action: merge The PR is ready for merge by the caretaker and removed pr: needs review labels Apr 28, 2017
@mmalerba
Copy link
Contributor

@crisbeto needs rebase

@mmalerba mmalerba removed the action: merge The PR is ready for merge by the caretaker label Apr 28, 2017
* Adds the `scrollStrategy` option to the overlay state, allowing the consumer to specify what scroll handling strategy they'd want to use. Also includes a `ScrollStrategy` interface that users can utilize to build their own strategies.
* Adds the `RepositionScrollStrategy`, `CloseScrollStrategy` and `NoopScrollStrategy` as initial, out-of-the-box strategies.
* Sets the `RepositionScrollStrategy` by default on all the connected overlays and removes some repetitive logic from the tooltip, autocomplete, menu and select.

**Note:** I'll add a `BlockScrollStrategy` in a follow-up PR. I wanted to keep this one shorter.

Relates to angular#4093.
@crisbeto crisbeto added the action: merge The PR is ready for merge by the caretaker label Apr 29, 2017
@andrewseguin andrewseguin merged commit c8ec981 into angular:master May 2, 2017
@YeomansIII
Copy link
Contributor

How does one use these scroll strategies on a MdDialog? Does that require a separate change?

@crisbeto
Copy link
Member Author

The dialog currently has a scroll strategy to disable scrolling. We're still working on a way to be able to override the strategy per component.

@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 Sep 6, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker cla: yes PR author has agreed to Google's Contributor License Agreement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants