Button
Token-driven button with variants, tones, icons, loading, and link rendering.
Playground
Configure a Button live — every change re-renders in the active theme and writes the matching JSX below.
Variants
contained (default), soft, outlined, and text. Each derives its color
from the active tone's tokens, so it re-themes automatically.
Tones
primary (default), neutral, and danger. Tone re-points the color knobs
the variants read, so every variant works in every tone.
Icons, loading & links
Use startIcon / endIcon for leading or trailing glyphs, loading for a
non-interactive spinner state, and href to render a semantically-correct
<a> styled as a button (for navigation rather than actions).
Sizes
sm, md (default), lg. Heights come from the --cajon-btn-height-* tokens
and the radius from --cajon-btn-radius, so a theme can size and shape buttons
to its brand — e.g. the codazen-web theme uses tall pill buttons.
Usage
import { Button } from '@cajon-ui/react';
<Button>Save</Button>
<Button variant="soft" tone="neutral">Secondary</Button>
<Button tone="danger">Delete</Button>
<Button endIcon={<ArrowIcon />}>Start the Conversation</Button>
<Button loading>Saving…</Button>
<Button href="/contact" variant="outlined">Contact sales</Button>
<Button fullWidth>Continue</Button>
<Button disabled>Unavailable</Button>Props
| Prop | Type | Default | Notes |
|---|---|---|---|
variant | contained | soft | outlined | text | contained | Visual style |
tone | primary | neutral | danger | primary | Intent color |
size | sm | md | lg | md | Control height |
loading | boolean | false | Spinner + aria-busy, non-interactive |
startIcon | ReactNode | — | Icon before the label |
endIcon | ReactNode | — | Icon after the label |
href | string | — | Renders an <a> (with target / rel) instead of a <button> |
fullWidth | boolean | false | Stretch to container |
When rendered as a <button>, all native <button> attributes (onClick,
type, disabled, …) pass through. The component forwards its ref to the
underlying <button> or <a>.