Combobox
A searchable select input that combines a text input with a dropdown list. Built on @base-ui/react with type-to-filter, keyboard navigation, single and multi-select modes, chip display, and animated transitions.
Anatomy
<Combobox> wraps a <ComboboxInput> (search input with optional trigger/clear buttons) and <ComboboxContent> (the dropdown). Content holds <ComboboxList> with <ComboboxItem> elements. For multi-select, use <ComboboxChips> in place of <ComboboxInput>.
Sub-components
| Component | Purpose |
|---|---|
Combobox | Root provider (alias for ComboboxPrimitive.Root) |
ComboboxInput | Search input with optional trigger/clear buttons (showTrigger, showClear) |
ComboboxContent | Dropdown content with positioning and animation |
ComboboxList | Scrollable option list |
ComboboxItem | Individual selectable option |
ComboboxGroup / ComboboxLabel | Grouped options with label |
ComboboxEmpty | Empty state shown when no items match |
ComboboxSeparator | Visual divider between groups |
ComboboxChips / ComboboxChip | Multi-select chip display |
ComboboxChipsInput | Text input embedded inside the chips container |
useComboboxAnchor | Hook to anchor the popup to the chips container |
Examples
Basic
Single-select with type-to-filter and keyboard navigation.
With clear button
Add showClear to display a reset button once a value is selected.
With groups
Use ComboboxGroup, ComboboxLabel, and ComboboxSeparator to organize items into categories.
Custom items
Render any content inside ComboboxItem — icons, avatars, badges, etc.
Multiple selection (chips)
Pass multiple to the root and use ComboboxChips + useComboboxAnchor to anchor the popup to the chip container.
Disabled
Pass disabled to ComboboxInput to prevent interaction.
Invalid state
Pass aria-invalid to ComboboxInput for form validation feedback.
Auto highlight
Pass autoHighlight to the root to automatically highlight the first matching item as the user types.
Design Guidelines
Do
- Use for large option sets. When users need to search/filter through many items (countries, users, tags).
- Provide an empty state. Show a helpful message via
ComboboxEmptywhen no results match. - Use chips for multi-select.
ComboboxChipsprovides clear visual feedback for selected items. - Show the trigger icon. The dropdown arrow (
showTrigger) helps users discover it's a select-like input.
Don't
- Don't use for small option sets. Under 5 items, a simple Select or RadioGroup is better.
- Don't forget ComboboxEmpty. Without it, users see a blank dropdown when nothing matches.
- Don't use for free-text input. Combobox is for selecting from a predefined list, not entering arbitrary values.
Code
Basic / clear button
<Combobox>
{/* showClear reveals an ✕ button once a value is selected */}
<ComboboxInput placeholder="Search frameworks..." showTrigger showClear />
<ComboboxContent>
<ComboboxList>
<ComboboxEmpty>No frameworks found.</ComboboxEmpty>
<ComboboxItem value="next">Next.js</ComboboxItem>
<ComboboxItem value="remix">Remix</ComboboxItem>
<ComboboxItem value="astro">Astro</ComboboxItem>
</ComboboxList>
</ComboboxContent>
</Combobox>With groups
<Combobox>
<ComboboxInput placeholder="Search libraries..." showTrigger />
<ComboboxContent>
<ComboboxList>
<ComboboxEmpty>No results found.</ComboboxEmpty>
<ComboboxGroup>
<ComboboxLabel>Frontend</ComboboxLabel>
<ComboboxItem value="react">React</ComboboxItem>
<ComboboxItem value="vue">Vue</ComboboxItem>
</ComboboxGroup>
<ComboboxSeparator />
<ComboboxGroup>
<ComboboxLabel>Backend</ComboboxLabel>
<ComboboxItem value="express">Express</ComboboxItem>
<ComboboxItem value="fastify">Fastify</ComboboxItem>
</ComboboxGroup>
</ComboboxList>
</ComboboxContent>
</Combobox>Multiple selection with chips
const [selected, setSelected] = useState<string[]>([])
const anchor = useComboboxAnchor()
<Combobox multiple value={selected} onValueChange={(val) => setSelected(val)}>
<ComboboxChips ref={anchor}>
{selected.map((val) => (
<ComboboxChip key={val}>{val}</ComboboxChip>
))}
<ComboboxChipsInput placeholder="Search frameworks..." />
</ComboboxChips>
<ComboboxContent anchor={anchor}>
<ComboboxList>
<ComboboxEmpty>No frameworks found.</ComboboxEmpty>
<ComboboxItem value="next">Next.js</ComboboxItem>
<ComboboxItem value="remix">Remix</ComboboxItem>
</ComboboxList>
</ComboboxContent>
</Combobox>Disabled / invalid / auto-highlight
{/* Disabled */}
<ComboboxInput disabled showTrigger placeholder="..." />
{/* Invalid — triggers red ring via InputGroup's has-[[aria-invalid=true]] selector */}
<ComboboxInput aria-invalid showTrigger placeholder="..." />
{/* Auto highlight first match while typing */}
<Combobox autoHighlight>
<ComboboxInput placeholder="Start typing..." showTrigger />
...
</Combobox>Accessibility
- Built on Base UI Combobox — implements the WAI-ARIA combobox pattern.
- Active item is tracked via
data-highlighted; selected item viadata-selected. - Arrow keys navigate, Enter selects, Escape closes.
aria-invalidonComboboxInputactivates the destructive ring via the parentInputGroup's CSS selector.- Popup animates with slide-in, fade-in, and zoom-in on open; reverses on close.