● Primitives / Button
Button.
Button is the system's primary interactive control. It wraps the shadcn-svelte implementation with Superbloom tokens, variants, and sizes used across the header, CTAs, and sheets.
How the primitive behaves
Button renders as a native button or, when href is set, as a styled link with disabled handling. Variants map to semantic roles in the UI: primary fill, bordered outline, quiet ghost, and destructive emphasis.
Theme toggle reuses buttonVariants for a ghost icon control without duplicating styles. Sheet close actions compose Button inside the sheet primitive.
Source of truth
Implementation lives in components/ui/button (CLI-managed). Storybook and this site import through $lib/system. Regenerate via shadcn-svelte; do not hand-edit the ui file.
Primitive roles
Button is an atom, not a layout pattern. Patterns and sections compose it; routes should not reimplement button styling ad hoc.
Primary action
Submits forms, confirms steps, and drives the main call to action on a page.
Secondary action
Outline, ghost, and secondary variants support quieter actions beside a primary control.
Navigation affordance
The link variant and href prop render anchor semantics when the control should navigate.
Anatomy
Variants and sizes are the main API surface. Children carry the visible label or icon.
Variants
Sizes
Variant
Controls fill, border, and emphasis: default, outline, secondary, ghost, destructive, link.
Size
Height and padding scale from xs through lg, plus dedicated icon sizes.
Label or icon
Text children for standard buttons; icon-only buttons require an accessible name.
Disabled state
Reduced opacity and no pointer events. Link buttons use aria-disabled when href is set.
Guidelines
- Import Button from $lib/system in product code so primitives stay on the public Superbloom API.
- Use default for the single strongest action in a group. Use outline or ghost for secondary actions.
- Reserve destructive for irreversible or high-risk actions, not generic cancel buttons.
- Prefer one primary button per view. Additional actions should step down in visual weight.
- Icon-only buttons must include aria-label. Pair icons with text when space allows.
- Hover, pressed, and focus styles are built in. Test them in the canvas rather than duplicating states in docs.
In practice
Is this the main action?
Use variant default.
Should it navigate?
Pass href and keep button semantics via the component.
Is it icon-only?
Add aria-label and pick an icon size.
Is the action dangerous?
Use variant destructive with clear label text.
Need every variant in Storybook?
See Primitives / Button for the full matrix.
Related primitives
Other primitives in the system, in the same order as the documentation sidebar.