BridgeComfortable

Previews use

Applies to every design system preview on the site. The Bridge app chrome stays the same.

Brand

Density

Combobox

Stable

A text input that filters a list of options as the user types, then selects one or several of them. Built for long lists and async search (people, repositories, tokens).

Updated Oct 16, 2026

Rendered with the real component
Light
Dark

When to use

Use it for

  • Choosing from a long or growing list where typing is faster than scrolling: reviewers, repositories, components, tokens.
  • Results come from a server: control inputValue, fetch, pass the results as options with filter={null} and loading while waiting.
  • Several values from a long list (multiple): selected values become removable chips inside the field.

Not for

  • Short known lists (under about ten): use Select, which needs no typing.
  • Free text with suggestions (a search box): the value must be one of the options here, so use Input or an autocomplete pattern.
  • Two or three options: use RadioGroup.

Do and don't

Every example is rendered with the real component, so it always matches what ships.

Do

Add a second line when names are ambiguous

A role or an email under the name helps pick the right Ada, and is matched by screen readers too.

Do

Write an empty message that says what to try

"No one matches. Check the spelling or invite them." turns a dead end into a next step.

Don't

Spinner with no words

While loading, say what is happening ("Searching people"). The message is also announced to screen readers.

Don't

Combobox for a handful of fixed options

Typing to find one of three themes is slower than seeing them. Use Select or RadioGroup.

Accessibility

  • Base UI Combobox: the input has role combobox with aria-expanded, aria-controls and aria-activedescendant; the popup is a listbox.
  • Keyboard: typing filters; Down Arrow opens and moves; Enter selects; Escape closes, then clears; with multiple, Left Arrow from the start of the input moves through the chips and Backspace removes one.
  • loading renders the message in a live status region and sets aria-busy on the popup; the empty message is announced the same way.
  • The clear and toggle buttons inside the field have accessible names ("Clear selection", "Show options"); each chip remove button says "Remove <name>".
  • The Field label names the input; hint and error are linked through aria-describedby.
  • The popup is portaled and re-applies the theme, brand and density of its field.

Anatomy and tokens

Read from packages/react/src/components/Combobox/Combobox.module.css at build time. Every value is a token: open one to see its alias chain in both themes.

51 tokens 29 semantic or component, change with theme and brand 6 density, change with comfortable or compact 16 from the shared scales

Props

Parsed from the TypeScript types in packages/react/src/components/Combobox/Combobox.tsx, so this table cannot drift from the code. It also accepts every native <input> attribute except value, defaultValue, onChange, size, prefix, children.

Prop Type Default Description
options required ComboboxOption[] none The options to filter. For async search, pass the latest results and set `filter={null}`.
multiple boolean false Pick several values, shown as removable chips.
value ComboboxValue none Selected value (controlled): a string, an array with `multiple`, or null.
defaultValue ComboboxValue none Initially selected value (uncontrolled).
onValueChange (value: ComboboxValue) => void none Called with the new value (string, string[] with `multiple`, or null).
inputValue string none Text in the input (controlled). Use it to drive an async search.
defaultInputValue string none No description in the code yet.
onInputValueChange (inputValue: string) => void none Called on every keystroke with the query.
filter ((option: ComboboxOption, query: string) => boolean) | null none Custom matcher, or `null` to show `options` as given (already filtered by a server). Default: case and accent insensitive "contains".
loading boolean false Results are loading: shows a spinner row, sets aria-busy and announces `loadingMessage`.
loadingMessage string 'Loading results' Announced and shown while loading. Default "Loading results".
emptyMessage ReactNode 'No matches. Try another name.' Shown when no option matches. Say what to try next.
label string none Visible label. When set, the Combobox wraps itself in a Field. Leave unset inside a Field.
hint ReactNode none Help under the label (Field description). Only with `label`.
error ReactNode none Error message. Only with `label`.
hideLabel boolean none No description in the code yet.
size 'sm' | 'md' | 'lg' 'md' Height follows the density tokens. Default `md`.
prefix ReactNode none Content before the query, usually a search Icon.
open boolean none Popup open state (controlled).
defaultOpen boolean none No description in the code yet.
onOpenChange (open: boolean) => void none No description in the code yet.

Playground

Change the props and see the real Combobox update. Controls are generated from the TypeScript props; nothing here changes the system.

<Combobox label="Reviewer" placeholder="Search people" />
size

Workbench

For contributors: every state with the accessibility panel, in the component workbench (Storybook). The stories double as visual test fixtures; the guidance on this page is the user documentation (open Combobox in Storybook) .

Embed Storybook stories here (8)

Loads from https://bridge-storybook.floriangouloubi.com (set STORYBOOK_URL at build time). If Storybook is not running, the frames stay empty.

Default

Grouped

Multiple

WithError

Open

AsyncSearch

Loading

AllStates

Changelog

  • New

    Forms: Field (label, description, error wired by Base UI Field) and Input rebuilt on it (prefix, suffix, sizes; label, hint and error props kept). New Textarea (autosize, character count), Select (groups, descriptions), Combobox (filtering, async loading and empty states, multiple with chips), Checkbox (indeterminate, parent), CheckboxGroup, RadioGroup, Switch, Slider (single and range), NumberField (steppers, units) and Form (server errors with a focusable error summary, FormActions footer).

    Unreleased (current version 0.1.0, no release tagged yet) , Oct 17, 2026

All release notes