Combobox
Searchable dropdown for selecting from a filterable list of options.
Building blocks: Combobox, ComboboxInput, ComboboxContent, ComboboxList, ComboboxItem, plus chips for multi-select (ComboboxChips, ComboboxChip, ComboboxChipsInput, useComboboxAnchor). For a closed button that opens a searchable list, use ComboboxTriggerButton + ComboboxSearch inside the popup. Popup lists use ScrollArea with edge hints.
Filtering requires this structure (Base UI):
- Pass
items={...}onCombobox(the filterable collection). - Put
ComboboxEmptyas a sibling ofComboboxList, not inside it. - Give
ComboboxLista single function child(item) => <ComboboxItem value={item}>….
Static <ComboboxItem> children without items never filter — you’ll see the full list and “No results” together. That was the old Radix-style demo shape.
autoHighlight (optional) highlights the first match while typing. Prefer Form.Combobox in product forms — see Form.
Basic
Multiple (chips)
Base UI / shadcn pattern: multiple + ComboboxChips + ComboboxValue (render chips) + list function child. Type to filter, pick items, remove with chip ×.
With groups
Picker (button trigger)
Closed control, search inside the popup — the pattern for long grouped catalogs. size="sm" on ComboboxContent densifies labels and rows; ComboboxSearch is the padded in-popup field.
With clear button
Disabled
With disabled items
Form.Combobox
RHF wrapper around the same composition. Field values stay string / string[]. With creatable, a synthetic list item is appended when the query has no exact match (Base UI creatable pattern) — selecting it commits the new string.
External search
For server-backed catalogs, control the query with inputValue and onInputValueChange, and set filterMode="external". External mode renders items as supplied instead of applying Base UI’s client filter a second time. loading shows loadingMessage (default Loading…) and temporarily suppresses a speculative Create row. Selecting, creating, or clearing sends an empty query through onInputValueChange; debounce or fetch from that callback as needed.
const [query, setQuery] = useState("");
<Form.Combobox
multiple
creatable
items={results}
inputValue={query}
onInputValueChange={setQuery}
filterMode="external"
loading={fetching}
loadingMessage="Searching tags…"
/>;Selected chips are retained when an external result page is replaced, including the last known option label. Omit these props for the existing client-filtered, internally managed behavior.
Reference
ComboboxContent
| Prop | Type | Default | Description |
|---|---|---|---|
size | "md" | "sm" | "md" | Popup list density for items and group labels |
align | "start" | "center" | "end" | "start" | Alignment along the trigger edge |
ComboboxTriggerButton
Button-styled trigger for the picker layout. Defaults to variant="secondary", size="sm", font-normal. Pass variant="ghost" to blend into a toolbar.
ComboboxSearch
Padded search field for inside the popup. Use with ComboboxTriggerButton. Do not put ComboboxInput in the popup by hand — this owns the inset.
ComboboxList
| Prop | Type | Default | Description |
|---|---|---|---|
flush | boolean | true outside a popup, false inside ComboboxContent | Drop the bottom gutter so an inline list can sit against a parent scroller or footer. Popup lists keep the highlight-radius gutter. |
ComboboxItem / ComboboxLabel
size is inherited from ComboboxContent. indicator={false} selects with accent fill instead of a check column.