Components

Button with variants and sizes, plus icon and loading slots.

Install

npx shadcn@latest add @alix/button

Preview

Usage

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

Examples

01

Hierarchy in one row

One default button per view; everything beside it steps down — outline for the alternative, ghost for the escape.

<Button rightIcon={<ArrowRight />}>Start engagement</Button>
<Button variant="outline">Schedule a call</Button>
<Button variant="ghost">Not now</Button>
02

Sizes

Four sizes share one optical center-line, so mixed rows still align.

<Button size="xs" variant="outline">Extra small</Button>
<Button size="sm" variant="outline">Small</Button>
<Button variant="outline">Default</Button>
<Button size="lg" variant="outline">Large</Button>
03

Icons and loading

Icon slots take any node; while loading, the spinner replaces the left icon and the label stays put — no width jump.

<Button leftIcon={<Plus />}>New request</Button>
<Button variant="outline" rightIcon={<Download />}>Export</Button>
<Button loading>Saving changes</Button>
<Button variant="destructive">Remove access</Button>
04

Beside an icon button

A labelled action plus a quiet icon sibling — the pairing used across the dashboards' toolbars.

<Inline gap="sm">
  <Button variant="outline" leftIcon={<Download />}>Export report</Button>
  <IconButton variant="ghost" aria-label="Add to workspace"><Plus /></IconButton>
</Inline>

When to use it

Use it for

  • The action a page or panel exists for — one default-variant button per view.
  • Secondary paths beside it: outline for a real alternative, ghost for dismiss/skip.
  • Destructive confirmation steps — the tinted variant reads as caution without shouting.

Reach for something else

  • Navigation that just goes somewhere — use a link, or the link variant at most.
  • Icon-only actions — IconButton owns that contract (and enforces the aria-label).
  • CMS-fed sections — blocks take serializable action data, not Button instances.

Props

PropTypeDefaultDescription
variant"default" | "secondary" | "destructive" | "outline" | "ghost" | "link""default"Visual style.
size"default" | "xs" | "sm" | "lg""default"Control size.
loadingbooleanfalseShows a spinner and disables the button.
leftIcon / rightIconReactNodeIcon slots rendered before / after the label.

See also