Skip to content

Commit ddae877

Browse files
committed
refactor(cdk/a11y): switch active index to signal internally
Turns the `_activeIndex` of the key manager into a signal internally to help resolve "changed after checked" errors in some components.
1 parent eb9abc3 commit ddae877

File tree

1 file changed

+12
-12
lines changed

1 file changed

+12
-12
lines changed

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

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export type ListKeyManagerModifierKey = 'altKey' | 'ctrlKey' | 'metaKey' | 'shif
3939
* of items, it will set the active item correctly when arrow events occur.
4040
*/
4141
export class ListKeyManager<T extends ListKeyManagerOption> {
42-
private _activeItemIndex = -1;
42+
private _activeItemIndex = signal(-1);
4343
private _activeItem = signal<T | null>(null);
4444
private _wrap = false;
4545
private _typeaheadSubscription = Subscription.EMPTY;
@@ -209,7 +209,7 @@ export class ListKeyManager<T extends ListKeyManagerOption> {
209209
this.updateActiveItem(item);
210210

211211
if (this._activeItem() !== previousActiveItem) {
212-
this.change.next(this._activeItemIndex);
212+
this.change.next(this._activeItemIndex());
213213
}
214214
}
215215

@@ -279,7 +279,7 @@ export class ListKeyManager<T extends ListKeyManagerOption> {
279279

280280
case PAGE_UP:
281281
if (this._pageUpAndDown.enabled && isModifierAllowed) {
282-
const targetIndex = this._activeItemIndex - this._pageUpAndDown.delta;
282+
const targetIndex = this._activeItemIndex() - this._pageUpAndDown.delta;
283283
this._setActiveItemByIndex(targetIndex > 0 ? targetIndex : 0, 1);
284284
break;
285285
} else {
@@ -288,7 +288,7 @@ export class ListKeyManager<T extends ListKeyManagerOption> {
288288

289289
case PAGE_DOWN:
290290
if (this._pageUpAndDown.enabled && isModifierAllowed) {
291-
const targetIndex = this._activeItemIndex + this._pageUpAndDown.delta;
291+
const targetIndex = this._activeItemIndex() + this._pageUpAndDown.delta;
292292
const itemsLength = this._getItemsArray().length;
293293
this._setActiveItemByIndex(targetIndex < itemsLength ? targetIndex : itemsLength - 1, -1);
294294
break;
@@ -312,7 +312,7 @@ export class ListKeyManager<T extends ListKeyManagerOption> {
312312

313313
/** Index of the currently active item. */
314314
get activeItemIndex(): number | null {
315-
return this._activeItemIndex;
315+
return this._activeItemIndex();
316316
}
317317

318318
/** The active item. */
@@ -337,12 +337,12 @@ export class ListKeyManager<T extends ListKeyManagerOption> {
337337

338338
/** Sets the active item to the next enabled item in the list. */
339339
setNextItemActive(): void {
340-
this._activeItemIndex < 0 ? this.setFirstItemActive() : this._setActiveItemByDelta(1);
340+
this._activeItemIndex() < 0 ? this.setFirstItemActive() : this._setActiveItemByDelta(1);
341341
}
342342

343343
/** Sets the active item to a previous enabled item in the list. */
344344
setPreviousItemActive(): void {
345-
this._activeItemIndex < 0 && this._wrap
345+
this._activeItemIndex() < 0 && this._wrap
346346
? this.setLastItemActive()
347347
: this._setActiveItemByDelta(-1);
348348
}
@@ -366,7 +366,7 @@ export class ListKeyManager<T extends ListKeyManagerOption> {
366366

367367
// Explicitly check for `null` and `undefined` because other falsy values are valid.
368368
this._activeItem.set(activeItem == null ? null : activeItem);
369-
this._activeItemIndex = index;
369+
this._activeItemIndex.set(index);
370370
this._typeahead?.setCurrentSelectedItemIndex(index);
371371
}
372372

@@ -398,7 +398,7 @@ export class ListKeyManager<T extends ListKeyManagerOption> {
398398
const items = this._getItemsArray();
399399

400400
for (let i = 1; i <= items.length; i++) {
401-
const index = (this._activeItemIndex + delta * i + items.length) % items.length;
401+
const index = (this._activeItemIndex() + delta * i + items.length) % items.length;
402402
const item = items[index];
403403

404404
if (!this._skipPredicateFn(item)) {
@@ -414,7 +414,7 @@ export class ListKeyManager<T extends ListKeyManagerOption> {
414414
* it encounters either end of the list, it will stop and not wrap.
415415
*/
416416
private _setActiveInDefaultMode(delta: -1 | 1): void {
417-
this._setActiveItemByIndex(this._activeItemIndex + delta, delta);
417+
this._setActiveItemByIndex(this._activeItemIndex() + delta, delta);
418418
}
419419

420420
/**
@@ -456,8 +456,8 @@ export class ListKeyManager<T extends ListKeyManagerOption> {
456456
if (activeItem) {
457457
const newIndex = newItems.indexOf(activeItem);
458458

459-
if (newIndex > -1 && newIndex !== this._activeItemIndex) {
460-
this._activeItemIndex = newIndex;
459+
if (newIndex > -1 && newIndex !== this._activeItemIndex()) {
460+
this._activeItemIndex.set(newIndex);
461461
this._typeahead?.setCurrentSelectedItemIndex(newIndex);
462462
}
463463
}

0 commit comments

Comments
 (0)