diff --git a/src/cdk/a11y/list-key-manager.spec.ts b/src/cdk/a11y/list-key-manager.spec.ts index 1209d1c38490..3a2924900a7f 100644 --- a/src/cdk/a11y/list-key-manager.spec.ts +++ b/src/cdk/a11y/list-key-manager.spec.ts @@ -7,6 +7,7 @@ import {ActiveDescendantKeyManager} from './activedescendant-key-manager'; import {FocusKeyManager} from './focus-key-manager'; import {ListKeyManager} from './list-key-manager'; import {FocusOrigin} from './focus-monitor'; +import {Subject} from 'rxjs/Subject'; class FakeFocusable { @@ -23,11 +24,13 @@ class FakeHighlightable { } class FakeQueryList extends QueryList { + changes = new Subject>(); items: T[]; get length() { return this.items.length; } get first() { return this.items[0]; } toArray() { return this.items; } some() { return this.items.some.apply(this.items, arguments); } + notifyOnChanges() { this.changes.next(this); } } @@ -71,6 +74,17 @@ describe('Key managers', () => { spyOn(keyManager, 'setActiveItem').and.callThrough(); }); + it('should maintain the active item if the amount of items changes', () => { + expect(keyManager.activeItemIndex).toBe(0); + expect(keyManager.activeItem!.getLabel()).toBe('one'); + + itemList.items.unshift(new FakeFocusable('zero')); + itemList.notifyOnChanges(); + + expect(keyManager.activeItemIndex).toBe(1); + expect(keyManager.activeItem!.getLabel()).toBe('one'); + }); + describe('Key events', () => { it('should emit tabOut when the tab key is pressed', () => { diff --git a/src/cdk/a11y/list-key-manager.ts b/src/cdk/a11y/list-key-manager.ts index 89a01d01fb06..d11782a0d8bf 100644 --- a/src/cdk/a11y/list-key-manager.ts +++ b/src/cdk/a11y/list-key-manager.ts @@ -50,7 +50,18 @@ export class ListKeyManager { // Buffer for the letters that the user has pressed when the typeahead option is turned on. private _pressedLetters: string[] = []; - constructor(private _items: QueryList) { } + constructor(private _items: QueryList) { + _items.changes.subscribe((newItems: QueryList) => { + if (this._activeItem) { + const itemArray = newItems.toArray(); + const newIndex = itemArray.indexOf(this._activeItem); + + if (newIndex > -1 && newIndex !== this._activeItemIndex) { + this._activeItemIndex = newIndex; + } + } + }); + } /** * Stream that emits any time the TAB key is pressed, so components can react