Skip to content

Commit

Permalink
fix(dialog): move focus into container if no focusable elements are f…
Browse files Browse the repository at this point in the history
…ound (#6524)

Fixes #6513.
  • Loading branch information
crisbeto authored and kara committed Aug 22, 2017
1 parent e0b1094 commit 4e12072
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 3 deletions.
9 changes: 8 additions & 1 deletion src/lib/dialog/dialog-container.ts
Expand Up @@ -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',
Expand Down Expand Up @@ -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. */
Expand Down
1 change: 1 addition & 0 deletions src/lib/dialog/dialog.scss
Expand Up @@ -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%;
Expand Down
20 changes: 18 additions & 2 deletions src/lib/dialog/dialog.spec.ts
Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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 = [
Expand All @@ -961,7 +975,8 @@ const TEST_DIRECTIVES = [
DirectiveWithViewContainer,
ComponentWithOnPushViewContainer,
ContentElementDialog,
DialogWithInjectedData
DialogWithInjectedData,
DialogWithoutFocusableElements
];

@NgModule({
Expand All @@ -973,7 +988,8 @@ const TEST_DIRECTIVES = [
ComponentWithTemplateRef,
PizzaMsg,
ContentElementDialog,
DialogWithInjectedData
DialogWithInjectedData,
DialogWithoutFocusableElements,
],
})
class DialogTestModule { }

0 comments on commit 4e12072

Please sign in to comment.