mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(dialog): move focus into container if no focusable elements are found (#6524)
Fixes #6513.
This commit is contained in:
committed by
Kara
parent
e0b1094d62
commit
4e120723eb
@@ -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. */
|
||||
|
||||
@@ -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%;
|
||||
|
||||
@@ -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 { }
|
||||
|
||||
Reference in New Issue
Block a user