Combobox
A React source recipe with Base UI behavior and the public TIS Combobox classes and tokens.
Design
Functional preview
Running with the React source recipe distributed through shadcn and based on Base UI.
Open the React · shadcn/Base UI playground
Anatomy
- Brazil
Type to filter countries.
.ds-combobox) — wrapper with input, icon, clear, and chevron.2 Input (
.ds-combobox__input) — editable text with role="combobox".3 Icon (
.ds-combobox__icon) — optional, decorative.4 Listbox (
.ds-combobox__listbox) — popup with filterable options.5 Option (
.ds-combobox__option) — selectable item with role="option".6 Label and helper — external via
ds-field (ADR-017).
Default
- Argentina
- Brazil
- Chile
Type to filter countries.
Open listbox
Compose with ds-field for label, helper, and error. Wrap .ds-combobox and .ds-combobox__listbox in .ds-combobox-anchor to position the popup. The public ds-tis/combobox module (initComboboxes / destroyComboboxes) is required for open state, filtering, selection, and keyboard. Event: ds-combobox-change.
- Argentina
- Brazil
- Chile
- Colombia (unavailable)
Type to filter countries.
Sizes
| Size | Height | Padding |
|---|---|---|
Small (--sm) | component.combobox.height.sm (32px) | component.combobox.padding-x.sm |
Medium (--md) | component.combobox.height.md (40px) | component.combobox.padding-x.md |
Large (--lg) | component.combobox.height.lg (48px) | component.combobox.padding-x.lg |
States
Error
Disabled
Read-only
Figma API
The live component set composes the shared field (ADR-019) with a local listbox. State covers Default, Hover, Focus, and Disabled; Filled, Error, and Read-only are separate properties, like Select.
| Property | Type | Repo equivalent |
|---|---|---|
Show Label | BOOLEAN | ds-field + .ds-field__label |
Label | TEXT | .ds-field__label |
Placeholder | TEXT | placeholder no input |
Content | TEXT | valor preenchido em .ds-combobox__input |
Show Left Icon / Left Icon | BOOLEAN / INSTANCE_SWAP | .ds-combobox__icon |
Show Clear Button / Clear Icon | BOOLEAN / INSTANCE_SWAP | .ds-combobox__clear |
Chevron Icon | INSTANCE_SWAP | .ds-combobox__chevron |
Show Helper Text / Helper Text | BOOLEAN / TEXT | .ds-field__helper |
Error Message | TEXT | .ds-field__error + ds-combobox--error |
Size | VARIANT | ds-combobox--sm / --md / --lg |
State | VARIANT | Default, Hover, Focus, Disabled |
Filled / Error / Read-only | BOOLEAN | ds-combobox--filled, --error, --readonly |
Usage
When to use
Best practices
Content guidelines
| Rule | Example |
|---|---|
| Placeholder em sentence case | "Choose a country" — not "COUNTRY" |
| Options concisas e consistentes | "Brazil", "United States" |
Sempre com ds-field + label | <label for="country">Country</label> |
Related
React composition
import {
Combobox,
ComboboxAnchor,
ComboboxChevron,
ComboboxClear,
ComboboxContent,
ComboboxControl,
ComboboxField,
ComboboxInput,
ComboboxItem,
ComboboxLabel,
ComboboxList,
ComboboxPortal,
ComboboxPositioner,
} from "@/components/ui/combobox"
<Combobox items={countries} itemToStringLabel={(item) => item.label}>
<ComboboxField>
<ComboboxLabel htmlFor="country">País</ComboboxLabel>
<ComboboxAnchor>
<ComboboxControl>
<ComboboxInput id="country" placeholder="Busque um país" />
<ComboboxClear />
<ComboboxChevron />
</ComboboxControl>
<ComboboxPortal>
<ComboboxPositioner>
<ComboboxContent>
<ComboboxList>
{(item, index) => (
<ComboboxItem key={item.value} index={index} value={item}>
{item.label}
</ComboboxItem>
)}
</ComboboxList>
</ComboboxContent>
</ComboboxPositioner>
</ComboboxPortal>
</ComboboxAnchor>
</ComboboxField>
</Combobox>Implementation
- Status
- Beta
- Distribution
- Source via shadcn
Installation
Configure the namespace once in the React integration guide.
npx shadcn@latest add @tis/comboboxpnpm dlx shadcn@latest add @tis/comboboxyarn dlx shadcn@latest add @tis/comboboxbunx --bun shadcn@latest add @tis/comboboxPublic contract
- Registry item
@tis/combobox- Provider
- Base UI
- Distribution
- Source copied into the application
- Status
- Beta
Accessibility
Keyboard interaction
| Key | Action |
|---|---|
Arrow Down / Arrow Up | Moves focus between options when listbox is open |
Enter | Selects focused option and closes listbox |
Escape | Closes listbox and returns focus to input |
| Typing | Filters options (product implementation) |
Accessibility
| WCAG criterion | Requirement | Status |
|---|---|---|
| 4.1.2 Name, Role, Value (A) | role="combobox", aria-expanded, aria-controls, role="listbox" / role="option" | ✓ |
| 1.3.1 Info and Relationships (A) | Label via ds-field; error with aria-invalid + aria-describedby | ✓ |
| 2.4.11 Focus Appearance (AA) | Visible focus ring on field and options | ✓ |
Output responsibility
Preserve Base UI semantics and test real content, focus visibility, and accessible names in the consuming application.
Validation evidence
Covered by its independent Storybook output plus browser, responsive, keyboard, Axe, and bundle checks.