Home

Button

A pill-shaped button for an action, in seven variants (default, secondary, outline, ghost, destructive, destructive-outline, link) and five sizes, with a loading state.

ui.buttoncomponents/ui/button.tsx

Use case

For the AI

Use it for anything a person presses to make something happen: Save Changes at the foot of a client form, New Order on a page's title row, Send Invoice, Cancel in a dialog. The default (ink) variant is the one thing to do on the view; secondary, outline and ghost carry the rest; destructive marks an action that deletes or voids something. With render it can draw a link that looks like a button, such as View Invoice going to another page.

Use it when

  • The main action of a form or a page (the default variant)
  • Supporting actions beside it: Cancel, Export, Duplicate
  • An action that deletes or voids something (destructive, destructive-outline)
  • A link that should look like a button (render a Link)

Use something else when

Examples

Variants
Sizes: xs, sm, default, lg, xl
With icons, loading, disabled

Code

Import

import Link from "next/link"
import { PlusIcon } from "@/components/icons"
import { Button } from "@/components/ui/button"

Usage

<div className="flex justify-end gap-2">
  <Button variant="ghost">Cancel</Button>
  <Button type="submit" loading={saving}>
    Save Changes
  </Button>
</div>

<Button variant="secondary">
  <PlusIcon />
  New Order
</Button>

<Button variant="destructive-outline">Void Invoice</Button>

<Button variant="link" render={<Link href="/invoices/2041" />}>
  View Invoice
</Button>

Rules

  • One default (ink) Button per view, the one thing to do; the rest are secondary, outline or ghost.
  • Labels in Title Case (Save Changes, Send Invoice).
  • A Button is type="button" by default: the submit button of a form must say type="submit".
  • Never set a size class on an icon inside a Button: each size sets its icons.
  • While its action runs, pass loading: the label hides, a spinner shows and the button is disabled at the same width.