Skip to content

Commit 60d45b9

Browse files
committed
refactor(sidenav): expose api to update content margins
Exposes an API so that consumers can trigger an update of the content margins manually. This allows the sidenav to handle some cases that might not have accounted for. Fixes #15777.
1 parent f6edba3 commit 60d45b9

File tree

2 files changed

+57
-57
lines changed

2 files changed

+57
-57
lines changed

src/lib/sidenav/drawer.ts

Lines changed: 56 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ export class MatDrawerContainer implements AfterContentInit, DoCheck, OnDestroy
521521
if (_dir) {
522522
_dir.change.pipe(takeUntil(this._destroyed)).subscribe(() => {
523523
this._validateDrawers();
524-
this._updateContentMargins();
524+
this.updateContentMargins();
525525
});
526526
}
527527

@@ -530,7 +530,7 @@ export class MatDrawerContainer implements AfterContentInit, DoCheck, OnDestroy
530530
if (viewportRuler) {
531531
viewportRuler.change()
532532
.pipe(takeUntil(this._destroyed))
533-
.subscribe(() => this._updateContentMargins());
533+
.subscribe(() => this.updateContentMargins());
534534
}
535535

536536
this._autosize = defaultAutosize;
@@ -549,7 +549,7 @@ export class MatDrawerContainer implements AfterContentInit, DoCheck, OnDestroy
549549
if (!this._drawers.length ||
550550
this._isDrawerOpen(this._start) ||
551551
this._isDrawerOpen(this._end)) {
552-
this._updateContentMargins();
552+
this.updateContentMargins();
553553
}
554554

555555
this._changeDetectorRef.markForCheck();
@@ -558,7 +558,7 @@ export class MatDrawerContainer implements AfterContentInit, DoCheck, OnDestroy
558558
this._doCheckSubject.pipe(
559559
debounceTime(10), // Arbitrary debounce time, less than a frame at 60fps
560560
takeUntil(this._destroyed)
561-
).subscribe(() => this._updateContentMargins());
561+
).subscribe(() => this.updateContentMargins());
562562
}
563563

564564
ngOnDestroy() {
@@ -578,6 +578,56 @@ export class MatDrawerContainer implements AfterContentInit, DoCheck, OnDestroy
578578
this._drawers.forEach(drawer => drawer.close());
579579
}
580580

581+
/**
582+
* Recalculates and updates the inline styles for the content. Note that this should be used
583+
* sparingly, because it causes a reflow.
584+
*/
585+
updateContentMargins() {
586+
// 1. For drawers in `over` mode, they don't affect the content.
587+
// 2. For drawers in `side` mode they should shrink the content. We do this by adding to the
588+
// left margin (for left drawer) or right margin (for right the drawer).
589+
// 3. For drawers in `push` mode the should shift the content without resizing it. We do this by
590+
// adding to the left or right margin and simultaneously subtracting the same amount of
591+
// margin from the other side.
592+
let left = 0;
593+
let right = 0;
594+
595+
if (this._left && this._left.opened) {
596+
if (this._left.mode == 'side') {
597+
left += this._left._width;
598+
} else if (this._left.mode == 'push') {
599+
const width = this._left._width;
600+
left += width;
601+
right -= width;
602+
}
603+
}
604+
605+
if (this._right && this._right.opened) {
606+
if (this._right.mode == 'side') {
607+
right += this._right._width;
608+
} else if (this._right.mode == 'push') {
609+
const width = this._right._width;
610+
right += width;
611+
left -= width;
612+
}
613+
}
614+
615+
// If either `right` or `left` is zero, don't set a style to the element. This
616+
// allows users to specify a custom size via CSS class in SSR scenarios where the
617+
// measured widths will always be zero. Note that we reset to `null` here, rather
618+
// than below, in order to ensure that the types in the `if` below are consistent.
619+
left = left || null!;
620+
right = right || null!;
621+
622+
if (left !== this._contentMargins.left || right !== this._contentMargins.right) {
623+
this._contentMargins = {left, right};
624+
625+
// Pull back into the NgZone since in some cases we could be outside. We need to be careful
626+
// to do it only when something changed, otherwise we can end up hitting the zone too often.
627+
this._ngZone.run(() => this._contentMarginChanges.next(this._contentMargins));
628+
}
629+
}
630+
581631
ngDoCheck() {
582632
// If users opted into autosizing, do a check every change detection cycle.
583633
if (this._autosize && this._isPushed()) {
@@ -603,7 +653,7 @@ export class MatDrawerContainer implements AfterContentInit, DoCheck, OnDestroy
603653
this._element.nativeElement.classList.add('mat-drawer-transition');
604654
}
605655

606-
this._updateContentMargins();
656+
this.updateContentMargins();
607657
this._changeDetectorRef.markForCheck();
608658
});
609659

