diff --git a/src/lib/dialog/dialog-config.ts b/src/lib/dialog/dialog-config.ts index 73c5a5e9b73..770a26a7d5b 100644 --- a/src/lib/dialog/dialog-config.ts +++ b/src/lib/dialog/dialog-config.ts @@ -95,6 +95,12 @@ export class MatDialogConfig { /** Whether the dialog should focus the first focusable element on open. */ autoFocus?: boolean = true; + /** + * Whether the dialog should restore focus to the + * previously-focused element, after it's closed. + */ + restoreFocus?: boolean = true; + /** Scroll strategy to be used for the dialog. */ scrollStrategy?: ScrollStrategy; diff --git a/src/lib/dialog/dialog-container.ts b/src/lib/dialog/dialog-container.ts index a214567a6fb..d03f34e0cb6 100644 --- a/src/lib/dialog/dialog-container.ts +++ b/src/lib/dialog/dialog-container.ts @@ -148,7 +148,7 @@ export class MatDialogContainer extends BasePortalOutlet { const toFocus = this._elementFocusedBeforeDialogWasOpened; // We need the extra check, because IE can set the `activeElement` to null in some cases. - if (toFocus && typeof toFocus.focus === 'function') { + if (this._config.restoreFocus && toFocus && typeof toFocus.focus === 'function') { toFocus.focus(); } diff --git a/src/lib/dialog/dialog.spec.ts b/src/lib/dialog/dialog.spec.ts index 12bb6023482..b382ab78e96 100644 --- a/src/lib/dialog/dialog.spec.ts +++ b/src/lib/dialog/dialog.spec.ts @@ -1009,6 +1009,37 @@ describe('MatDialog', () => { .toBe('MAT-DIALOG-CONTAINER', 'Expected dialog container to be focused.'); })); + it('should be able to disable focus restoration', fakeAsync(() => { + // Create a element that has focus before the dialog is opened. + const button = document.createElement('button'); + button.id = 'dialog-trigger'; + document.body.appendChild(button); + button.focus(); + + const dialogRef = dialog.open(PizzaMsg, { + viewContainerRef: testViewContainerRef, + restoreFocus: false + }); + + flushMicrotasks(); + viewContainerFixture.detectChanges(); + flushMicrotasks(); + + expect(document.activeElement.id) + .not.toBe('dialog-trigger', 'Expected the focus to change when dialog was opened.'); + + dialogRef.close(); + flushMicrotasks(); + viewContainerFixture.detectChanges(); + tick(500); + + expect(document.activeElement.id).not.toBe('dialog-trigger', + 'Expected focus not to have been restored.'); + + document.body.removeChild(button); + })); + + }); describe('dialog content elements', () => {