Button
Primary action control with seven variants, four sizes, a loading state and slot support for links.
Preview
Live preview
Usage
Examples
Variants for intent
<Button>Save changes</Button>
<Button variant="secondary">Cancel</Button>
<Button variant="outline">Preview</Button>
<Button variant="ghost">Dismiss</Button>
<Button variant="link">Learn more</Button>
<Button variant="destructive">Delete project</Button>
<Button variant="glow">Deploy</Button>Sizes and icon button
<Button size="sm">Small</Button>
<Button size="md">Medium</Button>
<Button size="lg">Large</Button>
<Button size="icon" aria-label="Add project">
<Plus className="size-4" />
</Button>Loading and asChild link
<Button loading>Save changes</Button>
<Button asChild>
<Link to="/components">Browse components</Link>
</Button>Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "default" | "secondary" | "outline" | "ghost" | "link" | "glow" | "destructive" | "default" | Visual role. glow adds the signature luminous border; destructive for irreversible actions. |
| size | "sm" | "md" | "lg" | "icon" | "md" | icon renders a square 36×36 button — give it an aria-label. |
| asChild | boolean | — | Render the child element instead of <button> — for links, router anchors and icon libraries. |
| loading | boolean | — | Disables the button, sets aria-busy and swaps the label to "Saving". |
| disabled | boolean | — | Native disabled state — dimmed and unreachable by click or tab. |
| …native button attrs | ButtonHTMLAttributes<HTMLButtonElement> | — | type, onClick, form, aria-*, … |
Accessibility
Accessibility notes
- Buttons are natively focusable and announced as "button" — never use a clickable div.
- Icon-only buttons need an accessible name: aria-label describing the outcome ("Add project", not "plus").
- loading sets aria-busy and blocks pointer events; keep the width stable so the layout does not jump.
- destructive actions belong on destructive variant buttons and should be confirmed elsewhere for irreversible work.
- asChild renders an <a> or router Link — the visual style stays, semantics follow the child.