forked from angular/components
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(overlay): add scroll handling strategies
* 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.
- Loading branch information
Showing
17 changed files
with
346 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import {inject, TestBed, async} from '@angular/core/testing'; | ||
import {NgModule, Component} from '@angular/core'; | ||
import {Subject} from 'rxjs/Subject'; | ||
import { | ||
PortalModule, | ||
ComponentPortal, | ||
Overlay, | ||
OverlayState, | ||
OverlayRef, | ||
OverlayModule, | ||
ScrollStrategy, | ||
ScrollDispatcher, | ||
CloseScrollStrategy, | ||
} from '../../core'; | ||
|
||
|
||
describe('CloseScrollStrategy', () => { | ||
let overlayRef: OverlayRef; | ||
let componentPortal: ComponentPortal<MozarellaMsg>; | ||
let scrolledSubject = new Subject(); | ||
|
||
beforeEach(async(() => { | ||
TestBed.configureTestingModule({ | ||
imports: [OverlayModule, PortalModule, OverlayTestModule], | ||
providers: [ | ||
{provide: ScrollDispatcher, useFactory: () => { | ||
return {scrolled: (delay: number, callback: () => any) => { | ||
return scrolledSubject.asObservable().subscribe(callback); | ||
}}; | ||
}} | ||
] | ||
}); | ||
|
||
TestBed.compileComponents(); | ||
})); | ||
|
||
beforeEach(inject([Overlay, ScrollDispatcher], (overlay: Overlay, | ||
scrollDispatcher: ScrollDispatcher) => { | ||
|
||
let overlayState = new OverlayState(); | ||
overlayState.scrollStrategy = new CloseScrollStrategy(scrollDispatcher); | ||
overlayRef = overlay.create(overlayState); | ||
componentPortal = new ComponentPortal(MozarellaMsg); | ||
})); | ||
|
||
it('should detach the overlay as soon as the user scrolls', () => { | ||
overlayRef.attach(componentPortal); | ||
spyOn(overlayRef, 'detach'); | ||
|
||
scrolledSubject.next(); | ||
expect(overlayRef.detach).toHaveBeenCalled(); | ||
}); | ||
|
||
it('should not attempt to detach the overlay after it has been detached', () => { | ||
overlayRef.attach(componentPortal); | ||
overlayRef.detach(); | ||
|
||
spyOn(overlayRef, 'detach'); | ||
scrolledSubject.next(); | ||
|
||
expect(overlayRef.detach).not.toHaveBeenCalled(); | ||
}); | ||
|
||
}); | ||
|
||
|
||
/** Simple component that we can attach to the overlay. */ | ||
@Component({template: '<p>Mozarella</p>'}) | ||
class MozarellaMsg { } | ||
|
||
|
||
/** Test module to hold the component. */ | ||
@NgModule({ | ||
imports: [OverlayModule, PortalModule], | ||
declarations: [MozarellaMsg], | ||
entryComponents: [MozarellaMsg], | ||
}) | ||
class OverlayTestModule { } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import {ScrollStrategy} from './scroll-strategy'; | ||
import {OverlayRef} from '../overlay-ref'; | ||
import {Subscription} from 'rxjs/Subscription'; | ||
import {ScrollDispatcher} from './scroll-dispatcher'; | ||
|
||
|
||
/** | ||
* Strategy that will close the overlay as soon as the user starts scrolling. | ||
*/ | ||
export class CloseScrollStrategy implements ScrollStrategy { | ||
private _scrollSubscription: Subscription|null = null; | ||
private _overlayRef: OverlayRef; | ||
|
||
constructor(private _scrollDispatcher) { } | ||
|
||
attach(overlayRef: OverlayRef) { | ||
this._overlayRef = overlayRef; | ||
} | ||
|
||
enable() { | ||
if (!this._scrollSubscription) { | ||
this._scrollSubscription = this._scrollDispatcher.scrolled(null, () => { | ||
if (this._overlayRef.hasAttached()) { | ||
this._overlayRef.detach(); | ||
} | ||
|
||
this.disable(); | ||
}); | ||
} | ||
} | ||
|
||
disable() { | ||
if (this._scrollSubscription) { | ||
this._scrollSubscription.unsubscribe(); | ||
this._scrollSubscription = null; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import {ScrollStrategy} from './scroll-strategy'; | ||
|
||
/** | ||
* Scroll strategy that doesn't do anything. | ||
*/ | ||
export class NoopScrollStrategy implements ScrollStrategy { | ||
enable() { } | ||
disable() { } | ||
attach() { } | ||
} |
Oops, something went wrong.