Components
Displays a list of options for the user to pick from — triggered by a button.
Playground
Select from its parts — a SelectTrigger holding the SelectValue, and a SelectContent with one SelectItem per option. The placeholder renders in muted text until a value is picked.import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectLabel,
SelectTrigger,
SelectValue,
} from "@workspace/ui/components/select"
<Select>
<SelectTrigger className="w-44">
<SelectValue placeholder="Select a fruit" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>Fruits</SelectLabel>
<SelectItem value="apple">Apple</SelectItem>
<SelectItem value="banana">Banana</SelectItem>
<SelectItem value="blueberry">Blueberry</SelectItem>
<SelectItem value="grapes">Grapes</SelectItem>
<SelectItem value="pineapple">Pineapple</SelectItem>
</SelectGroup>
</SelectContent>
</Select>SelectGroup and a SelectLabel per group, and divide groups with a SelectSeparator. Labels are announced with each option by assistive technology.<Select>
<SelectTrigger className="w-44">
<SelectValue placeholder="Pick a food" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>Fruits</SelectLabel>
<SelectItem value="apple">Apple</SelectItem>
<SelectItem value="banana">Banana</SelectItem>
</SelectGroup>
<SelectSeparator />
<SelectGroup>
<SelectLabel>Vegetables</SelectLabel>
<SelectItem value="carrot">Carrot</SelectItem>
<SelectItem value="spinach">Spinach</SelectItem>
</SelectGroup>
</SelectContent>
</Select><Select>
<SelectTrigger className="w-64">
<SelectValue placeholder="Select a timezone" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>North America</SelectLabel>
<SelectItem value="est">Eastern Standard Time (EST)</SelectItem>
{/* … */}
</SelectGroup>
<SelectGroup>
<SelectLabel>Europe & Africa</SelectLabel>
<SelectItem value="gmt">Greenwich Mean Time (GMT)</SelectItem>
{/* … */}
</SelectGroup>
</SelectContent>
</Select>default (36px) and sm (32px). Set size on the SelectTrigger; the sm size matches sm inputs and buttons in dense layouts.<Select>
<SelectTrigger size="sm" className="w-44">
<SelectValue placeholder="Small" />
</SelectTrigger>
<SelectContent>…</SelectContent>
</Select>
<Select>
<SelectTrigger className="w-44">
<SelectValue placeholder="Default" />
</SelectTrigger>
<SelectContent>…</SelectContent>
</Select>Field, FieldLabel and FieldDescription in forms. Point the label's htmlFor at the trigger's id so clicking it opens the select.Used for emails and in-app copy.
<Field>
<FieldLabel htmlFor="language">Language</FieldLabel>
<Select defaultValue="en">
<SelectTrigger id="language" className="w-full">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="en">English</SelectItem>
<SelectItem value="pt">Português</SelectItem>
<SelectItem value="es">Español</SelectItem>
</SelectContent>
</Select>
<FieldDescription>
Used for emails and in-app copy.
</FieldDescription>
</Field>defaultValue for uncontrolled selects, or value and onValueChange to control the selection — the callback receives the newly selected item's value string.Active theme: System
const [value, setValue] = React.useState("system")
<Select value={value} onValueChange={setValue}>
<SelectTrigger className="w-44">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="light">Light</SelectItem>
<SelectItem value="dark">Dark</SelectItem>
<SelectItem value="system">System</SelectItem>
</SelectContent>
</Select>disabled on the Select root to disable the whole control, or on a single SelectItem to make just that option unselectable.<Select disabled>
<SelectTrigger className="w-44">
<SelectValue placeholder="Unavailable" />
</SelectTrigger>
<SelectContent>…</SelectContent>
</Select>
<Select>
<SelectTrigger className="w-44">
<SelectValue placeholder="Shipping speed" />
</SelectTrigger>
<SelectContent>
<SelectItem value="standard">Standard</SelectItem>
<SelectItem value="express" disabled>
Express (sold out)
</SelectItem>
</SelectContent>
</Select>aria-invalid on the SelectTrigger to show the invalid styles — a destructive border and ring on the trigger. Inside a Field, add data-invalid to the wrapper so the label turns destructive too.A country is required.
<Field data-invalid>
<FieldLabel htmlFor="country">Country</FieldLabel>
<Select>
<SelectTrigger id="country" aria-invalid className="w-full">
<SelectValue placeholder="Select a country" />
</SelectTrigger>
<SelectContent>…</SelectContent>
</Select>
<FieldDescription>A country is required.</FieldDescription>
</Field>dir="rtl" to the Select root — Radix stamps its own direction on the control (defaulting to LTR), and the prop keeps the caret, the item indicator and keyboard navigation mirrored. Alternatively, wrap the app in the design system's DirectionProvider.<div dir="rtl">
<Select dir="rtl">
<SelectTrigger className="w-44">
<SelectValue placeholder="اختر فاكهة" />
</SelectTrigger>
<SelectContent>
<SelectItem value="apple">تفاح</SelectItem>
<SelectItem value="banana">موز</SelectItem>
<SelectItem value="grapes">عنب</SelectItem>
</SelectContent>
</Select>
</div>defaultValue or controlled via value + onValueChange. Inside a form the selected item's value submits under name like a native select. The content defaults to position="item-aligned", which overlays the selected item on the trigger like a native macOS select; use popper to drop it below the trigger instead.| Component | Prop | Default |
|---|---|---|
| Select | value?: string | — |
| Select | defaultValue?: string | — |
| Select | onValueChange?: (value: string) => void | — |
| Select | open?: boolean · onOpenChange?: (open: boolean) => void | — |
| Select | disabled?: boolean | false |
| Select | required?: boolean | false |
| Select | name?: string | — |
| Select | dir?: "ltr" | "rtl" | — |
| SelectTrigger | size?: "sm" | "default" | "default" |
| SelectContent | position?: "item-aligned" | "popper" | "item-aligned" |
| SelectContent | side? · align? · sideOffset? (popper only) | — |
| SelectItem | value: string | required |
| SelectItem | disabled?: boolean | false |
| SelectItem | textValue?: string | — |
Tokens used
11 design tokens consumed by the Select component.
--input
Input
--ring
Ring
--destructive
Destructive
--popover
Popover
--popover-foreground
Popover Foreground
--foreground
Foreground
--accent
Accent
--accent-foreground
Accent Foreground
--muted-foreground
Muted Foreground
--border
Border
--spacing
Spacing unit (4px)