Combobox
Filterable selection input with single and multiple selection patterns.
Installation
The component is exported from @by/experience-system. Add the package with your package manager:
pnpm add @by/experience-systemIn this monorepo, depend on the workspace package (for example via workspace:* or your catalog) so imports resolve to packages/experience-system.
Composition
Simple
A single-line input and a flat list.
Combobox
├── ComboboxInput
└── ComboboxContent
├── ComboboxEmpty
└── ComboboxList
├── ComboboxItem
└── ComboboxItemComboboxTrigger is rendered inside ComboboxInput by default, and ComboboxClear is optional via showClear.
With chips
Multi-select with multiple, chips, and a chips input.
Combobox
├── ComboboxChips
│ ├── ComboboxValue
│ │ └── ComboboxChip
│ └── ComboboxChipsInput
└── ComboboxContent
├── ComboboxEmpty
└── ComboboxList
├── ComboboxItem
└── ComboboxItemWith groups and collection
Nested items per group using ComboboxCollection inside each ComboboxGroup, with separators between groups.
Combobox
├── ComboboxInput
└── ComboboxContent
├── ComboboxEmpty
└── ComboboxList
├── ComboboxGroup
│ ├── ComboboxLabel
│ └── ComboboxCollection
│ ├── ComboboxItem
│ └── ComboboxItem
├── ComboboxSeparator
└── ComboboxGroup
├── ComboboxLabel
└── ComboboxCollection
├── ComboboxItem
└── ComboboxItemUsage
import {
Combobox,
ComboboxContent,
ComboboxEmpty,
ComboboxInput,
ComboboxItem,
ComboboxList,
} from '@by/experience-system';Combobox is a client component ('use client' in the package). Use it inside a Client Component when using the Next.js App Router.
const frameworks = ['Next.js', 'SvelteKit', 'Nuxt.js', 'Remix', 'Astro'];
<Combobox items={frameworks}>
<ComboboxInput placeholder="Select a framework..." />
<ComboboxContent>
<ComboboxEmpty>No framework found.</ComboboxEmpty>
<ComboboxList>
{(item) => (
<ComboboxItem key={item} value={item}>
{item}
</ComboboxItem>
)}
</ComboboxList>
</ComboboxContent>
</Combobox>;Examples
Basic
Single-select combobox with filterable options.
Multiple
Use multiple with chips to select more than one value.
Clear button
Set showClear on ComboboxInput to render a clear action.
Groups
Use ComboboxGroup, ComboboxLabel, and ComboboxCollection for grouped options.
Custom items
Provide object items and map display/submission values with itemToStringValue.
API Reference
The API mirrors Base UI Combobox, with Experience System styling and field-surface extensions (size, appearance, showTrigger, showClear, and read-only behavior).
Combobox
Maps to Base UI Combobox.Root.
| Prop | Type | Default |
|---|---|---|
items | Value[] | Group[] | — |
value / defaultValue | Value | Value[] | null | — |
onValueChange | (value, eventDetails) => void | — |
inputValue / defaultInputValue | string | number | string[] | — |
onInputValueChange | (inputValue, eventDetails) => void | — |
open / defaultOpen | boolean | false (defaultOpen) |
onOpenChange | (open, eventDetails) => void | — |
multiple | boolean | false |
autoHighlight | boolean | false |
highlightItemOnHover | boolean | true |
disabled | boolean | false |
readOnly | boolean | false (Experience System passthrough) |
required | boolean | false |
name / form / id | string | — |
filter | ComboboxFilter | null | — |
itemToStringLabel / itemToStringValue | (item) => string | auto for { label, value } |
className | string | — |
| Data attribute | Values |
|---|---|
data-slot | combobox |
data-readonly | present when readOnly is true |
ComboboxInput
Maps to Base UI Combobox.Input, rendered in an InputGroup surface.
| Prop | Type | Default |
|---|---|---|
showTrigger | boolean | true |
showClear | boolean | false |
size | sm | md | lg | md |
appearance | default | filled | default |
aria-invalid | boolean | — |
placeholder | string | — |
disabled | boolean | false |
| Data attribute | Values |
|---|---|
data-slot | combobox-input (Base UI input element) |
data-popup-open | present when popup is open |
data-list-empty | present when list has no items |
data-disabled | present when disabled |
data-readonly | present when read-only |
data-invalid | present when invalid (Field.Root integration) |
ComboboxContent
Combines Base UI Combobox.Positioner + Combobox.Popup.
| Prop | Type | Default |
|---|---|---|
side | 'top' | 'bottom' | 'left' | 'right' | 'inline-end' | 'inline-start' | 'bottom' |
align | 'start' | 'center' | 'end' | 'start' |
sideOffset | number | 4 |
alignOffset | number | 0 |
anchor | Element | VirtualElement | Ref | null | trigger/chips anchor |
| Data attribute | Values |
|---|---|
data-slot | combobox-content |
data-side | popup side |
data-align | popup alignment |
data-open / data-closed | popup state |
data-empty | present when list is empty |
| CSS variable | Description |
|---|---|
--anchor-height | Anchor height |
--anchor-width | Anchor width |
--available-height | Available viewport height |
--available-width | Available viewport width |
--transform-origin | Popup transform origin |
ComboboxList
Maps to Base UI Combobox.List.
| Prop | Type | Default |
|---|---|---|
children | ReactNode | (item, index) => ReactNode | — |
| Data attribute | Values |
|---|---|
data-slot | combobox-list |
ComboboxItem
Maps to Base UI Combobox.Item.
| Prop | Type | Default |
|---|---|---|
value | Value | null |
disabled | boolean | false |
index | number | auto |
onClick | (event) => void | — |
children | ReactNode | — |
| Data attribute | Values |
|---|---|
data-slot | combobox-item |
data-selected | present when selected |
data-highlighted | present when highlighted |
data-disabled | present when disabled |
ComboboxGroup
Maps to Base UI Combobox.Group.
| Prop | Type | Default |
|---|---|---|
items | Value[] | — |
children | ReactNode | — |
| Data attribute | Values |
|---|---|
data-slot | combobox-group |
ComboboxLabel
Maps to Base UI Combobox.GroupLabel.
| Prop | Type | Default |
|---|---|---|
children | ReactNode | — |
| Data attribute | Values |
|---|---|
data-slot | combobox-label |
ComboboxCollection
Maps to Base UI Combobox.Collection.
| Prop | Type | Default |
|---|---|---|
children | (item, index) => ReactNode | — |
| Data attribute | Values |
|---|---|
data-slot | combobox-collection |
ComboboxEmpty
Maps to Base UI Combobox.Empty.
| Prop | Type | Default |
|---|---|---|
children | ReactNode | — |
| Data attribute | Values |
|---|---|
data-slot | combobox-empty |
ComboboxSeparator
Maps to Base UI Combobox.Separator.
| Prop | Type | Default |
|---|---|---|
orientation | 'horizontal' | 'vertical' | 'horizontal' |
| Data attribute | Values |
|---|---|
data-slot | combobox-separator |
ComboboxChips
Maps to Base UI Combobox.Chips with Experience System field-surface options.
| Prop | Type | Default |
|---|---|---|
showTrigger | boolean | true |
showClear | boolean | false |
size | sm | md | lg | md |
appearance | default | filled | default |
aria-invalid | boolean | — |
| Data attribute | Values |
|---|---|
data-slot | combobox-chips |
data-readonly | present when read-only |
data-disabled | present when disabled |
ComboboxChip
Maps to Base UI Combobox.Chip with optional remove action.
| Prop | Type | Default |
|---|---|---|
showRemove | boolean | true |
removeAriaLabel | string | inferred from chip label |
children | ReactNode | — |
| Data attribute | Values |
|---|---|
data-slot | combobox-chip |
ComboboxChipsInput
Maps to Base UI Combobox.Input for multiple mode.
| Prop | Type | Default |
|---|---|---|
fieldSize | sm | md | lg | inherits chips size |
placeholder | string | — |
disabled | boolean | false |
readOnly | boolean | inherited from root |
| Data attribute | Values |
|---|---|
data-slot | combobox-chip-input |
ComboboxTrigger
Maps to Base UI Combobox.Trigger.
| Prop | Type | Default |
|---|---|---|
aria-label | string | 'Open options' (Experience System) |
disabled | boolean | false |
| Data attribute | Values |
|---|---|
data-slot | combobox-trigger |
data-popup-open | present when popup is open |
data-placeholder | present when no value is selected |
ComboboxValue
Maps to Base UI Combobox.Value.
| Prop | Type | Default |
|---|---|---|
placeholder | ReactNode | — |
children | ReactNode | (selectedValue) => ReactNode | — |
| Data attribute | Values |
|---|---|
data-slot | combobox-value |
Accessibility
Provide an accessible name for the form control (ComboboxInput with label/htmlFor, or aria-label when needed), and keep empty/status content mounted so assistive technologies announce filtering updates correctly. Group labels (ComboboxLabel) and chips remove actions should use clear text labels.
Keyboard interactions
| Key | Description |
|---|---|
ArrowDown / ArrowUp | Move highlight through items; can open and navigate the popup. |
Enter | Selects the highlighted item. |
Esc | Closes the popup. |
Tab | Moves focus according to normal tab order. |
Backspace | In multiple mode, chip removal behavior is available via chip remove controls. |
See Base UI Combobox accessibility guidance and shadcn/ui Combobox composition examples.
Source in the repo: packages/experience-system/src/components/Combobox/Combobox.tsx. Agent-oriented contracts: packages/experience-system/src/components/Combobox/Combobox.instructions.md.