Skip to content

Commit 110a8ea

Browse files
committed
fix(dialog): dialog content not being read out by screen readers
Currently we focus the first focusable element inside a dialog as per the accessibility recommendations, however moving focus to the first item causes some screen readers not to read out the rest of the dialog content. These changes switch to focusing the dialog container by default which allows screen readers to read out everything. If users press tab, they'll land on the first tabbable element anyways. The old behavior can still be opted into via the `autoFocus` option. Fixes #10591.
1 parent 4701c7b commit 110a8ea

File tree

3 files changed

+23
-6
lines changed

3 files changed

+23
-6
lines changed

e2e/components/dialog-e2e.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ describe('dialog', () => {
5959
await element(by.id('default')).click();
6060

6161
await waitForDialog();
62-
await expectFocusOn('mat-dialog-container input');
62+
await expectFocusOn('mat-dialog-container');
6363
});
6464

6565
it('should restore focus to the element that opened the dialog', async () => {
@@ -76,7 +76,7 @@ describe('dialog', () => {
7676
await element(by.id('default')).click();
7777

7878
await waitForDialog();
79-
await pressKeys(Key.TAB, Key.TAB, Key.TAB);
79+
await pressKeys(Key.TAB, Key.TAB, Key.TAB, Key.TAB);
8080
await expectFocusOn('#close');
8181
});
8282

src/lib/dialog/dialog-config.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,11 @@ export class MatDialogConfig<D = any> {
9292
/** Aria label to assign to the dialog element */
9393
ariaLabel?: string | null = null;
9494

95+
// Note that this is disabled by default, because while the a11y recommendations are to focus
96+
// the first focusable element, doing so prevents screen readers from reading out the
97+
// rest of the dialog's content.
9598
/** Whether the dialog should focus the first focusable element on open. */
96-
autoFocus?: boolean = true;
99+
autoFocus?: boolean = false;
97100

98101
/**
99102
* Whether the dialog should restore focus to the

src/lib/dialog/dialog.spec.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -949,18 +949,32 @@ describe('MatDialog', () => {
949949
beforeEach(() => document.body.appendChild(overlayContainerElement));
950950
afterEach(() => document.body.removeChild(overlayContainerElement));
951951

952-
it('should focus the first tabbable element of the dialog on open', fakeAsync(() => {
952+
it('should focus the dialog container by default', fakeAsync(() => {
953953
dialog.open(PizzaMsg, {
954-
viewContainerRef: testViewContainerRef
954+
viewContainerRef: testViewContainerRef,
955955
});
956956

957957
viewContainerFixture.detectChanges();
958958
flushMicrotasks();
959959

960960
expect(document.activeElement!.tagName)
961-
.toBe('INPUT', 'Expected first tabbable element (input) in the dialog to be focused.');
961+
.toBe('MAT-DIALOG-CONTAINER', 'Expected dialog container to be focused.');
962962
}));
963963

964+
it('should focus the first tabbable element of the dialog on open when autoFocus is enabled',
965+
fakeAsync(() => {
966+
dialog.open(PizzaMsg, {
967+
viewContainerRef: testViewContainerRef,
968+
autoFocus: true
969+
});
970+
971+
viewContainerFixture.detectChanges();
972+
flushMicrotasks();
973+
974+
expect(document.activeElement!.tagName)
975+
.toBe('INPUT', 'Expected first tabbable element (input) in the dialog to be focused.');
976+
}));
977+
964978
it('should allow disabling focus of the first tabbable element', fakeAsync(() => {
965979
dialog.open(PizzaMsg, {
966980
viewContainerRef: testViewContainerRef,

0 commit comments

Comments
 (0)