Skip to content

Commit 230bdb5

Browse files
committed
fix(cdk/dialog): resolve hydration error in focus trap
Disables focus traps on the server, because they insert DOM nodes that can throw off hydration.
1 parent 10fbe36 commit 230bdb5

File tree

1 file changed

+12
-8
lines changed

1 file changed

+12
-8
lines changed

src/cdk/dialog/dialog-container.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
InteractivityChecker,
1515
} from '@angular/cdk/a11y';
1616
import {OverlayRef} from '@angular/cdk/overlay';
17-
import {_getFocusedElementPierceShadowDom} from '@angular/cdk/platform';
17+
import {Platform, _getFocusedElementPierceShadowDom} from '@angular/cdk/platform';
1818
import {
1919
BasePortalOutlet,
2020
CdkPortalOutlet,
@@ -35,6 +35,7 @@ import {
3535
Optional,
3636
ViewChild,
3737
ViewEncapsulation,
38+
inject,
3839
} from '@angular/core';
3940
import {DialogConfig} from './dialog-config';
4041

@@ -71,13 +72,14 @@ export class CdkDialogContainer<C extends DialogConfig = DialogConfig>
7172
extends BasePortalOutlet
7273
implements OnDestroy
7374
{
75+
private _platform = inject(Platform);
7476
protected _document: Document;
7577

7678
/** The portal outlet inside of this container into which the dialog content will be loaded. */
7779
@ViewChild(CdkPortalOutlet, {static: true}) _portalOutlet: CdkPortalOutlet;
7880

7981
/** The class that traps and manages focus within the dialog. */
80-
private _focusTrap: FocusTrap;
82+
private _focusTrap: FocusTrap | null = null;
8183

8284
/** Element that was focused before the dialog was opened. Save this to restore upon close. */
8385
private _elementFocusedBeforeDialogWasOpened: HTMLElement | null = null;
@@ -247,7 +249,7 @@ export class CdkDialogContainer<C extends DialogConfig = DialogConfig>
247249
break;
248250
case true:
249251
case 'first-tabbable':
250-
this._focusTrap.focusInitialElementWhenReady().then(focusedSuccessfully => {
252+
this._focusTrap?.focusInitialElementWhenReady().then(focusedSuccessfully => {
251253
// If we weren't able to find a focusable element in the dialog, then focus the dialog
252254
// container instead.
253255
if (!focusedSuccessfully) {
@@ -327,12 +329,14 @@ export class CdkDialogContainer<C extends DialogConfig = DialogConfig>
327329

328330
/** Sets up the focus trap. */
329331
private _initializeFocusTrap() {
330-
this._focusTrap = this._focusTrapFactory.create(this._elementRef.nativeElement);
332+
if (this._platform.isBrowser) {
333+
this._focusTrap = this._focusTrapFactory.create(this._elementRef.nativeElement);
331334

332-
// Save the previously focused element. This element will be re-focused
333-
// when the dialog closes.
334-
if (this._document) {
335-
this._elementFocusedBeforeDialogWasOpened = _getFocusedElementPierceShadowDom();
335+
// Save the previously focused element. This element will be re-focused
336+
// when the dialog closes.
337+
if (this._document) {
338+
this._elementFocusedBeforeDialogWasOpened = _getFocusedElementPierceShadowDom();
339+
}
336340
}
337341
}
338342

0 commit comments

Comments
 (0)