Combobox
Searchable single-select input. Composes Popover + Command (cmdk) + a styled trigger. Pass a list of { value, label } options.
Default
Pre-selected
Disabled
Installation
pnpm
pnpm dlx @hex-core/cli add comboboxAPI Reference
| Prop | Type | Default | Description |
|---|---|---|---|
optionsrequired | object | — | Array of { value: string, label: string, disabled?: boolean } |
value | string | — | Controlled selected option value |
onChange | function | — | Callback when the user picks an option: (value: string) => void |
placeholder | string | Select… | Text shown on the trigger when nothing is selected |
searchPlaceholder | string | Search… | Placeholder for the filter input |
emptyText | string | No results found. | Shown inside the list when the search has no matches |
disabled | boolean | false | Disable the trigger |
aria-label | string | — | Accessible label — required when no adjacent visible <label> is used |
AI Guidance
When to use
Use for a select input when the list is >~8 items or users benefit from typing to narrow. Fuzzy search + keyboard nav + selected-item checkmark.
When not to use
Don't use for native-select parity on mobile (use Select). Don't use for multi-select (this component is single-value — compose Command + Popover yourself for multi). Don't use for free-text entry (use Input).
Common mistakes
- Passing duplicate option values (breaks selection and filtering)
- Two options with identical labels — cmdk dedupes by the Item's filter value (the label here), so one will be dropped from the list
- Using the label as the value — fine if stable, but prefer a short stable `value` string
- Forgetting to bind value + onChange — uncontrolled mode doesn't exist on this wrapper
- Mixing translated labels without keying on value — label changes won't update selection
- Missing aria-label when there's no adjacent visible <label>
Accessibility
Trigger has role='combobox' + aria-expanded. Popover traps focus inside the CommandInput. Options are announced via cmdk's aria-activedescendant wiring.
Token budget: 900