diff --git a/src/lib/checkbox/checkbox.spec.ts b/src/lib/checkbox/checkbox.spec.ts index 73b6f50177f6..4eb8b1175a9e 100644 --- a/src/lib/checkbox/checkbox.spec.ts +++ b/src/lib/checkbox/checkbox.spec.ts @@ -33,6 +33,7 @@ describe('MatCheckbox', () => { CheckboxWithChangeEvent, CheckboxWithFormControl, CheckboxWithoutLabel, + CheckboxWithTabindexAttr, ], providers: [ {provide: ViewportRuler, useClass: FakeViewportRuler} @@ -677,6 +678,20 @@ describe('MatCheckbox', () => { }); + describe('with native tabindex attribute', () => { + + it('should properly detect native tabindex attribute', async(() => { + fixture = TestBed.createComponent(CheckboxWithTabindexAttr); + fixture.detectChanges(); + + const checkbox = fixture.debugElement + .query(By.directive(MdCheckbox)).componentInstance as MdCheckbox; + + expect(checkbox.tabIndex) + .toBe(5, 'Expected tabIndex property to have been set based on the native attribute'); + })); + }); + describe('with multiple checkboxes', () => { beforeEach(() => { fixture = TestBed.createComponent(MultipleCheckboxes); @@ -998,3 +1013,9 @@ class CheckboxWithFormControl { class CheckboxWithoutLabel { label: string; } + +/** Test component with the native tabindex attribute. */ +@Component({ + template: `` +}) +class CheckboxWithTabindexAttr {} diff --git a/src/lib/checkbox/checkbox.ts b/src/lib/checkbox/checkbox.ts index 97ffec3de20d..563e31ae0782 100644 --- a/src/lib/checkbox/checkbox.ts +++ b/src/lib/checkbox/checkbox.ts @@ -9,6 +9,7 @@ import {coerceBooleanProperty} from '@angular/cdk/coercion'; import { AfterViewInit, + Attribute, ChangeDetectionStrategy, ChangeDetectorRef, Component, @@ -27,10 +28,12 @@ import { CanColor, CanDisable, CanDisableRipple, + HasTabIndex, MatRipple, mixinColor, mixinDisabled, mixinDisableRipple, + mixinTabIndex, RippleRef, } from '@angular/material/core'; import {FocusMonitor, FocusOrigin} from '@angular/cdk/a11y'; @@ -79,7 +82,7 @@ export class MatCheckboxBase { constructor(public _renderer: Renderer2, public _elementRef: ElementRef) {} } export const _MatCheckboxMixinBase = - mixinColor(mixinDisableRipple(mixinDisabled(MatCheckboxBase)), 'accent'); + mixinTabIndex(mixinColor(mixinDisableRipple(mixinDisabled(MatCheckboxBase)), 'accent')); /** @@ -104,13 +107,13 @@ export const _MatCheckboxMixinBase = '[class.mat-checkbox-label-before]': 'labelPosition == "before"', }, providers: [MAT_CHECKBOX_CONTROL_VALUE_ACCESSOR], - inputs: ['disabled', 'disableRipple', 'color'], + inputs: ['disabled', 'disableRipple', 'color', 'tabIndex'], encapsulation: ViewEncapsulation.None, preserveWhitespaces: false, changeDetection: ChangeDetectionStrategy.OnPush }) export class MatCheckbox extends _MatCheckboxMixinBase implements ControlValueAccessor, - AfterViewInit, OnDestroy, CanColor, CanDisable, CanDisableRipple { + AfterViewInit, OnDestroy, CanColor, CanDisable, HasTabIndex, CanDisableRipple { /** * Attached to the aria-label attribute of the host element. In most cases, arial-labelledby will @@ -156,9 +159,6 @@ export class MatCheckbox extends _MatCheckboxMixinBase implements ControlValueAc /** Whether the label should appear after or before the checkbox. Defaults to 'after' */ @Input() labelPosition: 'before' | 'after' = 'after'; - /** Tabindex value that is passed to the underlying input element. */ - @Input() tabIndex: number = 0; - /** Name value will be applied to the input element if present */ @Input() name: string | null = null; @@ -199,8 +199,11 @@ export class MatCheckbox extends _MatCheckboxMixinBase implements ControlValueAc constructor(renderer: Renderer2, elementRef: ElementRef, private _changeDetectorRef: ChangeDetectorRef, - private _focusMonitor: FocusMonitor) { + private _focusMonitor: FocusMonitor, + @Attribute('tabindex') tabIndex: string) { super(renderer, elementRef); + + this.tabIndex = parseInt(tabIndex) || 0; } ngAfterViewInit() {