ListBox overview
TailNG ListBox ships as headless primitives. Use tngListbox on the owned list container and tngOption on each option host to keep roving focus, selection, and typeahead behavior consistent while you fully control the DOM.
Imports
Primitive import
import { TngListboxDirective, TngOptionDirective } from '@tailng-ui/primitives';
Usage baseline
Listbox primitive usage
<div
tngListbox
tabindex="0"
[multiple]="true"
[value]="selectedValues()"
(valueChange)="selectedValues.set(toArray($event))"
>
@for (option of options; track option.id) {
<div tngOption [tngValue]="option.id">{{ option.label }}</div>
}
</div>
Listbox variants
The same primitive contract rendered with an owned plain-CSS shell and a light Tailwind shell.
Plain CSS listbox
Accessibility baseline
Keyboard and ARIA contracts for deterministic interaction behavior.
Components integration
Shared primitives and wrappers for TailNG form controls.
Styling contracts
State hooks and CSS contracts for custom product skins.
Testing harness
Regression suites for keyboard, pointer, and typeahead behavior.
Wrapper roadmap (disabled)
Upcoming wrapper exploration for richer listbox composition.
selected: Components integration
Tailwind listbox
Accessibility baseline
Keyboard and ARIA contracts for deterministic interaction behavior.
Components integration
Shared primitives and wrappers for TailNG form controls.
Styling contracts
State hooks and CSS contracts for custom product skins.
Testing harness
Regression suites for keyboard, pointer, and typeahead behavior.
Wrapper roadmap (disabled)
Upcoming wrapper exploration for richer listbox composition.
selected: Styling contracts
Behavior baseline
- Arrow keys drive active option roving inside the focused listbox.
Spacetoggles active selection andEntercommits selection.- Typeahead is enabled by default for printable keys.
Tableaves the current listbox; option nodes stay out of the normal tab order.- State hooks are exposed through
data-active,data-selected, anddata-disabled.