Skip to content

Commit 7b8ef4d

Browse files
committed
fix(cdk/a11y): activeItem out of date if active index is removed from ListKeyManager
Fixes the `activeItem` on the `ListKeyManager` not matching the item at the `activeItemIndex`, if the `activeItem` is removed from the list. Fixes #14345.
1 parent 70120bd commit 7b8ef4d

File tree

2 files changed

+20
-4
lines changed

2 files changed

+20
-4
lines changed

src/cdk/a11y/key-manager/list-key-manager.spec.ts

+15-2
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,28 @@ describe('Key managers', () => {
8282
spyOn(keyManager, 'setActiveItem').and.callThrough();
8383
});
8484

85-
it('should maintain the active item if the amount of items changes', () => {
85+
it('should maintain the active item if the amount of items changes', fakeAsync(() => {
8686
expect(keyManager.activeItemIndex).toBe(0);
8787
expect(keyManager.activeItem!.getLabel()).toBe('one');
8888
itemList.reset([new FakeFocusable('zero'), ...itemList.toArray()]);
8989
itemList.notifyOnChanges();
90+
tick();
9091

9192
expect(keyManager.activeItemIndex).toBe(1);
9293
expect(keyManager.activeItem!.getLabel()).toBe('one');
93-
});
94+
}));
95+
96+
it('should keep the active item in sync if the active item is removed', fakeAsync(() => {
97+
expect(keyManager.activeItemIndex).toBe(0);
98+
expect(keyManager.activeItem!.getLabel()).toBe('one');
99+
100+
itemList.reset(itemList.toArray().slice(1));
101+
itemList.notifyOnChanges();
102+
tick();
103+
104+
expect(keyManager.activeItemIndex).toBe(0);
105+
expect(keyManager.activeItem!.getLabel()).toBe('two');
106+
}));
94107

95108
it('should start off the activeItem as null', () => {
96109
expect(new ListKeyManager([]).activeItem).toBeNull();

src/cdk/a11y/key-manager/list-key-manager.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,11 @@ export class ListKeyManager<T extends ListKeyManagerOption> {
7070
const itemArray = newItems.toArray();
7171
const newIndex = itemArray.indexOf(this._activeItem);
7272

73-
if (newIndex > -1 && newIndex !== this._activeItemIndex) {
74-
this._activeItemIndex = newIndex;
73+
if (newIndex !== this._activeItemIndex) {
74+
// Timeout is required to avoid "changed after checked" errors.
75+
setTimeout(() => {
76+
this.updateActiveItem(newIndex > -1 ? newIndex : this._activeItemIndex);
77+
}, 0);
7578
}
7679
}
7780
});

0 commit comments

Comments
 (0)