diff --git a/src/lib/sidenav/drawer-container.html b/src/lib/sidenav/drawer-container.html index 4791878555ef..4482b0783403 100644 --- a/src/lib/sidenav/drawer-container.html +++ b/src/lib/sidenav/drawer-container.html @@ -5,6 +5,6 @@ - + diff --git a/src/lib/sidenav/drawer.spec.ts b/src/lib/sidenav/drawer.spec.ts index f76bbcf43ed8..193bf341179a 100644 --- a/src/lib/sidenav/drawer.spec.ts +++ b/src/lib/sidenav/drawer.spec.ts @@ -15,6 +15,7 @@ import {A11yModule} from '@angular/cdk/a11y'; import {PlatformModule} from '@angular/cdk/platform'; import {ESCAPE} from '@angular/cdk/keycodes'; import {dispatchKeyboardEvent} from '@angular/cdk/testing'; +import {CdkScrollable} from '@angular/cdk/scrolling'; describe('MatDrawer', () => { @@ -496,6 +497,7 @@ describe('MatDrawerContainer', () => { DrawerContainerStateChangesTestApp, AutosizeDrawer, BasicTestApp, + DrawerContainerWithContent, ], }); @@ -692,6 +694,27 @@ describe('MatDrawerContainer', () => { expect(fixture.componentInstance.drawer.opened).toBe(false); })); + it('should expose a scrollable when the consumer has not specified drawer content', + fakeAsync(() => { + const fixture = TestBed.createComponent(DrawerContainerTwoDrawerTestApp); + + fixture.detectChanges(); + + expect(fixture.componentInstance.drawerContainer.scrollable instanceof CdkScrollable) + .toBe(true); + })); + + it('should expose a scrollable when the consumer has specified drawer content', + fakeAsync(() => { + const fixture = TestBed.createComponent(DrawerContainerWithContent); + + fixture.detectChanges(); + + expect(fixture.componentInstance.drawerContainer.scrollable instanceof CdkScrollable) + .toBe(true); + })); + + }); @@ -874,3 +897,16 @@ class AutosizeDrawer { @ViewChild(MatDrawer) drawer: MatDrawer; fillerWidth = 0; } + + +@Component({ + template: ` + + Drawer + Content + + `, +}) +class DrawerContainerWithContent { + @ViewChild(MatDrawerContainer) drawerContainer: MatDrawerContainer; +} diff --git a/src/lib/sidenav/drawer.ts b/src/lib/sidenav/drawer.ts index ef1aa22a0cdf..7101bab9f6bd 100644 --- a/src/lib/sidenav/drawer.ts +++ b/src/lib/sidenav/drawer.ts @@ -11,7 +11,7 @@ import {Directionality} from '@angular/cdk/bidi'; import {coerceBooleanProperty} from '@angular/cdk/coercion'; import {ESCAPE} from '@angular/cdk/keycodes'; import {Platform} from '@angular/cdk/platform'; -import {CdkScrollable} from '@angular/cdk/scrolling'; +import {CdkScrollable, ScrollDispatcher} from '@angular/cdk/scrolling'; import {DOCUMENT} from '@angular/common'; import { AfterContentChecked, @@ -75,10 +75,14 @@ export function MAT_DRAWER_DEFAULT_AUTOSIZE_FACTORY(): boolean { changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, }) -export class MatDrawerContent implements AfterContentInit { +export class MatDrawerContent extends CdkScrollable implements AfterContentInit { constructor( private _changeDetectorRef: ChangeDetectorRef, - @Inject(forwardRef(() => MatDrawerContainer)) public _container: MatDrawerContainer) { + @Inject(forwardRef(() => MatDrawerContainer)) public _container: MatDrawerContainer, + elementRef: ElementRef, + scrollDispatcher: ScrollDispatcher, + ngZone: NgZone) { + super(elementRef, scrollDispatcher, ngZone); } ngAfterContentInit() { @@ -401,6 +405,7 @@ export class MatDrawer implements AfterContentInit, AfterContentChecked, OnDestr export class MatDrawerContainer implements AfterContentInit, DoCheck, OnDestroy { @ContentChildren(MatDrawer) _drawers: QueryList; @ContentChild(MatDrawerContent) _content: MatDrawerContent; + @ViewChild(MatDrawerContent) _userContent: MatDrawerContent; /** The drawer child with the `start` position. */ get start(): MatDrawer | null { return this._start; } @@ -471,7 +476,9 @@ export class MatDrawerContainer implements AfterContentInit, DoCheck, OnDestroy readonly _contentMarginChanges = new Subject<{left: number|null, right: number|null}>(); /** Reference to the CdkScrollable instance that wraps the scrollable content. */ - @ViewChild(CdkScrollable) scrollable: CdkScrollable; + get scrollable(): CdkScrollable { + return this._userContent || this._content; + } constructor(@Optional() private _dir: Directionality, private _element: ElementRef, diff --git a/src/lib/sidenav/sidenav.md b/src/lib/sidenav/sidenav.md index c8aed710e66e..d2164b3eff68 100644 --- a/src/lib/sidenav/sidenav.md +++ b/src/lib/sidenav/sidenav.md @@ -109,8 +109,8 @@ The `` can render in one of three different ways based on the `mode | Mode | Description | |--------|-----------------------------------------------------------------------------------------| -| `over` | Sidenav floats over the primary content, which is covered by a backdrop | -| `push` | Sidenav pushes the primary content out of its way, also covering it with a backdrop | +| `over` | Sidenav floats over the primary content, which is covered by a backdrop | +| `push` | Sidenav pushes the primary content out of its way, also covering it with a backdrop | | `side` | Sidenav appears side-by-side with the main content, shrinking the main content's width to make space for the sidenav. | If no `mode` is specified, `over` is used by default. @@ -186,10 +186,10 @@ To react to scrolling inside the ``, you can get a hold o `CdkScrollable` instance through the `MatSidenavContainer`. ```ts -class YourComponent { +class YourComponent implements AfterViewInit { @ViewChild(MatSidenavContainer) sidenavContainer: MatSidenavContainer; - constructor() { + ngAfterViewInit() { this.sidenavContainer.scrollable.elementScrolled().subscribe(() => /* react to scrolling */); } } diff --git a/src/lib/sidenav/sidenav.ts b/src/lib/sidenav/sidenav.ts index 79474bd04c32..74f8ef3a94c1 100644 --- a/src/lib/sidenav/sidenav.ts +++ b/src/lib/sidenav/sidenav.ts @@ -17,10 +17,13 @@ import { Input, ViewEncapsulation, QueryList, + ElementRef, + NgZone, } from '@angular/core'; import {MatDrawer, MatDrawerContainer, MatDrawerContent} from './drawer'; import {matDrawerAnimations} from './drawer-animations'; import {coerceBooleanProperty, coerceNumberProperty} from '@angular/cdk/coercion'; +import {ScrollDispatcher} from '@angular/cdk/scrolling'; @Component({ @@ -38,8 +41,11 @@ import {coerceBooleanProperty, coerceNumberProperty} from '@angular/cdk/coercion export class MatSidenavContent extends MatDrawerContent { constructor( changeDetectorRef: ChangeDetectorRef, - @Inject(forwardRef(() => MatSidenavContainer)) container: MatSidenavContainer) { - super(changeDetectorRef, container); + @Inject(forwardRef(() => MatSidenavContainer)) container: MatSidenavContainer, + elementRef: ElementRef, + scrollDispatcher: ScrollDispatcher, + ngZone: NgZone) { + super(changeDetectorRef, container, elementRef, scrollDispatcher, ngZone); } }