Introducing PrimeReact v11-alpha 🎉Discover Now

useSelect

Hook that manages select dropdown state, keyboard navigation, and popup positioning.

basic-demo

Usage#

import { useSelect } from '@primereact/headless/select';
 
const select = useSelect({ options: cities, optionLabel: 'name' });
const { rootProps, triggerProps, listProps, positionerProps, popupProps, arrowProps, state, listbox } = select;
 
return (
    <div {...rootProps}>
        <button {...triggerProps}></button>
        <div {...positionerProps}>
            <div {...popupProps}>
                <ul {...listProps}></ul>
            </div>
            <div {...arrowProps} />
        </div>
    </div>
);

useSelect composes useListbox and usePopover internally, managing trigger interaction, keyboard navigation, and popup positioning — see Primitive for a component-based API.

Features#

  • rootProps, triggerProps, listProps, positionerProps, popupProps, arrowProps, indicatorProps, clearProps, and filterProps return spread-ready prop objects
  • Composes useListbox internally — the returned listbox instance provides option iteration, selection state, and useListboxOption support
  • show(), hide(), toggle(), and focus() for imperative popup and trigger control
  • getSelectedOptionLabel() and hasValue() for reading the current selection
  • filterProps for integrating a search input inside the popup
  • setRendered() controls whether the overlay has been rendered at least once, useful for lazy rendering strategies

Behavior#

Default Value#

Set defaultValue for uncontrolled selection.

const select = useSelect({ defaultValue: 'NY' });

Controlled#

Pass value and onValueChange for controlled selection state.

const [selected, setSelected] = React.useState(null);
 
const select = useSelect({
    value: selected,
    onValueChange: (e) => setSelected(e.value)
});

Option Fields#

Use optionLabel, optionValue, optionDisabled, and optionKey to map fields when options are objects.

const select = useSelect({
    options: cities,
    optionLabel: 'name',
    optionValue: 'code',
    optionDisabled: 'inactive',
    optionKey: 'code'
});

Grouped Options#

Set optionGroupLabel and optionGroupChildren to support grouped option structures.

const select = useSelect({
    options: groupedCities,
    optionLabel: 'label',
    optionGroupLabel: 'label',
    optionGroupChildren: 'items'
});

Multiple Selection#

Set multiple to allow selecting more than one item. The value becomes an array.

const select = useSelect({ multiple: true });

Focus Behavior#

Use autoOptionFocus to automatically focus the first option when the popup opens, selectOnFocus to select while navigating, and focusOnHover to move focus with mouse hover.

const select = useSelect({ autoOptionFocus: true, selectOnFocus: true });

Disabled#

Set disabled to prevent all interaction.

const select = useSelect({ disabled: true });

Use open and onOpenChange for controlled popup state, or defaultOpen for uncontrolled initial state.

const [open, setOpen] = React.useState(false);
 
const select = useSelect({
    options: cities,
    optionLabel: 'name',
    open,
    onOpenChange: (e) => setOpen(e.value)
});

Set closeOnEscape to dismiss the overlay with the Escape key, autoFocus to move focus into the overlay when it opens, and trapped to keep focus within the overlay.

const select = useSelect({ closeOnEscape: true, autoFocus: true, trapped: true });

Filter#

Use filterProps to render a search input inside the popup. Pass filterValue and onFilterValueChange for controlled filtering, or defaultFilterValue for an initial uncontrolled filter text.

const [filterValue, setFilterValue] = React.useState('');
 
const select = useSelect({
    options: cities,
    optionLabel: 'name',
    filterValue,
    onFilterValueChange: (e) => setFilterValue(e.query)
});
 
<input {...select.filterProps} placeholder="Search..." />;

Meta Key Selection#

Enable metaKeySelection to require holding the meta key (Cmd/Ctrl) to select or deselect an option.

const select = useSelect({ metaKeySelection: true });

Locale#

Set locale to control the locale used for string comparison.

const select = useSelect({ locale: 'tr-TR' });

Custom Styling with Data Attributes#

Every prop object includes data-scope="select" and a data-part that identifies the element. State-driven attributes appear or disappear automatically.

PartState Attributes
triggerdata-positioner-open
popupdata-open
indicatordata-open, data-closed

Options rendered via useListboxOption use data-scope="listbox" with the following state attributes.

PartState Attributes
optiondata-selected, data-unselected, data-focused, data-disabled
optionindicatordata-selected, data-unselected
/* Trigger focus ring */
[data-scope='select'][data-part='trigger']:focus-visible {
    outline: 2px solid var(--p-primary-color);
    outline-offset: -2px;
}
 
/* Open/close indicator rotation */
[data-scope='select'][data-part='indicator'][data-open] {
    transform: rotate(180deg);
}
 
/* Popup entrance */
[data-scope='select'][data-part='popup'][data-open] {
    border: 1px solid var(--p-content-border-color);
    border-radius: 6px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
 
/* Option states */
[data-scope='listbox'][data-part='option'][data-focused] {
    background: var(--p-surface-100);
}
[data-scope='listbox'][data-part='option'][data-selected] {
    background: var(--p-primary-color);
    color: var(--p-primary-contrast-color);
}
[data-scope='listbox'][data-part='option'][data-disabled] {
    opacity: 0.5;
    pointer-events: none;
}

API#

useSelect#

NameTypeDefault
valueunknown—
The current selected value of the select.
defaultValueunknown—
The default selected value when used in uncontrolled mode.
filterValuestring—
The current filter text value (controlled).
defaultFilterValuestring—
The default filter text value when used in uncontrolled mode.
openboolean—
Controlled open state of the select overlay.
defaultOpenboolean—
Default open state for uncontrolled mode.
optionsunknown[]—
An array of options to display.
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 component should be disabled.
localestring—
The locale to use for localization.
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.
metaKeySelectionboolean—
When enabled, requires holding the meta key to select/deselect.
multipleboolean—
When enabled, allows multiple items to be selected.
filterboolean—
When enabled, displays a filter input in the dropdown.
filterMatchMode"endsWith" | "startsWith" | "contains" | "equals"—
Defines how the filter should match options.
appendTo"body" | HTMLElement | "self"—
A valid query selector or an HTMLElement to specify where the overlay gets attached.
tabIndexnumber—
Index of the element in tabbing order.
invalidboolean—
When present, it specifies that the component is in an invalid state.
ariaLabelstring—
Used to define a string that labels the input element.
ariaLabelledBystring—
Identifier of the underlying input element.
closeOnEscapeboolean—
When enabled, the overlay closes when Escape key is pressed.
autoFocusboolean—
When enabled, the overlay receives focus automatically when opened.
trappedboolean—
When enabled, focus is trapped within the overlay.
onValueChange(event: useSelectValueChangeEvent) => void—
Callback to invoke when the selected value changes.
onFilterValueChange(event: useSelectFilterValueChangeEvent) => void—
Callback when the filter value changes.
onOpenChange(event: useSelectOpenChangeEvent) => void—
Callback to invoke when the open state changes.

Accessibility#

See Select Primitive for WAI-ARIA compliance details and keyboard support.