Search for a command to run...
Styled dropdown for picking one of many. Trigger matches `Input` chrome (bordered, transparent fill). Content is a glass popover with a brand-tinted check beside the selected item. On mobile, prefer `NativeSelect` for the system picker UX.
SelectValue renders the active item's <SelectItemText>. Pass a placeholder for the empty state. The trigger's width is yours to set (className="w-48", etc.); the content auto-matches a minimum width to the trigger via --radix-select-trigger-width.
SelectThe state container. Forwards every Radix Select.Root prop.
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | Controlled selected value. |
defaultValue | string | — | Uncontrolled initial value. |
onValueChange | (value: string) => void | — | Fires when the user picks a different item. |
open | boolean | — | Controlled open state. |
defaultOpen | boolean | false | Uncontrolled initial open state. |
onOpenChange | (open: boolean) => void | — | Fires when the menu opens or closes. |
disabled | boolean | false | Disables the entire select. |
required | boolean | false | Marks the form field as required (native <form> integration). |
name | string | — | Form field name (for native submission). |
SelectTriggerThe interactive control that opens the menu. Forwards every Radix Select.Trigger prop.
| Prop | Type | Default | Description |
|---|---|---|---|
size | "sm" | "default" | "default" | default = h-9 (matches Input default); sm = h-8 for inline / dense rows. |
className | string | — | Override widths (w-48, w-full) or compose with form-row classes. The trigger always inherits the bordered + transparent-fill chrome from Input. |
Open-state border + ring reuse the focus chrome so the trigger keeps reading as "active" while the menu is up.
SelectValueRenders the active item's text, or a placeholder when nothing is selected.
| Prop | Type | Default | Description |
|---|---|---|---|
placeholder | ReactNode | — | Shown (in text-fg-mid) when no value is selected. |
children | ReactNode | — | Custom render for the active value (rare — usually omit). |
SelectContentThe floating menu. Portaled to the document root. Forwards every Radix Select.Content prop.
| Prop | Type | Default | Description |
|---|---|---|---|
position | "item-aligned" | "popper" | "popper" | popper anchors below the trigger with sideOffset. item-aligned overlays the trigger so the selected item stays put. |
sideOffset | number | 6 | Gap between trigger and menu when position="popper". |
side | "top" | "right" | "bottom" | "left" | "bottom" | Preferred side. Floating-UI flips when the preferred side would clip. |
align | "start" | "center" | "end" | "start" | Alignment along the cross-axis. |
avoidCollisions | boolean | true | Disable to lock to the preferred side even when clipped. |
Content sets origin-(--radix-select-content-transform-origin) so it scales from the trigger, not center.
SelectItemA picker option. Forwards every Radix Select.Item prop.
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | The value this item represents. Required, unique within the menu. |
disabled | boolean | false | Disables this item only. Visually dimmed; keyboard nav skips it. |
textValue | string | — | Override the text used for typeahead when children isn't a simple string. |
SelectGroup + SelectLabelGroup related items and label the cluster. The label is a <div> with font-medium text-fg-low text-xs — it does not activate on click.
SelectSeparatorA bg-sand-9/12 (matches border-subtle) horizontal rule. Use it to break sections inside the menu.
SelectScrollUpButton / SelectScrollDownButtonAuto-mounted by SelectContent. They appear only when the menu exceeds the viewport. No props to set in practice — kept exported in case a consumer wants to render them outside the default position.
Use Select for 5–25 mutually exclusive options where typing isn't expected. For free-text
or search-as-you-type, reach for Combobox. For 2–4 options, ToggleGroup or RadioCard reads
faster.
Set a placeholder (via <SelectValue placeholder="Choose…" /> ) for any uncontrolled select that allows no default. The trigger renders the placeholder in
text-fg-mid so the form row still reads as empty rather than blank.
Pair Selects with Input in form grids — they share the same bordered, transparent-fill chrome
and the same h-9 / h-8 size axis, so rows line up automatically.
Group items with SelectGroup + SelectLabel when the option set has obvious clusters (date
ranges by unit, regions by continent). The label gives the cluster a name and keyboard nav still
moves linearly through items.
Use Select when the user genuinely needs to search the option set. Past ~25 options the
eye can't scan the menu — Combobox (with type-ahead) is the right tool.
Render trigger labels longer than the trigger width. The *:data-[slot=select-value] class will
line-clamp-1 for safety, but the truncation reads as broken — give the trigger more width
instead.
Mount Selects inside a Dialog / Sheet / Popover without testing the portal layering. The
content is portaled to document.body, so an in-modal Select usually just works — but custom
z-index stacks in the surrounding surface can clip it. The default z-50 is your starting
point.