Skip to main content

IconButton

stablev0.1.0

Square button that renders a single icon with no text label. Requires an accessible aria-label. Shares the variant × priority × size pattern with Button. Use for toolbar actions, close/dismiss, and any action where the icon alone is sufficient context (pair with Tooltip for disambiguation).

Variants

Primary
Secondary
Tertiary
Small (sm)
Disabled

Examples

<IconButton icon={<Icon name="plus" />} aria-label="Add item" />
<IconButton variant="destructive" priority="secondary" icon={<Icon name="trash-2" />} aria-label="Delete" />
<IconButton variant="ia" priority="secondary" icon={<Icon name="bot" gradient="ia" />} aria-label="AI assist" />
<IconButton size="sm" priority="tertiary" icon={<Icon name="x" />} aria-label="Close" />

Props

PropType
iconReactNode — The icon element to render (must be aria-hidden; the button carries the accessible label)
variant"default" | "destructive" | "ia" — Visual intent (default: "default")
priority"primary" | "secondary" | "tertiary" — Visual weight (default: "primary")
size"sm" | "md" — Size: sm=24px, md=36px (default: "md")
activeboolean — Active/toggle-on state (default: false)
aria-labelstring — Required accessible label (no visible text)
aria-disabledboolean | "true" — Disabled look that keeps the tab stop and pointer events, so a Tooltip explaining why stays reachable by hover and keyboard; activation is ignored (onClick, the asChild child's own handler, link navigation), while the click event still propagates to document listeners. Use native `disabled` when no explanation is needed (IconButton.rfc.md §9.1)

Accessibility

2.1 AAWCAG pass

primary dark: --text-negative-primary (#18191b) on --color-filigran-brand-primary (blue-400 #42caff) = 9.32:1 ✅ primary light: --text-negative-primary (#f2f2f3) on --color-filigran-brand-primary (darkblue-700 #0015a8) = 11.2:1 ✅ secondary icon dark: --color-filigran-brand-primary (#42caff) on grayblue-1000 (#070d18) = 10.30:1 ✅ destructive primary hover/active: --text-negative-primary on --color-feedback-error-tertiary = 8.1:1 dark / 8.8:1 light ✅ (hover/active darkens the filled destructive fill; error-tertiary keeps the icon legible — replaced error-secondary, which failed AA at 1.8:1 dark / 2.5:1 light) Keyboard: standard button focus ring. aria-label required (no visible text). aria-disabled: the button stays focusable and hoverable and conveys the state to assistive technology; a click, Enter or Space does nothing (no onClick, no navigation on the asChild path) but the click still propagates, so a document click-away listener sees it. It paints the disabled tokens of its priority (primary bg-elevation-disabled + text-default-primary; secondary text-icon-disabled + border-elevation-disabled, no fill; tertiary text-icon-disabled, no fill; no IA gradient border), exempt from contrast (WCAG 1.4.3 Note 1). Pair it with a Tooltip that says why.