Overview
Combobox is a select whose list you can search. Type to filter, pick one value — or several, rendered as removable chips — from a list that can run into the hundreds.
Where it sits among the value controls:
- Short closed list — Select or Radio Group; opening a filterable popup for six options adds steps, not clarity.
- Long or growing list — Combobox. This component.
- Input that may not exist on any list — Autocomplete (free text with suggestions) or Tags Input (collect many free values).
- Running commands — Command. A combobox commits values; it never performs actions.
Anatomy
The field combines an input (which both filters and displays the selection), a popup of filtered options, and in multiple mode a chip per selected value with its own remove control. Optional parts cover everything real lists need: ComboboxGroup/ComboboxGroupLabel for structure, ComboboxEmpty for zero matches, ComboboxStatus for result counts, ComboboxClear for one-click reset, and ComboboxTrigger when the field should open like a select rather than type-first.
Behavior
Keyboard.
Filtering matches against option labels as you type. When nothing matches, ComboboxEmpty states that plainly — an empty popup with no message reads as breakage.
Multiple mode. Set multiple and every choice becomes a chip instead of replacing the input's text. Chips are individually removable without reopening the popup, and the input keeps filtering for the next pick. Selections survive further searching because they are held by reference, not by what the input currently shows.
Result status. With async data, ComboboxStatus reports how many options matched — the difference between "3 results" and a silently shorter list.
States
Disabled fields skip focus and submission. Invalid state follows aria-invalid with a danger border, announced to assistive technology; pair it with a FieldError explaining what to do. While options load asynchronously, keep the previous list visible and show loading via ComboboxStatus rather than blanking the popup — a flash of "no matches" during fetch teaches people their data is gone.
Long labels wrap inside the popup; chips truncate with ellipsis and expose their full label through aria-label. Colors come from tokens; layout mirrors in RTL because the popup anchors logically.
Accessibility
The input carries its accessible name from your visible label. The filtered list is a proper listbox: screen readers announce option count as you type, which option is highlighted, and each chip's name for removal ("Remove Riya Patel"). Nothing depends on color or position — selected options are marked by state, not styling alone.
Typeahead plus count announcements make large lists workable non-visually, but option copy still matters: put distinguishing words first ("Invoice INV-2042", not "INV-2042 — an invoice").
Installation
Usage
import {
Combobox,
ComboboxEmpty,
ComboboxInput,
ComboboxItem,
ComboboxList,
ComboboxPopup,
} from "@/components/ui/combobox";<Combobox items={teammates}>
<ComboboxPopup>
<ComboboxInput placeholder="Search teammates…" />
<ComboboxList>
{(item) => (
<ComboboxItem key={item.value} value={item}>
{item.label}
</ComboboxItem>
)}
</ComboboxList>
<ComboboxEmpty>No teammates match.</ComboboxEmpty>
</ComboboxPopup>
</Combobox>Don't do this
A closed set behind an open-texture control
// Bad
<Combobox items={[{ label: "Small" }, { label: "Medium" }, { label: "Large" }]} />// Good
<Select items={sizes} />When the whole list fits under a thumb, search is ceremony: people must type to see what they could have scanned instantly. Filtering pays off only when scanning costs more than typing — dozens of options, or ones people already know by name.
Silently empty while loading
// Bad
<ComboboxPopup>
{loading ? null : <ComboboxList>…</ComboboxList>}
{/* shows an empty popup mid-fetch */}
</ComboboxPopup>// Good
<ComboboxPopup>
<ComboboxStatus>{loading ? "Loading…" : `${matches.length} results`}</ComboboxStatus>
<ComboboxList>…</ComboboxList>
</ComboboxPopup>An unexplained blank list mid-fetch announces "no such person exists", and users conclude the feature is broken before the network answers. Say what is happening where the results would appear.
Examples
Multiple selection with chips
Grouped options
Clearable
In a form
API reference
Parts: ComboboxInput, ComboboxTrigger, ComboboxPopup, ComboboxList, ComboboxItem, ComboboxChip(s), ComboboxGroup(Label), ComboboxEmpty, ComboboxStatus, ComboboxClear, ComboboxValue.
See the Base UI Combobox API.