Combobox
Text input that filters a list as you type and commits one value, with optional off-list custom values.
Description
Combobox is built on React Aria's ComboBox: the trigger is a text input, so you type to filter the list, arrow through matches, and commit one value. It composes a Combobox.Input and a Combobox.Popover surface holding Combobox.Item rows, with optional Combobox.Section, Combobox.Label, and Combobox.Footer slots. The list, items, and section headings are the same surface as Dropdown and Select, so a row looks identical across all three. size is set on the root and cascades through context to every item, label, and icon.
Reach for it when the set of options is long enough that scrolling is slower than typing, or when the value might not be in the list at all. With allowsCustomValue the field accepts a value you type that no option matches, which is the one thing a Select cannot do. It binds to a Field like any other control and inherits its size and invalid/disabled/loading state.
The free tier covers the input trigger, plain Combobox.Item rows, the empty state, custom values, and the three sizes. Smart items (a leading media slot, a secondary description, a trailing slot) and grouped Combobox.Section + Combobox.Label are Pro, matching the Dropdown tiers. Do not use a combobox when the choices are few and always visible (use Select or a Radio Group), or for a list of commands rather than values (use Dropdown).
Installation
Anatomy
Usage
Examples
The free tier covers the input, plain Combobox.Item rows, the empty state, and custom values. Richer previews (smart items, grouped sections) are marked with a Pro badge; the live demo still runs, but the source needs a Pro seat.
Sizes
Three sizes (xs, sm, md) set on the root cascade to the input shell, item height, label, and icon size. sm is the default.
Custom value
Pass allowsCustomValue to accept a typed value that no option matches. Pair it with allowsEmptyCollection so the popover stays open to show the empty state as you type.
Token picker
Smart items with a brand icon, a price description, and a trailing holdings amount, grouped under section headers. A grouped combobox filters its own data: keep inputValue controlled, compute the matching groups yourself, and pass them as items on the root (rendered with a function child on Combobox.Popover plus a Collection for each group's items). This bypasses React Aria's built-in filter, which does not support sections.
Member picker
A searchable assignee list with an Avatar, a name, and a secondary email, grouped into suggested and all members.
Accessibility
Combobox inherits React Aria's combobox interaction model. The input owns DOM focus and carries role="combobox" with aria-expanded; arrow keys drive virtual focus (aria-activedescendant) in the role="listbox" popup while you keep typing.
ARIA notes:
- Give the
Comboboxanaria-label(or wrap it in aFieldwith aLabel) when there is no visible label; the accessible name lands on the input. - The popover closes when the filtered list is empty. Set
allowsEmptyCollectionon the root to keep it open sorenderEmptyState(a no-match hint) can show. - With
allowsCustomValue, committing text that matches no option keeps that text as the value instead of clearing the field; without it, an unmatched entry reverts on blur. - For the full focus, filtering, and selection behavior, see the React Aria ComboBox docs.
Styling
Tailwind override: pass className to merge Tailwind classes on Combobox.Input (the shell), Combobox.Popover, or any sub-part (merged via cn()):
Data slots and attributes: the component sets these for CSS targeting:
data-slot="combobox-input"on the text input,combobox-triggeron the chevron toggle button,combobox-chevronon the icon,combobox-contenton the surface, andcombobox-listboxon the list. Rows carrycombobox-item, groupscombobox-group, headingscombobox-label. The item internals reuse the dropdown slots:dropdown-item-container/dropdown-item-content/dropdown-item-label/dropdown-item-description/dropdown-item-indicator, plusdropdown-footer.data-size="xs" | "sm" | "md"mirrors the root size; the chevron button carriesdata-state="open" | "closed".- The input trigger reuses the
Inputshell, so itsfocus-within,invalid,disabled, andloadingborders are identical to a plainInput. - React Aria manages
data-focused,data-selected, anddata-disabledon each item; wrappers style throughgroup-data-[focused]/itemandgroup-data-[selected]/item.
Target a state in CSS:
Related Components
- Select: form-value picker whose trigger is a button showing the value. Use it when the options are a fixed, known set and free text is not needed.
- Dropdown Menu: the same list surface opened from a button, for commands and actions rather than a value.
- Command (Pro): a searchable command palette in a modal shell.
API Reference
Combobox.* reuses the Dropdown/Select item surface, so item props match Select.Item. The combobox-specific parts are the root, Combobox.Input, and Combobox.Popover.
Combobox
The root. Wraps React Aria's ComboBox, so its selection, input, and collection props pass through. Provides the size/state context.
Props
Variants
Combobox.Input
The trigger: a text input in the shared Input shell with a trailing chevron toggle. The interior is a slot row, so it hosts leading and trailing content beside the input at the right size, gap, and padding. Pass the selected item's media (a flag, an avatar) as startContent to keep it visible in the field, or a clear button as endContent. Extends the native input props.
Props
Combobox.Popover
The floating surface (alias Combobox.Content). Renders the ListBox. Extends React Aria's PopoverProps; defaults to placement="bottom start" and offset={8}.
Props
Combobox.Item
A list row. Mirrors Select.Item. A plain label with an optional leading media, value (alias for id), and size are free; description, trailing, and indicator opt into the smart layout (Pro). textValue, isDisabled, and the React Aria ListBoxItem props pass through. The typed filter matches against textValue (derived from a plain-text label).