diff --git a/src/lib/checkbox/checkbox.spec.ts b/src/lib/checkbox/checkbox.spec.ts index d6d829f37c0f..a14e901772d8 100644 --- a/src/lib/checkbox/checkbox.spec.ts +++ b/src/lib/checkbox/checkbox.spec.ts @@ -33,6 +33,7 @@ describe('MdCheckbox', () => { CheckboxWithChangeEvent, CheckboxWithFormControl, CheckboxWithoutLabel, + CheckboxWithTabindexAttr, ], providers: [ {provide: ViewportRuler, useClass: FakeViewportRuler} @@ -677,6 +678,20 @@ describe('MdCheckbox', () => { }); + 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 86096cd2861d..6b7f730c1533 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, @@ -26,11 +27,14 @@ import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms'; import { CanColor, CanDisable, - CanDisableRipple, MATERIAL_COMPATIBILITY_MODE, + CanDisableRipple, + HasTabIndex, + MATERIAL_COMPATIBILITY_MODE, MdRipple, mixinColor, mixinDisabled, mixinDisableRipple, + mixinTabIndex, RippleRef, } from '@angular/material/core'; import {FocusMonitor, FocusOrigin} from '@angular/cdk/a11y'; @@ -79,7 +83,7 @@ export class MdCheckboxBase { constructor(public _renderer: Renderer2, public _elementRef: ElementRef) {} } export const _MdCheckboxMixinBase = - mixinColor(mixinDisableRipple(mixinDisabled(MdCheckboxBase)), 'accent'); + mixinTabIndex(mixinColor(mixinDisableRipple(mixinDisabled(MdCheckboxBase)), 'accent')); /** @@ -105,13 +109,13 @@ export const _MdCheckboxMixinBase = }, providers: [MD_CHECKBOX_CONTROL_VALUE_ACCESSOR], viewProviders: [{provide: MATERIAL_COMPATIBILITY_MODE, useValue: true}], - inputs: ['disabled', 'disableRipple', 'color'], + inputs: ['disabled', 'disableRipple', 'color', 'tabIndex'], encapsulation: ViewEncapsulation.None, preserveWhitespaces: false, changeDetection: ChangeDetectionStrategy.OnPush }) export class MdCheckbox extends _MdCheckboxMixinBase implements ControlValueAccessor, AfterViewInit, - OnDestroy, CanColor, CanDisable, CanDisableRipple { + OnDestroy, CanColor, CanDisable, CanDisableRipple, HasTabIndex { /** * Attached to the aria-label attribute of the host element. In most cases, arial-labelledby will @@ -157,9 +161,6 @@ export class MdCheckbox extends _MdCheckboxMixinBase implements ControlValueAcce /** 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; @@ -200,8 +201,11 @@ export class MdCheckbox extends _MdCheckboxMixinBase implements ControlValueAcce 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() {