Button
FreeA familiar action with immediate focus, a tactile press, and optional pending or label feedback that stays on the button itself.
Invite your team
Teammates get access to every project in Forma Studio.
Installation #
pnpm dlx shadcn@latest add https://caliperui.site/r/button.json
Adds its 2 files to components/ui/, each with its own stylesheet, and installs their packages. No account needed. The first part also adds Caliper UI’s tokens; import them once as in Installation.
Usage #
Name the result, not the gesture: “Send invite”, not “Submit”. Keep one primary action per decision and use secondary or ghost for the rest.
Pass loading while your handler runs. The button keeps focus, exposes aria-busy and blocks repeat activation, so you don’t need to disable it yourself.
Use asChild to give a link the button treatment without nesting interactive elements.
import { Button } from "@/components/ui/button" export function InviteFooter({ pending, onSend }) { return ( <footer className="flex justify-end gap-2"> <Button variant="ghost">Cancel</Button> <Button loading={pending} onClick={onSend}> Send invite </Button> </footer> ) }
Examples #
Four emphases
Default is ink. Secondary sits on the canvas, ghost reveals a fill on interaction, destructive is reserved for irreversible actions.
With an icon
Icons are 16 px with an 8 px gap. Icon-only buttons need an aria-label.
Label feedback
feedbackKey animates a meaningful label change, such as Save to Saved, without moving the layout around it.
As a link
asChild applies the button treatment to an anchor, keeping native link behaviour.
API reference #
Accepts every native button prop and a ref, plus:
Accessibility #
A native button with a visible 2 px focus ring at 2 px offset. Disabled uses the native attribute; loading keeps the button focusable and announces busy state.
Motion #
A press sinks rather than shrinks: the button travels 1 px down, its lift becomes an inner shade, and it settles back on the settle curve. Text and layout never scale. Reduced motion removes the travel; the shade still answers the press.