Skip to content
SevenUI
Esc
navigateopen⌘Jpreview
Sign in
On this page

Select

Displays a select menu built on the Base UI Select primitive.

"use client";

import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectLabel,
  SelectTrigger,
  SelectValue,
} from "@/registry/base/ui/select";

const fruits = [
  { value: "apple", label: "Apple" },
  { value: "banana", label: "Banana" },
  { value: "blueberry", label: "Blueberry" },
  { value: "grapes", label: "Grapes" },
];

export default function SelectDemo() {
  return (
    <Select items={fruits}>
      <SelectTrigger className="w-45">
        <SelectValue placeholder="Select a fruit" />
      </SelectTrigger>
      <SelectContent>
        <SelectGroup>
          <SelectLabel>Fruits</SelectLabel>
          {fruits.map((fruit) => (
            <SelectItem key={fruit.value} value={fruit.value}>
              {fruit.label}
            </SelectItem>
          ))}
        </SelectGroup>
      </SelectContent>
    </Select>
  );
}

Installation

npx shadcn@latest add https://sevenui.dev/r/select.json

Usage

"use client";

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

const fruits = [
  { value: "apple", label: "Apple" },
  { value: "banana", label: "Banana" },
  { value: "blueberry", label: "Blueberry" },
  { value: "grapes", label: "Grapes" },
];

export default function SelectDemo() {
  return (
    <Select items={fruits}>
      <SelectTrigger className="w-45">
        <SelectValue placeholder="Select a fruit" />
      </SelectTrigger>
      <SelectContent>
        <SelectGroup>
          <SelectLabel>Fruits</SelectLabel>
          {fruits.map((fruit) => (
            <SelectItem key={fruit.value} value={fruit.value}>
              {fruit.label}
            </SelectItem>
          ))}
        </SelectGroup>
      </SelectContent>
    </Select>
  );
}

Examples

Groups

Grouped options with labels, a separator, and the small trigger size.

"use client";

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

const timezones = {
  Europe: [
    { value: "europe-istanbul", label: "Istanbul" },
    { value: "europe-london", label: "London" },
    { value: "europe-berlin", label: "Berlin" },
  ],
  America: [
    { value: "america-new-york", label: "New York" },
    { value: "america-los-angeles", label: "Los Angeles" },
  ],
};

const items = Object.values(timezones).flat();

export default function SelectGroups() {
  return (
    <Select items={items} defaultValue="europe-istanbul">
      <SelectTrigger size="sm" className="w-45">
        <SelectValue />
      </SelectTrigger>
      <SelectContent>
        <SelectGroup>
          <SelectLabel>Europe</SelectLabel>
          {timezones.Europe.map((zone) => (
            <SelectItem key={zone.value} value={zone.value}>
              {zone.label}
            </SelectItem>
          ))}
        </SelectGroup>
        <SelectSeparator />
        <SelectGroup>
          <SelectLabel>America</SelectLabel>
          {timezones.America.map((zone) => (
            <SelectItem key={zone.value} value={zone.value}>
              {zone.label}
            </SelectItem>
          ))}
        </SelectGroup>
      </SelectContent>
    </Select>
  );
}

API reference

Select

Extends the Base UI Select Root — all its props apply.

Prop Type Default
items Record<string, ReactNode> | { label, value }[]
value / defaultValue item value (array when multiple)
onValueChange (value) => void
multiple boolean false
disabled / required / readOnly boolean false

When items is given, SelectValue renders the matching item’s label instead of the raw value.

SelectTrigger

Extends the Base UI Trigger.

Prop Type Default
size "default" | "sm" "default"

SelectContent

Renders through Select.PortalSelect.PositionerSelect.Popup, and always sets alignItemWithTrigger={false} on the Positioner so the popup opens as a plain dropdown below the trigger instead of the Base UI default, which overlaps the selected item on the trigger like a native macOS select.

SelectValue, SelectItem, SelectGroup, SelectLabel, SelectSeparator, SelectScrollUpButton, SelectScrollDownButton

Styled Base UI parts. SelectItem takes the option value (and disabled); the scroll buttons appear automatically when the list overflows.

Was this page helpful?