Components / Button
Button
Buttons trigger actions. ALPHA ships variants spanning emphasis levels and intents, plus sm/md/lg sizes — composed from a single base via class variants.
Variants
Every variant is the same base button with a different emphasis and intent. Pick by the weight the action deserves in its context, not by colour.
| Variant | When to use |
|---|---|
default | Primary action. One per view. |
flat | Primary action without elevation, for dense toolbars. |
secondary | Supporting action beside a primary button. |
destructive | Irreversible action — pair with a confirmation step. |
outline | Low-emphasis action that still needs a visible boundary. |
outlineFlat | Outline without elevation, for grouped controls. |
ghost | Minimal action inside dense layouts and menus. |
ghostSecondary | Muted ghost for tertiary actions. |
ghostDestructive | Destructive action in a low-emphasis position. |
link | Inline navigation styled as text. |
icon | Square icon-only button — pair with aria-label. |
Sizes
Size is geometry only — it never changes what an action means.
| Size | When to use |
|---|---|
sm | 32px control height for dense UI. |
md | 40px default control height. |
lg | 48px height for prominent placements. |
States
The focus ring is driven by :focus-visible, so it appears for keyboard navigation and stays out of the way for pointer users — tab to a button below to see it.
| State | When to use |
|---|---|
disabled | Drops to 45% opacity and leaves the tab order. |
loading | Shows a spinner, sets aria-busy and blocks interaction, so a pending action cannot be double-submitted. |
Props
| Prop | Type | Default | Notes |
|---|---|---|---|
variant | ButtonVariant | "default" | Emphasis and intent. See the variant table above. |
size | "sm" | "md" | "lg" | "md" | Control height. Geometry only — never changes intent. |
disabled | boolean | false | Non-interactive, 45% opacity. |
loading | boolean | false | Shows a spinner, sets aria-busy and blocks interaction. |
asChild | boolean | false | Render the child element instead of a <button>, keeping the styling. |
Guidelines
- Use exactly one default button per view — competing primaries erase the hierarchy.
- Reserve destructive for irreversible actions, and always pair it with a confirmation step.
- Icon-only buttons must carry an aria-label; the glyph is not an accessible name.