primitives

Button

Four variants, three sizes, leading + trailing icon slots, polymorphic on the element.


Button is the action primitive. Four variants, three sizes, optional leading/trailing icon slots, polymorphic via as on web so you can render a navigation link with the same shape.

API

<Button onClick={save}>Save</Button>

<Button variant="ghost" size="sm">Cancel</Button>

<Button variant="danger" iconLeading={<Icon name="trash" />}>
  Delete
</Button>

<Button as="a" href="/sign-up">Sign up</Button>

<Button variant="link" iconTrailing={<Icon name="arrowRight" />}>
  Learn more
</Button>

<Button loading>Saving…</Button>

Props

PropTypeDefault
asElementType (web only)"button"
variant"primary" | "ghost" | "link" | "danger""primary"
size"sm" | "md" | "lg""md"
loadingboolean (disabled + aria-busy)false
disabledbooleanfalse
iconLeadingReactNode-
iconTrailingReactNode-
fullWidthbooleanfalse
onClick (web) / onPress (native)() => void-

Variants

VariantUse it when
primaryThe one CTA on the screen. Orange fill, white text.
ghostSecondary actions. Transparent bg, stroke border, theme text.
linkInline link-like action. No height / padding / radius; just text + accent color.
dangerDestructive actions (delete, sign out). Red fill, white text.

Size scale

SizeWeb heightNative heightFont size
sm283213
md364014
lg444815

Polymorphism caveat

Same as Box: React's forwardRef erases polymorphic generics at the type level. The exported Button is cast to restore the generic. Same pattern Radix uses. Web only; native always renders a Pressable.