Actions

Button

Trigger an action — submit a form, open a dialog, confirm a destructive change.

Importimport { Button } from "@/components/ui/Button";
Sourcesrc/components/ui/Button

Use primary for the one action a surface is really asking for, secondary for alternatives beside it, tertiary and ghost for low-priority actions, and danger for anything destructive. A surface with two primary buttons has no primary button.

For an icon with no label, reach for IconButton instead — it carries the accessible name and the tooltip for you.

Variants

Nine variants, plus two aliases kept for the shadcn-shaped call sites that predate the hand-rolled library: default resolves to primary and destructive to danger. Prefer the canonical names in new code.

Accent variants

accent and accent-soft take their colour from the surface they sit on rather than from a prop — see Contextual accent. The same markup is purple in the builder and green in the CMS.

Sizes

s for dense toolbars and panel rows, m for standalone actions, lg for a page's single main call to action. sm, md and default are accepted aliases that normalise to s, m and m.

Icons

Pass leftIcon or rightIcon rather than putting an icon in children — the wrapper spans set the gap and are marked aria-hidden, so the icon never reaches a screen reader as stray content.

Disabled

Disabled buttons are not focusable and give no explanation, so prefer leaving the button enabled and reporting the problem on submit — unless the reason is already visible on screen.

Rendering as a link

asChildhands the button's classes to the child element instead of rendering a <button>. Use it for navigation, so the thing that looks like a button is an anchor and behaves like one — middle-click, open in new tab, copy address.

leftIcon and rightIconwork here exactly as they do on a plain button: the icons are composed around the child's own content, inside the anchor.

Both point at the library so the examples stay clickable.

Props

Button

PropTypeDefaultDescription
variant"primary" | "secondary" | "tertiary" | "ghost" | "danger" | "outline" | "link" | "accent" | "accent-soft" | "default" | "destructive""primary"Semantic role. `default` and `destructive` are aliases for `primary` and `danger`.
size"s" | "m" | "lg" | "icon" | "sm" | "md" | "default""m"`sm` → `s`, `md`/`default` → `m`. Use `icon` only for square icon buttons.
leftIconReactNodeIcon before the label, wrapped and hidden from assistive technology.
rightIconReactNodeIcon after the label, wrapped and hidden from assistive technology.
asChildbooleanfalseApply the button's styling to the single child element instead of a button.
type"button" | "submit" | "reset""button"Defaults to `button` so a button inside a form does not submit by accident.