Button

A versatile button component for triggering actions and events. Features a satisfying press animation and multiple visual variants.

Variants

<Button>Default</Button>
<Button variant="destructive">Destructive</Button>
<Button variant="outline">Outline</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="amber">Amber</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button>

Sizes

<Button size="default">Default</Button>
<Button size="sm">Small</Button>
<Button size="lg">Large</Button>
<Button size="icon" aria-label="Add"><Plus /></Button>

With Icons

<Button><Plus /> Create New</Button>
<Button variant="outline">Continue <ArrowRight /></Button>
<Button variant="secondary"><Download /> Download</Button>

Loading State

<Button disabled>
  <Loader2 className="animate-spin" />
  Please wait
</Button>

API Reference

PropTypeDefaultDescription
variant"default" | "destructive" | "outline" | "secondary" | "amber" | "ghost" | "link""default"The visual style of the button. Each variant has a distinct color scheme and border treatment.
size"default" | "sm" | "lg" | "icon""default"Controls the height, padding, and border-radius of the button.
asChildbooleanfalseWhen true, the button merges its props onto its child element instead of rendering a <button> tag. Useful for rendering links styled as buttons.
classNamestringAdditional CSS classes to apply to the button element.
disabledbooleanfalseWhen true, prevents interaction and reduces opacity. Inherited from the native button element.

Accessibility

Icon-only buttons (size="icon", or buttons with no visible text children) MUST provide an aria-label so assistive technology can announce what the control does.

<Button size="icon" aria-label="Add item"><Plus /></Button>

The default button height is 40px. For mobile-primary contexts, prefer size="lg" (44px) to meet WCAG 2.5.5 touch target guidance.

The press-down animation respects prefers-reduced-motion and is disabled for users who request reduced motion.