---
title: Combo box (React) - USWDS + Tailwind
description: Help people find and select an option from a long list with a
  searchable combo box.
---

# Combo box

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

## Examples

### Default

```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

```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.

| Prop | Type | Default | Description |
| - | - | - | - |
| `options` | `{ value: string; label: string }[]` | `[]` | Options available for selection. |
| `defaultValue` | `string` | `—` | Initial selected value. |
| `onValueChange` | `({ value: string; label: string }) => void` | `—` | Receives selection changes. |
| `disableFiltering` | `boolean` | `false` | Shows supplied options without built-in filtering. |
| `disabled` | `boolean` | `false` | Disables selection. |
| `required` | `boolean` | `—` | Requires a value. |
| `showClearButton` | `boolean` | `true` | Renders the clear button when true. |
| `showToggleButton` | `boolean` | `true` | Renders the toggle button when true. |
| `filter` | `string` | `.*{{query}}.*` | Regex template matched against each option label. Defaults to .\*{{query}}.\*; query substitutions are escaped literal text. |
| `filterExtras` | `Record<string, string>` | `—` | Capture-group regexes for additional placeholders in filter. The first capture replaces its placeholder. |
| `ariaDisabled` | `boolean` | `false` | Marks the control disabled for assistive technology while keeping it operable. |
| `name` | `string` | `—` | 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. |

| Attribute | Value | Purpose |
| - | - | - |
| `data-state` | `open \| closed` | Style the open and closed states. |
| `data-disabled` | `Present when disabled` | Style 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.

| Prop | Type | Description |
| - | - | - |
| `children` | `ReactNode \| ({ options }) => ReactNode` | Can render from filtered options. |

| Attribute | Value | Purpose |
| - | - | - |
| `data-state` | `open \| closed` | Style 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.

| Prop | Type | Description |
| - | - | - |
| `id` | `string (required)` | Generated ID from the rendered option. |
| `value` | `string (required)` | Option value. |
| `label` | `string (required)` | Option label. |

| Attribute | Value | Purpose |
| - | - | - |
| `aria-selected` | `true \| false` | Styles the selected option. |
| `data-highlighted` | `Present when highlighted` | Styles the highlighted option. |
| `data-value` | `Option value` | Identifies 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.
