useSelect
Hook that manages select dropdown state, keyboard navigation, and popup positioning.
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, andfilterPropsreturn spread-ready prop objects- Composes
useListboxinternally — the returnedlistboxinstance provides option iteration, selection state, anduseListboxOptionsupport show(),hide(),toggle(), andfocus()for imperative popup and trigger controlgetSelectedOptionLabel()andhasValue()for reading the current selectionfilterPropsfor integrating a search input inside the popupsetRendered()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 });Popup Control#
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)
});Popup Behavior#
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.
| Part | State Attributes |
|---|---|
trigger | data-positioner-open |
popup | data-open |
indicator | data-open, data-closed |
Options rendered via useListboxOption use data-scope="listbox" with the following state attributes.
| Part | State Attributes |
|---|---|
option | data-selected, data-unselected, data-focused, data-disabled |
optionindicator | data-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#
| Name | Type | Default |
|---|---|---|
value | unknown | — |
| The current selected value of the select. | ||
defaultValue | unknown | — |
| The default selected value when used in uncontrolled mode. | ||
filterValue | string | — |
| The current filter text value (controlled). | ||
defaultFilterValue | string | — |
| The default filter text value when used in uncontrolled mode. | ||
open | boolean | — |
| Controlled open state of the select overlay. | ||
defaultOpen | boolean | — |
| Default open state for uncontrolled mode. | ||
options | unknown[] | — |
| An array of options to display. | ||
optionKey | string | — |
| Unique key for each option. | ||
optionLabel | string | — |
| Label field for each option. | ||
optionValue | string | — |
| Value field for each option. | ||
optionDisabled | string | — |
| Field to check if an option is disabled. | ||
optionGroupLabel | string | — |
| Label field for option groups. | ||
optionGroupChildren | string | — |
| Field that contains the children options in a group. | ||
disabled | boolean | — |
| When present, it specifies that the component should be disabled. | ||
locale | string | — |
| The locale to use for localization. | ||
autoOptionFocus | boolean | — |
| When enabled, the focused option is automatically highlighted. | ||
selectOnFocus | boolean | — |
| When enabled, the focused option is automatically selected. | ||
focusOnHover | boolean | — |
| When enabled, the focused option changes on hover. | ||
metaKeySelection | boolean | — |
| When enabled, requires holding the meta key to select/deselect. | ||
multiple | boolean | — |
| When enabled, allows multiple items to be selected. | ||
filter | boolean | — |
| 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. | ||
tabIndex | number | — |
| Index of the element in tabbing order. | ||
invalid | boolean | — |
| When present, it specifies that the component is in an invalid state. | ||
ariaLabel | string | — |
| Used to define a string that labels the input element. | ||
ariaLabelledBy | string | — |
| Identifier of the underlying input element. | ||
closeOnEscape | boolean | — |
| When enabled, the overlay closes when Escape key is pressed. | ||
autoFocus | boolean | — |
| When enabled, the overlay receives focus automatically when opened. | ||
trapped | boolean | — |
| 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.