Installation
Theme
Mode

Forms & input

Button

Triggers an action or event. Six emphasis levels from primary to link, four sizes, leading/trailing icons, and loading and disabled states — all themeable across presets and modes.

$npx shadcn@latest add @orbit/button

Playground

VariantSize

Variants

Pick by emphasis, not by looks.

Primary — the single most important action on a view. One per context.
Secondary — the neutral workhorse for everything else.
Tinted — soft brand emphasis between primary and secondary.
Ghost — minimal emphasis for dense rows, menus, and repeated inline actions.
Destructive — reserved for irreversible actions. Pair with a confirmation step.
Link — navigates or reveals; sits inline with text.

Sizes

xs 24px · sm 28px · md 32px (default) · lg 38px. Interactive controls keep a 44px minimum hit target in touch contexts via spacing.

States

Loading swaps the leading icon for a spinner and blocks interaction while keeping width stable. Disabled drops to a flat neutral treatment.

Icon-only

Square buttons for toolbars and dense rows. Always pass an aria-label so screen readers and tooltips have a name.

Full width

Stretches to the container — dialogs, forms, and mobile layouts.

Props

PropTypeDefaultDescription
variant"primary" | "secondary" | "tinted" | "ghost" | "destructive" | "link""primary"Emphasis level.
size"xs" | "sm" | "md" | "lg""md"Control height: 24 / 28 / 32 / 38px.
iconLeftReactNodeIcon before the label. Replaced by a spinner while loading.
iconRightReactNodeIcon after the label. Stays visible while loading.
iconOnlybooleanfalseSquare icon button — pass the icon as children and set aria-label.
loadingbooleanfalseShows a spinner, sets aria-busy, and blocks pointer interaction.
disabledbooleanfalseNative disabled state.
fullWidthbooleanfalseStretch to fill the container.
…restButtonHTMLAttributesEverything else is forwarded to the native <button>, including ref.

Usage

Do

One primary action per view

Make the single most likely next step obvious; everything else is secondary or ghost.

Don’t

Stack two primaries together

Competing high-emphasis buttons leave people unsure which to choose.

Do

Use verb-first, 1–2 word labels

“Create task”, “Export”, “Delete project” — the label alone should say what happens.

Don’t

Ship icon-only with no label

Always pass an aria-label so screen readers and tooltips have a name.

Keyboard & accessibility

Native <button> semantics. Tab moves focus, Enter and Space activate, aria-busy is set while loading, and the 3px focus ring uses the themed --ring token.

Tab to see the focus ring