Components
Actions
Buttons start, approve, pause and delete things. Each view has at most one primary action, and destructive actions always name what they remove.
ButtonButtonLinkbuttonStyles()
Variants
Hierarchy comes from the variant, not from size. Primary for the one action that moves the work forward, secondary and outline for the rest, ghost for low emphasis and danger for anything that removes data.
light
dark
Sizes
Medium is the portal default at 36px. Small fits table rows and toolbars at 32px. Large is for onboarding and empty states. Every size clears the 24px minimum target from WCAG 2.2.
States
Hover darkens the fill, press nudges the button down by a pixel, and focus shows a 2px ring with a 2px gap. Disabled buttons switch to the muted surface so they stay legible but clearly inactive. Loading keeps the label and adds a spinner.
Icons and icon buttons
Leading icons describe the action, trailing arrows promise navigation. Icon-only buttons always carry an accessible name and a tooltip.
Pause dispatchDelete rule
Links that look like buttons
If it navigates, it is a link. ButtonLink renders a real anchor with button styling, so it opens in a new tab and announces as a link.
API
Button accepts every native button attribute. Type defaults to button so it never submits a form by accident.
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger' | 'link' | 'primary' | Visual weight and meaning. |
| size | 'sm' | 'md' | 'lg' | 'icon-sm' | 'icon' | 'icon-lg' | 'md' | Height, padding and icon size. |
| loading | boolean | false | Shows a spinner, sets aria-busy and disables the button. |
| disabled | boolean | false | Moves to the muted surface with a not-allowed cursor. |
| type | 'button' | 'submit' | 'reset' | 'button' | Set submit explicitly inside forms. |
Do
One primary action per view
The primary button marks the single step that moves the migration forward. Everything else steps down a level.
Don't
Stack several primary buttons
When everything is primary nothing is. Operators hesitate, and the riskiest action looks as safe as the routine one.
Do
Name the object of a destructive action
“Delete 12 redirects” tells the operator exactly what disappears. Pair it with a confirmation that repeats the count.
Don't
Use vague verbs on risky buttons
“OK”, “Continue” or “Proceed” on a destructive dialog invites a reflex click.