diff --git a/src/lib/list/selection-list.spec.ts b/src/lib/list/selection-list.spec.ts index 388c93a3499c..8ff20613a8c3 100644 --- a/src/lib/list/selection-list.spec.ts +++ b/src/lib/list/selection-list.spec.ts @@ -270,6 +270,49 @@ describe('MatSelectionList', () => { }); }); + describe('with tabindex', () => { + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [MatListModule], + declarations: [ + SelectionListWithTabindexAttr, + SelectionListWithTabindexBinding, + ] + }); + + TestBed.compileComponents(); + })); + + it('should properly handle native tabindex attribute', () => { + const fixture = TestBed.createComponent(SelectionListWithTabindexAttr); + const selectionList = fixture.debugElement.query(By.directive(MatSelectionList)); + + expect(selectionList.componentInstance.tabIndex) + .toBe(5, 'Expected the selection-list tabindex to be set to the attribute value.'); + }); + + it('should support changing the tabIndex through binding', () => { + const fixture = TestBed.createComponent(SelectionListWithTabindexBinding); + const selectionList = fixture.debugElement.query(By.directive(MatSelectionList)); + + expect(selectionList.componentInstance.tabIndex) + .toBe(0, 'Expected the tabIndex to be set to "0" by default.'); + + fixture.componentInstance.tabIndex = 3; + fixture.detectChanges(); + + expect(selectionList.componentInstance.tabIndex) + .toBe(3, 'Expected the tabIndex to updated through binding.'); + + fixture.componentInstance.disabled = true; + fixture.detectChanges(); + + expect(selectionList.componentInstance.tabIndex) + .toBe(-1, 'Expected the tabIndex to be set to "-1" if selection list is disabled.'); + }); + }); + describe('with single option', () => { let fixture: ComponentFixture; let listOption: DebugElement; @@ -523,3 +566,16 @@ class SelectionListWithSelectedOption { `}) class SelectionListWithOnlyOneOption { } + +@Component({ + template: `` +}) +class SelectionListWithTabindexAttr {} + +@Component({ + template: `` +}) +class SelectionListWithTabindexBinding { + tabIndex: number; + disabled: boolean; +} diff --git a/src/lib/list/selection-list.ts b/src/lib/list/selection-list.ts index a0c4829fa8c6..0d134b5133a5 100644 --- a/src/lib/list/selection-list.ts +++ b/src/lib/list/selection-list.ts @@ -12,6 +12,7 @@ import {SelectionModel} from '@angular/cdk/collections'; import {SPACE} from '@angular/cdk/keycodes'; import { AfterContentInit, + Attribute, ChangeDetectionStrategy, ChangeDetectorRef, Component, @@ -32,16 +33,19 @@ import { import { CanDisable, CanDisableRipple, + HasTabIndex, MatLine, MatLineSetter, mixinDisabled, mixinDisableRipple, + mixinTabIndex, } from '@angular/material/core'; /** @docs-private */ export class MatSelectionListBase {} -export const _MatSelectionListMixinBase = mixinDisableRipple(mixinDisabled(MatSelectionListBase)); +export const _MatSelectionListMixinBase = + mixinTabIndex(mixinDisableRipple(mixinDisabled(MatSelectionListBase))); /** @docs-private */ export class MatListOptionBase {} @@ -188,10 +192,10 @@ export class MatListOption extends _MatListOptionMixinBase moduleId: module.id, selector: 'mat-selection-list', exportAs: 'matSelectionList', - inputs: ['disabled', 'disableRipple'], + inputs: ['disabled', 'disableRipple', 'tabIndex'], host: { 'role': 'listbox', - '[attr.tabindex]': '_tabIndex', + '[tabIndex]': 'tabIndex', 'class': 'mat-selection-list', '(focus)': 'focus()', '(keydown)': '_keydown($event)', @@ -202,11 +206,8 @@ export class MatListOption extends _MatListOptionMixinBase preserveWhitespaces: false, changeDetection: ChangeDetectionStrategy.OnPush }) -export class MatSelectionList extends _MatSelectionListMixinBase - implements FocusableOption, CanDisable, CanDisableRipple, AfterContentInit { - - /** Tab index for the selection-list. */ - _tabIndex = 0; +export class MatSelectionList extends _MatSelectionListMixinBase implements FocusableOption, + CanDisable, CanDisableRipple, HasTabIndex, AfterContentInit { /** The FocusKeyManager which handles focus. */ _keyManager: FocusKeyManager; @@ -217,16 +218,14 @@ export class MatSelectionList extends _MatSelectionListMixinBase /** The currently selected options. */ selectedOptions: SelectionModel = new SelectionModel(true); - constructor(private _element: ElementRef) { + constructor(private _element: ElementRef, @Attribute('tabindex') tabIndex: string) { super(); + + this.tabIndex = parseInt(tabIndex) || 0; } ngAfterContentInit(): void { this._keyManager = new FocusKeyManager(this.options).withWrap(); - - if (this.disabled) { - this._tabIndex = -1; - } } /** Focus the selection-list. */