Shadcn.io is not affiliated with official shadcn/ui
Shadcn Select
React select for theme, status, and timezone pickers. Built with TypeScript and Tailwind CSS for Next.js using Base UI — grouped options and typeahead search.
A select is a button that opens a custom list. Click an option and the list closes. Use it for theme, status, or timezone — a closed set that should match the rest of the form.
Looking for a neobrutalism version for shadcn?
Same select, thicker borders. The NeoBrutalism select is the kit if you want that look.
Usage
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"<Select>
<SelectTrigger className="w-[180px]">
<SelectValue placeholder="Theme" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectItem value="light">Light</SelectItem>
<SelectItem value="dark">Dark</SelectItem>
<SelectItem value="system">System</SelectItem>
</SelectGroup>
</SelectContent>
</Select>defaultValue for uncontrolled. value plus onValueChange when you own the state.
Composition
Align Item With Trigger
position="item-aligned" (the default) parks the selected row on the trigger. position="popper" docks to the edge like a popover.
Groups
SelectGroup plus SelectLabel, with a SelectSeparator between chunks.
Scrollable
Timezones by region. Scroll buttons appear when the list is taller than the viewport.
Disabled
disabled on Select greys the trigger. On SelectItem it keeps the row in the list.
Invalid
aria-invalid on SelectTrigger. data-invalid on Field. Both, or the label stays the wrong color.
RTL
Wrap with DirectionProvider and dir="rtl". Copy stays Arabic.
API
Prop
Type
SelectTrigger
Prop
Type
SelectContent
Prop
Type
SelectItem
Prop
Type
SelectValue takes placeholder. SelectGroup, SelectLabel, and SelectSeparator take className.
Keyboard
| Key | Action |
|---|---|
Space | Open on the trigger. Select the focused item |
Enter | Open on the trigger. Select the focused item |
ArrowDown / ArrowUp | Open on the trigger. Next / previous item |
| Letter keys | Jump to a matching item |
Escape | Close and return focus to the trigger |
Tab | Leave the select |
Notes
Empty string is not a value
SelectItem cannot use value="". Use placeholder on SelectValue for the empty state, or a real token like none.
Give Root a name if it should post with the form. Radix already renders a hidden native <select>.
With other components
Label, description, error
FormValidate the choice
LabelName the trigger
InputSame form row
Button GroupCompact filter bar
CardSettings on a card
Questions
Related
Was this page helpful?
Sign in to leave feedback.
Scroll Area
React scroll area for overflow lists and image galleries. Built with TypeScript and Tailwind CSS for Next.js using Base UI — custom scrollbars, native wheel and touch.
Separator
React separator for menus, forms, and list rows. Built with TypeScript and Tailwind CSS for Next.js using Base UI — horizontal or vertical, decorative by default.