Components
Select
One choice from a list, in a compact control.
Default
const products = [
{ value: "mrkdwn", label: "mrkdwn" },
{ value: "buena-mono", label: "buena mono" },
];
<Select defaultValue="mrkdwn" items={products}>
<SelectTrigger className="w-48">
<SelectValue placeholder="Choose a product" />
</SelectTrigger>
<SelectContent>
{products.map((product) => (
<SelectItem key={product.value} value={product.value}>
{product.label}
</SelectItem>
))}
</SelectContent>
</Select> Groups, scroll & states
<Select defaultValue="mrkdwn">
<SelectTrigger aria-invalid>…</SelectTrigger>
<SelectContent alignItemWithTrigger={false}>
<SelectGroup>
<SelectLabel>Apps</SelectLabel>
<SelectItem value="mrkdwn">mrkdwn</SelectItem>
</SelectGroup>
<SelectSeparator />
<SelectItem value="archived" disabled>Archived</SelectItem>
</SelectContent>
</Select>
Left to right: SelectGroup +
SelectLabel + SelectSeparator;
a scrollable list capped with max-h-48 (scroll arrows
appear); a disabled trigger with a disabled item; an
aria-invalid trigger; and
alignItemWithTrigger={false}, which drops the popup
below the trigger instead of overlaying the selected item on it (the default).
Sizes, prefix & required
{/* Sizes */}
<SelectTrigger size="sm">…</SelectTrigger>
<SelectTrigger>…</SelectTrigger>
{/* Prefix (leading icon) + built-in chevron suffix */}
<SelectTrigger>
<ArrowUpCircle className="size-4 opacity-60" />
<SelectValue />
</SelectTrigger>
{/* Required */}
<Select required>
<SelectTrigger>
<SelectValue placeholder="Please select an option" />
</SelectTrigger>
</Select> Sizes use size="sm" vs the default.
Prefix and suffix: a leading icon before
SelectValue is the prefix; the built-in chevron is the
suffix. Required passes required on
Select next to a labelled field.
Markdown for agents: /design/select.md · spec: /design.md