Pop-up Button
A pop-up button that opens a menu of options, in bordered and System Settings styles.
"use client"
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
export default function SelectDemo() {
return (
<Select defaultValue="medium" items={{ small: "Small", medium: "Medium", large: "Large" }}>
<SelectTrigger className="w-32">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="small">Small</SelectItem>
<SelectItem value="medium">Medium</SelectItem>
<SelectItem value="large">Large</SelectItem>
</SelectContent>
</Select>
)
}Installation
pnpm dlx shadcn@latest add @cupertinoui/selectThe first install also adds the macOS theme. See Installation to set up the registry.
Usage
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
<Select defaultValue="medium">
<SelectTrigger>
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="small">Small</SelectItem>
<SelectItem value="medium">Medium</SelectItem>
</SelectContent>
</Select>By default the menu opens over the trigger with the selected item aligned to it, like a macOS pop-up button. Pass alignItemWithTrigger={false} to open it below instead.
Give Select an items map (value → label) so SelectValue shows the chosen item's label rather than its value, as in Base UI.
Examples
Borderless
The style System Settings uses in grouped forms: the value followed by chevrons in a round chip.
"use client"
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
// The pop-up style used in System Settings rows.
export default function SelectBorderless() {
return (
<div className="flex w-80 items-center justify-between rounded-mac-group bg-mac-group px-2.5 py-2">
<span className="text-mac-body">Dock position on screen</span>
<Select defaultValue="bottom" items={{ left: "Left", bottom: "Bottom", right: "Right" }}>
<SelectTrigger variant="borderless">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="left">Left</SelectItem>
<SelectItem value="bottom">Bottom</SelectItem>
<SelectItem value="right">Right</SelectItem>
</SelectContent>
</Select>
</div>
)
}Sizes
"use client"
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
export default function SelectSizes() {
return (
<div className="flex flex-wrap items-center justify-center gap-3">
{(["sm", "default", "lg"] as const).map((size) => (
<Select key={size} defaultValue="png" items={{ png: "PNG", jpeg: "JPEG", heic: "HEIC" }}>
<SelectTrigger size={size}>
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="png">PNG</SelectItem>
<SelectItem value="jpeg">JPEG</SelectItem>
<SelectItem value="heic">HEIC</SelectItem>
</SelectContent>
</Select>
))}
</div>
)
}Groups
Labels and separators organize long menus.
"use client"
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectLabel,
SelectSeparator,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
export default function SelectGroups() {
return (
<Select items={{ sf: "SF Pro", ny: "New York", mono: "SF Mono", helvetica: "Helvetica Neue", menlo: "Menlo" }}>
<SelectTrigger className="w-44">
<SelectValue placeholder="Choose a font" />
</SelectTrigger>
<SelectContent alignItemWithTrigger={false}>
<SelectGroup>
<SelectLabel>System</SelectLabel>
<SelectItem value="sf">SF Pro</SelectItem>
<SelectItem value="ny">New York</SelectItem>
<SelectItem value="mono">SF Mono</SelectItem>
</SelectGroup>
<SelectSeparator />
<SelectGroup>
<SelectLabel>Other</SelectLabel>
<SelectItem value="helvetica">Helvetica Neue</SelectItem>
<SelectItem value="menlo" disabled>
Menlo
</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
)
}API Reference
Every part forwards the props of the underlying Base UI Select part. The props below are the ones CupertinoUI adds or changes.
Select
| Prop | Type | Description |
|---|---|---|
value / defaultValue | string | The selected value. |
items | Record<string, ReactNode> | { value, label }[] | The labels SelectValue shows for each value. |
onValueChange | (value: string) => void | Called when the selection changes. |
SelectTrigger
| Prop | Type | Description |
|---|---|---|
variant | "default" | "borderless"Default: "default" | Bordered pop-up button or the System Settings style. |
size | "sm" | "default" | "lg"Default: "default" | 20, 24 or 28pt tall. |
className | string | Extra classes, merged with the component's own. |
SelectContent
| Prop | Type | Description |
|---|---|---|
alignItemWithTrigger | booleanDefault: true | Opens over the trigger with the chosen item on it; false opens below. |
className | string | Extra classes, merged with the component's own. |
SelectItem
| Prop | Type | Description |
|---|---|---|
value | string | The value of the option. |
disabled | boolean | Dims the option. |