@@ -17,6 +17,7 @@ import {
17
17
} from '@angular/cdk/portal' ;
18
18
import { DOCUMENT } from '@angular/common' ;
19
19
import {
20
+ AfterViewInit ,
20
21
ChangeDetectionStrategy ,
21
22
ChangeDetectorRef ,
22
23
Component ,
@@ -72,7 +73,7 @@ export function throwDialogContentAlreadyAttachedError() {
72
73
'(@dialog.done)' : '_animationDone.next($event)' ,
73
74
} ,
74
75
} )
75
- export class CdkDialogContainer extends BasePortalOutlet implements OnDestroy {
76
+ export class CdkDialogContainer extends BasePortalOutlet implements OnDestroy , AfterViewInit {
76
77
private readonly _document : Document ;
77
78
78
79
/** State of the dialog animation. */
@@ -150,6 +151,16 @@ export class CdkDialogContainer extends BasePortalOutlet implements OnDestroy {
150
151
} ) ;
151
152
}
152
153
154
+ /** If the dialog view completes initialization, the open animation starts. */
155
+ ngAfterViewInit ( ) {
156
+ // Save the previously focused element. This element will be re-focused
157
+ // when the dialog closes.
158
+ this . _savePreviouslyFocusedElement ( ) ;
159
+ // Move focus onto the dialog immediately in order to prevent the user
160
+ // from accidentally opening multiple dialogs at the same time.
161
+ this . _focusDialogContainer ( ) ;
162
+ }
163
+
153
164
/** Destroy focus trap to place focus back to the element focused before the dialog opened. */
154
165
ngOnDestroy ( ) {
155
166
this . _focusTrap . destroy ( ) ;
@@ -165,7 +176,6 @@ export class CdkDialogContainer extends BasePortalOutlet implements OnDestroy {
165
176
throwDialogContentAlreadyAttachedError ( ) ;
166
177
}
167
178
168
- this . _savePreviouslyFocusedElement ( ) ;
169
179
return this . _portalHost . attachComponentPortal ( portal ) ;
170
180
}
171
181
@@ -178,7 +188,6 @@ export class CdkDialogContainer extends BasePortalOutlet implements OnDestroy {
178
188
throwDialogContentAlreadyAttachedError ( ) ;
179
189
}
180
190
181
- this . _savePreviouslyFocusedElement ( ) ;
182
191
return this . _portalHost . attachTemplatePortal ( portal ) ;
183
192
}
184
193
@@ -193,7 +202,6 @@ export class CdkDialogContainer extends BasePortalOutlet implements OnDestroy {
193
202
throwDialogContentAlreadyAttachedError ( ) ;
194
203
}
195
204
196
- this . _savePreviouslyFocusedElement ( ) ;
197
205
return this . _portalHost . attachDomPortal ( portal ) ;
198
206
}
199
207
@@ -222,11 +230,14 @@ export class CdkDialogContainer extends BasePortalOutlet implements OnDestroy {
222
230
private _savePreviouslyFocusedElement ( ) {
223
231
if ( this . _document ) {
224
232
this . _elementFocusedBeforeDialogWasOpened = this . _document . activeElement as HTMLElement ;
233
+ }
234
+ }
225
235
226
- // Move focus onto the dialog immediately in order to prevent the user from accidentally
227
- // opening multiple dialogs at the same time. Needs to be async, because the element
228
- // may not be focusable immediately.
229
- Promise . resolve ( ) . then ( ( ) => this . _elementRef . nativeElement . focus ( ) ) ;
236
+ /** Focuses the dialog container. */
237
+ private _focusDialogContainer ( ) {
238
+ // Note that there is no focus method when rendering on the server.
239
+ if ( this . _elementRef . nativeElement . focus ) {
240
+ this . _elementRef . nativeElement . focus ( ) ;
230
241
}
231
242
}
232
243
0 commit comments