Skip to content
This repository was archived by the owner on Dec 18, 2024. It is now read-only.

Commit 347c538

Browse files
committed
fix(component-sidenav): responsive issues w/ screens 720px to 960px width
- close over sidenav on nav item selection Fixes #686. Closes #687.
1 parent c97ec4e commit 347c538

File tree

9 files changed

+68
-19
lines changed

9 files changed

+68
-19
lines changed

src/app/pages/component-page-header/component-page-header.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ h1 {
2323
margin: 8px;
2424
min-width: 64px;
2525
display: none;
26+
2627
@media (max-width: $small-breakpoint-width) {
2728
display: flex;
2829
align-items: center;

src/app/pages/component-sidenav/_component-sidenav-theme.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
border-top: solid 1px rgba(mat-color($foreground, secondary-text), .1)
3232
}
3333

34-
a {
34+
button {
3535
color: mat-color($foreground, secondary-text);
3636

3737
&.docs-component-viewer-sidenav-item-selected,

src/app/pages/component-sidenav/component-nav.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010
</button>
1111
<mat-nav-list dense [@bodyExpansion]="panel.expanded ? 'expanded' : 'collapsed'"
1212
id="panel-{{category.id}}" [attr.aria-label]="category.name">
13-
<a mat-list-item *ngFor="let component of category.items"
14-
[routerLink]="'/' + (params | async)?.section+ '/' + component.id"
15-
routerLinkActive="docs-component-viewer-sidenav-item-selected"
16-
[attr.aria-current]="currentItemId === component.id ? 'page': 'false'">
13+
<button mat-list-item *ngFor="let component of category.items"
14+
[ngClass]="{'docs-component-viewer-sidenav-item-selected': currentItemId === component.id}"
15+
[attr.aria-current]="currentItemId === component.id ? 'page': 'false'"
16+
(click)="selectNavItem(component.id)">
1717
{{component.name}}
18-
</a>
18+
</button>
1919
</mat-nav-list>
2020
<hr *ngIf="!last" />
2121
</div>

src/app/pages/component-sidenav/component-sidenav.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
[opened]="(isScreenSmall | async) === false"
66
[mode]="(isScreenSmall | async) ? 'over' : 'side'"
77
[fixedInViewport]="(isScreenSmall | async)"
8-
[fixedTopGap]="92">
8+
[fixedTopGap]="(isExtraScreenSmall | async) ? 92 : 56">
99
<app-component-nav [params]="params"></app-component-nav>
1010
</mat-sidenav>
1111
<div class="docs-component-sidenav-content">
12-
<component-page-header (toggleSidenav)="sidenav.toggle()"></component-page-header>
12+
<component-page-header (toggleSidenav)="toggleSidenav(sidenav)"></component-page-header>
1313
<div class="docs-component-sidenav-inner-content">
1414
<main class="docs-component-sidenav-body-content">
1515
<!-- If on large screen, menu resides to left of content -->
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import {Injectable} from '@angular/core';
2+
import {MatSidenav} from '@angular/material/sidenav';
3+
4+
@Injectable({providedIn : 'root'})
5+
export class ComponentSidenavService {
6+
private _sidenav: MatSidenav;
7+
8+
constructor() {}
9+
10+
get sidenav(): MatSidenav { return this._sidenav; }
11+
12+
set sidenav(value: MatSidenav) { this._sidenav = value; }
13+
}

src/app/pages/component-sidenav/component-sidenav.ts

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,12 @@ import {HttpClientModule} from '@angular/common/http';
3737
import {StackBlitzButtonModule} from '../../shared/stack-blitz';
3838
import {SvgViewerModule} from '../../shared/svg-viewer/svg-viewer';
3939
import {ExampleModule} from '@angular/components-examples';
40+
import {ComponentSidenavService} from './component-sidenav.service';
41+
import {MatDrawerToggleResult} from '@angular/material/sidenav/drawer';
4042
import {MatListModule} from '@angular/material/list';
4143

42-
const SMALL_WIDTH_BREAKPOINT = 720;
44+
const EXTRA_SMALL_WIDTH_BREAKPOINT = 720;
45+
const SMALL_WIDTH_BREAKPOINT = 959;
4346

4447
@Component({
4548
selector: 'app-component-sidenav',
@@ -50,21 +53,30 @@ const SMALL_WIDTH_BREAKPOINT = 720;
5053
export class ComponentSidenav implements OnInit {
5154
@ViewChild(MatSidenav) sidenav: MatSidenav;
5255
params: Observable<Params>;
56+
isExtraScreenSmall: Observable<boolean>;
5357
isScreenSmall: Observable<boolean>;
5458

5559
constructor(public docItems: DocumentationItems,
5660
private _route: ActivatedRoute,
61+
private componentSidenavService: ComponentSidenavService,
5762
zone: NgZone,
5863
breakpoints: BreakpointObserver) {
64+
this.isExtraScreenSmall =
65+
breakpoints.observe(`(max-width: ${EXTRA_SMALL_WIDTH_BREAKPOINT}px)`)
66+
.pipe(map(breakpoint => breakpoint.matches));
5967
this.isScreenSmall = breakpoints.observe(`(max-width: ${SMALL_WIDTH_BREAKPOINT}px)`)
60-
.pipe(map(breakpoint => breakpoint.matches));
68+
.pipe(map(breakpoint => breakpoint.matches));
6169
}
6270

6371
ngOnInit() {
6472
// Combine params from all of the path into a single object.
6573
this.params = combineLatest(
66-
this._route.pathFromRoot.map(route => route.params),
67-
Object.assign);
74+
this._route.pathFromRoot.map(route => route.params), Object.assign);
75+
}
76+
77+
toggleSidenav(sidenav: MatSidenav): Promise<MatDrawerToggleResult> {
78+
this.componentSidenavService.sidenav = sidenav;
79+
return this.componentSidenavService.sidenav.toggle();
6880
}
6981
}
7082

@@ -85,8 +97,8 @@ export class ComponentNav implements OnInit, OnDestroy {
8597
currentItemId: string;
8698
private _onDestroy = new Subject<void>();
8799

88-
constructor(public docItems: DocumentationItems,
89-
private _router: Router) { }
100+
constructor(public docItems: DocumentationItems, private _router: Router,
101+
private componentSidenavService: ComponentSidenavService) {}
90102

91103
ngOnInit() {
92104
this._router.events.pipe(
@@ -135,6 +147,28 @@ export class ComponentNav implements OnInit, OnDestroy {
135147
getExpanded(category: string): boolean {
136148
return this.expansions[category] === undefined ? true : this.expansions[category];
137149
}
150+
151+
/**
152+
* If the component sidenav can be resolved, then close it, and wait for it to be closed,
153+
* before navigating to avoid jank.
154+
* @param path component.id sub-path to use for navigation
155+
*/
156+
selectNavItem(path: string): void {
157+
if (this.componentSidenavService.sidenav) {
158+
this.componentSidenavService.sidenav.close().then(() => this.openNavItem(path));
159+
} else {
160+
this.openNavItem(path);
161+
}
162+
}
163+
164+
/**
165+
* @param path component.id sub-path to use for navigation
166+
*/
167+
openNavItem(path: string) {
168+
this.params.subscribe((params: Params) => {
169+
this._router.navigateByUrl(`/${params.section}/${path}`);
170+
});
171+
}
138172
}
139173

140174
const routes: Routes = [ {

src/app/pages/guide-list/guide-list.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
flex-grow: 1;
1111
margin: $content-padding-side;
1212

13-
@media (max-width: $small-breakpoint-width) {
13+
@media (max-width: $extra-small-breakpoint-width) {
1414
margin: 0;
1515
}
1616
}

src/app/pages/guide-viewer/guide-viewer.scss

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ $guide-content-margin-side-xs: 15px;
3030
max-width: 940px;
3131
margin: 0 auto;
3232

33-
@media (max-width: $small-breakpoint-width) {
33+
@media (max-width: $extra-small-breakpoint-width) {
3434
flex-direction: column;
3535
}
3636
}
@@ -39,7 +39,7 @@ $guide-content-margin-side-xs: 15px;
3939
flex-grow: 1;
4040
width: 80%;
4141

42-
@media (max-width: $small-breakpoint-width) {
42+
@media (max-width: $extra-small-breakpoint-width) {
4343
width: 100%;
4444
}
4545
}
@@ -50,7 +50,7 @@ table-of-contents {
5050

5151
// Reposition on top of content on small screens and remove
5252
// sticky positioning
53-
@media (max-width: $small-breakpoint-width) {
53+
@media (max-width: $extra-small-breakpoint-width) {
5454
order: -1;
5555
position: inherit;
5656
width: auto;

src/styles/_constants.scss

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
@import '../../node_modules/@angular/material/theming';
22

3-
$small-breakpoint-width: 720px;
3+
$extra-small-breakpoint-width: 720px;
4+
$small-breakpoint-width: 959px;
45

56
/* For desktop, the content should be aligned with the page title. */
67
$content-padding-side: 70px;

0 commit comments

Comments
 (0)