Skip to content

Commit ee20441

Browse files
authored
fix(aria/listbox): allow navigation to specific index (#33485)
Currently users are only able to programmatically focus the first option in a listbox which may not be enough for some cases. These changes add a `gotoIndex` method that should be a bit more flexible. Fixes #33483.
1 parent 4738e8b commit ee20441

2 files changed

Lines changed: 16 additions & 6 deletions

File tree

‎goldens/aria/listbox/index.api.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export class Listbox<V> implements OnDestroy {
1919
readonly element: HTMLElement;
2020
readonly focusMode: _angular_core.InputSignal<"roving" | "activedescendant">;
2121
gotoFirst(): void;
22+
gotoIndex(index: number): void;
2223
readonly id: _angular_core.InputSignal<string>;
2324
readonly multi: _angular_core.InputSignalWithTransform<boolean, unknown>;
2425
// (undocumented)

‎src/aria/listbox/listbox.ts‎

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,16 +136,15 @@ export class Listbox<V> implements OnDestroy {
136136
/** The ID of the active descendant in the listbox. */
137137
readonly activeDescendant: Signal<string | undefined>;
138138

139-
constructor() {
140-
// Map directives to their patterns for the ListboxPattern
141-
const orderedItemPatterns = computed(() =>
142-
this._collection.orderedItems().map(option => option._pattern),
143-
);
139+
private readonly _orderedItemPatterns = computed(() =>
140+
this._collection.orderedItems().map(option => option._pattern),
141+
);
144142

143+
constructor() {
145144
const inputs = {
146145
...this,
147146
id: this.id,
148-
items: orderedItemPatterns,
147+
items: this._orderedItemPatterns,
149148
activeItem: signal(undefined),
150149
textDirection: this.textDirection,
151150
element: () => this._elementRef.nativeElement,
@@ -210,4 +209,14 @@ export class Listbox<V> implements OnDestroy {
210209
gotoFirst() {
211210
this._pattern.listBehavior.first();
212211
}
212+
213+
/** Navigates to an item at a specific index in the listbox. */
214+
gotoIndex(index: number) {
215+
const patterns = this._orderedItemPatterns();
216+
const item = patterns[Math.min(Math.max(index, 0), patterns.length - 1)];
217+
218+
if (item) {
219+
this._pattern.listBehavior.goto(item);
220+
}
221+
}
213222
}

0 commit comments

Comments
 (0)