Button
Button is the standard control for visible actions, with built-in variants, sizes, loading behavior, and accessible disabled states.
Purpose
Button is the standard control for visible actions. Use a semantic link when navigation is the primary behavior.
Default button
Installation
With the Siteplane registry alias configured, add the component and import the installed source from your app.
CLI
pnpm dlx shadcn@4.16.1 add @siteplane/buttonImport
import { Button } from "@/components/ui/button";
import { ButtonWithIcon, IconButton, LoadingButton } from "@/components/ui/button-recipes";Need the machine-readable source metadata? View registry JSON.
Usage
Use the default Button for the primary action in a workflow.
import { Button } from "@/components/ui/button";
export function Example() {
return <Button>Save changes</Button>;
}Examples
Visual variants are one Button API. Pick the variant by workflow priority and semantic risk, not as separate components. Icon-only buttons need an accessible label.
Variants
With icons
Icon only
Sizes
Use the size prop to match the control to its surrounding density and hierarchy.
States
Set scale={false} when a button should keep its color, shadow and focus feedback without moving on hover or press.
Loading action
Grouped actions
With shortcut
Alignment and width
align positions the label inside the button; width controls how much space the button claims.
Surface button
surface only takes effect with the ghost variant: the row reads as a whole area and gets the muted full-area hover.
Bleed in a toolbar
bleed stretches the button to the container height and gives up its own corners, so it forms the edge of the bar.
Multiline label
multiline releases the fixed height and lets the label wrap.
Loading with error feedback
When the action rejects, LoadingButton calls onError and returns to idle.
API Reference
The reference lists the source-owned exports and props that are easy to miss in visual examples. Inherited Base UI props remain available unless the wrapper narrows them.
variantaccepts"default","secondary","outline","ghost","destructive","destructive-outline","link", and"success".sizeaccepts text sizes from"xs"through"xl"and the matching"icon-*"sizes. Without a local size, Button inheritsSiteplaneUIProvider controlSize.size="xl"is the opt-in customer-facing CTA format: 56px high with an 18px/24px label. Combine it withwidth="full"for a container-filling CTA and with a surroundingSiteplaneUIProvider radius="sm"for the global 8px main corner; size itself never overrides radius.render={<Link href="…" />}changes the underlying element while retaining Button styling and omits the invalid buttontypeattribute.loadingdisables the control, sets busy semantics, and displays the native loading indicator.scale={false}disables both hover and press scaling while preserving color, shadow, focus, loading, and disabled states. Use it when a trigger sits inside a larger custom element that must not move.align,width, andmultilinecontrol content layout.bleedmakes the Button form a flush container edge.surfaceis for full-row or full-card actions and disables scale automatically.IconButtonrequires an accessiblelabel;ButtonWithIconandLoadingButtonare shared recipes, not new primitives.
Motion
Component motion uses the shared Siteplane motion contract. See the global motion guide for provider setup, tokens and reduced-motion behavior.
- Default hover and press states use the central Button scale, duration, shadow, and reduced-motion tokens.
scale={false}removes hover and press transforms only.surfaceavoids scale for full-area actions.- Loading recipes keep their idle width and crossfade between label and pending content without a second nested animation.
Accessibility
- Use Button for actions and a semantic anchor for navigation through the
renderprop. - Every icon-only Button needs an accessible label.
- Loading and disabled Buttons must remain unavailable and expose their state; do not simulate disabled state with styling alone.
- Keep visible focus and the coarse-pointer target supplied by the primitive.
Implementation Guidance
- Never use a raw HTML button for a visible Siteplane control.
- Use existing variants, sizes, and recipes instead of copying primitive class strings.
- Prefer
scale={false}for embedded triggers that must remain stationary; do not remove the remaining hover, pressed, or focus feedback.