Skip to main content
The Select component provides a dropdown menu for selecting from a list of options with support for groups, multiple selections, and custom alignment.

Installation

npx shadcn@latest add @eo-n/select

Usage

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

export default function Example() {
  const items = [
    { label: "Apple", value: "apple" },
    { label: "Banana", value: "banana" },
    { label: "Cherry", value: "cherry" },
  ];

  return (
    <Select items={items}>
      <SelectTrigger>
        <SelectValue placeholder="Select a fruit" />
      </SelectTrigger>
      <SelectContent>
        {items.map(({ label, value }) => (
          <SelectItem key={value} value={value}>
            {label}
          </SelectItem>
        ))}
      </SelectContent>
    </Select>
  );
}

Examples

Default

const items = [
  { label: "Select theme", value: null },
  { label: "System default", value: "system" },
  { label: "Light", value: "light" },
  { label: "Dark", value: "dark" },
];

<Select items={items}>
  <SelectTrigger>
    <SelectValue />
  </SelectTrigger>
  <SelectContent>
    {items.map(({ label, value }) => (
      <SelectItem key={value} value={value}>
        {label}
      </SelectItem>
    ))}
  </SelectContent>
</Select>

With Groups

import { SelectGroup, SelectGroupLabel } from "@/components/ui/select";

<Select items={items}>
  <SelectTrigger>
    <SelectValue placeholder="Select a fruit" />
  </SelectTrigger>
  <SelectContent>
    <SelectGroup>
      <SelectGroupLabel>Fruits</SelectGroupLabel>
      <SelectItem value="apple">Apple</SelectItem>
      <SelectItem value="banana">Banana</SelectItem>
      <SelectItem value="cherry">Cherry</SelectItem>
    </SelectGroup>
    <SelectGroup>
      <SelectGroupLabel>Vegetables</SelectGroupLabel>
      <SelectItem value="carrot">Carrot</SelectItem>
      <SelectItem value="lettuce">Lettuce</SelectItem>
      <SelectItem value="tomato">Tomato</SelectItem>
    </SelectGroup>
  </SelectContent>
</Select>

Align Trigger

Align the popup width with the trigger element.
<Select items={items}>
  <SelectTrigger>
    <SelectValue placeholder="Select..." />
  </SelectTrigger>
  <SelectContent alignItemWithTrigger>
    {items.map(({ label, value }) => (
      <SelectItem key={value} value={value}>
        {label}
      </SelectItem>
    ))}
  </SelectContent>
</Select>

Multiple Selection

<Select items={items} multiple>
  <SelectTrigger>
    <SelectValue placeholder="Select multiple" />
  </SelectTrigger>
  <SelectContent>
    {items.map(({ label, value }) => (
      <SelectItem key={value} value={value}>
        {label}
      </SelectItem>
    ))}
  </SelectContent>
</Select>

Small Size

<Select items={items}>
  <SelectTrigger size="sm">
    <SelectValue placeholder="Small select" />
  </SelectTrigger>
  <SelectContent>
    {items.map(({ label, value }) => (
      <SelectItem key={value} value={value}>
        {label}
      </SelectItem>
    ))}
  </SelectContent>
</Select>

With Icons

import { Moon, Sun, Monitor } from "lucide-react";

<Select items={items}>
  <SelectTrigger>
    <SelectValue placeholder="Select theme" />
  </SelectTrigger>
  <SelectContent>
    <SelectItem value="light">
      <Sun />
      Light
    </SelectItem>
    <SelectItem value="dark">
      <Moon />
      Dark
    </SelectItem>
    <SelectItem value="system">
      <Monitor />
      System
    </SelectItem>
  </SelectContent>
</Select>

Controlled

import { useState } from "react";

function ControlledSelect() {
  const [value, setValue] = useState("apple");

  return (
    <Select items={items} value={value} onValueChange={setValue}>
      <SelectTrigger>
        <SelectValue />
      </SelectTrigger>
      <SelectContent>
        {items.map(({ label, value }) => (
          <SelectItem key={value} value={value}>
            {label}
          </SelectItem>
        ))}
      </SelectContent>
    </Select>
  );
}

API Reference

Select

Extends all props from @base-ui/react Select.Root component.
items
array
required
Array of items for the select. Each item should have a label and value.
value
string | string[]
The controlled selected value(s).
defaultValue
string | string[]
The default selected value(s) when uncontrolled.
onValueChange
function
Callback fired when the selected value changes.
(value: string | string[]) => void
multiple
boolean
default:"false"
Whether multiple items can be selected.
disabled
boolean
Whether the select is disabled.
required
boolean
Whether the select is required in a form.
name
string
The name attribute for form submission.

SelectTrigger

size
string
default:"default"
The size of the trigger button.Options: default | sm
className
string
Additional CSS classes to apply.

SelectValue

placeholder
string
Placeholder text when no value is selected.
className
string
Additional CSS classes to apply.

SelectContent

sideOffset
number
default:"4"
The distance in pixels from the trigger.
alignItemWithTrigger
boolean
default:"false"
Whether to align the selected item with the trigger.
className
string
Additional CSS classes to apply.

SelectItem

value
string
required
The value of the item.
disabled
boolean
Whether the item is disabled.
className
string
Additional CSS classes to apply.

SelectGroup

Groups related select items together.

SelectGroupLabel

className
string
Additional CSS classes to apply.

SelectSeparator

Visual separator between select items.
className
string
Additional CSS classes to apply.

TypeScript

import { Select as SelectPrimitive } from "@base-ui/react";

const Select = SelectPrimitive.Root;

interface SelectTriggerProps
  extends React.ComponentProps<typeof SelectPrimitive.Trigger> {
  size?: "sm" | "default";
}

type SelectItemProps = React.ComponentProps<typeof SelectPrimitive.Item>;

Accessibility

  • Fully keyboard accessible (Arrow keys, Enter, Escape)
  • Proper ARIA attributes
  • Focus management
  • Scrollable with scroll indicators
  • Works with form labels
  • Screen reader support

Build docs developers (and LLMs) love