diff --git a/src/cdk/a11y/focus-trap/focus-trap.spec.ts b/src/cdk/a11y/focus-trap/focus-trap.spec.ts index c82dca07b9b7..5d91fbc4a6fa 100644 --- a/src/cdk/a11y/focus-trap/focus-trap.spec.ts +++ b/src/cdk/a11y/focus-trap/focus-trap.spec.ts @@ -16,6 +16,7 @@ describe('FocusTrap', () => { FocusTrapWithSvg, FocusTrapWithoutFocusableElements, FocusTrapWithAutoCapture, + FocusTrapUnfocusableTarget, ], }); @@ -138,6 +139,18 @@ describe('FocusTrap', () => { focusTrapInstance.focusLastTabbableElement(); expect(document.activeElement!.id).toBe('last'); }); + + it('should warn if the initial focus target is not focusable', () => { + const alternateFixture = TestBed.createComponent(FocusTrapUnfocusableTarget); + alternateFixture.detectChanges(); + focusTrapInstance = fixture.componentInstance.focusTrapDirective.focusTrap; + + spyOn(console, 'warn'); + focusTrapInstance.focusInitialElement(); + + expect(console.warn).toHaveBeenCalled(); + }); + }); describe('special cases', () => { @@ -235,6 +248,16 @@ class FocusTrapTargets { @ViewChild(CdkTrapFocus) focusTrapDirective: CdkTrapFocus; } +@Component({ + template: ` +
+
+
+ ` +}) +class FocusTrapUnfocusableTarget { + @ViewChild(CdkTrapFocus) focusTrapDirective: CdkTrapFocus; +} @Component({ template: ` diff --git a/src/cdk/a11y/focus-trap/focus-trap.ts b/src/cdk/a11y/focus-trap/focus-trap.ts index 08d068928e5b..faed08f64131 100644 --- a/src/cdk/a11y/focus-trap/focus-trap.ts +++ b/src/cdk/a11y/focus-trap/focus-trap.ts @@ -18,6 +18,7 @@ import { NgZone, OnDestroy, DoCheck, + isDevMode, } from '@angular/core'; import {take} from 'rxjs/operators'; import {InteractivityChecker} from '../interactivity-checker/interactivity-checker'; @@ -189,6 +190,12 @@ export class FocusTrap { `will be removed in 8.0.0`, redirectToElement); } + // Warn the consumer if the element they've pointed to + // isn't focusable, when not in production mode. + if (isDevMode() && !this._checker.isFocusable(redirectToElement)) { + console.warn(`Element matching '[cdkFocusInitial]' is not focusable.`, redirectToElement); + } + redirectToElement.focus(); return true; }