Installation
Theme
Mode

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/select

Selection 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.

Single — mode of least surprise for short lists. The current choice gets a check.
Multi — multiple · chips collapse to a count past two values.
Grouped — consecutive options with the same group render under a section header.

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.

Status · dots — Priority · icons
Status
Priority
People · avatars + hints — Roles · descriptions
Assignee
Role

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.

Label + hint — error with message — disabled
Status

Shown on the board and in reports.

Status

Status is required

Status
Disabled options — dimmed and skipped by keyboard navigation
Clearable — an inline × resets the selection without opening the popup

Controlled

Pass value and onValueChange to own the state — single reports a string or null, multiple reports a string array.

Status

value: "inprogress"

Labels

2 selected · ["frontend","bug"]

Props

PropTypeDefaultDescription
itemsSelectOption[]Options rendered in the popup, in order. Consecutive items with the same group share a section header.
valuestring | string[] | nullControlled value. Pair with onValueChange.
defaultValuestring | string[] | nullnull / []Initial value when uncontrolled.
onValueChange(value) => voidCalled with the next value — string | null (single) or string[] (multiple).
multiplebooleanfalseMulti-select: checkbox rows, trigger chips, and a Clear / Done footer.
size"sm" | "md""md"Control height: 30 / 34px.
labelstringVisible label above the control; clicking it focuses the trigger.
hintstringHelp text below the control.
errorboolean | stringfalseDanger border + ring; a string also replaces the hint with a danger message.
placeholderstring"Select…"Shown in text-3 until a value is set.
disabledbooleanfalseDisables the whole control.
clearablebooleanfalseShows an inline × that resets the selection when a value is set.
widthstringFixed control width (e.g. “220px”); defaults to fit-content with a 160px minimum.
name / required / idstring / boolean / stringForm integration — a hidden input submits the value via Base UI.
PropTypeDefaultDescription
valuestringSelectOption — unique value, submitted with forms.
labelstringSelectOption — row text, also used for keyboard typeahead.
leadReactNodeSelectOption — 20px leading slot: dot, avatar, icon, or project mark.
descriptionstringSelectOption — second line; the row grows from 34 to 44px.
hintstringSelectOption — trailing mono hint, hidden once selected.
groupstringSelectOption — section header shared by consecutive options.
disabledbooleanSelectOption — dimmed to 45% and skipped by keyboard navigation.

Usage

Do

Show how many are selected

Multi-select surfaces chips, then a +N count, and a footer tally — never hide the selection.

Don’t

Recolor a status per screen

Keep status, priority, and label colors identical everywhere so they stay learnable.

Do

Keep labels parallel

All nouns or all verbs — options that share grammar scan cleanly.

Don’t

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.

Keys
Space / Enter / ↓Open the listbox↑ ↓Move the highlightEnterSelect the highlighted optionEscClose without changingTypeTypeahead — jump to a matching optionrolelistbox / option semantics via Base UI
Tab to the trigger, open with Space, navigate with the arrow keys
Assignee
Priority