Make your AI a shadcn expert

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.

Scroll to load preview...

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

SelectValue
SelectLabel
SelectItem
SelectItem
SelectSeparator

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.

Scroll to load preview...

Groups

SelectGroup plus SelectLabel, with a SelectSeparator between chunks.

Scroll to load preview...

Scrollable

Timezones by region. Scroll buttons appear when the list is taller than the viewport.

Scroll to load preview...

Disabled

disabled on Select greys the trigger. On SelectItem it keeps the row in the list.

Scroll to load preview...

Invalid

aria-invalid on SelectTrigger. data-invalid on Field. Both, or the label stays the wrong color.

Scroll to load preview...

RTL

Wrap with DirectionProvider and dir="rtl". Copy stays Arabic.

Scroll to load preview...

API

Prop

Type

SelectTrigger

Prop

Type

SelectContent

Prop

Type

SelectItem

Prop

Type

SelectValue takes placeholder. SelectGroup, SelectLabel, and SelectSeparator take className.

Keyboard

KeyAction
SpaceOpen on the trigger. Select the focused item
EnterOpen on the trigger. Select the focused item
ArrowDown / ArrowUpOpen on the trigger. Next / previous item
Letter keysJump to a matching item
EscapeClose and return focus to the trigger
TabLeave 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

Questions

Was this page helpful?

Sign in to leave feedback.