@@ -11,12 +11,12 @@ import {
11
11
import { DocumentationItems } from '../../shared/documentation-items/documentation-items' ;
12
12
import { MatIconModule } from '@angular/material/icon' ;
13
13
import { MatSidenav , MatSidenavModule } from '@angular/material/sidenav' ;
14
- import { ActivatedRoute , Params , Router , RouterModule , Routes } from '@angular/router' ;
14
+ import { ActivatedRoute , NavigationEnd , Params , Router , RouterModule , Routes } from '@angular/router' ;
15
15
import { CommonModule } from '@angular/common' ;
16
16
import { ComponentHeaderModule } from '../component-page-header/component-page-header' ;
17
17
import { FooterModule } from '../../shared/footer/footer' ;
18
18
import { combineLatest , Observable , Subject } from 'rxjs' ;
19
- import { map , startWith , switchMap , takeUntil } from 'rxjs/operators' ;
19
+ import { filter , map , startWith , switchMap , takeUntil } from 'rxjs/operators' ;
20
20
import { animate , state , style , transition , trigger } from '@angular/animations' ;
21
21
import { CdkAccordionModule } from '@angular/cdk/accordion' ;
22
22
import { BreakpointObserver } from '@angular/cdk/layout' ;
@@ -29,17 +29,27 @@ import {
29
29
ComponentApi ,
30
30
ComponentExamples ,
31
31
ComponentOverview ,
32
- ComponentViewer , ComponentViewerModule
32
+ ComponentViewer ,
33
+ ComponentViewerModule
33
34
} from '../component-viewer/component-viewer' ;
34
35
import { DocViewerModule } from '../../shared/doc-viewer/doc-viewer-module' ;
35
36
import { FormsModule } from '@angular/forms' ;
36
37
import { HttpClientModule } from '@angular/common/http' ;
37
38
import { StackBlitzButtonModule } from '../../shared/stack-blitz' ;
38
39
import { SvgViewerModule } from '../../shared/svg-viewer/svg-viewer' ;
39
40
import { ExampleModule } from '@angular/components-examples' ;
41
+ import { MatDrawerToggleResult } from '@angular/material/sidenav/drawer' ;
40
42
import { MatListModule } from '@angular/material/list' ;
41
43
42
- const SMALL_WIDTH_BREAKPOINT = 720 ;
44
+ // These constants are used by the ComponentSidenav for orchestrating the MatSidenav in a responsive
45
+ // way. This includes hiding the sidenav, defaulting it to open, changing the mode from over to
46
+ // side, determining the size of the top gap, and whether the sidenav is fixed in the viewport.
47
+ // The values were determined through the combination of Material Design breakpoints and careful
48
+ // testing of the application across a range of common device widths (360px+).
49
+ // These breakpoint values need to stay in sync with the related Sass variables in
50
+ // src/styles/_constants.scss.
51
+ const EXTRA_SMALL_WIDTH_BREAKPOINT = 720 ;
52
+ const SMALL_WIDTH_BREAKPOINT = 959 ;
43
53
44
54
@Component ( {
45
55
selector : 'app-component-sidenav' ,
@@ -50,21 +60,39 @@ const SMALL_WIDTH_BREAKPOINT = 720;
50
60
export class ComponentSidenav implements OnInit {
51
61
@ViewChild ( MatSidenav ) sidenav : MatSidenav ;
52
62
params : Observable < Params > ;
63
+ isExtraScreenSmall : Observable < boolean > ;
53
64
isScreenSmall : Observable < boolean > ;
54
65
55
66
constructor ( public docItems : DocumentationItems ,
56
67
private _route : ActivatedRoute ,
68
+ private _router : Router ,
57
69
zone : NgZone ,
58
70
breakpoints : BreakpointObserver ) {
71
+ this . isExtraScreenSmall =
72
+ breakpoints . observe ( `(max-width: ${ EXTRA_SMALL_WIDTH_BREAKPOINT } px)` )
73
+ . pipe ( map ( breakpoint => breakpoint . matches ) ) ;
59
74
this . isScreenSmall = breakpoints . observe ( `(max-width: ${ SMALL_WIDTH_BREAKPOINT } px)` )
60
- . pipe ( map ( breakpoint => breakpoint . matches ) ) ;
75
+ . pipe ( map ( breakpoint => breakpoint . matches ) ) ;
61
76
}
62
77
63
78
ngOnInit ( ) {
64
79
// Combine params from all of the path into a single object.
65
80
this . params = combineLatest (
66
- this . _route . pathFromRoot . map ( route => route . params ) ,
67
- Object . assign ) ;
81
+ this . _route . pathFromRoot . map ( route => route . params ) , Object . assign ) ;
82
+
83
+ this . _router . events . pipe (
84
+ filter ( ( event ) => event instanceof NavigationEnd ) ,
85
+ map ( ( event ) => this . isScreenSmall )
86
+ ) . subscribe ( ( shouldCloseSideNav ) => {
87
+ if ( shouldCloseSideNav && this . sidenav ) {
88
+ this . sidenav . close ( ) ;
89
+ }
90
+ }
91
+ ) ;
92
+ }
93
+
94
+ toggleSidenav ( sidenav : MatSidenav ) : Promise < MatDrawerToggleResult > {
95
+ return sidenav . toggle ( ) ;
68
96
}
69
97
}
70
98
@@ -85,8 +113,7 @@ export class ComponentNav implements OnInit, OnDestroy {
85
113
currentItemId : string ;
86
114
private _onDestroy = new Subject < void > ( ) ;
87
115
88
- constructor ( public docItems : DocumentationItems ,
89
- private _router : Router ) { }
116
+ constructor ( public docItems : DocumentationItems , private _router : Router ) { }
90
117
91
118
ngOnInit ( ) {
92
119
this . _router . events . pipe (
0 commit comments