Icon button
An icon-only button with a required label that becomes its aria-label and tooltip.
import { IconButton } from "@arcadia/ui"ghost and muted. In the composer, + is the secondary disc and send the inverse one.label is required: it becomes the aria-label and the tooltip's title, because a tooltip is not a label. The default size is sm (24px). Compose it as a popup trigger with render: <MenuTrigger render={<IconButton icon="more" label="More" />} />. A dot-only glyph (more) draws at --icon-1 whatever the tone: at the muted rank its three dots peak under the row's own secondary line and read as specks.
Examples
Tooltips
Hover or focus: the title, a glyph shortcut as key caps, and an optional subtitle. Use tooltip={false} when the label is already visible beside it.
rootStyle takes where the button sits (margins, self-alignment, flex and grid placement, size bounds) and the knobs below, each a token of its kind. A colour, a raw length or any other property is a type error: a look that comes up twice becomes a variant.
--ib-size- Ref<Control | IconSize>Default var(--control-sm)
- Box width and height.
--ib-radius- Ref<Radius>Default var(--radius-md)
- Corner radius (a pill is full).
--ib-icon- Ref<IconSize>Default var(--icon-md)
- Glyph and spinner size.
--ib-bg- PaintDefault transparent
- Fill at rest.
--ib-bg-hover- PaintDefault var(--fill-4)
- Fill under the pointer.
--ib-bg-open- PaintDefault var(--ib-bg-hover)
- Fill when toggled on (
pressed) or while its popup is open. --ib-bg-disabled- PaintDefault transparent
- Fill when disabled.
--ib-fg- PaintDefault var(--icon-2)
- Glyph colour at rest.
--ib-fg-hover- PaintDefault var(--icon-1)
- Glyph colour under the pointer.
--ib-fg-open- PaintDefault var(--ib-fg-hover)
- Glyph colour when toggled on or open.
--ib-fg-disabled- PaintDefault var(--icon-4)
- Glyph colour when disabled.
--ib-border- PaintDefault transparent
- A 1px inset ring. Default transparent.
Variants, tones and sizes only reassign knobs, and each state reads its own (--ib-bg-hover, --ib-fg-disabled), so a knob you set never drops a state. A toggled-on button and an open popup's trigger share the --ib-*-open pair.
label is the whole accessible name. shortcut shows in the tooltip and is exposed as aria-keyshortcuts ("⌘N" reads as Meta+N), never as part of the name; binding the key is yours. Tooltips open after 350ms, and once one has shown, its neighbours open instantly for 200ms.
A disabled icon button can't be focused, so its tooltip never shows. When it needs to say why, add focusableWhenDisabled so it stays focusable with aria-disabled.
- EnterSpace
- Activate
IconButton
iconrequired- IconName
labelrequired- string
- Required: becomes
aria-labeland the tooltip title. A tooltip is not a label. shortcut- string | readonly string[]
- Shown in the tooltip and exposed as
aria-keyshortcuts:"⌘N",["⌘","N"],"mod+n","⏎". variant- "ghost" | "secondary" | "inverse"Default "ghost"
ghost;secondary, a fill-3 disc (a composer's+);inverse, an ink disc (send and stop).tone- "neutral" | "muted" | "plan"
muteddrops the glyph one rank (icon-3);planis Plan mode's distance blue (oninverse, a blue disc: the plan-mode send). A dot-only glyph (more) takes no rank: it draws at label ink (icon-1) whatever the tone.size- "xs" | "sm" | "md" | "lg"Default "sm"
- Boxes 20 / 24 / 28 / 32.
shape- "rounded" | "pill"Default "pill"
pressed- boolean
- Toggle state:
aria-pressed+data-pressed(drawn like an open popup's trigger:--ib-bg-open). loading- booleanDefault false
- Busy: the glyph becomes a spinner,
aria-busy, activation blocked, focus kept. flush- boolean
- Negative margin of (box − glyph) / 2 so the glyph aligns optically with neighbouring text edges.
tooltip- false | IconButtonTooltipOptions
- Tooltip options, or
falsefor none (e.g. when the label is already visible next to it). rootStyle- IconButtonStyle
- Typed StyleX override: where the button sits and its
--ib-*knobs. render- RenderProp<{ disabled: boolean }>
- Replace the rendered element, e.g.
render={<a href="/settings" />}, or a function of props and state. disabled- boolean
- Native disabled: no pointer events, no tooltip, skipped by Tab.
focusableWhenDisabled- boolean
- Keep a disabled control focusable and hoverable (
aria-disabled), so a tooltip can say why. nativeButton- boolean
- Button semantics, inferred from what renders: a
<button>is native, an<a>stays a link, anything else getsrole="button"and key handling.falseforces button semantics on whatever renders (a link acting as a button). className- string
- A product's hook class for its own layout rules. Being retired: new code places an icon button with
rootStyle; the call sites left are counted by ui.lint (kit-classname) and only go down.
Rest props go to <button> props.