Forms & input
Select
Choose from a set of options — one or many. Built for the things project teams pick constantly: status, priority, assignees, labels, and projects, with groups and rich option content.
npx shadcn@latest add @orbit/selectSelection patterns
Single picks one value and marks it with a check. Multi toggles values with checkboxes, collapses to chips in the trigger, and adds a Clear / Done footer. Groups organize longer, categorized lists.
Rich options
A leading slot adapts per option: a color dot, a priority glyph, an avatar, or a square project mark — plus an optional second line and a trailing hint that hides once selected.
Sizes
md 34px matches the input and date controls; sm 30px fits inline table cells and toolbars.
States
Open shows the pri border with a 3px themed ring. Error swaps both for danger. Disabled drops to a flat surface-2 treatment; individual options can be disabled too.
Shown on the board and in reports.
Status is required
Controlled
Pass value and onValueChange to own the state — single reports a string or null, multiple reports a string array.
value: "inprogress"
2 selected · ["frontend","bug"]
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| items | SelectOption[] | — | Options rendered in the popup, in order. Consecutive items with the same group share a section header. |
| value | string | string[] | null | — | Controlled value. Pair with onValueChange. |
| defaultValue | string | string[] | null | null / [] | Initial value when uncontrolled. |
| onValueChange | (value) => void | — | Called with the next value — string | null (single) or string[] (multiple). |
| multiple | boolean | false | Multi-select: checkbox rows, trigger chips, and a Clear / Done footer. |
| size | "sm" | "md" | "md" | Control height: 30 / 34px. |
| label | string | — | Visible label above the control; clicking it focuses the trigger. |
| hint | string | — | Help text below the control. |
| error | boolean | string | false | Danger border + ring; a string also replaces the hint with a danger message. |
| placeholder | string | "Select…" | Shown in text-3 until a value is set. |
| disabled | boolean | false | Disables the whole control. |
| clearable | boolean | false | Shows an inline × that resets the selection when a value is set. |
| width | string | — | Fixed control width (e.g. “220px”); defaults to fit-content with a 160px minimum. |
| name / required / id | string / boolean / string | — | Form integration — a hidden input submits the value via Base UI. |
| Prop | Type | Default | Description |
|---|---|---|---|
| value | string | — | SelectOption — unique value, submitted with forms. |
| label | string | — | SelectOption — row text, also used for keyboard typeahead. |
| lead | ReactNode | — | SelectOption — 20px leading slot: dot, avatar, icon, or project mark. |
| description | string | — | SelectOption — second line; the row grows from 34 to 44px. |
| hint | string | — | SelectOption — trailing mono hint, hidden once selected. |
| group | string | — | SelectOption — section header shared by consecutive options. |
| disabled | boolean | — | SelectOption — dimmed to 45% and skipped by keyboard navigation. |
Usage
Show how many are selected
Multi-select surfaces chips, then a +N count, and a footer tally — never hide the selection.
Recolor a status per screen
Keep status, priority, and label colors identical everywhere so they stay learnable.
Keep labels parallel
All nouns or all verbs — options that share grammar scan cleanly.
Reach for Select past ~7 unfamiliar options
Typeahead helps, but long flat lists want a searchable combobox instead.
Keyboard & accessibility
Base UI provides the listbox/option roles, focus management, and typeahead. The label is associated with the trigger, hint and error text are linked via aria-describedby, and error sets aria-invalid.