suiss/ui · Component
Combobox
A text input with a filterable list of options, for choosing one or more values by typing.
Combobox is an open-source component from suiss/ui for React, React Native, SwiftUI and Jetpack Compose. The @esuiss/ui CLI copies its source into your project, so you own the code.
Combobox is built on the Base UI Combobox. The Combobox root takes the items to choose from and holds the value. ComboboxInput renders the text field inside an InputGroup, with an optional button that opens the list and an optional clear button. ComboboxContent renders the popup in a portal; inside it, ComboboxList renders each item through a render function, ComboboxEmpty appears when nothing matches, and ComboboxItem shows a check mark when selected. Group related items with ComboboxGroup, ComboboxLabel, ComboboxCollection and ComboboxSeparator.
For multiple selection, replace ComboboxInput with ComboboxChips, which shows each selected value as a ComboboxChip next to a ComboboxChipsInput. Use a combobox when the list is long enough that typing to filter helps. For a short, fixed list without filtering, use a select; for a list of actions rather than values, use a command menu.
Installation
CLI
Works in any project with a components.json. See Installation for the one-line registry setup. Or use the suiss/ui CLI:
Manual
- Install the dependencies and add the
cnhelper:
-
Add the pieces it builds on: Button, Input Group.
-
Copy the source into
components/ui/combobox.tsx:
- Update the import paths to match your project.
Usage
Pass items to the root and a function as the child of ComboboxList, which receives each item and returns a ComboboxItem with a matching value. The value is uncontrolled with defaultValue, or controlled with value and onValueChange. To read or control the typed text, use inputValue and onInputValueChange.
For grouped data, pass groups as items, render a ComboboxGroup with its own items for each one, and render its items with ComboboxCollection. For multiple selection, set multiple on the root, create a ref with useComboboxAnchor, attach it to ComboboxChips, and pass it as anchor to ComboboxContent so the popup aligns to the chips field. Use ComboboxValue with a render function to map the selected values to chips.
Examples
With clear button
A combobox with a starting value and a clear button, enabled with showClear.
Disabled
A disabled combobox whose input and toggle button cannot be focused or used.
Grouped
Options grouped by region with labels and separators between groups.
Highlight match
A controlled inputValue used to emphasize the matching part of each option.
Multiple
Multiple selection shown as removable chips, with Backspace removing the last chip.
API Reference
Combobox
The root that holds the items, the selected value and the open state.
Also accepts the props of ComboboxPrimitive.Root.
ComboboxValue
Renders the current value, or passes it to a render function, for example to draw chips.
Also accepts the props of ComboboxPrimitive.Value.Props.
ComboboxTrigger
A button that opens the list, with a caret icon.
Also accepts the props of ComboboxPrimitive.Trigger.Props.
ComboboxInput
The text field, rendered inside an InputGroup with optional open and clear buttons.
| Prop | Type | Default | Description |
|---|---|---|---|
showTrigger | boolean | true | Shows the button at the end of the field that opens the list. |
showClear | boolean | false | Shows a clear button at the end of the field. When shown, it hides the open button. |
Also accepts the props of ComboboxPrimitive.Input.Props.
ComboboxContent
The popup, rendered in a portal and positioned below the input.
Also accepts the props of ComboboxPrimitive.Popup.Props, ComboboxPrimitive.Positioner.Props.
ComboboxList
The scrollable list that renders items through a render function.
Also accepts the props of ComboboxPrimitive.List.Props.
ComboboxItem
A selectable option that shows a check mark when selected.
Also accepts the props of ComboboxPrimitive.Item.Props.
ComboboxGroup
Groups related options and takes its own items.
Also accepts the props of ComboboxPrimitive.Group.Props.
ComboboxLabel
The visible label of a group.
Also accepts the props of ComboboxPrimitive.GroupLabel.Props.
ComboboxCollection
Renders the items of a group through a render function.
Also accepts the props of ComboboxPrimitive.Collection.Props.
ComboboxEmpty
Content shown when no options match the typed text.
Also accepts the props of ComboboxPrimitive.Empty.Props.
ComboboxSeparator
A divider between groups.
Also accepts the props of ComboboxPrimitive.Separator.Props.
ComboboxChips
The field that holds selected values as chips in multiple selection.
Also accepts the props of React.ComponentPropsWithRef<typeof ComboboxPrimitive.Chips>, ComboboxPrimitive.Chips.Props.
ComboboxChip
A selected value shown as a chip, with an optional remove button.
| Prop | Type | Default | Description |
|---|---|---|---|
showRemove | boolean | true | Shows a button inside the chip that removes the value. |
removeLabel | string | Remove {value} | Accessible name of the remove button. Defaults to Remove followed by the chip text. |
Also accepts the props of ComboboxPrimitive.Chip.Props.
ComboboxChipsInput
The text field placed after the chips in multiple selection.
Also accepts the props of ComboboxPrimitive.Input.Props.
Accessibility
- The input has the
comboboxrole and setsaria-expandedto reflect whether the list is open. - The popup has the
listboxrole, options have theoptionrole and selected options setaria-selected; groups have thegrouprole and take their name fromComboboxLabel. - Typing filters the options. Arrow keys move the highlight, Enter selects the highlighted option, and Escape closes the list.
- In multiple selection, Backspace in the empty input removes the last chip.
- The open button is labelled
Show optionsand the clear button is labelledClear. - When disabled, the input and the open button are disabled and removed from the Tab order.
- Give the input an accessible name with a visible label or
aria-label.
Notes
- Styling hooks:
data-slotvalues such ascombobox-content,combobox-list,combobox-item,combobox-label,combobox-empty,combobox-chips,combobox-chip,combobox-chip-removeandcombobox-chip-input. - Highlighted items get
data-highlightedand disabled items getdata-disabled. - The popup matches the width of its anchor through
--anchor-widthand limits its height to the available space. - Uses the
popover,accent,primary,secondaryandbordercolors.
Web preview
Combobox pairs a text input with a floating list that filters its items as the user types. ComboboxInput draws the field with a caret trigger and an optional clear button, and ComboboxContent renders the list through a portal (inside a full-window overlay on iOS), positioned below the input and as wide as it.
For multiple selection, set multiple and use ComboboxChips with a ComboboxChip per selected value and a ComboboxChipsInput for typing. Each chip has a remove button.
Installation
The CLI also adds what it builds on: Button, Icon, Text. On React Native it also adds the animated view components/ui/animated-view.tsx.
Manual
- Install the dependencies:
-
Add the pieces it builds on: Button, Icon, Text, and the primitives
components/primitives/combobox.tsx,components/primitives/field.tsx,components/primitives/positioner.tsx,components/primitives/use-render.tsx, and the animated viewcomponents/ui/animated-view.tsxfrom the next step. -
Copy the animated view into
components/ui/animated-view.tsx:
- Copy the source into
components/ui/combobox.tsx:
- Update the import paths to match your project.
- Install the dependencies:
-
Add the pieces it builds on: Button, Icon, Text, and the primitives
components/primitives/combobox.tsx,components/primitives/field.tsx,components/primitives/positioner.tsx,components/primitives/use-render.tsx, and the animated viewcomponents/ui/animated-view.tsxfrom the next step. -
Copy the animated view into
components/ui/animated-view.tsx:
- Copy the source into
components/ui/combobox.tsx:
- Update the import paths to match your project.
- Install the dependencies:
-
Add the pieces it builds on: Button, Icon, Text, and the primitives
components/primitives/combobox.tsx,components/primitives/field.tsx,components/primitives/positioner.tsx,components/primitives/use-render.tsx, and the animated viewcomponents/ui/animated-view.tsxfrom the next step. -
Copy the animated view into
components/ui/animated-view.tsx:
- Copy the source into
components/ui/combobox.tsx:
- Update the import paths to match your project.
-
Target iOS 17 or later.
-
Add the Swift package to your app:
- Copy the theme files every view uses:
- Copy the source and every file it uses:
- Add the files to your app target.
- Set
minSdkto 24 or higher and add the dependencies:
- Copy the theme files every view uses:
- Copy the source and every file it uses:
- Update the
com.esuiss.uipackage names to match your project.
Usage
Pass items to the root and render the filtered list with a function child of ComboboxList. For grouped items, render a ComboboxGroup per group with a ComboboxLabel and a ComboboxCollection. Add ComboboxEmpty for the no-results message.
Use value, defaultValue and onValueChange for the selection, and inputValue with onInputValueChange for the typed text. For object items, provide itemToStringLabel. filter, limit and locale tune matching.
With chips, create a ref with useComboboxAnchor(), attach it to ComboboxChips, and pass it to ComboboxContent as anchor so the list lines up with the chips field. On ComboboxInput, set showClear to add a clear button and showTrigger={false} to hide the caret.
Examples
Default
Web preview
With value
Starts with a selected value.
Web preview
With clear
A clear button through showClear.
Web preview
Grouped
Items in labelled groups with separators.
Web preview
Multiple
Multiple selection shown as removable chips.
Web preview
With label
Linked to a Label with helper text.
Web preview
Disabled
A disabled combobox.
Web preview
Invalid
The invalid style with an error message.
Web preview
API Reference
Combobox
The root that holds the items, the selected value, the typed text and the open state.
| Prop | Type | Default | Description |
|---|---|---|---|
items | Item[] | ComboboxItemGroup<Item>[] | - | The items to filter, flat or grouped. |
value | Value | Value[] | null | - | The selected value, for controlled use. |
defaultValue | Value | Value[] | null | - | The initial value when uncontrolled. |
onValueChange | (value, details) => void | - | Called when the selection changes. |
multiple | boolean | false | Allows several values to be selected. |
inputValue | string | - | The typed text, for controlled use. |
onInputValueChange | (inputValue: string, details) => void | - | Called when the typed text changes. |
filter | ComboboxFilter<Item> | null | - | Custom filter function; null turns filtering off. |
limit | number | - | The maximum number of items shown. |
itemToStringLabel | (itemValue: Value) => string | - | Returns the label shown for an item value. |
openOnInputClick | boolean | true | Opens the list when the input is pressed. |
open | boolean | - | Whether the list is open, for controlled use. |
defaultOpen | boolean | false | Whether the list starts open when uncontrolled. |
onOpenChange | (open: boolean, details) => void | - | Called when the list opens or closes. |
disabled | boolean | false | Disables the combobox. |
readOnly | boolean | false | Shows the value without allowing changes. |
ComboboxTrigger
Round button that opens the list.
| Prop | Type | Default | Description |
|---|---|---|---|
children | React.ReactNode | - |
Also accepts the props of React.ComponentProps<typeof ComboboxPrimitive.Trigger>.
ComboboxInput
Text field with caret trigger and optional clear button.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | |
children | React.ReactNode | - | |
showTrigger | boolean | true | Shows the caret button. Defaults to true. |
showClear | boolean | false | Shows a clear button when there is text or a value. |
invalid | boolean | - | Shows the destructive border; also read from a surrounding Field. |
Also accepts the props of React.ComponentProps<typeof ComboboxPrimitive.Input>.
ComboboxContent
Floating popup for the list.
| Prop | Type | Default | Description |
|---|---|---|---|
portalHost | string | - | Name of the portal host to render into. |
Also accepts the props of React.ComponentProps<typeof ComboboxPrimitive.Popup>, PositionerProps.
ComboboxList
Scrollable list of items.
Also accepts the props of React.ComponentProps<typeof ComboboxPrimitive.List>.
ComboboxItem
Selectable option with a check mark when selected.
| Prop | Type | Default | Description |
|---|---|---|---|
children | React.ReactNode | - |
Also accepts the props of React.ComponentProps<typeof ComboboxPrimitive.Item>.
ComboboxGroup
Group of items.
Also accepts the props of React.ComponentProps<typeof ComboboxPrimitive.Group>.
ComboboxLabel
Heading for a group.
Also accepts the props of React.ComponentProps<typeof ComboboxPrimitive.GroupLabel>.
ComboboxEmpty
Message shown when nothing matches.
Also accepts the props of React.ComponentProps<typeof ComboboxPrimitive.Empty>.
ComboboxSeparator
Line between groups.
Also accepts the props of React.ComponentProps<typeof ComboboxPrimitive.Separator>.
ComboboxChips
Field that holds chips for multiple selection.
| Prop | Type | Default | Description |
|---|---|---|---|
invalid | boolean | - | Shows the destructive border. |
Also accepts the props of React.ComponentProps<typeof ComboboxPrimitive.Chips>.
ComboboxChip
Selected value with a remove button.
| Prop | Type | Default | Description |
|---|---|---|---|
showRemove | boolean | true | Shows the remove button. Defaults to true. |
removeLabel | string | Remove {value} | Accessible name of the remove button. Defaults to Remove followed by the chip text. |
Also accepts the props of React.ComponentProps<typeof ComboboxPrimitive.Chip>.
ComboboxChipsInput
Text input inside the chips field.
Also accepts the props of React.ComponentProps<typeof ComboboxPrimitive.Input>.
Accessibility
- The input has the
comboboxrole withexpandedanddisabledstate. - Items have the
optionrole withselectedanddisabledstate; the list has thelistrole. - The empty message is a polite live region.
- The trigger, clear and chip remove buttons are labelled "Show options", "Clear" and "Remove".
Notes
- Uses
bg-secondary,bg-popover,border-ringandborder-destructivetokens; light and dark follow the system appearance. - In Uniwind and NativeWind, a focused field also draws the
ring-3 ring-ring/50focus ring. - Fade animations respect the system Reduce Motion setting.