IconButton
Action button composed of a single icon. Shares the palette, variants and
sizes of Button, but with padding/border optimized
for a single centered glyph.
When to use
| ✅ Use when… | 🚫 Avoid when… |
|---|---|
|
Colors
<IconButton icon={<Icon icon={thumbsUp} />} color="primary" />
<IconButton icon={<Icon icon={thumbsUp} />} color="secondary" />
<IconButton icon={<Icon icon={thumbsUp} />} color="tertiary" />
<IconButton icon={<Icon icon={thumbsUp} />} color="success" />
<IconButton icon={<Icon icon={thumbsUp} />} color="warning" />
<IconButton icon={<Icon icon={thumbsUp} />} color="danger" />Variants
<IconButton icon={<Icon icon={thumbsUp} />} variant="contained" />
<IconButton icon={<Icon icon={thumbsUp} />} color="secondary" variant="outlined" />
<IconButton icon={<Icon icon={thumbsUp} />} variant="linked" />Ghost (chrome cluster)
variant="ghost" is the bare control for app chrome: nothing at rest (no
fill, border or shadow — only the glyph ink), a circular wash on hover /
focus / active. Never an underline. An icon-only linked IconButton gets
the same wash instead of the text underline.
<IconButton variant="ghost" size="small" icon={<Icon icon={cog} />} label="Settings" /><IconButton icon={<Icon icon={cog} />} size="extraSmall" />
<IconButton icon={<Icon icon={cog} />} size="small" />
<IconButton icon={<Icon icon={cog} />} size="medium" />
<IconButton icon={<Icon icon={cog} />} size="large" />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. |
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. |
label | string | — | Accessible name of the button, rendered as `aria-label` — required for
screen readers since the button has no visible text.
@example ```tsx
<IconButton icon={<Icon icon={trash} />} label="Delete item" />
``` |
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). |
loadingComponent | ReactNode | — | Component displayed in place of the icon when `isLoading` is true.
When omitted, the default `Spinner` is used. |
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. |
Besides the props above, every component accepts the layout props (spacing, color, flex/grid, sizing, border) — not repeated here.