Button
Push buttons in every macOS 27 style: the accent-filled default button, bordered, tinted, borderless and destructive, from mini to extra large.
@cupertinoui/buttonRegistry JSON "use client"
import { Button } from "@/components/ui/button"
export default function ButtonDemo() {
return (
<div className="flex flex-wrap items-center gap-2">
<Button variant="secondary">Cancel</Button>
<Button>Save</Button>
</div>
)
}Installation
pnpm dlx shadcn@latest add @cupertinoui/buttonThe first install also adds the macOS theme. See Installation to set up the registry.
Usage
import { Button } from "@/components/ui/button"
<Button variant="secondary">Cancel</Button>
<Button>Save</Button>Examples
Variants
Default is the accent-filled default button of a window. Bordered is the standard push button; tinted, borderless and destructive cover the rest of the macOS 27 styles.
"use client"
import { Button } from "@/components/ui/button"
export default function ButtonVariants() {
return (
<div className="flex flex-wrap items-center justify-center gap-2">
<Button>Default</Button>
<Button variant="secondary">Bordered</Button>
<Button variant="tinted">Tinted</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Borderless</Button>
<Button variant="destructive">Delete</Button>
<Button variant="link">Learn More</Button>
</div>
)
}Sizes
Mini, small and medium buttons are rounded rectangles. Large and extra large buttons are capsules, as in macOS 27.
"use client"
import { Button } from "@/components/ui/button"
export default function ButtonSizes() {
return (
<div className="flex flex-wrap items-center justify-center gap-2">
<Button variant="secondary" size="xs">Mini</Button>
<Button variant="secondary" size="sm">Small</Button>
<Button variant="secondary">Medium</Button>
<Button variant="secondary" size="lg">Large</Button>
<Button variant="secondary" size="xl">Extra Large</Button>
</div>
)
}With an icon
"use client"
import { DownloadIcon, PlusIcon, ShareIcon, TrashIcon } from "lucide-react"
import { Button } from "@/components/ui/button"
export default function ButtonWithIcon() {
return (
<div className="flex flex-wrap items-center justify-center gap-2">
<Button>
<DownloadIcon /> Download
</Button>
<Button variant="secondary">
<ShareIcon /> Share…
</Button>
<Button variant="secondary" size="icon" aria-label="Add">
<PlusIcon />
</Button>
<Button variant="secondary" size="icon-lg" aria-label="Move to Trash">
<TrashIcon />
</Button>
</div>
)
}Disabled
"use client"
import { Button } from "@/components/ui/button"
export default function ButtonDisabled() {
return (
<div className="flex flex-wrap items-center justify-center gap-2">
<Button disabled>Default</Button>
<Button variant="secondary" disabled>
Bordered
</Button>
<Button variant="tinted" disabled>
Tinted
</Button>
</div>
)
}API Reference
Every part forwards the props of the underlying element. The props below are the ones CupertinoUI adds or changes.
Button
Base UI's Button: a native button, or another element with render.
| Prop | Type | Description |
|---|---|---|
variant | "default" | "secondary" | "tinted" | "outline" | "ghost" | "destructive" | "link"Default: "default" | The button style. |
size | "xs" | "sm" | "default" | "lg" | "xl" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | "icon-xl"Default: "default" | Mini (16pt), small (20pt), medium (24pt), large (28pt) or extra large (36pt). |
render | ReactElement | Render another element with the button's styles, e.g. render={<Link href="/docs" />}. Add nativeButton={false} when it isn't a <button>. |
className | string | Extra classes, merged with the component's own. |