@@ -101,7 +101,6 @@ export function MAT_DRAWER_DEFAULT_AUTOSIZE_FACTORY(): boolean {
101
101
'class' : 'mat-drawer-content' ,
102
102
'[style.margin-left.px]' : '_container._contentMargins.left' ,
103
103
'[style.margin-right.px]' : '_container._contentMargins.right' ,
104
- 'ngSkipHydration' : '' ,
105
104
} ,
106
105
changeDetection : ChangeDetectionStrategy . OnPush ,
107
106
encapsulation : ViewEncapsulation . None ,
@@ -151,13 +150,12 @@ export class MatDrawerContent extends CdkScrollable implements AfterContentInit
151
150
'[@transform]' : '_animationState' ,
152
151
'(@transform.start)' : '_animationStarted.next($event)' ,
153
152
'(@transform.done)' : '_animationEnd.next($event)' ,
154
- 'ngSkipHydration' : '' ,
155
153
} ,
156
154
changeDetection : ChangeDetectionStrategy . OnPush ,
157
155
encapsulation : ViewEncapsulation . None ,
158
156
} )
159
157
export class MatDrawer implements AfterViewInit , AfterContentChecked , OnDestroy {
160
- private _focusTrap : FocusTrap ;
158
+ private _focusTrap : FocusTrap | null = null ;
161
159
private _elementFocusedBeforeDrawerWasOpened : HTMLElement | null = null ;
162
160
163
161
/** Whether the drawer is initialized. Used for disabling the initial animation. */
@@ -477,14 +475,19 @@ export class MatDrawer implements AfterViewInit, AfterContentChecked, OnDestroy
477
475
478
476
ngAfterViewInit ( ) {
479
477
this . _isAttached = true ;
480
- this . _focusTrap = this . _focusTrapFactory . create ( this . _elementRef . nativeElement ) ;
481
- this . _updateFocusTrapState ( ) ;
482
478
483
479
// Only update the DOM position when the sidenav is positioned at
484
480
// the end since we project the sidenav before the content by default.
485
481
if ( this . _position === 'end' ) {
486
482
this . _updatePositionInParent ( 'end' ) ;
487
483
}
484
+
485
+ // Needs to happen after the position is updated
486
+ // so the focus trap anchors are in the right place.
487
+ if ( this . _platform . isBrowser ) {
488
+ this . _focusTrap = this . _focusTrapFactory . create ( this . _elementRef . nativeElement ) ;
489
+ this . _updateFocusTrapState ( ) ;
490
+ }
488
491
}
489
492
490
493
ngAfterContentChecked ( ) {
@@ -498,10 +501,7 @@ export class MatDrawer implements AfterViewInit, AfterContentChecked, OnDestroy
498
501
}
499
502
500
503
ngOnDestroy ( ) {
501
- if ( this . _focusTrap ) {
502
- this . _focusTrap . destroy ( ) ;
503
- }
504
-
504
+ this . _focusTrap ?. destroy ( ) ;
505
505
this . _anchor ?. remove ( ) ;
506
506
this . _anchor = null ;
507
507
this . _animationStarted . complete ( ) ;
@@ -607,7 +607,12 @@ export class MatDrawer implements AfterViewInit, AfterContentChecked, OnDestroy
607
607
* matches the tab order. We also need to be able to move it back to `start` if the sidenav
608
608
* started off as `end` and was changed to `start`.
609
609
*/
610
- private _updatePositionInParent ( newPosition : 'start' | 'end' ) {
610
+ private _updatePositionInParent ( newPosition : 'start' | 'end' ) : void {
611
+ // Don't move the DOM node around on the server, because it can throw off hydration.
612
+ if ( ! this . _platform . isBrowser ) {
613
+ return ;
614
+ }
615
+
611
616
const element = this . _elementRef . nativeElement ;
612
617
const parent = element . parentNode ! ;
613
618
@@ -638,7 +643,6 @@ export class MatDrawer implements AfterViewInit, AfterContentChecked, OnDestroy
638
643
host : {
639
644
'class' : 'mat-drawer-container' ,
640
645
'[class.mat-drawer-container-explicit-backdrop]' : '_backdropOverride' ,
641
- 'ngSkipHydration' : '' ,
642
646
} ,
643
647
changeDetection : ChangeDetectionStrategy . OnPush ,
644
648
encapsulation : ViewEncapsulation . None ,
0 commit comments