Back to Design System

Select

A Radix-powered dropdown for choosing a single value. Mirrors native select behavior while supporting keyboard navigation, search, and accessible labelling.

Overview

Use for

  • Forms that require a constrained list of options.
  • Settings panels that need searchable select menus.
  • Inline controls such as filter chips or toolbar selectors.

Avoid for

  • Large data sets that require async loading—use Combobox (Command) pattern.
  • Binary choices—`Switch` or `RadioGroup` communicate state changes faster.
  • Multi-select requirements—use the `DropdownMenu` with checkbox items.

Examples

Default select

import {
  Select,
  SelectTrigger,
  SelectValue,
  SelectContent,
  SelectItem,
} from "@/components/ui/select"

export function ColorSelect() {
  return (
    <Select defaultValue="pixexid">
      <SelectTrigger className="w-[220px]">
        <SelectValue placeholder="Choose theme" />
      </SelectTrigger>
      <SelectContent>
        <SelectItem value="pixexid">Pixexid</SelectItem>
        <SelectItem value="midnight">Midnight</SelectItem>
        <SelectItem value="aurora">Aurora</SelectItem>
      </SelectContent>
    </Select>
  )
}

Grouped options

import {
  Select,
  SelectTrigger,
  SelectValue,
  SelectContent,
  SelectGroup,
  SelectLabel,
  SelectItem,
  SelectSeparator,
} from "@/components/ui/select"

export function PlanSelect() {
  return (
    <Select defaultValue="starter">
      <SelectTrigger className="w-[260px]">
        <SelectValue placeholder="Select plan" />
      </SelectTrigger>
      <SelectContent>
        <SelectGroup>
          <SelectLabel>Starter</SelectLabel>
          <SelectItem value="starter">Starter — $0/mo</SelectItem>
          <SelectItem value="creator">Creator — $12/mo</SelectItem>
        </SelectGroup>
        <SelectSeparator />
        <SelectGroup>
          <SelectLabel>Teams</SelectLabel>
          <SelectItem value="studio">Studio — $39/mo</SelectItem>
          <SelectItem value="enterprise">Enterprise — Talk to sales</SelectItem>
        </SelectGroup>
      </SelectContent>
    </Select>
  )
}

Controlled state

Use `value` + `onValueChange` to control selection.

import { useState } from "react"
import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from "@/components/ui/select"

export function SelectWithState() {
  const [value, setValue] = useState("pixexid")

  return (
    <div className="space-y-2">
      <label className="text-sm font-medium text-foreground">Workspace</label>
      <Select value={value} onValueChange={setValue}>
        <SelectTrigger className="w-[240px]">
          <SelectValue />
        </SelectTrigger>
        <SelectContent>
          <SelectItem value="pixexid">Pixexid</SelectItem>
          <SelectItem value="design">Design Studio</SelectItem>
          <SelectItem value="marketing">Marketing experiments</SelectItem>
        </SelectContent>
      </Select>
      <p className="text-xs text-neutral-strong">Selected: {value}</p>
    </div>
  )
}

Props

PropTypeDefaultDescription
onValueChange(value: string) => voidCallback fired when a new option is selected.
valuestringControlled value for the select trigger.
defaultValuestringInitial value for uncontrolled usage.
disabledbooleanfalseDisables the trigger and hides the content from keyboard navigation.

Accessibility

Keyboard support

  • Space or Enter opens the menu.
  • Use arrow keys to move between options; first letter search is built in via Radix.
  • Esc closes without changing the value.

Best practices

  • Always provide a label outside the trigger for screen readers.
  • Ensure `SelectValue` has a placeholder for empty selections.
  • Group related options with `SelectGroup` and `SelectLabel` to improve navigation.