@@ -635,7 +685,7 @@ export class MatDrawerContainer implements AfterContentInit, DoCheck, OnDestroy
635685
if (drawer) {
636686
drawer._modeChanged.pipe(takeUntil(merge(this._drawers.changes, this._destroyed)))
637687
.subscribe(() => {
638-
this._updateContentMargins();
688+
this.updateContentMargins();
639689
this._changeDetectorRef.markForCheck();
640690
});
641691
}
@@ -712,55 +762,4 @@ export class MatDrawerContainer implements AfterContentInit, DoCheck, OnDestroy
712762
return drawer != null && drawer.opened;
713763
}
714764

715-
/**
716-
* Recalculates and updates the inline styles for the content. Note that this should be used
717-
* sparingly, because it causes a reflow.
718-
*/
719-
private _updateContentMargins() {
720-
// 1. For drawers in `over` mode, they don't affect the content.
721-
// 2. For drawers in `side` mode they should shrink the content. We do this by adding to the
722-
// left margin (for left drawer) or right margin (for right the drawer).
723-
// 3. For drawers in `push` mode the should shift the content without resizing it. We do this by
724-
// adding to the left or right margin and simultaneously subtracting the same amount of
725-
// margin from the other side.
726-
727-
let left = 0;
728-
let right = 0;
729-
730-
if (this._left && this._left.opened) {
731-
if (this._left.mode == 'side') {
732-
left += this._left._width;
733-
} else if (this._left.mode == 'push') {
734-
let width = this._left._width;
735-
left += width;
736-
right -= width;
737-
}
738-
}
739-
740-
if (this._right && this._right.opened) {
741-
if (this._right.mode == 'side') {
742-
right += this._right._width;
743-
} else if (this._right.mode == 'push') {
744-
let width = this._right._width;
745-
right += width;
746-
left -= width;
747-
}
748-
}
749-
750-
// If either `right` or `left` is zero, don't set a style to the element. This
751-
// allows users to specify a custom size via CSS class in SSR scenarios where the
752-
// measured widths will always be zero. Note that we reset to `null` here, rather
753-
// than below, in order to ensure that the types in the `if` below are consistent.
754-
left = left || null!;
755-
right = right || null!;
756-
757-
if (left !== this._contentMargins.left || right !== this._contentMargins.right) {
758-
this._contentMargins = {left, right};
759-
760-
// Pull back into the NgZone since in some cases we could be outside. We need to be careful
761-
// to do it only when something changed, otherwise we can end up hitting the zone too often.
762-
this._ngZone.run(() => this._contentMarginChanges.next(this._contentMargins));
763-
}
764-
765-
}
766765
}

tools/public_api_guard/lib/sidenav.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export declare class MatDrawerContainer implements AfterContentInit, DoCheck, On
6262
ngDoCheck(): void;
6363
ngOnDestroy(): void;
6464
open(): void;
65+
updateContentMargins(): void;
6566
}
6667

6768
export declare class MatDrawerContent extends CdkScrollable implements AfterContentInit {

0 commit comments

Comments
 (0)