Browse the docs
Inputs / Select & MultiSelect

Select & MultiSelect

Pick one or pick many from a taped paper sheet. The trigger has the fields' wobbly marker outline and boils while open, picks get a tick that draws itself in, and in a MultiSelect every pick sticks onto the trigger as washi tape. Add a search box for long lists, like a people picker.

Client componentWCAG AANew
Brush
Paper
Collaborator
Tags
Sort by
Paper
Pick a paper before you post.
Brush
Locked while the sketch is shipping.
Collaborator

Change every prop live in the playground.

Props

Select

PropTypeDefaultWhat it does
label requiredReactNode—The visible label. Required: every field needs a name.
options requiredSelectOption[]—The choices, in order: `value`, `label`, and optional `hint`, `group`, `lead`, `tone`, `disabled`.
classNamestringnoneExtra class on the field wrapper.
defaultValuestringnull (nothing picked)Uncontrolled initial value.
disabledbooleanfalseGreys out the trigger so the list can't be opened.
errorReactNodenoneAn error that says how to fix it. Turns the outline tomato; it's read as the trigger's description.
hintReactNodenoneHelp under the field.
loadingbooleanfalseWhile options are on their way: a skeleton line in the trigger, hopping dots instead of the chevron, and the trigger waits (aria-busy, can't open).
onValueChange(value: string) => voidnoneCalled with the picked option's value.
placeholderstring"Choose…"Shown while nothing is picked.
searchablebooleanfalseAdds a search box at the top of the list that filters by label and hint.
searchLabelstring"Search"The search box's label and placeholder.
size"sm" | "md"none`md` (default) or `sm` for toolbars.
valuestringnoneControlled picked value; `null` means nothing is picked.

MultiSelect

PropTypeDefaultWhat it does
label requiredReactNode—The visible label. Required: every field needs a name.
options requiredSelectOption[]—The choices, in order: `value`, `label`, and optional `hint`, `group`, `lead`, `tone`, `disabled`.
classNamestringnoneExtra class on the field wrapper.
defaultValuestring[][]Uncontrolled initial values.
disabledbooleanfalseGreys out the trigger so the list can't be opened.
errorReactNodenoneAn error that says how to fix it. Turns the outline tomato; it's read as the trigger's description.
hintReactNodenoneHelp under the field.
loadingbooleanfalseWhile options are on their way: a skeleton line in the trigger, hopping dots instead of the chevron, and the trigger waits (aria-busy, can't open).
onValueChange(value: string[]) => voidnoneCalled with the full new list of picked values each time one is added or removed.
placeholderstring"Choose…"Shown while nothing is picked.
searchablebooleanfalseAdds a search box at the top of the list that filters by label and hint.
searchLabelstring"Search"The search box's label and placeholder.
size"sm" | "md"none`md` (default) or `sm` for toolbars.
valuestring[]noneControlled picked values.

Use it well

DoUse it for 6 or more choices, or when space is tight. Turn on searchable once a list gets long enough to scroll.
Don'tHide 2 to 5 choices people should compare at a glance; a RadioGroup shows them all at once.

Accessibility

  • The trigger is a button with aria-haspopup="listbox"; the sheet is a listbox of options with aria-selected, and aria-multiselectable in a MultiSelect.
  • Arrows move (disabled options are skipped), Home and End jump, a typed letter jumps, Enter or Space picks, Escape closes and puts focus back on the trigger, Tab closes.
  • Picked is never color alone: a tick, or a ticked box, draws in. Errors are read as the trigger's description.
  • With searchable on, a combobox at the top keeps focus while arrows move through the matches.
Five stamps!

All aboard.

You took the whole tour. Here's Holo Pip, a foil sticker for riders who finish. It's in your playground tray now, for good.