Skip to content

Commit 117637c

Browse files
annieywmmalerba
authored andcommitted
docs(material/dialog): add a11y section about manual focus restoration (#21011)
(cherry picked from commit 9f641d1)
1 parent c287f5d commit 117637c

File tree

6 files changed

+63
-0
lines changed

6 files changed

+63
-0
lines changed

src/components-examples/material/dialog/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ ng_module(
1414
"//src/material/button",
1515
"//src/material/dialog",
1616
"//src/material/input",
17+
"//src/material/menu",
1718
"@npm//@angular/forms",
1819
],
1920
)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<mat-dialog-content>
2+
This is a dialog
3+
</mat-dialog-content>
4+
<mat-dialog-actions>
5+
<button mat-button mat-dialog-close>Okay</button>
6+
</mat-dialog-actions>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<button mat-button [matMenuTriggerFor]="menu" #menuTrigger>Menu</button>
2+
<mat-menu #menu="matMenu">
3+
<button mat-menu-item (click)="openDialog()">Open dialog</button>
4+
</mat-menu>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import {Component, ViewChild} from '@angular/core';
2+
import {MatDialog} from '@angular/material/dialog';
3+
import {MatMenuTrigger} from '@angular/material/menu';
4+
/**
5+
* @title Dialog launched from a menu
6+
*/
7+
@Component({
8+
selector: 'dialog-from-menu-example',
9+
templateUrl: 'dialog-from-menu-example.html',
10+
})
11+
export class DialogFromMenuExample {
12+
@ViewChild('menuTrigger') menuTrigger: MatMenuTrigger;
13+
14+
constructor(public dialog: MatDialog) {}
15+
16+
openDialog() {
17+
// #docregion focus-restoration
18+
const dialogRef = this.dialog.open(DialogFromMenuExampleDialog, {restoreFocus: false});
19+
20+
// Manually restore focus to the menu trigger since the element that
21+
// opens the dialog won't be in the DOM any more when the dialog closes.
22+
dialogRef.afterClosed().subscribe(() => this.menuTrigger.focus());
23+
// #enddocregion focus-restoration
24+
}
25+
}
26+
27+
@Component({
28+
selector: 'dialog-from-menu-dialog',
29+
templateUrl: 'dialog-from-menu-example-dialog.html',
30+
})
31+
export class DialogFromMenuExampleDialog {}

src/components-examples/material/dialog/index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {FormsModule} from '@angular/forms';
44
import {MatButtonModule} from '@angular/material/button';
55
import {MatDialogModule} from '@angular/material/dialog';
66
import {MatInputModule} from '@angular/material/input';
7+
import {MatMenuModule} from '@angular/material/menu';
78
import {
89
DialogContentExample,
910
DialogContentExampleDialog
@@ -17,6 +18,10 @@ import {
1718
DialogOverviewExample,
1819
DialogOverviewExampleDialog
1920
} from './dialog-overview/dialog-overview-example';
21+
import {
22+
DialogFromMenuExample,
23+
DialogFromMenuExampleDialog
24+
} from './dialog-from-menu/dialog-from-menu-example';
2025

2126
export {
2227
DialogContentExample,
@@ -25,6 +30,8 @@ export {
2530
DialogDataExampleDialog,
2631
DialogElementsExample,
2732
DialogElementsExampleDialog,
33+
DialogFromMenuExample,
34+
DialogFromMenuExampleDialog,
2835
DialogOverviewExample,
2936
DialogOverviewExampleDialog,
3037
};
@@ -36,6 +43,8 @@ const EXAMPLES = [
3643
DialogDataExampleDialog,
3744
DialogElementsExample,
3845
DialogElementsExampleDialog,
46+
DialogFromMenuExample,
47+
DialogFromMenuExampleDialog,
3948
DialogOverviewExample,
4049
DialogOverviewExampleDialog,
4150
];
@@ -46,6 +55,7 @@ const EXAMPLES = [
4655
MatButtonModule,
4756
MatDialogModule,
4857
MatInputModule,
58+
MatMenuModule,
4959
FormsModule,
5060
],
5161
declarations: EXAMPLES,

src/material/dialog/dialog.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,17 @@ be configured by setting the `cdkFocusInitial` attribute on another focusable el
173173
Tabbing through the elements of the dialog will keep focus inside of the dialog element,
174174
wrapping back to the first tabbable element when reaching the end of the tab sequence.
175175

176+
#### Focus Restoration
177+
Upon closing, the dialog returns focus to the element that had focus when the dialog opened.
178+
In some cases, however, this previously focused element no longer exists in the DOM, such as
179+
menu items. To manually restore focus to an appropriate element in such cases, you can disable
180+
`restoreFocus` in `MatDialogConfig` and pass it into the `open` method.
181+
Then you can return focus manually by subscribing to the `afterClosed` observable on `MatDialogRef`.
182+
183+
<!-- example({"example":"dialog-from-menu",
184+
"file":"dialog-from-menu-example.ts",
185+
"region":"focus-restoration"}) -->
186+
176187
#### Keyboard interaction
177188
By default pressing the escape key will close the dialog. While this behavior can
178189
be turned off via the `disableClose` option, users should generally avoid doing so

0 commit comments

Comments
 (0)