Skip to content

Commit 583fe15

Browse files
crisbetojelbourn
authored andcommitted
fix(drawer): show backdrop in "side" mode if hasBackdrop is explicitly set to true (#10251)
Currently we only use `hasBackdrop` to hide the backdrop, however setting it to `true` explicitly also expresses an intent that the consumer might want the backdrop to always be shown. These changes make it so backdrop will also be shown for `side` drawers if `hasBackdrop` is set to `true`.
1 parent 0c64b15 commit 583fe15

File tree

6 files changed

+62
-14
lines changed

6 files changed

+62
-14
lines changed

src/demo-app/sidenav/sidenav-demo.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
<div class="demo-sidenav-area" *ngIf="isLaunched">
66
<mat-toolbar *ngIf="showHeader && !coverHeader">Header</mat-toolbar>
7-
<mat-sidenav-container>
7+
<mat-sidenav-container [hasBackdrop]="hasBackdrop">
88
<mat-sidenav #start (open)="myinput.focus()" [mode]="mode"
99
[fixedInViewport]="fixed" [fixedTopGap]="fixedTop" [fixedBottomGap]="fixedBottom">
1010
Start Side Sidenav
@@ -41,6 +41,7 @@
4141
<h3>Sidenav</h3>
4242
<button mat-button (click)="start.toggle(undefined, 'mouse')">Toggle Start Side Sidenav</button>
4343
<button mat-button (click)="end.toggle(undefined, 'mouse')">Toggle End Side Sidenav</button>
44+
<mat-checkbox [(ngModel)]="hasBackdrop">Has backdrop</mat-checkbox>
4445
<mat-checkbox [(ngModel)]="fixed">Fixed mode</mat-checkbox>
4546
<mat-checkbox [(ngModel)]="coverHeader">Sidenav covers header/footer</mat-checkbox>
4647
</div>

src/demo-app/sidenav/sidenav-demo.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export class SidenavDemo {
2525
showHeader = false;
2626
showFooter = false;
2727
modeIndex = 0;
28+
hasBackdrop: boolean;
2829
get mode() { return ['side', 'over', 'push'][this.modeIndex]; }
2930
get fixedTop() { return this.fixed && this.showHeader && !this.coverHeader ? 64 : 0; }
3031
get fixedBottom() { return this.fixed && this.showFooter && !this.coverHeader ? 64 : 0; }

src/lib/sidenav/drawer.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ $mat-drawer-over-drawer-z-index: 4;
4545
overflow: hidden;
4646
}
4747
}
48+
49+
// When the consumer explicitly enabled the backdrop,
50+
// we have to pull the side drawers above it.
51+
&.mat-drawer-container-explicit-backdrop .mat-drawer-side {
52+
z-index: $mat-drawer-backdrop-z-index;
53+
}
4854
}
4955

5056
.mat-drawer-backdrop {

src/lib/sidenav/drawer.spec.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,35 @@ describe('MatDrawerContainer', () => {
643643
expect(fixture.nativeElement.querySelector('.mat-drawer-backdrop')).toBeFalsy();
644644
}));
645645

646+
it('should be able to explicitly enable the backdrop in `side` mode', fakeAsync(() => {
647+
const fixture = TestBed.createComponent(BasicTestApp);
648+
const root = fixture.nativeElement;
649+
650+
fixture.componentInstance.drawer.mode = 'side';
651+
fixture.detectChanges();
652+
fixture.componentInstance.drawer.open();
653+
fixture.detectChanges();
654+
tick();
655+
fixture.detectChanges();
656+
657+
let backdrop = root.querySelector('.mat-drawer-backdrop.mat-drawer-shown');
658+
659+
expect(backdrop).toBeFalsy();
660+
661+
fixture.componentInstance.hasBackdrop = true;
662+
fixture.detectChanges();
663+
backdrop = root.querySelector('.mat-drawer-backdrop.mat-drawer-shown');
664+
665+
expect(backdrop).toBeTruthy();
666+
expect(fixture.componentInstance.drawer.opened).toBe(true);
667+
668+
backdrop.click();
669+
fixture.detectChanges();
670+
tick();
671+
672+
expect(fixture.componentInstance.drawer.opened).toBe(false);
673+
}));
674+
646675
});
647676

648677

