Usage
Tracks the active option of a single-select combobox and handles its keys, while DOM focus stays on the control. It powers Selector and CommandPalette; use it to build a combobox those components do not cover. It renders nothing and sets no attributes: the caller renders the control, the listbox and the options, and wires role, aria-expanded, aria-controls and aria-activedescendant from what it returns.
tsimport {useCombobox} from '@astryxdesign/core/Selector'
Best practices
| Guidance | Practices |
|---|---|
| Do | Render each option with |
| Do | For type-to-select without a search field, run useTypeahead's handler first and fall through to this |
| Do | Announce the number of results through useAnnounce when the options change for a new query. |
| Don't | Move DOM focus onto the options; the active option is announced through |
Parameters
| Param | Type | Description |
|---|---|---|
optionsrequired | UseComboboxOptions | Configuration object. |
options.selectableItemsrequired | [] | The options in the same order as they render. Options with |
options.isOpenrequired | boolean | Whether the list is shown. The caller owns this state. |
options.onOpenrequired | () => unknown | Called to show the list. Return |
options.onCloserequired | () => void | Called when the hook hides the list; the hook resets the highlight first. When the caller closes the list itself (an outside press, say), it should also call |
options.listboxIdrequired | string | The listbox element's id. Option ids are derived from it through |
options.value | string | The selected value. Without search, opening by a press, Enter or Space highlights it, or the first option when nothing is selected; ArrowDown and ArrowUp open on the first and last option. |
options.onSelect | (value: string) => void | Called with the picked value. Picking also closes the list. |
options.onClear | () => void | Clears the value. When provided, Delete or Backspace on the closed control clears it, so clearing is not pointer-only. Ignored while the list is open or with |
options.hasSearch | boolean (default: false) | Whether the list has its own search field. Space then types instead of picking, opening by a press or Enter does not pre-highlight (ArrowDown and ArrowUp still open on the first and last option), and printable keys on the closed control go to |
options.onSearchSeed | (char: string) => void | With |
options.isDisabled | boolean (default: false) | Whether the control ignores clicks and keys. |
Returns
| Field | Type | Description |
|---|---|---|
| highlightedIndex | number | Index of the active option, or -1 when none is active. With |
| setHighlightedIndex | (index: number) => void | Sets the active option, for example from a filter that changes the options. |
| getItemId | (index: number) => string | The id to render on the option at |
| onTriggerClick | () => void | Toggles the list from a press on the control. |
| onKeyDown | (e: React.KeyboardEvent) => void | Key handler for the control that keeps focus. ArrowDown and ArrowUp open the list or move the active option; Enter (and Space without search) picks it or opens the list; Escape and Tab close it; Home, End, PageUp and PageDown jump to the first or last option. An editable control that keeps Home and End for the caret does not pass them to this handler, as CommandPalette does. |
| onItemSelect | (item: ) => void | Picks an option from a press on it, then closes the list. |
| onItemMouseEnter | (item: , index: number) => void | Makes the hovered option active without scrolling the list or moving focus. |
Use with shadcn
Already using the shadcn registry workflow? Install the real Astryx package and a local public re-export. Component implementation source stays in Astryx. How compatibility works.
This install URL expires with the draft preview.bashnpx shadcn@4.19.0 add https://astryx-jb5599s86-fbopensource.vercel.app/shadcn/hooks/use-combobox.json