From 5fb8b44c9b28d71be702b9a864481ec7f5815db0 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Fri, 7 Dec 2018 18:05:27 +0100 Subject: [PATCH] fix(checkbox): redirect focus to underlying input element (#13959) Currently the `mat-checkbox` host element isn't focusable, which means that if consumers decided to use something like `cdkFocusInitial` on it, nothing would happen. These changes tweak the `tabindex` so the element is focusable and add a `focus` listener that'll redirect focus to the `input`. Relates to #13953. --- src/lib/checkbox/checkbox.scss | 1 + src/lib/checkbox/checkbox.spec.ts | 11 ++++++++++- src/lib/checkbox/checkbox.ts | 3 ++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/lib/checkbox/checkbox.scss b/src/lib/checkbox/checkbox.scss index 15e625cf80de..a367499b6481 100644 --- a/src/lib/checkbox/checkbox.scss +++ b/src/lib/checkbox/checkbox.scss @@ -182,6 +182,7 @@ $_mat-checkbox-mark-stroke-size: 2 / 15 * $mat-checkbox-size !default; cursor: pointer; -webkit-tap-highlight-color: transparent; + outline: 0; .mat-ripple-element:not(.mat-checkbox-persistent-ripple) { opacity: 0.16; diff --git a/src/lib/checkbox/checkbox.spec.ts b/src/lib/checkbox/checkbox.spec.ts index f5838aaf7144..bc043d4bcea9 100644 --- a/src/lib/checkbox/checkbox.spec.ts +++ b/src/lib/checkbox/checkbox.spec.ts @@ -370,6 +370,15 @@ describe('MatCheckbox', () => { expect(document.activeElement).toBe(inputElement); }); + it('should focus on underlying input element when the host is focused', () => { + expect(document.activeElement).not.toBe(inputElement); + + checkboxNativeElement.focus(); + fixture.detectChanges(); + + expect(document.activeElement).toBe(inputElement); + }); + it('should forward the value to input element', () => { testComponent.checkboxValue = 'basic_checkbox'; fixture.detectChanges(); @@ -790,7 +799,7 @@ describe('MatCheckbox', () => { fixture.detectChanges(); const checkbox = fixture.debugElement.query(By.directive(MatCheckbox)).nativeElement; - expect(checkbox.getAttribute('tabindex')).toBeFalsy(); + expect(checkbox.getAttribute('tabindex')).toBe('-1'); }); }); diff --git a/src/lib/checkbox/checkbox.ts b/src/lib/checkbox/checkbox.ts index c30bc5a6ab79..67f8a0687340 100644 --- a/src/lib/checkbox/checkbox.ts +++ b/src/lib/checkbox/checkbox.ts @@ -119,12 +119,13 @@ export const _MatCheckboxMixinBase: host: { 'class': 'mat-checkbox', '[id]': 'id', - '[attr.tabindex]': 'null', + '[attr.tabindex]': '-1', // Reset back to -1 so that the `focus` event still works. '[class.mat-checkbox-indeterminate]': 'indeterminate', '[class.mat-checkbox-checked]': 'checked', '[class.mat-checkbox-disabled]': 'disabled', '[class.mat-checkbox-label-before]': 'labelPosition == "before"', '[class._mat-animation-noopable]': `_animationMode === 'NoopAnimations'`, + '(focus)': '_inputElement.nativeElement.focus()', }, providers: [MAT_CHECKBOX_CONTROL_VALUE_ACCESSOR], inputs: ['disableRipple', 'color', 'tabIndex'],