Components · Select
Select
Choosing one value from a known, finite set. Radix supplies the listbox ARIA model, typeahead and focus behaviour; LUC supplies the trigger chrome — identical to Input — and the menu surface. If the list needs searching that is Combobox; if the action needs running that is CommandMenu.
Examples
Trigger and menu
One size token drives the trigger height, the type scale and the menu rhythm, so a dropdown is never hand-tuned.
Applies to every chart in the group.
Value: 1y
Placeholder shows until a venue is chosen.
Disabled controls keep their label and value.
A venue is required for this run
<Select defaultValue="1y">
<SelectTrigger aria-label="Range">
<SelectValue placeholder="Choose a range" />
</SelectTrigger>
<SelectContent>
<SelectItem value="1y">1 year</SelectItem>
</SelectContent>
</Select>Sizes
One size drives the trigger's height, its type scale and the menu's rhythm, so a dropdown is never hand-tuned.
sm
md
lg
<Select size="sm">…</Select>
<Select size="md">…</Select>
<Select size="lg">…</Select>A long list scrolls
The menu caps its own height and scrolls, so a hundred-option list stays inside the viewport.
Type a few letters to jump — the listbox has typeahead.
<Select>
<SelectTrigger aria-label="Instrument">
<SelectValue placeholder="Choose an instrument" />
</SelectTrigger>
<SelectContent>
{symbols.map((symbol) => (
<SelectItem key={symbol} value={symbol}>{symbol}</SelectItem>
))}
</SelectContent>
</Select>Groups, descriptions and disabled options
A group is a heading, not a nesting level. Descriptions carry the code or the unit; the label stays short.
The universe drives every downstream column.
<Select>
<SelectTrigger aria-label="Instrument">
<SelectValue placeholder="Choose an instrument" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>Equities</SelectLabel>
<SelectItem value="AAPL" description="Nasdaq">Apple</SelectItem>
</SelectGroup>
<SelectSeparator />
<SelectItem value="SPX" disabled description="Unavailable">S&P 500</SelectItem>
</SelectContent>
</Select>Usage
import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from "@luc/ui";<Select value={range} onValueChange={setRange}>
<SelectTrigger aria-label="Range">
<SelectValue placeholder="Choose a range" />
</SelectTrigger>
<SelectContent>
<SelectItem value="1y">1 year</SelectItem>
</SelectContent>
</Select>The trigger is the tab stop and the menu owns the active option; `size` on the root drives both. Radix supplies the listbox model, the typeahead and the focus behaviour.
API
Read from the published TypeScript API, so a prop that is not listed here does not exist and a default that is listed is the one the compiler sees.
| Export | Kind | Signature |
|---|---|---|
Select | 14 documented props | ({ size, children, ...props }: SelectProps) => import("@types/react").JSX.Element |
SelectContent | 18 documented props | ({ className, children, size, position, sideOffset, ...props }: SelectContentProps) => import("@types/react").JSX.Element |
SelectGroup | 1 documented props | import("@types/react").ForwardRefExoticComponent<RadixSelect.SelectGroupProps & import("@types/react").RefAttributes<HTMLDivElement>> |
SelectItem | 5 documented props | ({ className, children, description, ...props }: SelectItemProps) => import("@types/react").JSX.Element |
SelectLabel | 1 documented props | ({ className, ...props }: React.ComponentPropsWithRef<typeof RadixSelect.Label>) => import("@types/react").JSX.Element |
SelectRoot | 13 documented props | import("@types/react").FC<RadixSelect.SelectProps> |
SelectSeparator | 1 documented props | import("@types/react").ForwardRefExoticComponent<RadixSelect.SelectSeparatorProps & import("@types/react").RefAttributes<HTMLDivElement>> |
SelectTrigger | 4 documented props | ({ className, children, size, leadingIcon, invalid, disabled, id, ...props }: SelectTriggerProps) => import("@types/react").JSX.Element |
SelectValue | 2 documented props | import("@types/react").ForwardRefExoticComponent<RadixSelect.SelectValueProps & import("@types/react").RefAttributes<HTMLSpanElement>> |
Select props
Type: SelectProps
Values the compiler reads from the declaration.
| Prop | Type | Default | Notes |
|---|---|---|---|
autoComplete?inherited | string | undefined | — | |
children?inherited | ReactNode | — | |
defaultOpen?inherited | boolean | undefined | — | |
defaultValue?inherited | string | undefined | — | |
dir?inherited | Direction | undefined | — | |
disabled?inherited | boolean | undefined | — | |
form?inherited | string | undefined | — | |
name?inherited | string | undefined | — | |
onOpenChange?inherited | ((open: boolean) => void) | undefined | — | |
onValueChange?inherited | ((value: string) => void) | undefined | — | |
open?inherited | boolean | undefined | — | |
required?inherited | boolean | undefined | — | |
size? | ControlSize | undefined | — | Control size, shared by the trigger and the menu. Default `md`. |
value?inherited | string | undefined | — |
SelectContent props18 props
SelectContent props
Type: SelectContentProps
Values the compiler reads from the declaration.
| Prop | Type | Default | Notes |
|---|---|---|---|
align?inherited | "center" | "start" | "end" | undefined | — | |
alignOffset?inherited | number | undefined | — | |
arrowPadding?inherited | number | undefined | — | |
asChild?inherited | boolean | undefined | — | |
avoidCollisions?inherited | boolean | undefined | — | |
collisionBoundary?inherited | Boundary | Boundary[] | undefined | — | |
collisionPadding?inherited | number | Partial<Record<"top" | "right" | "bottom" | "left", number>> | undefined | — | |
forceMount?inherited | true | undefined | — | Used to force mounting when more control is needed. Useful when controlling animation with React animation libraries. |
hideWhenDetached?inherited | boolean | undefined | — | |
onCloseAutoFocus?inherited | ((event: Event) => void) | undefined | — | Event handler called when auto-focusing on close. Can be prevented. |
onEscapeKeyDown?inherited | ((event: KeyboardEvent) => void) | undefined | — | Event handler called when the escape key is down. Can be prevented. |
onPointerDownOutside?inherited | ((event: PointerDownOutsideEvent) => void) | undefined | — | Event handler called when the a `pointerdown` event happens outside of the `DismissableLayer`. Can be prevented. |
position?inherited | "item-aligned" | "popper" | undefined | — | |
side?inherited | "top" | "right" | "bottom" | "left" | undefined | — | |
sideOffset?inherited | number | undefined | — | |
size? | ControlSize | undefined | — | |
sticky?inherited | "partial" | "always" | undefined | — | |
updatePositionStrategy?inherited | "always" | "optimized" | undefined | — |
SelectGroup props1 props
SelectGroup props
Type: SelectGroupProps & RefAttributes<HTMLDivElement>
Values the compiler reads from the declaration.
| Prop | Type | Default | Notes |
|---|---|---|---|
asChild?inherited | boolean | undefined | — |
SelectItem props5 props
SelectItem props
Type: SelectItemProps
Values the compiler reads from the declaration.
| Prop | Type | Default | Notes |
|---|---|---|---|
asChild?inherited | boolean | undefined | — | |
description? | ReactNode | — | Secondary line under the main label. |
disabled?inherited | boolean | undefined | — | |
textValue?inherited | string | undefined | — | |
valueinherited | string | — |
SelectLabel props1 props
SelectLabel props
Type: RadixSelect.SelectLabelProps & RefAttributes<HTMLDivElement>
Values the compiler reads from the declaration.
| Prop | Type | Default | Notes |
|---|---|---|---|
asChild?inherited | boolean | undefined | — |
SelectRoot props13 props
SelectRoot props
Type: SelectProps
Values the compiler reads from the declaration.
| Prop | Type | Default | Notes |
|---|---|---|---|
autoComplete?inherited | string | undefined | — | |
children?inherited | ReactNode | — | |
defaultOpen?inherited | boolean | undefined | — | |
defaultValue?inherited | string | undefined | — | |
dir?inherited | Direction | undefined | — | |
disabled?inherited | boolean | undefined | — | |
form?inherited | string | undefined | — | |
name?inherited | string | undefined | — | |
onOpenChange?inherited | ((open: boolean) => void) | undefined | — | |
onValueChange?inherited | ((value: string) => void) | undefined | — | |
open?inherited | boolean | undefined | — | |
required?inherited | boolean | undefined | — | |
value?inherited | string | undefined | — |
SelectSeparator props1 props
SelectSeparator props
Type: SelectSeparatorProps & RefAttributes<HTMLDivElement>
Values the compiler reads from the declaration.
| Prop | Type | Default | Notes |
|---|---|---|---|
asChild?inherited | boolean | undefined | — |
SelectTrigger props4 props
SelectTrigger props
Type: SelectTriggerProps
Values the compiler reads from the declaration.
| Prop | Type | Default | Notes |
|---|---|---|---|
asChild?inherited | boolean | undefined | — | |
invalid? | boolean | undefined | — | |
leadingIcon? | ReactNode | — | Leading icon or avatar. Decorative by default. |
size? | ControlSize | undefined | — |
SelectValue props2 props
SelectValue props
Type: SelectValueProps & RefAttributes<HTMLSpanElement>
Values the compiler reads from the declaration.
| Prop | Type | Default | Notes |
|---|---|---|---|
asChild?inherited | boolean | undefined | — | |
placeholder?inherited | ReactNode | — |
Guidelines
Do
- Use it for one value out of a known set that a reader recognises on sight; the options stay behind one click.
- Put the short name in `SelectItem` and the code or unit in its `description`, rather than making the label long.
- Set `size` on the root so the trigger and the menu keep one rhythm, and `invalid` on the trigger when the form rejected the value.
Don't
- Use a select for a list that has to be searched — that is `Combobox`; for an action that runs, that is `Command`.
- Use `SelectItem` for navigation: it sets a value, it does not go anywhere.
- Style the trigger's height or padding by hand: the size token exists so a dropdown matches the input beside it.
Three controls, three different jobs
- Select
- Pick one of a handful of known options. No search.
- Combobox
- Search, then pick. Long or async lists.
- CommandMenu
- Execute something: navigate, run, toggle.
Accessibility
Radix supplies the listbox model: Enter or Space opens, the arrow keys move the active option, Home and End jump to the ends, typeahead selects by letter and Escape closes and returns focus to the trigger. The trigger carries the accessible name, and a `placeholder` is announced only until a value is chosen.
Related