| 68 | providers: [{provide: LISTBOX, useExisting: Listbox}], |
| 69 | }) |
| 70 | export class Listbox<V> implements OnDestroy { |
| 71 | /** A unique identifier for the listbox. */ |
| 72 | readonly id = input(inject(_IdGenerator).getId('ng-listbox-', true)); |
| 73 | |
| 74 | /** A reference to the host element. */ |
| 75 | private readonly _elementRef = inject(ElementRef); |
| 76 | |
| 77 | /** A reference to the host element. */ |
| 78 | readonly element = this._elementRef.nativeElement as HTMLElement; |
| 79 | |
| 80 | /** The collection of Options. */ |
| 81 | readonly _collection = new SortedCollection<Option<V>>(); |
| 82 | |
| 83 | /** A signal wrapper for directionality. */ |
| 84 | protected readonly textDirection = inject(Directionality).valueSignal.asReadonly(); |
| 85 | |
| 86 | /** Whether the list is vertically or horizontally oriented. */ |
| 87 | readonly orientation = input<'vertical' | 'horizontal'>('vertical'); |
| 88 | |
| 89 | /** Whether multiple items in the list can be selected at once. */ |
| 90 | readonly multi = input(false, {transform: booleanAttribute}); |
| 91 | |
| 92 | /** Whether focus should wrap when navigating. */ |
| 93 | readonly wrap = input(true, {transform: booleanAttribute}); |
| 94 | |
| 95 | /** |
| 96 | * Whether to allow disabled items to receive focus. When `true`, disabled items are |
| 97 | * focusable but not interactive. When `false`, disabled items are skipped during navigation. |
| 98 | */ |
| 99 | readonly softDisabled = input(true, {transform: booleanAttribute}); |
| 100 | |
| 101 | /** |
| 102 | * The focus strategy used by the list. |
| 103 | * - `roving`: Focus is moved to the active item using `tabindex`. |
| 104 | * - `activedescendant`: Focus remains on the listbox container, and `aria-activedescendant` is used to indicate the active item. |
| 105 | */ |
| 106 | readonly focusMode = input<'roving' | 'activedescendant'>('roving'); |
| 107 | |
| 108 | /** |
| 109 | * The selection strategy used by the list. |
| 110 | * - `follow`: The focused item is automatically selected. |
| 111 | * - `explicit`: Items are selected explicitly by the user (e.g., via click or spacebar). |
| 112 | */ |
| 113 | readonly selectionMode = input<'follow' | 'explicit'>('follow'); |
| 114 | |
| 115 | /** The amount of time before the typeahead search is reset. */ |
| 116 | readonly typeaheadDelay = input<number>(500); // Picked arbitrarily. |
| 117 | |
| 118 | /** Whether the listbox is disabled. */ |
| 119 | readonly disabled = input(false, {transform: booleanAttribute}); |
| 120 | |
| 121 | /** Whether the listbox is readonly. */ |
| 122 | readonly readonly = input(false, {transform: booleanAttribute}); |
| 123 | |
| 124 | /** The tabindex of the listbox. */ |
| 125 | readonly tabIndex = input(undefined, { |
| 126 | alias: 'tabindex', |
| 127 | transform: tabIndexTransform, |
nothing calls this directly
no test coverage detected
searching dependent graphs…