Components · shadcn button
Button
A capsule, for anything you press. Red marks the one action to take on a screen, so primary is never the default.
Variants
Primary is the accent fill, once per screen. Secondary (the default) is a text-colored outline. Quiet is text only, for toolbars and icon buttons. Danger is an outlined tint with a leading WarningCircle. It is never a solid red fill and never sits beside a primary.
Show codeHide code
<Button variant="primary">Register now</Button>
<Button>See schedule</Button>
<Button variant="quiet">Cancel</Button>
<Button variant="danger"><WarningCircleIcon aria-hidden />Reject applicant</Button>Show codeHide code
<Button variant="danger"><WarningCircleIcon aria-hidden />Reject applicant</Button>Sizes
Small for toolbars, chip rows and admin; medium (44px) by default; large for the hero only.
Show codeHide code
<Button size="sm">Download</Button>
<Button>Download</Button>
<Button size="lg" variant="primary">Register now</Button>States
| State | Behavior |
|---|---|
| Hover | accent-hover (primary) or a surface-strong fill (others), 120ms. Pointer devices only. |
| Active | accent-active (primary), plus a 1px downward press. |
| Focus-visible | The global 2px focus outline with an offset. |
| Disabled | surface fill, subtle text, no hover. Explain why nearby. Never disable submit to signal an invalid form. |
| Loading | Spinner + progressive label (“Send” → “Sending…”), aria-busy. Presses are ignored and focus stays put. |
Show codeHide code
<Button variant="primary" loading={sending}>
{sending ? "Sending…" : "Send"}
</Button>Show codeHide code
<Button disabled>Closed</Button>With icons
An optional leading icon; a trailing ArrowRight only for “go to” actions. Icon-only buttons take an aria-label in the page language and keep a 44px hit area.
Show codeHide code
<Button variant="primary">See all events <ArrowRightIcon aria-hidden /></Button>
<Button><DownloadSimpleIcon aria-hidden />Download the guide</Button>
<Button variant="quiet" size="icon" aria-label="Delete"><TrashIcon aria-hidden /></Button>Rules
Don’t
Two red buttons on one screen, such as “Register” and “Send” side by side.
Do
One primary per screen; everything else secondary or quiet.
<button>for actions, links for navigation, never a clickable<div>. To render a link that looks like a button:<Button nativeButton={false} render={<Link href="/events" />}>.- Toggles use
aria-pressed(see Toggle and filter chips). - Short verbs: “Register”, “Send”, “View gallery”. Never “Click here”.
- Inside
tone-inkthe same tokens render correctly with no extra code.

