From fcfa90da4e31f16473dd7db3c8079d9e1397ef6d Mon Sep 17 00:00:00 2001 From: crisbeto Date: Fri, 14 Jun 2019 19:39:54 +0200 Subject: [PATCH] fix(dialog): don't move focus to dialog container if focus is already inside the dialog This is a follow-up to https://github.com/angular/components/pull/16221. What we hadn't accounted for in the aforementioned PR is that the consumer may have turned off `autoFocus` so that they can handle it themselves and with our changes focus would be reset back to the container. These changes add an extra check which will ensure that focus is only moved if it's not inside the dialog already. --- src/material/dialog/dialog-container.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/material/dialog/dialog-container.ts b/src/material/dialog/dialog-container.ts index a1d6d7de7e43..aba1d40747ab 100644 --- a/src/material/dialog/dialog-container.ts +++ b/src/material/dialog/dialog-container.ts @@ -132,20 +132,28 @@ export class MatDialogContainer extends BasePortalOutlet { /** Moves the focus inside the focus trap. */ private _trapFocus() { + const element = this._elementRef.nativeElement; + if (!this._focusTrap) { - this._focusTrap = this._focusTrapFactory.create(this._elementRef.nativeElement); + this._focusTrap = this._focusTrapFactory.create(element); } - // If were to attempt to focus immediately, then the content of the dialog would not yet be + // If we 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. if (this._config.autoFocus) { this._focusTrap.focusInitialElementWhenReady(); } else { + const activeElement = this._document.activeElement; + // Otherwise ensure that focus is on the dialog container. It's possible that a different // component tried to move focus while the open animation was running. See: - // https://github.com/angular/components/issues/16215 - this._elementRef.nativeElement.focus(); + // https://github.com/angular/components/issues/16215. Note that we only want to do this + // if the focus isn't inside the dialog already, because it's possible that the consumer + // turned off `autoFocus` in order to move focus themselves. + if (activeElement !== element && !element.contains(activeElement)) { + element.focus(); + } } }