8.4k

Select

A common form component for choosing a predefined value in a dropdown menu.

API Reference

Installation

pnpm dlx shadcn@latest add https://coss.com/ui/r/select.json

Usage

import {
  Select,
  SelectItem,
  SelectPopup,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"
const items = [
  { label: "Select framework", value: null },
  { label: "Next.js", value: "next" },
  { label: "Vite", value: "vite" },
  { label: "Astro", value: "astro" },
]
 
<Select items={items}>
  <SelectTrigger>
    <SelectValue />
  </SelectTrigger>
  <SelectPopup>
    {items.map((item) => (
      <SelectItem key={item.value} value={item}>
        {item.label}
      </SelectItem>
    ))}
  </SelectPopup>
  </Select>

Examples

For accessible labelling and validation, prefer using the Field component to wrap selects. See the related example: Select field.

Small Size

Large Size

Disabled

Without Item Alignment

With Groups

Multiple Selection

Form Integration

Comparing with Radix / shadcn

If you’re already familiar with Radix UI and shadcn/ui, this guide highlights the small differences and similarities so you can get started with coss.com ui quickly.

Important: Base UI changes how options are provided. Instead of deriving options from children only (Radix pattern), you should pass an items prop (array or record) so values and labels are known before hydration. This avoids SSR pitfalls and improves mount performance. Alternatively, provide a function child to SelectValue to format the label. See the Base UI Select docs.

Prop Mapping

ComponentRadix UI PropBase UI Prop
Selectitemsitems
SelectValueplaceholderremoved
SelectPopupalignItemWithTriggerno equivalent

Quick Checklist

  • Set items prop on Select
  • Remove placeholder from Select
  • Prefer SelectPopup instead of SelectContent
  • If you used asChild on parts, switch to the render prop

Additional Notes

Size Comparison

coss.com ui select sizes are more compact compared to shadcn/ui, making them better suited for dense applications:

SizeHeight (shadcn/ui)Height (coss.com ui)
sm32px28px
default36px32px
lg-36px

So, for example, if you were using the default size in shadcn/ui and you want to preserve the original height, you should use the lg size in coss.com ui.

New Prop

Base UI introduces the alignItemWithTrigger prop to control whether the SelectContent overlaps the SelectTrigger so the selected item's text is aligned with the trigger's value text.

Comparison Example

shadcn/ui
<Select>
  <SelectTrigger>
    <SelectValue placeholder="Select a framework" />
  </SelectTrigger>
  <SelectContent>
    <SelectItem value="next">Next.js</SelectItem>
    <SelectItem value="vite">Vite</SelectItem>
    <SelectItem value="astro">Astro</SelectItem>
  </SelectContent>
</Select>
coss.com ui
[!code word:items:2]
<Select
  items={[
    { label: "Select a framework", value: null },
    { label: "Next.js", value: "next" },
    { label: "Vite", value: "vite" },
    { label: "Astro", value: "astro" },
  ]}
>
  <SelectTrigger>
    <SelectValue />
  </SelectTrigger>
  <SelectPopup alignItemWithTrigger={false}>
    {items.map((item) => (
      <SelectItem key={item.value} value={item}>
        {item.label}
      </SelectItem>
    ))}
  </SelectPopup>
</Select>

coss.com ui

Built by and for the team of Cal.com, Inc. — the leading commercial open source company (“coss”).