Introducing PrimeReact v11-alpha 🎉Discover Now

useListbox

Hook that manages listbox selection state, keyboard navigation, and option search.

  • New York
  • Rome
  • London
  • Istanbul
  • Paris
basic-demo

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, and isOptionDisabled for reading metadata off arbitrary option shapes
  • Grouping — optionGroupLabel / optionGroupChildren with group header detection via useListboxOption
  • Per-option hook — useListboxOption returns ARIA-attributed props and state flags (selected, focused, disabled, group) for each row
  • Imperative hooks — onOptionSelect(event, option, index) and onClearClick(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.

ScopePartStates
listboxoptiondata-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#

NameTypeDefault
valueunknown—
The current value of the listbox. For single selection, this is a single value. For multiple selection, this is an array of values.
defaultValueunknown—
The default value of the listbox when used in uncontrolled mode.
optionsT[]—
An array of options to display in the listbox.
optionKeystring—
Unique key for each option.
optionLabelstring—
Label field for each option.
optionValuestring—
Value field for each option.
optionDisabledstring—
Field to check if an option is disabled.
optionGroupLabelstring—
Label field for option groups.
optionGroupChildrenstring—
Field that contains the children options in a group.
disabledboolean—
When present, it specifies that the listbox should be disabled.
invalidboolean—
When present, it specifies that the component should have invalid state style.
localestring—
The locale to use for localization. Used for accessibility labels.
multipleboolean—
When present, allows selecting multiple options.
metaKeySelectionboolean—
When enabled, requires holding the meta key (Ctrl/Cmd) to select/deselect items in multiple selection mode.
autoOptionFocusboolean—
When enabled, the focused option is automatically highlighted.
selectOnFocusboolean—
When enabled, the focused option is automatically selected.
focusOnHoverboolean—
When enabled, the focused option changes on hover.
tabIndexnumber—
Index of the element in tabbing order.
onValueChange(event: useListboxValueChangeEvent) => void—
Callback to invoke when the value changes.

useListboxOption#

NameTypeDefault
optionunknown—
The option data object.
indexnumber—
The index of the option in the list.
groupbooleanfalse
Whether the option is a group header.
disabledbooleanfalse
Whether the option is disabled.
contextuseListboxInstance—
The parent listbox instance providing state and methods.

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.