Design guidance
ComboBox is the right choice when your list has many options (more than ~7) and you want to help users narrow options via text. For shorter, fixed lists, consider Select instead.
▾
When to use ComboBox vs Select
| Situation | Recommendation |
|---|---|
| Short list (<7 items), no typing needed | Use Select |
| Long list, users filter by typing | Use ComboBox |
| Free-form text + suggestions | Use ComboBox with allowsCustomValue |
| Async search (server-side filtering) | Use ComboBox with onInputChange |
Anatomy
- Label — always visible above the field (never placeholder-only).
- Input — text field where the user types.
- Dropdown button — chevron that opens/closes the listbox.
- Listbox — filtered options rendered in a popover.
- Description / error text — below the field for help and validation.
Basic ComboBox (S2)
import {ComboBox, Item} from '@react-spectrum/s2'; <ComboBox label="Component"> <Item>Button</Item> <Item>ComboBox</Item> <Item>TextField</Item> </ComboBox>
Controlled with async loading
import {ComboBox, Item} from '@react-spectrum/s2'; import {useAsyncList} from 'react-stately'; function AsyncComboBox() { const list = useAsyncList({ async load({signal, filterText}) { const res = await fetch( `/api/search?q=${filterText}`, {signal} ); const json = await res.json(); return {items: json.results}; }, }); return ( <ComboBox label="Search" items={list.items} inputValue={list.filterText} onInputChange={list.setFilterText} loadingState={list.loadingState} onLoadMore={list.loadMore}> {(item) => <Item key={item.id}>{item.name}</Item>} </ComboBox> ); }
Key props — ComboBox (S2)
| Prop | Type | Description |
|---|---|---|
label | ReactNode | Always provide a label for accessibility. |
inputValue | string | Controlled text input value. |
selectedKey | Key | Controlled selected item key. |
onInputChange | (value: string) => void | Fires on every keystroke. |
onSelectionChange | (key: Key) => void | Fires when user picks an option. |
allowsCustomValue | boolean | Allows free-form text not in the list. |
loadingState | 'loading' | 'loadingMore' | 'idle' | … | Shows spinner in appropriate state. |
isDisabled | boolean | Disables the combobox. |