@@ -666,7 +695,7 @@ class DrawerContainerTwoDrawerTestApp {
666695
@Component({
667696
template: `
668697
<mat-drawer-container (backdropClick)="backdropClicked()" [hasBackdrop]="hasBackdrop">
669-
<mat-drawer #drawer position="start"
698+
<mat-drawer #drawer="matDrawer" position="start"
670699
(opened)="open()"
671700
(openedStart)="openStart()"
672701
(closed)="close()"
@@ -683,8 +712,9 @@ class BasicTestApp {
683712
closeCount = 0;
684713
closeStartCount = 0;
685714
backdropClickedCount = 0;
686-
hasBackdrop = true;
715+
hasBackdrop: boolean | null = null;
687716

717+
@ViewChild('drawer') drawer: MatDrawer;
688718
@ViewChild('drawerButton') drawerButton: ElementRef;
689719
@ViewChild('openButton') openButton: ElementRef;
690720
@ViewChild('closeButton') closeButton: ElementRef;

src/lib/sidenav/drawer.ts

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,7 @@ export class MatDrawer implements AfterContentInit, AfterContentChecked, OnDestr
430430
styleUrls: ['drawer.css'],
431431
host: {
432432
'class': 'mat-drawer-container',
433+
'[class.mat-drawer-container-explicit-backdrop]': '_backdropOverride',
433434
},
434435
changeDetection: ChangeDetectionStrategy.OnPush,
435436
encapsulation: ViewEncapsulation.None,
@@ -458,19 +459,23 @@ export class MatDrawerContainer implements AfterContentInit, OnDestroy {
458459
set autosize(value: boolean) { this._autosize = coerceBooleanProperty(value); }
459460
private _autosize: boolean;
460461

461-
/** Whether the drawer container should have a backdrop while one of the sidenavs is open. */
462+
/**
463+
* Whether the drawer container should have a backdrop while one of the sidenavs is open.
464+
* If explicitly set to `true`, the backdrop will be enabled for drawers in the `side`
465+
* mode as well.
466+
*/
462467
@Input()
463468
get hasBackdrop() {
464-
if (this._hasBackdrop == null) {
469+
if (this._backdropOverride == null) {
465470
return !this._start || this._start.mode !== 'side' || !this._end || this._end.mode !== 'side';
466471
}
467472

468-
return this._hasBackdrop;
473+
return this._backdropOverride;
469474
}
470475
set hasBackdrop(value: any) {
471-
this._hasBackdrop = value == null ? null : coerceBooleanProperty(value);
476+
this._backdropOverride = value == null ? null : coerceBooleanProperty(value);
472477
}
473-
private _hasBackdrop: boolean | null;
478+
_backdropOverride: boolean | null;
474479

475480
/** Event emitted when the drawer backdrop is clicked. */
476481
@Output() readonly backdropClick: EventEmitter<void> = new EventEmitter<void>();
@@ -663,8 +668,8 @@ export class MatDrawerContainer implements AfterContentInit, OnDestroy {
663668

664669
/** Whether the container is being pushed to the side by one of the drawers. */
665670
private _isPushed() {
666-
return (this._isDrawerOpen(this._start) && this._start!.mode != 'over') ||
667-
(this._isDrawerOpen(this._end) && this._end!.mode != 'over');
671+
return (this._isDrawerOpen(this._start) && this._start.mode != 'over') ||
672+
(this._isDrawerOpen(this._end) && this._end.mode != 'over');
668673
}
669674

670675
_onBackdropClicked() {
@@ -675,16 +680,20 @@ export class MatDrawerContainer implements AfterContentInit, OnDestroy {
675680
_closeModalDrawer() {
676681
// Close all open drawers where closing is not disabled and the mode is not `side`.
677682
[this._start, this._end]
678-
.filter(drawer => drawer && !drawer.disableClose && drawer.mode !== 'side')
683+
.filter(drawer => drawer && !drawer.disableClose && this._canHaveBackdrop(drawer))
679684
.forEach(drawer => drawer!.close());
680685
}
681686

682687
_isShowingBackdrop(): boolean {
683-
return (this._isDrawerOpen(this._start) && this._start!.mode != 'side')
684-
|| (this._isDrawerOpen(this._end) && this._end!.mode != 'side');
688+
return (this._isDrawerOpen(this._start) && this._canHaveBackdrop(this._start)) ||
689+
(this._isDrawerOpen(this._end) && this._canHaveBackdrop(this._end));
690+
}
691+
692+
private _canHaveBackdrop(drawer: MatDrawer): boolean {
693+
return drawer.mode !== 'side' || !!this._backdropOverride;
685694
}
686695

687-
private _isDrawerOpen(drawer: MatDrawer | null): boolean {
696+
private _isDrawerOpen(drawer: MatDrawer | null): drawer is MatDrawer {
688697
return drawer != null && drawer.opened;
689698
}
690699

src/lib/sidenav/sidenav.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ export class MatSidenav extends MatDrawer {
106106
styleUrls: ['drawer.css'],
107107
host: {
108108
'class': 'mat-drawer-container mat-sidenav-container',
109+
'[class.mat-drawer-container-explicit-backdrop]': '_backdropOverride',
109110
},
110111
changeDetection: ChangeDetectionStrategy.OnPush,
111112
encapsulation: ViewEncapsulation.None,

0 commit comments

Comments
 (0)