Skip to content

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.

Preview
Show 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>
Preview
Show 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.

Preview
Show code
<Button size="sm">Download</Button>
<Button>Download</Button>
<Button size="lg" variant="primary">Register now</Button>

States

StateBehavior
Hoveraccent-hover (primary) or a surface-strong fill (others), 120ms. Pointer devices only.
Activeaccent-active (primary), plus a 1px downward press.
Focus-visibleThe global 2px focus outline with an offset.
Disabledsurface fill, subtle text, no hover. Explain why nearby. Never disable submit to signal an invalid form.
LoadingSpinner + progressive label (“Send” → “Sending…”), aria-busy. Presses are ignored and focus stays put.
LoadingPress it. The button keeps focus, ignores repeat presses and announces the new label.
Preview
Show code
<Button variant="primary" loading={sending}>
  {sending ? "Sending…" : "Send"}
</Button>
Disabled
Preview
Registration closed September 30.
Show 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.

Preview
Show 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-ink the same tokens render correctly with no extra code.