Skip to content

Buttons & actions

Button

stable

Buttons trigger an action or a state change. Use them for the actions on a page and its surfaces — not for navigation.

Overview

Every button is one component with a variant that sets its emphasis. Give a view a single high-emphasis default button for its primary action, and drop to secondary, outline, or ghost for everything else so the hierarchy stays readable.

destructive signals an irreversible or dangerous action; link renders button behaviour with the appearance of a text link.

When to use

  • Trigger an immediate action — submit, save, confirm, delete.
  • Give a screen one obvious primary action (a single default button).
  • Offer lower-priority actions with secondary, outline, or ghost.

When not to use

  • Navigating to another page or URL — use a link so it's a real anchor.
  • Turning a setting on or off — use a Switch or Toggle.
  • Choosing among options — use a Toggle group, Radio group, or Select.

Variants

  • defaultPrimary action — one per view.
  • secondaryA prominent but non-primary action.
  • outlineLow-emphasis action on a busy surface.
  • ghostMinimal action, e.g. in toolbars.
  • destructiveIrreversible or dangerous action.
  • destructiveOutlineDestructive intent, low emphasis — red at rest, solid red fill on hover.
  • linkButton behaviour that looks like a link.
  • size: sm | default | lg | iconicon = square, icon-only.

Do

  • Lead labels with a verb“Approve PO”, “Export ledger”.
  • Keep one primary button per vieweverything else lower-emphasis.
  • Give icon-only buttons an aria-labelso their purpose is announced.

Don't

  • Don't stack competing default buttonsthe primary action stops being obvious.
  • Don't use a button to navigatethat should be a link.
  • Don't write vague labelsavoid “OK” / “Submit” when a verb fits.

Accessibility

  • Renders a native <button>: focusable and activated with Enter or Space.
  • Icon-only buttons must set aria-label (or visually-hidden text).
  • Focus is shown with the visible ring token — don't remove the outline.
  • Disabled buttons aren't focusable; never rely on colour alone to convey state.
  • For on/off buttons, set aria-pressed (see Button group / Toggle).

Code

Basic
import { Button } from "~/components/ui/button";

<Button>Approve PO</Button>
<Button variant="secondary">Save draft</Button>
<Button variant="destructive">Void invoice</Button>
Sizes
<Button size="sm">Filter</Button>
<Button size="default">Approve PO</Button>
<Button size="lg">Approve & post</Button>
Icon only
<Button size="icon" aria-label="Edit entry">
  <PencilIcon />
</Button>

Related

Icon buttonSplit buttonButton groupToggle

More examples

Variants
Variant × size
Sizes
Leading icon
Trailing icon
Icon only
Loading per variant
Disabled
Full width
Split button

Last action:

Split variants
Icon button — variants
Icon button — sizes
FAB
Extended FAB
Button group

Viewing cash flow grouped by: Week

Group with icons
Toggle

Overdue-only filter: off

Single-select

Chart type: bars

Multi-select

Active marks: bold