Button
Buttons allow users to take actions and make decisions with a single tap.
When to use
| ✅ Use when… | 🚫 Avoid when… |
|---|---|
Buttons communicate actions that users can perform. They are typically placed throughout the user interface, in places like:
|
|
Colors
<Button color="primary" text="primary" />
<Button color="secondary" text="secondary" />
<Button color="tertiary" text="tertiary" />
<Button color="success" text="success" />
<Button color="warning" text="warning" />
<Button color="danger" text="danger" />Neutral (quiet chrome)
color="neutral" paints the button from the engine's quiet palette — a
Neutral-ramp interaction palette (rest / hover / pressed stops, AA ink) with
no brand hue. Use it for chrome CTAs that must not compete with the page's
primary action: a compact "trade" chip in the top bar, a secondary toolbar
action. All three variants work; IconButton and Link.Button accept it too.
<Button text="Trade" variant="outlined" size="small" color="neutral" />The neutral scale (neutral.70…) is still not accepted as a Button
color — it has no interaction stops. The palette lives at
theme.colors.quiet if you need it elsewhere.
Variants
There are four button variants:
- Contained (Default)
- Outlined
- Text (linked)
- Ghost — bare chrome control (nothing at rest, a wash on hover; never an underline). Meant for
IconButtonclusters, available onButtonfor lockstep.
<Button variant="contained" text="Contained" />
<Button color="secondary" variant="outlined" text="Outlined" />
<Button variant="linked" text="Text" />
<Button variant="ghost" text="Ghost" />Sizes
Four sizes available:
extraSmallsmallmedium(default)large
<Button size="extraSmall" text="extraSmall" />
<Button size="small" text="small" />
<Button size="medium" text="default" />
<Button size="large" text="large" />Icons
Sometimes you want icons on a given button to improve UX — logos are recognized faster than plain text. See all available icons in Icon.
<Button icon={<Icon icon={trash} />} text="Delete" color="warning" />
<Button icon={<Icon icon={upload} />} text="Upload" />
<Button icon={<Icon icon={shareAlt} />} text="Share" color="primary" variant="linked" />Interactive Demo
loading
Properties
Prop | Type | Default | Description |
|---|---|---|---|
color | "primary" | "secondary" | "tertiary" | "success" | "warning" | "danger" | "neutral" | primary | Semantic color of the button. |
containment | string | — | Containment marker for the `cq` channel: emits
`container-type` (+ `container-name` when the string form carries one,
e.g. `'inline-size card'`). Apply on the immediate wrapper of the
adapting component — NEVER on page-level shells. |
fullWidth | boolean | false | Expands the button to fill the container's full width. Useful in forms
on mobile and in primary CTAs. |
icon | ReactNode | null | Icon displayed next to the text. Accepts any `ReactNode`, but the
typical usage is with the `<Icon />` component.
@example ```tsx
<Button icon={<Icon icon={trash} />} text="Delete" />
``` |
iconPosition | "left" | "right" | left | Position of the icon relative to the text. |
isLoading | boolean | false | Replaces the content with a spinner while true. The button width is
preserved to avoid reflow during the transition.
Named `isLoading` (rather than `loading`) because `loading` is a native
`<button>` attribute. |
legibility | "on-photo" | — | Reading-shadow preset for text over a photographic background
(`on-photo`). Replaces the inline `style={{ textShadow }}` in the
consumer (brasil_2030 radar, gap A3). Token emission is deferred until a
2nd consumer asks for the raw var (see backlog). |
pageShell | boolean | — | Centers the element and caps the width at `theme.layout.pageMaxWidth`.
The page shell of a classic centered layout. |
readable | number | boolean | — | Makes the `color` legible against the page surface: `true` = WCAG AA
(4.5), a number sets a custom floor. Ignored with `contrast`.
See the Layout Props concept page for the full semantics. |
size | "small" | "medium" | "large" | "extraSmall" | medium | Size of the button. |
text | string | — | Text to display. Alternative to passing content via `children` — when
both are provided, `children` takes precedence. |
transform | string | — | CSS `transform` value (e.g. `translate(-50%, -33px)`). Never leaks
to the DOM as an attribute. |
variant | "contained" | "outlined" | "linked" | "ghost" | contained | Visual variant. |
Theming (theme.component.button)
The size scale is a component token: theme.component.button.size.{extraSmall,small,medium,large}, each carrying fontSize / fontWeight / textTransform? / py / px / borderRadius (foundation-scale keys). Override one field of one size without forking the component:
createTheme({
component: {
button: {
size: {
medium: { px: 'xl' },
},
},
},
});See also
- Storybook story: Components / Button
- Icon-only variant:
IconButton