Skip to main content

Combo box

Help people find and select an option from a long list with a searchable combo box.

Examples

Default

Breakpoints

Mobile

320px

Mobile Lg

480px

Tablet

640px

Desktop

1024px
combo-box-demo.tsx
import { Combobox } from '@uswds-tailwind/react'
const options = [
{ value: 'apple', label: 'Apple' },
{ value: 'apricot', label: 'Apricot' },
{ value: 'avocado', label: 'Avocado' },
{ value: 'banana', label: 'Banana' },
]
export default function ComboBoxDemo() {
return (
<div className="max-w-lg">
<Combobox.Root options={options}>
<Combobox.Label>Select a fruit</Combobox.Label>
<Combobox.Control>
<Combobox.Input />
<Combobox.IndicatorGroup>
<Combobox.ClearButton />
<Combobox.ToggleButton />
</Combobox.IndicatorGroup>
</Combobox.Control>
<Combobox.List>
{({ options }) => (
<>
{options.map(option => (
<Combobox.Item key={option.id} {...option}>
{option.label}
</Combobox.Item>
))}
<Combobox.EmptyItem />
</>
)}
</Combobox.List>
</Combobox.Root>
</div>
)
}

With Default Value

Breakpoints

Mobile

320px

Mobile Lg

480px

Tablet

640px

Desktop

1024px
combo-box-default-value-demo.tsx
import { Combobox } from '@uswds-tailwind/react'
const options = [
{ value: 'apple', label: 'Apple' },
{ value: 'apricot', label: 'Apricot' },
{ value: 'avocado', label: 'Avocado' },
{ value: 'banana', label: 'Banana' },
]
export default function ComboBoxDefaultValueDemo() {
return (
<div className="max-w-lg">
<Combobox.Root options={options} defaultValue="banana">
<Combobox.Label>Select a fruit</Combobox.Label>
<Combobox.Control>
<Combobox.Input />
<Combobox.IndicatorGroup>
<Combobox.ClearButton />
<Combobox.ToggleButton />
</Combobox.IndicatorGroup>
</Combobox.Control>
<Combobox.List>
{({ options }) => (
<>
{options.map(option => (
<Combobox.Item key={option.id} {...option}>
{option.label}
</Combobox.Item>
))}
<Combobox.EmptyItem />
</>
)}
</Combobox.List>
</Combobox.Root>
</div>
)
}

Component API

Root owns options and selection. Place Label, Control, Input, List, and option Item parts inside it. List supplies generated item IDs through its render callback.

Root<div>

Owns selection, query, filtering, and open state.

PropTypeDefaultDescription
options{ value: string; label: string }[][]Options available for selection.
defaultValuestring—Initial selected value.
onValueChange({ value: string; label: string }) => void—Receives selection changes.
disableFilteringbooleanfalseShows supplied options without built-in filtering.
disabledbooleanfalseDisables selection.
requiredboolean—Requires a value.
showClearButtonbooleantrueRenders the clear button when true.
showToggleButtonbooleantrueRenders the toggle button when true.
filterstring.*{{query}}.*Regex template matched against each option label. Defaults to .*{{query}}.*; query substitutions are escaped literal text.
filterExtrasRecord<string, string>—Capture-group regexes for additional placeholders in filter. The first capture replaces its placeholder.
ariaDisabledbooleanfalseMarks the control disabled for assistive technology while keeping it operable.
namestring—Machine form-bridge name. The React parts do not render a hidden select; use your own form bridge for the committed value.
ids{ root?: string; label?: string; input?: string; list?: string; trigger?: string; clearTrigger?: string }—Overrides generated part IDs. Use Root IDs when a label or external control needs a stable input or trigger target.
AttributeValuePurpose
data-stateopen | closedStyle the open and closed states.
data-disabledPresent when disabledStyle the disabled state.

Label<label>

Names the combobox.

Control<div>

Groups the input and option buttons.

Input<input>

Receives filter text.

List<ul>

Displays matching options.

PropTypeDescription
childrenReactNode | ({ options }) => ReactNodeCan render from filtered options.
AttributeValuePurpose
data-stateopen | closedStyle the open and closed states.

Item<li>

Spread an option from List's render callback onto Item so its generated id, value, and label stay together.

PropTypeDescription
idstring (required)Generated ID from the rendered option.
valuestring (required)Option value.
labelstring (required)Option label.
AttributeValuePurpose
aria-selectedtrue | falseStyles the selected option.
data-highlightedPresent when highlightedStyles the highlighted option.
data-valueOption valueIdentifies the option.

EmptyItem<li>

Displays when no options match.

IndicatorGroup<div>

Groups the clear and toggle buttons.

ClearButton<button>

Clears the selected option.

ToggleButton<button>

Opens or closes the option list.

Accessibility

Provide a visible Label or another accessible name. Keep Item indices aligned with the filtered options passed to List.