From 934be6f3833ba2843a8063735cb5a57c9fa6bd85 Mon Sep 17 00:00:00 2001 From: crisbeto Date: Tue, 7 Mar 2017 18:03:30 +0100 Subject: [PATCH] fix(select): unable to set a tabindex Fixes users not being able to override the `tabIndex` on `md-select`. Fixes #3474. --- src/lib/select/select.spec.ts | 13 +++++++++++-- src/lib/select/select.ts | 20 +++++++++++++------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/lib/select/select.spec.ts b/src/lib/select/select.spec.ts index aceba1735fbf..f2ada0a7fbf9 100644 --- a/src/lib/select/select.spec.ts +++ b/src/lib/select/select.spec.ts @@ -1081,10 +1081,17 @@ describe('MdSelect', () => { expect(select.getAttribute('aria-label')).toEqual('Food'); }); - it('should set the tabindex of the select to 0', () => { + it('should set the tabindex of the select to 0 by default', () => { expect(select.getAttribute('tabindex')).toEqual('0'); }); + it('should be able to override the tabindex', () => { + fixture.componentInstance.tabIndexOverride = 3; + fixture.detectChanges(); + + expect(select.getAttribute('tabindex')).toBe('3'); + }); + it('should set aria-required for required selects', () => { expect(select.getAttribute('aria-required')) .toEqual('false', `Expected aria-required attr to be false for normal selects.`); @@ -1583,7 +1590,8 @@ describe('MdSelect', () => { selector: 'basic-select', template: `
- + {{ food.viewValue }} @@ -1606,6 +1614,7 @@ class BasicSelect { isRequired: boolean; heightAbove = 0; heightBelow = 0; + tabIndexOverride: number; @ViewChild(MdSelect) select: MdSelect; @ViewChildren(MdOption) options: QueryList; diff --git a/src/lib/select/select.ts b/src/lib/select/select.ts index c0eb143bd086..b861ca65eb1c 100644 --- a/src/lib/select/select.ts +++ b/src/lib/select/select.ts @@ -99,7 +99,7 @@ export type MdSelectFloatPlaceholderType = 'always' | 'never' | 'auto'; encapsulation: ViewEncapsulation.None, host: { 'role': 'listbox', - '[attr.tabindex]': '_getTabIndex()', + '[attr.tabindex]': 'tabIndex', '[attr.aria-label]': 'placeholder', '[attr.aria-required]': 'required.toString()', '[attr.aria-disabled]': 'disabled.toString()', @@ -151,6 +151,9 @@ export class MdSelect implements AfterContentInit, ControlValueAccessor, OnDestr /** The animation state of the placeholder. */ private _placeholderState = ''; + /** Tab index for the element. */ + private _tabIndex: number = 0; + /** * The width of the trigger. Must be saved to set the min width of the overlay panel * and the width of the selected value. @@ -266,6 +269,15 @@ export class MdSelect implements AfterContentInit, ControlValueAccessor, OnDestr } private _floatPlaceholder: MdSelectFloatPlaceholderType = 'auto'; + /** Tab index for the select element. */ + @Input() + get tabIndex(): number { return this._disabled ? -1 : this._tabIndex; } + set tabIndex(value: number) { + if (typeof value !== 'undefined') { + this._tabIndex = value; + } + } + /** Combined stream of all of the child options' change events. */ get optionSelectionChanges(): Observable { return Observable.merge(...this.options.map(option => option.onSelectionChange)); @@ -452,12 +464,6 @@ export class MdSelect implements AfterContentInit, ControlValueAccessor, OnDestr } } - /** Returns the correct tabindex for the select depending on disabled state. */ - _getTabIndex() { - return this.disabled ? '-1' : '0'; - } - - /** * Sets the scroll position of the scroll container. This must be called after * the overlay pane is attached or the scroll container element will not yet be