Join our Discord Community

Select

Displays a list of options for the user to pick from—triggered by a button. Built for React applications with Next.js integration and TypeScript support.

That dropdown where you pick one option from a list? That's what a select does. But unlike the boring native select, this one actually looks good, works with your keyboard, and doesn't make you want to cry when you try to style it.

Pick your favorite

Clean dropdown with grouped options:

Loading component...

Built on Radix UI Select with full keyboard navigation, typeahead search, and proper ARIA support. This free open source React component handles all the complex positioning and focus management while looking exactly how you want.

npx shadcn@latest add select

Why custom selects beat native ones

Native selects are the IE6 of form controls. Custom selects fix everything:

  • Actually styleable - Make it match your design, not the OS
  • Typeahead search - Start typing to find options
  • Grouped options - Organize with labels and sections
  • Custom content - Icons, descriptions, whatever you need
  • Keyboard navigation - Arrow keys, Enter, Escape, it all works
  • Touch friendly - Works great on mobile without that weird picker

Useful select patterns

Country selector

With flags and search for long lists:

Loading component...

Status selector

Visual indicators for different states:

Loading component...

Form with validation

Integrated with react-hook-form and Zod:

Loading component...

Multi-column layout

When you need to show more info:

Loading component...

These patterns solve real problems. Country pickers that don't suck, status selectors with clear visual feedback, forms that validate properly.

Perfect for forms and filters

Works great anywhere users need to pick from a list - forms, filters, settings, preferences. The kind of places where a good select makes the difference between frustration and flow.

Drops right into Next.js projects. Full TypeScript support. Styled with Tailwind CSS to match the shadcn design system.

Built on Radix UI

Uses Radix UI Select under the hood, which handles the hard stuff:

  • Positioning magic - Always visible, even near edges
  • Focus management - Tab, arrows, everything just works
  • Typeahead - Start typing to jump to options
  • Portal rendering - No z-index nightmares
  • Scroll buttons - For long lists that need them
  • RTL support - Works with any text direction

API Reference

Select

The root container that manages select state.

PropTypeDefaultDescription
defaultValuestring-Default selected value for uncontrolled
valuestring-Controlled selected value
onValueChange(value: string) => void-Called when selection changes
defaultOpenbooleanfalseStart open for uncontrolled
openboolean-Controlled open state
onOpenChange(open: boolean) => void-Called when open state changes
disabledbooleanfalseDisable the select
namestring-Name for form submission
requiredbooleanfalseWhether selection is required

SelectTrigger

The button that opens the select.

PropTypeDefaultDescription
classNamestring-Additional CSS classes
asChildbooleanfalsePass functionality to child

Data attributes:

  • [data-state]: "open" | "closed"
  • [data-disabled]: Present when disabled
  • [data-placeholder]: Present when showing placeholder

SelectValue

Displays the selected value or placeholder.

PropTypeDefaultDescription
placeholderstring-Text when nothing selected
asChildbooleanfalsePass functionality to child

SelectContent

The dropdown panel containing options.

PropTypeDefaultDescription
classNamestring-Additional CSS classes
position"item-aligned" | "popper""item-aligned"Positioning mode
side"top" | "bottom""bottom"Preferred side (popper mode)
sideOffsetnumber4Distance from trigger
align"start" | "center" | "end""center"Alignment with trigger

SelectItem

Individual option in the select.

PropTypeDefaultDescription
classNamestring-Additional CSS classes
valuestringrequiredValue for this option
disabledbooleanfalseDisable this option
textValuestring-Text for typeahead if using custom content

Data attributes:

  • [data-state]: "checked" | "unchecked"
  • [data-highlighted]: Present when focused
  • [data-disabled]: Present when disabled

SelectGroup

Container for grouped items.

PropTypeDefaultDescription
classNamestring-Additional CSS classes

SelectLabel

Label for a group of items.

PropTypeDefaultDescription
classNamestring-Additional CSS classes

SelectSeparator

Visual separator between items or groups.

PropTypeDefaultDescription
classNamestring-Additional CSS classes

Keyboard Navigation

KeyAction
SpaceOpen select and focus selected/first item
EnterOpen select or select focused item
Arrow DownOpen select or move to next item
Arrow UpOpen select or move to previous item
HomeFocus first item
EndFocus last item
EscapeClose select
Page DownJump down multiple items
Page UpJump up multiple items
Any letterJump to item starting with letter

Common Patterns

PatternUse CaseImplementation
Simple listBasic selectionItems without groups
Grouped optionsOrganized choicesSelectGroup with SelectLabel
With iconsVisual optionsIcons in SelectItem
SearchableLong listsAdd search above viewport
With descriptionsComplex optionsMulti-line SelectItem content
Disabled optionsUnavailable choicesdisabled prop on SelectItem

Make selects that don't suck

Keep these in mind when building selects:

  • Set a width - Don't let it jump around when selection changes
  • Use placeholders - Tell users what they're selecting
  • Group related options - Makes scanning easier
  • Disable smartly - Gray out what's not available
  • Handle long lists - Add search or better grouping
  • Test keyboard nav - Should feel smooth with just arrows
  • Consider mobile - Touch targets need to be bigger
  • Match trigger to content - Width should usually match