@@ -31,11 +31,13 @@ import {
31
31
ElementRef ,
32
32
EmbeddedViewRef ,
33
33
Inject ,
34
+ Injector ,
34
35
NgZone ,
35
36
OnDestroy ,
36
37
Optional ,
37
38
ViewChild ,
38
39
ViewEncapsulation ,
40
+ afterNextRender ,
39
41
inject ,
40
42
} from '@angular/core' ;
41
43
import { DialogConfig } from './dialog-config' ;
@@ -102,6 +104,10 @@ export class CdkDialogContainer<C extends DialogConfig = DialogConfig>
102
104
103
105
protected readonly _changeDetectorRef = inject ( ChangeDetectorRef ) ;
104
106
107
+ private _injector = inject ( Injector ) ;
108
+
109
+ private _isDestroyed = false ;
110
+
105
111
constructor (
106
112
protected _elementRef : ElementRef ,
107
113
protected _focusTrapFactory : FocusTrapFactory ,
@@ -150,6 +156,7 @@ export class CdkDialogContainer<C extends DialogConfig = DialogConfig>
150
156
}
151
157
152
158
ngOnDestroy ( ) {
159
+ this . _isDestroyed = true ;
153
160
this . _restoreFocus ( ) ;
154
161
}
155
162
@@ -246,23 +253,33 @@ export class CdkDialogContainer<C extends DialogConfig = DialogConfig>
246
253
* cannot be moved then focus will go to the dialog container.
247
254
*/
248
255
protected _trapFocus ( ) {
256
+ if ( this . _isDestroyed ) {
257
+ return ;
258
+ }
259
+
249
260
const element = this . _elementRef . nativeElement ;
250
261
// If were to attempt to focus immediately, then the content of the dialog would not yet be
251
262
// ready in instances where change detection has to run first. To deal with this, we simply
252
263
// wait for the microtask queue to be empty when setting focus when autoFocus isn't set to
253
264
// dialog. If the element inside the dialog can't be focused, then the container is focused
254
265
// so the user can't tab into other elements behind it.
255
- switch ( this . _config . autoFocus ) {
266
+ const autoFocus = this . _config . autoFocus ;
267
+ switch ( autoFocus ) {
256
268
case false :
257
269
case 'dialog' :
258
270
// Ensure that focus is on the dialog container. It's possible that a different
259
271
// component tried to move focus while the open animation was running. See:
260
272
// https://github.com/angular/components/issues/16215. Note that we only want to do this
261
273
// if the focus isn't inside the dialog already, because it's possible that the consumer
262
274
// turned off `autoFocus` in order to move focus themselves.
263
- if ( ! this . _containsFocus ( ) ) {
264
- element . focus ( ) ;
265
- }
275
+ afterNextRender (
276
+ ( ) => {
277
+ if ( ! this . _containsFocus ( ) ) {
278
+ element . focus ( ) ;
279
+ }
280
+ } ,
281
+ { injector : this . _injector } ,
282
+ ) ;
266
283
break ;
267
284
case true :
268
285
case 'first-tabbable' :
@@ -275,10 +292,20 @@ export class CdkDialogContainer<C extends DialogConfig = DialogConfig>
275
292
} ) ;
276
293
break ;
277
294
case 'first-heading' :
278
- this . _focusByCssSelector ( 'h1, h2, h3, h4, h5, h6, [role="heading"]' ) ;
295
+ afterNextRender (
296
+ ( ) => {
297
+ this . _focusByCssSelector ( 'h1, h2, h3, h4, h5, h6, [role="heading"]' ) ;
298
+ } ,
299
+ { injector : this . _injector } ,
300
+ ) ;
279
301
break ;
280
302
default :
281
- this . _focusByCssSelector ( this . _config . autoFocus ! ) ;
303
+ afterNextRender (
304
+ ( ) => {
305
+ this . _focusByCssSelector ( autoFocus ! ) ;
306
+ } ,
307
+ { injector : this . _injector } ,
308
+ ) ;
282
309
break ;
283
310
}
284
311
}
0 commit comments