Forms & input
Multi-select
A token input for picking many values — labels on a task, several assignees, a set of projects. Selected values become removable chips inside the field; type to filter, click or Enter to add, Backspace to drop the last, and create new ones inline. The multi-value sibling of the Combobox, built on Base UI Combobox in multiple mode.
npx shadcn@latest add @orbit/multi-selectOverview
Click the field, type to filter, Enter or click to add a chip, Backspace on an empty field removes the last, and a non-matching term offers “Create”.
Datasets
Chips adapt to the data — colour dots for labels and projects, avatars for people. Give an item a color token for a tinted chip, or a lead/chipLead ReactNode for a neutral one.
Create inline
With creatable, a term that matches nothing offers a “Create” row — Enter or click adds it as a new chip without leaving the field. onCreate receives the new option so you can persist it.
created: —
Controlled
Pass value + onValueChange (string[]) to control the selection, or defaultValue for an uncontrolled start.
value: ["feature", "research"]
Sizes
sm 32px min-height · md 40px min-height (default, spec). The field grows as chips wrap to a new row.
States & overflow
Error switches the border and ring to the danger tokens. Disabled flattens the field and mutes the chips. maxChips collapses long selections into a “+N” summary.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| items | MultiSelectItem[] | — | Options to pick from. See the item shape below. |
| value | string[] | — | Selected values. Use with onValueChange for a controlled multi-select. |
| defaultValue | string[] | [] | Initial selection when uncontrolled. |
| onValueChange | (value: string[]) => void | — | Called with the full selection whenever it changes. |
| creatable | boolean | false | Offers a “Create” row when the query matches no option label. |
| onCreate | (item: MultiSelectItem) => void | — | Called with the newly created option when the create row is chosen. |
| label | string | — | Field label rendered above the control. |
| placeholder | string | "Add…" | Input placeholder, shown while nothing is selected. |
| emptyMessage | string | "No matches" | Message shown when no option matches the query. |
| maxChips | number | — | Show at most this many chips; the rest collapse into a “+N” summary. |
| size | "sm" | "md" | "md" | Field min-height: 32 / 40px. |
| error | boolean | false | Danger border + focus ring for validation errors. |
| disabled | boolean | false | Blocks interaction and flattens the field. |
| name | string | — | Identifies the field when a form is submitted. |
| className | string | — | Class applied to the outer wrapper. |
| Prop | Type | Default | Description |
|---|---|---|---|
| MultiSelectItem.value | string | — | Unique value identifying the option. |
| MultiSelectItem.label | string | — | Row and chip label; also what the filter matches. |
| MultiSelectItem.color | string | — | Token colour (e.g. "var(--danger)") — renders a dot and tints the chip. |
| MultiSelectItem.lead | ReactNode | — | Custom leading visual for the option row (e.g. a 20px avatar). |
| MultiSelectItem.chipLead | ReactNode | — | Chip-sized leading visual (e.g. a 17px avatar). Falls back to lead. |
| MultiSelectItem.meta | string | — | Trailing mono hint on the option row — role, team, count. |
| MultiSelectItem.disabled | boolean | false | Renders the option non-interactive. |
Usage
Use it whenever a field holds more than one value. For exactly one choice use the Combobox; for a fixed pair of options use a Toggle or Radio.
Make every chip removable
A visible remove on each token, plus Backspace, means correcting a selection is always one obvious action.
Use it for single values
If only one value is valid, a Combobox or Select communicates that constraint. Don’t let people add two.
Keep chips scannable
Carry the option’s colour or avatar into the chip so a dense field still reads at a glance.
Let it grow unbounded
For very large selections, summarise (“+5 more”) with maxChips or paginate the chips so the field doesn’t swallow the form.
Keyboard & accessibility
Full ARIA combobox semantics from Base UI: the input controls the listbox, chips form a labelled group with per-chip remove buttons, and the highlighted option is announced. Arrows also move between chips for keyboard removal.