Select
A dropdown menu of options triggered by a button. Built on Radix Select for full keyboard navigation, search-as-you-type, and accessibility. The trigger styling matches Input so Select fits cleanly into form layouts.
Installation
npx shadcn@latest add @wuko/selectUsage
Composition
Use the following composition to build a Select.
Groups
Use SelectGroup, SelectLabel, and SelectSeparator to organize related items into sections.
Scrollable
When the content exceeds the popover height, scroll buttons appear at the top and bottom for keyboard and mouse users.
<Select>
<SelectTrigger className="w-55">
<SelectValue placeholder="Select a timezone" />
</SelectTrigger>
<SelectContent>
<SelectItem value="utc-8">(UTC-08:00) Pacific Time</SelectItem>
<SelectItem value="utc-5">(UTC-05:00) Eastern Time</SelectItem>
<SelectItem value="utc-0">(UTC+00:00) UTC</SelectItem>
<SelectItem value="utc+1">(UTC+01:00) Berlin</SelectItem>
{/* ...more items */}
</SelectContent>
</Select>Disabled
Set disabled on the root Select to disable the whole control, or disabled on a single SelectItem to disable just that option.
<Select disabled>
<SelectTrigger className="w-45">
<SelectValue placeholder="Select a fruit" />
</SelectTrigger>
<SelectContent>
<SelectItem value="apple">Apple</SelectItem>
</SelectContent>
</Select>Invalid
Set aria-invalid="true" on the SelectTrigger to show an error state. The border and focus ring turn red.
<Select>
<SelectTrigger aria-invalid="true" className="w-45">
<SelectValue placeholder="Select a fruit" />
</SelectTrigger>
<SelectContent>
<SelectItem value="apple">Apple</SelectItem>
</SelectContent>
</Select>Sub-components
Each sub-component forwards className and all native props for its underlying Radix primitive.
| Prop | Type | Default | Description |
|---|---|---|---|
| Select | Radix Root | — | The root container. Controlled via value/onValueChange or uncontrolled via defaultValue. |
| SelectTrigger | Radix Trigger | — | The button that opens the menu. Styled like an Input. Accepts aria-invalid for error states. |
| SelectValue | Radix Value | — | Displays the selected value (or placeholder) inside the trigger. |
| SelectContent | Radix Content | position="popper" | The floating panel. Renders into a portal. Position prop: "popper" (aligns to trigger edge) or "item-aligned" (positions selected item over trigger). |
| SelectItem | Radix Item | — | A selectable option. Requires a value prop. Supports disabled. |
| SelectGroup | Radix Group | — | Wraps related items. Pair with SelectLabel for a section heading. |
| SelectLabel | Radix Label | — | A non-selectable heading for a SelectGroup. |
| SelectSeparator | Radix Separator | — | A thin divider between SelectGroups. |
Accessibility
- Built on Radix Select. Full keyboard support: Enter or Space opens, Arrow keys move between items, Esc closes, Home/End jump to first and last items, type-to-search jumps to the first matching item.
- The trigger automatically links to the content via
aria-controlsandaria-expanded. Screen readers announce the menu state and selected value. - For invalid state, set
aria-invalid="true"onSelectTrigger. The visual change is paired with the ARIA attribute so screen readers announce the error. SelectGroup+SelectLabelcreates a labeled section announced by screen readers (similar to<optgroup>in native select).- For form submission, pass
nameon the rootSelect. Radix renders a hidden native select for form compatibility.