Combobox
A searchable dropdown that combines select functionality with powerful filtering. Perfect for finding options in large lists, building command palettes, or when users need quick access through search.This component's API and documentation are under review and may change. Use with caution in production.
A searchable dropdown that combines select functionality with powerful filtering. Perfect for finding options in large lists, building command palettes, or when users need quick access through search.
Built on top of cmdk for search and filtering, and Radix Popover for positioning and focus management.
Playground
Installation
Usage
The trigger shows displayValue for the selected value. Without it, the trigger shows the raw value (for example apple, not Apple).
Anatomy
Combobox is a compound component with the following parts:
Root Props
The Root component manages state and provides context to all child components.
Trigger Props
The Trigger component renders as a button that opens the dropdown.
Trigger also supports all margin props (m, mx, my, mt, mr, mb, ml) with responsive values.
Content Props
The Content component renders the dropdown surface containing the search input and options list.
Input Props
The Input component renders the search field inside Content.
Item Props
Search matches the item's visible text, its value, and its keywords.
Other Components
Combobox.Value- ShowsdisplayValue, else the raw selected value, else the placeholderCombobox.List- Scrollable listbox that holds the items.labeloverrides its accessible nameCombobox.Group- Groups related items togetherCombobox.Label- Non-interactive heading. Inside a Group, it names the group for screen readersCombobox.Separator- Visual separator between items or groupsCombobox.Empty- Shown when no results match search. Only visible when filtering produces zero matches
Trigger Variants
Classic
Elevated style with subtle shadow for maximum visual impact.
Surface
Elevated surface style for standard form fields.
Soft
Subtle background for secondary selections.
Outline
Bordered style for clear field boundaries.
Ghost
Minimal style for utility controls.
Content Variants
Solid
Default opaque background for standard dropdowns with clear separation from the page.
Soft
Subtle background for content-heavy interfaces where less visual weight is desired.
Sizes
Set size on Root to control density across the entire combobox. Affects trigger height, content padding, and item spacing.
Colors
Use the color prop on Root to set semantic colors for the trigger and selected items. Chromatic colors highlight with step 9. Gray highlights with step 12 and inverts the text.
States
Loading
Set loading on Trigger while options are fetched. It shows a spinner, sets aria-busy, and keeps the popup closed.
Disabled
Set disabled on Root to prevent all interaction with the combobox.
Error
Use error on Trigger to indicate validation failures. It also sets aria-invalid.
Read Only
Use readOnly on Trigger to show the selected value without allowing changes. The trigger stays focusable and the popup does not open.
Groups and Labels
Organize options with groups and labels for better scannability in large lists. A Label inside a Group names that group for screen readers.
Controlled State
Control the selection and search values for full state management. Search also works uncontrolled; control it only when you need the text.
Display Value
Use the displayValue prop on Root to show a label for the selected value. Without it, the trigger shows the raw value. Keep the function stable (module scope or useCallback) so it does not run on every render.
Custom Filtering
Disable Built-in Filtering
For server-side search, disable the built-in filtering and fetch options with a data library such as React Query.
Custom Filter Function
Provide custom ranking logic for more control over search results. The item's visible text is passed as the first keyword.
Empty State
Use Combobox.Empty to provide helpful feedback when no results match the search.
Input Adornments
Add icons or elements before or after the search input for better visual context.
Responsive
Use responsive objects with size on Root to adapt sizing across different breakpoints.
Material
Use material on Trigger for the trigger background and on Content for the dropdown surface. Choose solid for opaque backgrounds, or translucent for depth over images or dynamic backgrounds. Content falls back to the Theme material.
Accessibility
The trigger follows the WAI-ARIA combobox pattern with a dialog popup. The popup holds a search field (itself a combobox) that controls the listbox of options.
Labelling
The combobox role does not take its name from its content, so the trigger needs a label. Use aria-label, aria-labelledby, or a <label htmlFor> pointing at the trigger. The same name labels the popup, the search field and the listbox. In development, an unlabelled trigger logs a warning.
Keyboard Navigation
- Space/Enter/Arrow Down - Open the dropdown when the trigger is focused
- Type - Filter options in real time
- Arrow Down/Up - Move the highlight through options
- Home/End - Jump to first/last option
- Enter - Select the highlighted option and close
- Escape - Close without selecting
- Tab - Close the dropdown and move focus to the next element
When the dropdown opens, the highlight starts on the selected option. Without a Combobox.Input, focus moves to the list so the keys above still work.
ARIA Attributes
role="combobox"witharia-haspopup="dialog",aria-expandedandaria-controlson the triggeraria-invalid,aria-busy,aria-readonlyandaria-disabledfollow theerror,loading,readOnlyanddisabledprops- The search field has
aria-controlspointing at the listbox andaria-activedescendantpointing at the highlighted option aria-selectedmarks the highlighted option;aria-checkedmarks the chosen option
Screen Readers
- The number of matching results, or "No results", is announced after typing pauses
- The chosen option is exposed with
aria-checked - Group labels name their groups
- The loading state is exposed with
aria-busy
Focus Management
- The search field receives focus when the dropdown opens
- Focus returns to the trigger when the dropdown closes
- In Windows High Contrast mode, the highlighted option shows a system outline
Changelog
Added
- Initial Combobox component with search and filtering
- Built on cmdk for fuzzy search and keyboard navigation
- Trigger variants: classic, surface, soft, outline, ghost
- Content variants: solid, soft
- Three sizes (1, 2, 3) with responsive support
- Custom filter function support via
filterprop displayValueprop for showing labels without mounting items- Groups, labels, and separators for organization
- Empty state component for no-results feedback
- Loading, error, disabled, and read-only states
- Input adornments (startAdornment, endAdornment)
- Full controlled state support (value, searchValue, open)
resetSearchOnSelectandresetSearchOnCloseoptions to control search clearingmaterialprop on Content- Result count announcements for screen readers
- Color prop for semantic styling
- Margin props with responsive support
- Windows High Contrast mode support
- Reduced motion support for animations
Removed
highContrastprop. Gray highlights with step 12 on its own, and text reads the strong ink by default.
Fixed
- Uncontrolled search can be typed into
- Search matches the item's visible text, not only its value
- Typing, hovering and selecting no longer re-render every item
- Hover and keyboard highlight use one source, so only one option is lit
- Opening highlights the selected option
- Responsive
sizebuilds valid class names for the search field readOnlyandloadingkeep the popup closed- Trigger ARIA matches the dialog popup and
aria-controlspoints at it - Performance optimization with lazy mounting (forceMount control)
- Focus management when opening/closing dropdown
© 2026 Kushagra Dhawan. Licensed under MIT. GitHub.