fix(dialog): move focus into container if no focusable elements are found (#6524)

Fixes #6513.
This commit is contained in:
Kristiyan Kostadinov
2017-08-22 20:26:19 +02:00
committed by Kara
parent e0b1094d62
commit 4e120723eb
3 changed files with 27 additions and 3 deletions
+8 -1
View File
@@ -65,6 +65,7 @@ export function throwMdDialogContentAlreadyAttachedError() {
],
host: {
'class': 'mat-dialog-container',
'tabindex': '-1',
'[attr.role]': '_config?.role',
'[attr.aria-labelledby]': '_ariaLabelledBy',
'[attr.aria-describedby]': '_config?.ariaDescribedBy || null',
@@ -143,7 +144,13 @@ export class MdDialogContainer extends BasePortalHost {
// If were to attempt to focus immediately, then the content of the dialog would not yet be
// ready in instances where change detection has to run first. To deal with this, we simply
// wait for the microtask queue to be empty.
this._focusTrap.focusInitialElementWhenReady();
this._focusTrap.focusInitialElementWhenReady().then(hasMovedFocus => {
// If we didn't find any focusable elements inside the dialog, focus the
// container so the user can't tab into other elements behind it.
if (!hasMovedFocus) {
this._elementRef.nativeElement.focus();
}
});
}
/** Restores focus to the element that was focused before the dialog opened. */
+1
View File
@@ -17,6 +17,7 @@ $mat-dialog-button-margin: 8px !default;
box-sizing: border-box;
overflow: auto;
max-width: $mat-dialog-max-width;
outline: 0;
// The dialog container should completely fill its parent overlay element.
width: 100%;
+18 -2
View File
@@ -721,6 +721,17 @@ describe('MdDialog', () => {
document.body.removeChild(input);
}));
it('should move focus to the container if there are no focusable elements in the dialog',
fakeAsync(() => {
dialog.open(DialogWithoutFocusableElements);
viewContainerFixture.detectChanges();
flushMicrotasks();
expect(document.activeElement.tagName)
.toBe('MD-DIALOG-CONTAINER', 'Expected dialog container to be focused.');
}));
});
describe('dialog content elements', () => {
@@ -952,6 +963,9 @@ class DialogWithInjectedData {
constructor(@Inject(MD_DIALOG_DATA) public data: any) { }
}
@Component({template: '<p>Pasta</p>'})
class DialogWithoutFocusableElements {}
// Create a real (non-test) NgModule as a workaround for
// https://github.com/angular/angular/issues/10760
const TEST_DIRECTIVES = [
@@ -961,7 +975,8 @@ const TEST_DIRECTIVES = [
DirectiveWithViewContainer,
ComponentWithOnPushViewContainer,
ContentElementDialog,
DialogWithInjectedData
DialogWithInjectedData,
DialogWithoutFocusableElements
];
@NgModule({
@@ -973,7 +988,8 @@ const TEST_DIRECTIVES = [
ComponentWithTemplateRef,
PizzaMsg,
ContentElementDialog,
DialogWithInjectedData
DialogWithInjectedData,
DialogWithoutFocusableElements,
],
})
class DialogTestModule { }