useListbox
Hook that manages listbox selection state, keyboard navigation, and option search.
- New York
- Rome
- London
- Istanbul
- Paris
Usage#
import { useListbox, useListboxOption } from '@primereact/headless/listbox';const listbox = useListbox({ options: cities, optionLabel: 'name' });
<div {...listbox.rootProps}>
<ul {...listbox.listProps}>
{listbox.getOptions().map((option, index) => {
const { optionProps, state } = useListboxOption({ option, index, context: listbox });
return <li {...optionProps}>{listbox.getOptionLabel(option)}</li>;
})}
</ul>
</div>;useListbox manages value state, keyboard focus cycling, type-ahead search, and ARIA attributes for option lists. See Primitive for a component-based API.
Features#
- Selection state, single or multiple selection with controlled or uncontrolled modes
- Keyboard navigation, arrow cycling, Home/End jumps, and built-in type-ahead that moves focus to matching options
- Option helpers,
getOptionLabel,getOptionValue,isSelected, andisOptionDisabledfor reading metadata off arbitrary option shapes - Grouping,
optionGroupLabel/optionGroupChildrenwith group header detection viauseListboxOption - Per-option hook,
useListboxOptionreturns ARIA-attributed props and state flags (selected,focused,disabled,group) for each row - Imperative hooks,
onOptionSelect(event, option, index)andonClearClick(event)for programmatic selection
Working with callbacks#
Controlled selection#
Pass value and onValueChange to drive the selection from outside state.
const [selected, setSelected] = React.useState(null);
const listbox = useListbox({
options: cities,
optionLabel: 'name',
value: selected,
onValueChange: (e) => setSelected(e.value)
});Multiple with meta-key additive selection#
Combine multiple with metaKeySelection to require Ctrl/Cmd for additive toggles, matching native multi-select semantics.
const listbox = useListbox({
options: cities,
optionLabel: 'name',
multiple: true,
metaKeySelection: true
});Grouped options#
Render group headers and options in a single pass using the per-option state from useListboxOption.
const listbox = useListbox({
options: groupedCities,
optionLabel: 'label',
optionGroupLabel: 'label',
optionGroupChildren: 'items'
});
listbox.getOptions().map((option, index) => {
const { optionProps, groupProps, state } = useListboxOption({ option, index, context: listbox });
if (state.group) return <div {...groupProps}>{listbox.getOptionGroupLabel(option)}</div>;
return <li {...optionProps}>{listbox.getOptionLabel(option)}</li>;
});Focus behavior tuning#
Use autoOptionFocus, selectOnFocus, and focusOnHover to shape how keyboard navigation and hover interact with selection.
const listbox = useListbox({
options: cities,
optionLabel: 'name',
autoOptionFocus: true,
selectOnFocus: true,
focusOnHover: true
});Styling with data attributes#
The hook exposes state through data-* attributes on each part. Use them as CSS selectors, no className juggling.
| Scope | Part | States |
|---|---|---|
listbox | option | data-selected, data-unselected, data-focused, data-disabled |
[data-scope='listbox'][data-part='option'][data-selected] {
background-color: #eff6ff;
color: #1d4ed8;
}
[data-scope='listbox'][data-part='option'][data-focused] {
outline: 1px solid #3b82f6;
}
[data-scope='listbox'][data-part='option'][data-disabled] {
opacity: 0.6;
pointer-events: none;
}API#
useListbox#
| Name | Type | Default |
|---|---|---|
useListboxOption#
Accessibility#
Arrow keys navigate options, Space selects with multi-select support, Home/End jump to ends, and Ctrl+A selects all in multiple mode. See Primitive for full WAI-ARIA compliance details.