@@ -44,7 +44,7 @@ import {
4444 signal ,
4545} from '@angular/core' ;
4646import { merge , Observable , Subject } from 'rxjs' ;
47- import { debounceTime , filter , map , mapTo , startWith , take , takeUntil } from 'rxjs/operators' ;
47+ import { debounceTime , delay , filter , map , mapTo , startWith , take , takeUntil } from 'rxjs/operators' ;
4848import { _animationsDisabled } from '../core' ;
4949
5050/**
@@ -100,14 +100,30 @@ export class MatDrawerContent extends CdkScrollable implements AfterContentInit
100100 private _platform = inject ( Platform ) ;
101101 private _changeDetectorRef = inject ( ChangeDetectorRef ) ;
102102 private _element = inject < ElementRef < HTMLElement > > ( ElementRef ) ;
103+ private _ngZone = inject ( NgZone ) ;
103104 private _isInert = false ;
104105 _container = inject ( MatDrawerContainer ) ;
105106
106107 ngAfterContentInit ( ) {
107108 this . _container . _contentMarginChanges . subscribe ( ( ) => this . _changeDetectorRef . markForCheck ( ) ) ;
108109 }
109110
110- _updateInert ( ) {
111+ _drawerToggled ( drawer : MatDrawer ) {
112+ if ( drawer . opened ) {
113+ // If the drawer is being opened, we need to wait until the animation is done before marking
114+ // the content is inert, because the drawer moves focus during the animation. We add a delay
115+ // to be safe.
116+ this . _ngZone . runOutsideAngular ( ( ) => {
117+ drawer . _animationEnd . pipe ( delay ( 50 ) , take ( 1 ) ) . subscribe ( ( ) => this . _updateInert ( ) ) ;
118+ } ) ;
119+ } else {
120+ // When the drawer is closing, we need to remove `inert` immediately so
121+ // the elements that focus is being restored to can become focusable.
122+ this . _updateInert ( ) ;
123+ }
124+ }
125+
126+ private _updateInert ( ) {
111127 const newValue = this . _container . _isShowingBackdrop ( ) ;
112128
113129 if ( newValue !== this . _isInert ) {
@@ -433,38 +449,24 @@ export class MatDrawer implements AfterViewInit, OnDestroy {
433449 if ( ! hasMovedFocus && typeof element . focus === 'function' ) {
434450 element . focus ( ) ;
435451 }
436-
437- // When capturing focus, we need to delay making the
438- // container inert until focus has actually been moved.
439- this . _notifyContentFocus ( ) ;
440452 } ,
441453 { injector : this . _injector } ,
442454 ) ;
443455 break ;
444456 case 'first-heading' :
445457 this . _focusByCssSelector ( 'h1, h2, h3, h4, h5, h6, [role="heading"]' ) ;
446- this . _notifyContentFocus ( ) ;
447458 break ;
448459 default :
449460 this . _focusByCssSelector ( this . autoFocus ! ) ;
450- this . _notifyContentFocus ( ) ;
451461 break ;
452462 }
453463 }
454464
455- private _notifyContentFocus ( ) {
456- ( this . _container ?. _content || this . _container ?. _userContent ) ?. _updateInert ( ) ;
457- }
458-
459465 /**
460466 * Restores focus to the element that was originally focused when the drawer opened.
461467 * If no element was focused at that time, the focus will be restored to the drawer.
462468 */
463469 private _restoreFocus ( focusOrigin : Exclude < FocusOrigin , null > ) {
464- // When restoring focus, we need remove `inert` as early as possible,
465- // because the element needs to become focusable before we can focus it.
466- this . _notifyContentFocus ( ) ;
467-
468470 if ( this . autoFocus === 'dialog' ) {
469471 return ;
470472 }
@@ -577,6 +579,7 @@ export class MatDrawer implements AfterViewInit, OnDestroy {
577579 }
578580
579581 this . _opened . set ( isOpen ) ;
582+ ( this . _container ?. _content || this . _container ?. _userContent ) ?. _drawerToggled ( this ) ;
580583
581584 if ( this . _container ?. _transitionsEnabled ) {
582585 // Note: it's important to set this as early as possible,
0 commit comments