Elements

Components / Forms

Select

A select menu built on Base UI with a positioned popup, groups, labels, and separators.

Always show the label, not the value. Base UI's SelectValue renders the raw value key unless you pass an items array (or record) of { value, label } to <Select>. With itemsset, the trigger shows “Harbourview” instead of harbourview.

Installation

bash
npx shadcn add https://raw.githubusercontent.com/levi-putna/elements/main/registry/select/registry.json

Basic

Select · trigger shows the label
tsx
import {
  Select, SelectContent, SelectItem, SelectTrigger, SelectValue,
} from "@/components/ui/select"

const buildings = [
  { value: "harbourview", label: "Harbourview" },
  { value: "parkside", label: "Parkside" },
  { value: "the-quay", label: "The Quay" },
]

{/* Pass `items` so the trigger shows the LABEL, not the value key */}
<Select items={buildings}>
  <SelectTrigger className="w-56">
    <SelectValue placeholder="Select a building" />
  </SelectTrigger>
  <SelectContent>
    {buildings.map((b) => (
      <SelectItem key={b.value} value={b.value}>{b.label}</SelectItem>
    ))}
  </SelectContent>
</Select>

Grouped

Select · groups + separator
tsx
{/* Pass the flattened roles as items so the label resolves */}
<Select items={roles}>
  <SelectTrigger className="w-56">
    <SelectValue placeholder="Select a role" />
  </SelectTrigger>
  <SelectContent>
    <SelectGroup>
      <SelectLabel>Committee</SelectLabel>
      <SelectItem value="chair">Chairperson</SelectItem>
      <SelectItem value="secretary">Secretary</SelectItem>
    </SelectGroup>
    <SelectSeparator />
    <SelectGroup>
      <SelectLabel>Owners</SelectLabel>
      <SelectItem value="owner">Lot owner</SelectItem>
      <SelectItem value="tenant">Tenant</SelectItem>
    </SelectGroup>
  </SelectContent>
</Select>

SelectTrigger props

PropTypeDefaultDescription
size"sm" | "default""default"Trigger height.
disabledboolean-Disables the select.