Build · New

Select

A field to pick one option, or several, from a list, with Input Field's label and states, and search when the list is long. Use it for 5 or more options; for fewer, radio buttons or checkboxes.

Preview

Mirrored is the same English content laid out right to left: it separates a mirroring bug from a translation one.

Installation

SoonInstalling from the registry opens at launch. Until then the command below is what it will be.
npx shadcn@latest add @ritla/select

Dependencies it brings: @base-ui/react, @phosphor-icons/react

Usage

import { Select } from "@/components/ui/select";
<Select label="Transfer purpose" options={[{ value: "rent", label: "Rent" }, …]} onValueChange={setPurpose} />

Examples

States

A short list (5 options) opens without search. Don't preselect an option unless it's a safe default.

Icon and description

icon and description per option, and disabled for one that isn't available. The chosen row shows a check.

Multi select

MultiSelect: chosen options are tags in the field, each with a remove button; typing in the field filters the list; rows carry a checkbox and the list stays open until Done.

Multi select states

Past maxTags tags the field sums up the rest (“+2 more”) until it's focused; error and disabled as on Input Field; onCreate adds “Create new” with what the person typed.

API reference

Select

PropTypeDefaultDescription
labelReactNodeFigma's Show label.
options{ value, label, description?, icon?, disabled? }[]The options.
value / defaultValuestring | nullThe chosen option's value.
onValueChange(value: string | null) => voidWhen an option is picked.
searchablebooleanoptions ≥ 8The search box at the top of the list.
placeholder / searchPlaceholder / emptyTextstringDefault: in the page language (“Choose an option”, “Search”, “No matches”).
namestringForm field name.
required / helperText / error / disabled…As on Input Field.

MultiSelect

PropTypeDefaultDescription
options{ value, label, description?, icon?, disabled? }[]The options, as on Select.
value / defaultValuestring[]The chosen options' values.
onValueChange(value: string[]) => voidWhen options are picked or removed.
maxTagsnumber3Tags shown while the field isn't focused; the rest become “+N more”.
onCreate(query: string) => voidAdds a “Create new” button to the list footer.
placeholder / emptyText / namestringAs on Select (“Choose options”).
label / required / helperText / error / disabled…As on Input Field.

Accessibility

Keyboard

Keys are written for left-to-right. In right-to-left the arrow keys swap: the one pointing toward the reading direction moves forward.

KeyAction
EnterSpaceArrowDownOpens the list.
ArrowUpArrowDownBetween options; Enter picks, Escape closes.
A–ZIn a short list: jumps to the option starting with the letter. In a long one: types into the search.
BackspaceMulti select, with nothing typed: removes the last tag.

ARIA

  • The field is a button tied to the label that opens a listbox; the chosen option is aria-selected and shows a visible check.
  • Helper text and errors are linked as on Input Field.
  • Multi select: the field is role="combobox", each row is one option with aria-selected (the checkbox is drawn, not a second control), the number chosen is announced (“3 selected”), and each tag has a “Remove” button with its name.

Arabic and RTL notes

Mirrors

  • The caret sits at the end of the field (the left), and the row icon and check swap sides.
  • The list carries the page direction and language, even when opened from an LTR island.

Does not mirror

  • The caret points down in both directions; the check doesn't mirror.
Numerals
Numbers in options are as you write them; use formatNumber for amounts.
Arabic typography
The field is label-16; rows label-14 Medium with label-12 descriptions.
Mixed-direction text
Each option and description takes dir="auto": an English name in an Arabic list runs left to right.

All components ›