Skip to content

Commit 1d4be69

Browse files
crisbetoVivian Hu
authored andcommitted
fix(slide-toggle): redirect focus to underlying input element (#13957)
Currently the `mat-slide-toggle` doesn't redirect focus to the underlying `input` element. This means that things like the focus trap's `cdkFocusInitial` won't work when they're set on the toggle host. These changes add a `tabindex` and set up a `focus` listener to forward focus to the input. Relates to #13953.
1 parent 3fb5522 commit 1d4be69

File tree

2 files changed

+12
-2
lines changed

2 files changed

+12
-2
lines changed

src/lib/slide-toggle/slide-toggle.spec.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,15 @@ describe('MatSlideToggle without forms', () => {
293293
expect(document.activeElement).toBe(inputElement);
294294
});
295295

296+
it('should focus on underlying input element when the host is focused', () => {
297+
expect(document.activeElement).not.toBe(inputElement);
298+
299+
slideToggleElement.focus();
300+
fixture.detectChanges();
301+
302+
expect(document.activeElement).toBe(inputElement);
303+
});
304+
296305
it('should set a element class if labelPosition is set to before', () => {
297306
expect(slideToggleElement.classList).not.toContain('mat-slide-toggle-label-before');
298307

@@ -355,7 +364,7 @@ describe('MatSlideToggle without forms', () => {
355364
fixture.detectChanges();
356365

357366
const slideToggle = fixture.debugElement.query(By.directive(MatSlideToggle)).nativeElement;
358-
expect(slideToggle.getAttribute('tabindex')).toBeFalsy();
367+
expect(slideToggle.getAttribute('tabindex')).toBe('-1');
359368
}));
360369
});
361370

src/lib/slide-toggle/slide-toggle.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,12 @@ export const _MatSlideToggleMixinBase:
8686
host: {
8787
'class': 'mat-slide-toggle',
8888
'[id]': 'id',
89-
'[attr.tabindex]': 'null',
89+
'[attr.tabindex]': '-1', // Needs to be `-1` so it can still receive programmatic focus.
9090
'[class.mat-checked]': 'checked',
9191
'[class.mat-disabled]': 'disabled',
9292
'[class.mat-slide-toggle-label-before]': 'labelPosition == "before"',
9393
'[class._mat-animation-noopable]': '_animationMode === "NoopAnimations"',
94+
'(focus)': '_inputElement.nativeElement.focus()',
9495
},
9596
templateUrl: 'slide-toggle.html',
9697
styleUrls: ['slide-toggle.css'],

0 commit comments

Comments
 (0)