Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions goldens/material/sidenav/index.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,11 @@ export class MatDrawerContent extends CdkScrollable implements AfterContentInit
// (undocumented)
_container: MatDrawerContainer;
// (undocumented)
_drawerToggled(drawer: MatDrawer): void;
// (undocumented)
ngAfterContentInit(): void;
protected _shouldBeHidden(): boolean;
// (undocumented)
_updateInert(): void;
// (undocumented)
static ɵcmp: i0.ɵɵComponentDeclaration<MatDrawerContent, "mat-drawer-content", never, {}, {}, never, ["*"], true, never>;
// (undocumented)
static ɵfac: i0.ɵɵFactoryDeclaration<MatDrawerContent, never>;
Expand Down
35 changes: 19 additions & 16 deletions src/material/sidenav/drawer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import {
signal,
} from '@angular/core';
import {merge, Observable, Subject} from 'rxjs';
import {debounceTime, filter, map, mapTo, startWith, take, takeUntil} from 'rxjs/operators';
import {debounceTime, delay, filter, map, mapTo, startWith, take, takeUntil} from 'rxjs/operators';
import {_animationsDisabled} from '../core';

/**
Expand Down Expand Up @@ -100,14 +100,30 @@ export class MatDrawerContent extends CdkScrollable implements AfterContentInit
private _platform = inject(Platform);
private _changeDetectorRef = inject(ChangeDetectorRef);
private _element = inject<ElementRef<HTMLElement>>(ElementRef);
private _ngZone = inject(NgZone);
private _isInert = false;
_container = inject(MatDrawerContainer);

ngAfterContentInit() {
this._container._contentMarginChanges.subscribe(() => this._changeDetectorRef.markForCheck());
}

_updateInert() {
_drawerToggled(drawer: MatDrawer) {
if (drawer.opened) {
// If the drawer is being opened, we need to wait until the animation is done before marking
// the content is inert, because the drawer moves focus during the animation. We add a delay
// to be safe.
this._ngZone.runOutsideAngular(() => {
drawer._animationEnd.pipe(delay(50), take(1)).subscribe(() => this._updateInert());
});
} else {
// When the drawer is closing, we need to remove `inert` immediately so
// the elements that focus is being restored to can become focusable.
this._updateInert();
}
}

private _updateInert() {
const newValue = this._container._isShowingBackdrop();

if (newValue !== this._isInert) {
Expand Down Expand Up @@ -433,38 +449,24 @@ export class MatDrawer implements AfterViewInit, OnDestroy {
if (!hasMovedFocus && typeof element.focus === 'function') {
element.focus();
}

// When capturing focus, we need to delay making the
// container inert until focus has actually been moved.
this._notifyContentFocus();
},
{injector: this._injector},
);
break;
case 'first-heading':
this._focusByCssSelector('h1, h2, h3, h4, h5, h6, [role="heading"]');
this._notifyContentFocus();
break;
default:
this._focusByCssSelector(this.autoFocus!);
this._notifyContentFocus();
break;
}
}

private _notifyContentFocus() {
(this._container?._content || this._container?._userContent)?._updateInert();
}

/**
* Restores focus to the element that was originally focused when the drawer opened.
* If no element was focused at that time, the focus will be restored to the drawer.
*/
private _restoreFocus(focusOrigin: Exclude<FocusOrigin, null>) {
// When restoring focus, we need remove `inert` as early as possible,
// because the element needs to become focusable before we can focus it.
this._notifyContentFocus();

if (this.autoFocus === 'dialog') {
return;
}
Expand Down Expand Up @@ -577,6 +579,7 @@ export class MatDrawer implements AfterViewInit, OnDestroy {
}

this._opened.set(isOpen);
(this._container?._content || this._container?._userContent)?._drawerToggled(this);

if (this._container?._transitionsEnabled) {
// Note: it's important to set this as early as possible,
Expand Down
Loading