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

ComponentPurpose
ComboboxRoot provider (alias for ComboboxPrimitive.Root)
ComboboxInputSearch input with optional trigger/clear buttons (showTrigger, showClear)
ComboboxContentDropdown content with positioning and animation
ComboboxListScrollable option list
ComboboxItemIndividual selectable option
ComboboxGroup / ComboboxLabelGrouped options with label
ComboboxEmptyEmpty state shown when no items match
ComboboxSeparatorVisual divider between groups
ComboboxChips / ComboboxChipMulti-select chip display
ComboboxChipsInputText input embedded inside the chips container
useComboboxAnchorHook 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 ComboboxEmpty when no results match.
  • Use chips for multi-select. ComboboxChips provides 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 via data-selected.
  • Arrow keys navigate, Enter selects, Escape closes.
  • aria-invalid on ComboboxInput activates the destructive ring via the parent InputGroup's CSS selector.
  • Popup animates with slide-in, fade-in, and zoom-in on open; reverses on close.