Skip to content

Commit d81445b

Browse files
crisbetokara
authored andcommitted
fix(focus-trap): enabled property not being coerced (#3417)
1 parent 0560eab commit d81445b

File tree

2 files changed

+50
-28
lines changed

2 files changed

+50
-28
lines changed

src/lib/core/a11y/focus-trap.spec.ts

Lines changed: 49 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,24 @@ import {Platform} from '../platform/platform';
77

88
describe('FocusTrap', () => {
99

10-
describe('with default element', () => {
11-
12-
let fixture: ComponentFixture<FocusTrapTestApp>;
13-
let focusTrapInstance: FocusTrap;
14-
let platform: Platform = new Platform();
10+
beforeEach(async(() => {
11+
TestBed.configureTestingModule({
12+
declarations: [FocusTrapDirective, FocusTrapWithBindings, SimpleFocusTrap, FocusTrapTargets],
13+
providers: [InteractivityChecker, Platform, FocusTrapFactory]
14+
});
1515

16-
beforeEach(async(() => {
17-
TestBed.configureTestingModule({
18-
declarations: [FocusTrapDirective, FocusTrapTestApp],
19-
providers: [InteractivityChecker, Platform, FocusTrapFactory]
20-
});
16+
TestBed.compileComponents();
17+
}));
2118

22-
TestBed.compileComponents();
19+
describe('with default element', () => {
20+
let fixture: ComponentFixture<SimpleFocusTrap>;
21+
let focusTrapInstance: FocusTrap;
2322

24-
fixture = TestBed.createComponent(FocusTrapTestApp);
23+
beforeEach(() => {
24+
fixture = TestBed.createComponent(SimpleFocusTrap);
2525
fixture.detectChanges();
2626
focusTrapInstance = fixture.componentInstance.focusTrapDirective.focusTrap;
27-
}));
27+
});
2828

2929
it('wrap focus from end to start', () => {
3030
// Because we can't mimic a real tab press focus change in a unit test, just call the
@@ -41,12 +41,28 @@ describe('FocusTrap', () => {
4141
focusTrapInstance.focusLastTabbableElement();
4242

4343
// In iOS button elements are never tabbable, so the last element will be the input.
44-
let lastElement = platform.IOS ? 'input' : 'button';
44+
let lastElement = new Platform().IOS ? 'input' : 'button';
4545

4646
expect(document.activeElement.nodeName.toLowerCase())
4747
.toBe(lastElement, `Expected ${lastElement} element to be focused`);
4848
});
4949

50+
it('should be enabled by default', () => {
51+
expect(focusTrapInstance.enabled).toBe(true);
52+
});
53+
54+
});
55+
56+
describe('with bindings', () => {
57+
let fixture: ComponentFixture<FocusTrapWithBindings>;
58+
let focusTrapInstance: FocusTrap;
59+
60+
beforeEach(() => {
61+
fixture = TestBed.createComponent(FocusTrapWithBindings);
62+
fixture.detectChanges();
63+
focusTrapInstance = fixture.componentInstance.focusTrapDirective.focusTrap;
64+
});
65+
5066
it('should clean up its anchor sibling elements on destroy', () => {
5167
const rootElement = fixture.debugElement.nativeElement as HTMLElement;
5268

@@ -73,21 +89,14 @@ describe('FocusTrap', () => {
7389
});
7490

7591
describe('with focus targets', () => {
76-
let fixture: ComponentFixture<FocusTrapTargetTestApp>;
92+
let fixture: ComponentFixture<FocusTrapTargets>;
7793
let focusTrapInstance: FocusTrap;
7894

79-
beforeEach(async(() => {
80-
TestBed.configureTestingModule({
81-
declarations: [FocusTrapDirective, FocusTrapTargetTestApp],
82-
providers: [InteractivityChecker, Platform, FocusTrapFactory]
83-
});
84-
85-
TestBed.compileComponents();
86-
87-
fixture = TestBed.createComponent(FocusTrapTargetTestApp);
95+
beforeEach(() => {
96+
fixture = TestBed.createComponent(FocusTrapTargets);
8897
fixture.detectChanges();
8998
focusTrapInstance = fixture.componentInstance.focusTrapDirective.focusTrap;
90-
}));
99+
});
91100

92101
it('should be able to prioritize the first focus target', () => {
93102
// Because we can't mimic a real tab press focus change in a unit test, just call the
@@ -106,6 +115,19 @@ describe('FocusTrap', () => {
106115
});
107116

108117

118+
@Component({
119+
template: `
120+
<div cdkTrapFocus>
121+
<input>
122+
<button>SAVE</button>
123+
</div>
124+
`
125+
})
126+
class SimpleFocusTrap {
127+
@ViewChild(FocusTrapDirective) focusTrapDirective: FocusTrapDirective;
128+
}
129+
130+
109131
@Component({
110132
template: `
111133
<div *ngIf="renderFocusTrap" [cdkTrapFocus]="isFocusTrapEnabled">
@@ -114,7 +136,7 @@ describe('FocusTrap', () => {
114136
</div>
115137
`
116138
})
117-
class FocusTrapTestApp {
139+
class FocusTrapWithBindings {
118140
@ViewChild(FocusTrapDirective) focusTrapDirective: FocusTrapDirective;
119141
renderFocusTrap = true;
120142
isFocusTrapEnabled = true;
@@ -131,6 +153,6 @@ class FocusTrapTestApp {
131153
</div>
132154
`
133155
})
134-
class FocusTrapTargetTestApp {
156+
class FocusTrapTargets {
135157
@ViewChild(FocusTrapDirective) focusTrapDirective: FocusTrapDirective;
136158
}

src/lib/core/a11y/focus-trap.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ export class FocusTrapDirective implements OnDestroy, AfterContentInit {
222222
/** Whether the focus trap is active. */
223223
@Input('cdkTrapFocus')
224224
get enabled(): boolean { return this.focusTrap.enabled; }
225-
set enabled(val: boolean) { this.focusTrap.enabled = val; }
225+
set enabled(value: boolean) { this.focusTrap.enabled = coerceBooleanProperty(value); }
226226

227227
constructor(private _elementRef: ElementRef, private _focusTrapFactory: FocusTrapFactory) {
228228
this.focusTrap = this._focusTrapFactory.create(this._elementRef.nativeElement, true);

0 commit comments

Comments
 (0)