@@ -31,11 +31,13 @@ import {
3131 ElementRef ,
3232 EmbeddedViewRef ,
3333 Inject ,
34+ Injector ,
3435 NgZone ,
3536 OnDestroy ,
3637 Optional ,
3738 ViewChild ,
3839 ViewEncapsulation ,
40+ afterNextRender ,
3941 inject ,
4042} from '@angular/core' ;
4143import { DialogConfig } from './dialog-config' ;
@@ -102,6 +104,10 @@ export class CdkDialogContainer<C extends DialogConfig = DialogConfig>
102104
103105 protected readonly _changeDetectorRef = inject ( ChangeDetectorRef ) ;
104106
107+ private _injector = inject ( Injector ) ;
108+
109+ private _isDestroyed = false ;
110+
105111 constructor (
106112 protected _elementRef : ElementRef ,
107113 protected _focusTrapFactory : FocusTrapFactory ,
@@ -150,6 +156,7 @@ export class CdkDialogContainer<C extends DialogConfig = DialogConfig>
150156 }
151157
152158 ngOnDestroy ( ) {
159+ this . _isDestroyed = true ;
153160 this . _restoreFocus ( ) ;
154161 }
155162
@@ -246,23 +253,33 @@ export class CdkDialogContainer<C extends DialogConfig = DialogConfig>
246253 * cannot be moved then focus will go to the dialog container.
247254 */
248255 protected _trapFocus ( ) {
256+ if ( this . _isDestroyed ) {
257+ return ;
258+ }
259+
249260 const element = this . _elementRef . nativeElement ;
250261 // If were to attempt to focus immediately, then the content of the dialog would not yet be
251262 // ready in instances where change detection has to run first. To deal with this, we simply
252263 // wait for the microtask queue to be empty when setting focus when autoFocus isn't set to
253264 // dialog. If the element inside the dialog can't be focused, then the container is focused
254265 // 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 ) {
256268 case false :
257269 case 'dialog' :
258270 // Ensure that focus is on the dialog container. It's possible that a different
259271 // component tried to move focus while the open animation was running. See:
260272 // https://github.com/angular/components/issues/16215. Note that we only want to do this
261273 // if the focus isn't inside the dialog already, because it's possible that the consumer
262274 // 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+ ) ;
266283 break ;
267284 case true :
268285 case 'first-tabbable' :
@@ -275,10 +292,20 @@ export class CdkDialogContainer<C extends DialogConfig = DialogConfig>
275292 } ) ;
276293 break ;
277294 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+ ) ;
279301 break ;
280302 default :
281- this . _focusByCssSelector ( this . _config . autoFocus ! ) ;
303+ afterNextRender (
304+ ( ) => {
305+ this . _focusByCssSelector ( autoFocus ! ) ;
306+ } ,
307+ { injector : this . _injector } ,
308+ ) ;
282309 break ;
283310 }
284311 }
0 commit comments