Combobox

Searchable dropdown for selecting from a list of options with keyboard navigation

Primitive

The combobox is a text input paired with a filtered, keyboard-navigable list of options. Use it for searchable selects, tag pickers, async autocompletes, or any select-from-many flow with more options than a dropdown comfortably holds.

Preview

Installation

Usage

Composition

Examples

Creatable

Let users add an option that isn't in the list from their typed input.

Multiple Selection

Pass multiple on Combobox to select more than one option.

Input Inside Popup

Move ComboboxInput inside ComboboxPopup so the search field sits in the dropdown.

Select country

Icons and Adornments

Pass start and end to ComboboxInput to place content inside the field. Use start for a leading search icon and end for trailing content like an async loading spinner. The end slot sits before the built-in clear and trigger buttons, so the chevron stays at the trailing edge.

Load options from a remote source by fetching on input changes. The useAsyncCombobox hook handles request cancellation, loading states, and keeps the selected value visible while new results stream in.

Async Search (Multiple)

Combine async search with multiple; selected items stay visible in the dropdown while new matches load.

Grouped

Wrap items in ComboboxGroup with a ComboboxGroupLabel for sticky section headers.

Selecting by ID

When your app stores IDs rather than item objects, build the list with createComboboxItems. getValue sets each item's selection value and getLabel sets the text used in the input and for filtering. The list still renders your full objects, but value and onValueChange work with the IDs, so pass the ID to ComboboxItem's value.

Stored value: u_2

Virtualized

Use ComboboxVirtualizedList for large lists (100+ items); it only renders items in the viewport, dramatically reducing DOM nodes.

Key concepts:

  1. Use useListVirtualizer hook - Handles scroll positioning, keyboard navigation, and item measurement. See useListVirtualizer docs for full API reference.
  2. Use useComboboxFilteredItems() inside Root - Call useComboboxFilteredItems() in a child component of Combobox to get internally filtered items without manual filtering boilerplate.
  3. Replace ComboboxList with ComboboxVirtualizedList - Accepts scrollRef and totalSize from the hook.
  4. Pass virtualized and items on Root - Enables virtualized mode with your full item list.
  5. Use useHighlightHandler - Pass a virtualizerRef to the child and use useHighlightHandler(virtualizerRef) on Root so keyboard navigation scrolls to the highlighted item.
  6. Override item margins - Pass className="mt-0! mb-0!" to ComboboxItem since virtualized items are absolutely positioned and the virtualizer handles padding.

Elevated Variant

Use variant="elevated" on ComboboxInput for a Card, Dialog, or popover surface, where the opaque default input would collapse into its parent. See the Surfaces docs.

On a Card surface
Use variant="elevated" on ComboboxInput when the combobox sits inside a Card, Dialog, or popover.
ValueDescription
defaultOpaque bg-input, for standard page backgrounds.
elevatedTranslucent bg-input-elevated, for Card, Dialog, or popovers.

Form Integration

Use Field with FieldLabel for labeling. See the Forms guide for more patterns.

API Reference

The Combobox component is built on top of Base UI's Combobox. All Base UI props are supported. The documentation below only covers custom props and modified defaults specific to our implementation.

For the complete Base UI API, see the Base UI Combobox documentation.

Props

ComboboxInput

Text input with built-in trigger and clear buttons. Wraps Base UI's Combobox.Input inside a Combobox.InputGroup.

ComboboxTriggerLabel

Accessible label for the input-inside-popup pattern, where the trigger is the form control. Wraps Base UI's Combobox.Label. Renders a <div>; clicking it focuses the trigger without opening the popup.

For the standard combobox pattern (input outside popup), use ComboboxLabel which renders a native <label> associated with the input.

ComboboxPopup

Dropdown container for the option list with positioning. Composes Base UI's Combobox.Positioner and Combobox.Popup. Positioning props (side, align, sideOffset, and so on) are forwarded to the Positioner; remaining props are forwarded to Combobox.Popup.

ComboboxList

Scrollable list of selectable options. Wraps Base UI's Combobox.Listbox.

ComboboxVirtualizedList

Virtualized scrollable container for large lists. Use with useListVirtualizer hook for optimal performance with 100+ items.

Hooks

useComboboxFilteredItems

Returns the internally filtered items from the Combobox Root. Must be called inside Combobox (Root). Simplifies virtualized implementations by eliminating manual query state, useDeferredValue, useFilter(), and useMemo filtering.

createComboboxItems

Builds a collection for the items prop from flat or grouped data. Each item's selection value comes from getValue, which must return a primitive (usually a stable ID), and its display and filter label from getLabel. Items can't have their own items array field, since that marks a group.

Create static collections at module scope. For data that loads or changes at runtime, wrap the call in React.useMemo() keyed on the data.