Combobox
An input field with an attached dropdown that allows users to search and select from a list of options.
Anatomy
Import and assemble the component:
1import { Combobox } from "@raystack/apsara";23<Combobox>4 <Combobox.Label />5 <Combobox.Input />6 <Combobox.Clear />7 <Combobox.Content>8 <Combobox.Empty />9 <Combobox.Status />10 <Combobox.Group>11 <Combobox.GroupLabel />12 <Combobox.Item />13 </Combobox.Group>14 <Combobox.Separator />15 </Combobox.Content>16</Combobox>
Usage
A combobox filters its list as the user types. The props below cover what the list holds, how many items can be picked, and who owns the value.
Basic
A simple combobox with search filtering built in. Type to filter options.
1<Combobox>2 <Combobox.Input placeholder="Enter a fruit" />3 <Combobox.Content>4 <Combobox.Item>Apple</Combobox.Item>5 <Combobox.Item>Banana</Combobox.Item>6 <Combobox.Item>Grape</Combobox.Item>7 <Combobox.Item>Orange</Combobox.Item>8 </Combobox.Content>9</Combobox>
With icons
You can pass the leadingIcon prop to Combobox.Item to display icons before item text.
1<Combobox>2 <Combobox.Input placeholder="Select a fruit" width={240} />3 <Combobox.Content>4 <Combobox.Item value="apple" leadingIcon={<Info size={16} />}>5 Apple6 </Combobox.Item>7 <Combobox.Item value="banana" leadingIcon={<X size={16} />}>8 Banana9 </Combobox.Item>10 <Combobox.Item value="grape" leadingIcon={<Home size={16} />}>11 Grape12 </Combobox.Item>13 <Combobox.Item value="orange" leadingIcon={<Laugh size={16} />}>14 Orange
With Field
Wrap the Combobox with Field to add a label, description, and error handling.
1<Field label="Favorite Fruit" description="Choose your favorite fruit">2 <Combobox>3 <Combobox.Input placeholder="Select a fruit" width={240} />4 <Combobox.Content>5 <Combobox.Item value="apple">Apple</Combobox.Item>6 <Combobox.Item value="banana">Banana</Combobox.Item>7 <Combobox.Item value="blueberry">Blueberry</Combobox.Item>8 <Combobox.Item value="grapes">Grapes</Combobox.Item>9 </Combobox.Content>10 </Combobox>11</Field>
Groups and separators
Organize items into groups with Combobox.GroupLabel and separators. Groups, group labels, and separators are hidden while the user is searching.
1<Combobox>2 <Combobox.Input placeholder="Search items" width={240} />3 <Combobox.Content>4 <Combobox.Group>5 <Combobox.GroupLabel>Fruits</Combobox.GroupLabel>6 <Combobox.Item value="apple">Apple</Combobox.Item>7 <Combobox.Item value="banana">Banana</Combobox.Item>8 </Combobox.Group>9 <Combobox.Separator />10 <Combobox.Group>11 <Combobox.GroupLabel>Vegetables</Combobox.GroupLabel>12 <Combobox.Item value="carrot">Carrot</Combobox.Item>13 <Combobox.Item value="broccoli">Broccoli</Combobox.Item>14 </Combobox.Group>
Multiple selection
Pass the multiple prop to enable multi-select. Selected values appear as chips in the input. Items display checkboxes in multiple mode.
The input shows the first two chips and a "+N" count for the rest. Press Backspace in an empty input to remove the last value. Press Left Arrow at the start of the input to move focus to the chips. On a focused chip, press Backspace or Delete to remove it.
1<Combobox multiple>2 <Combobox.Input placeholder="Select fruits" width={300} />3 <Combobox.Content>4 <Combobox.Item>Apple</Combobox.Item>5 <Combobox.Item>Banana</Combobox.Item>6 <Combobox.Item>Grape</Combobox.Item>7 <Combobox.Item>Orange</Combobox.Item>8 <Combobox.Item>Mango</Combobox.Item>9 <Combobox.Item>Pineapple</Combobox.Item>10 <Combobox.Item>Strawberry</Combobox.Item>11 <Combobox.Item>Watermelon</Combobox.Item>12 <Combobox.Item>Kiwi</Combobox.Item>13 <Combobox.Item>Lemon</Combobox.Item>14 <Combobox.Item>Lime</Combobox.Item>
Label and clear button
Combobox.Label renders a visible label linked to the input. Combobox.Clear renders a button that clears the value. It shows only when there is a value or input text. Place both anywhere inside Combobox.
1<Combobox multiple>2 <Flex direction="column" gap={2}>3 <Combobox.Label>Fruits</Combobox.Label>4 <Flex align="center" gap={2}>5 <Combobox.Input placeholder="Select fruits" width={300} />6 <Combobox.Clear />7 </Flex>8 </Flex>9 <Combobox.Content>10 <Combobox.Item>Apple</Combobox.Item>11 <Combobox.Item>Banana</Combobox.Item>12 <Combobox.Item>Grape</Combobox.Item>13 <Combobox.Item>Orange</Combobox.Item>14 </Combobox.Content>
Empty state
Combobox.Content shows "No results" when no item matches the input. To change the text, add Combobox.Empty as a direct child of Combobox.Content.
1<Combobox>2 <Combobox.Input placeholder="Type 'xyz'" width={240} />3 <Combobox.Content>4 <Combobox.Empty>No fruit matches your search</Combobox.Empty>5 <Combobox.Item>Apple</Combobox.Item>6 <Combobox.Item>Banana</Combobox.Item>7 <Combobox.Item>Grape</Combobox.Item>8 </Combobox.Content>9</Combobox>
Controlled
Use value and onValueChange for controlled behavior.
1(function ControlledDemo() {2 const [value, setValue] = React.useState("");3 const [inputValue, setInputValue] = React.useState("");45 return (6 <Flex direction="column" gap={5}>7 <Text>Selected: {value || "None"}</Text>8 <Combobox9 value={value}10 onValueChange={setValue}11 inputValue={inputValue}12 onInputValueChange={setInputValue}13 >14 <Combobox.Input placeholder="Enter a fruit" />
Using IDs as values
When your app stores IDs instead of item objects, wrap the data with Combobox.createItems. getValue returns the value that value and onValueChange use. getLabel returns the text shown in the input and used for filtering. Pass a function as the child of Combobox.Content to render each item that matches the input.
Create the collection at module scope for static data. For data that changes, wrap it in React.useMemo keyed by the data.
1(function CreateItemsDemo() {2 const users = [3 { id: "u1", name: "Jane Doe" },4 { id: "u2", name: "John Smith" },5 { id: "u3", name: "Ada Lovelace" },6 ];7 const items = React.useMemo(8 () =>9 Combobox.createItems(users, {10 getValue: (user) => user.id,11 getLabel: (user) => user.name,12 }),13 []14 );
API Reference
Root and input first, then the parts that make up the popup list.
Root Props
The Combobox component is composed of several parts, each with their own props.
The root element is the parent component that manages the combobox state including open/close, input value, and selection.
Prop
Type
Input Props
The input field that triggers the combobox dropdown and allows users to type and filter options.
Prop
Type
Content Props
The dropdown container that holds the combobox items.
Prop
Type
Item Props
Individual selectable options within the combobox. In single mode, selecting an item closes the dropdown. In multiple mode, items show checkboxes and the dropdown remains open.
When no value prop is provided, the text content of children is used as the value.
Prop
Type
Label Props
A visible label for the input. It renders a <label> whose htmlFor is the input id. Inside a Field, use the Field label instead.
Prop
Type
Clear Props
A button that clears the value and the input text. It renders IconButton and shows only when there is something to clear.
Prop
Type
Empty Props
The text shown when no item matches the input. Combobox.Content renders one with "No results" by default. Add Combobox.Empty as a direct child of Combobox.Content to change the text. Pass null as children to show nothing.
Prop
Type
Status Props
A visually hidden live region. Screen readers announce its text when it changes. Combobox.Content renders one by default that announces the number of matching items, for example "3 results". Add Combobox.Status as a direct child of Combobox.Content to change the text, for example to announce loading.
Prop
Type
Group Props
A way to group related combobox items together.
Prop
Type
GroupLabel Props
Renders a label in a combobox group. Wrap it in Combobox.Group.
Prop
Type
Separator Props
Visual divider between combobox items or groups.
Prop
Type
Slots
Every rendered part carries a stable data-slot attribute for styling and testing:
| Slot | Element |
|---|---|
combobox-label | The label for the input |
combobox-input | The text input that opens the popup |
combobox-chips | The container for chips and the input in multiple mode |
combobox-chip | A selected value in multiple mode |
combobox-chip-remove | The button that removes a chip |
combobox-chip-overflow | The "+N" count of chips that are not shown |
combobox-clear | The button that clears the value |
combobox-positioner | Wrapper that positions the popup |
combobox-content | The popup container |
combobox-status | The hidden live region that announces the number of results |
combobox-empty | The text shown when no item matches |
combobox-list | The scrollable list of items |
combobox-group | A group of related items |
combobox-group-label | The label for a group |
combobox-separator | The divider between items or groups |
combobox-item | A selectable option row |
combobox-item-text | The text label inside an item (when its children is a string) |
combobox-item-icon | The leading icon inside an item (when leadingIcon is set) |
Accessibility
- Follows the WAI-ARIA Combobox pattern
via Base UI Combobox: the input
is a
role="combobox"witharia-expandedandaria-controls, the popup list is alistbox, and each item is anoptionwitharia-selected. - Arrow keys move the highlight through visible options, Enter selects the highlighted option, and Escape closes the popup, and focus stays in the input the whole time, so typing to filter never loses the user's place.
- In multiple mode, each item renders a checkbox that mirrors its selected state, and selected values appear in the input as removable chips.
- The chips use Base UI's
Combobox.Chips, which hasrole="toolbar". Arrow keys move between chips, and Backspace or Delete removes the focused chip. Combobox.EmptyandCombobox.Statusare polite live regions. Screen readers announce "No results" and the number of matching items.- Group labels use Base UI's
Combobox.GroupLabel, which links the label to its group viaaria-labelledby, so wrapCombobox.GroupLabelinCombobox.Group. - Wrap the Combobox with Field to associate a visible label, description, and error message with the input.