You're in the Library

IconButton

A square button with only an icon, for frequent, recognizable actions in toolbars, table rows and headers. Its label is still required: it becomes the accessible name.
Stable
Edit

Preview appears after the next Storybook update.

IconButton example
<IconButton />
Rendered with the real componentFrom the code
Light
Dark

When to use

Use it for

  • Repeated row actions in tables and lists: edit, copy, delete, more.
  • Toolbars where space is tight and the icons are widely understood (close, copy, search, settings).
  • Opening a Menu of secondary actions (the more icon).

Not for

  • The primary action of a view: give it a text Button.
  • Any icon whose meaning is not obvious without its label: use a Button with iconStart instead.
  • Navigation to another page: use a Link.

Do and don't

Every example is rendered with the real component, so it always matches what ships.

Do

Name the action, not the picture

label="Delete token" is what a screen reader says. "Trash" describes the drawing, not what happens.

Do

Pair with a Tooltip showing the same label

Sighted mouse users get the name on hover; keyboard users get it on focus.

Don't

A row of filled icon buttons

Primary icon buttons in every row shout. Keep row actions ghost.

Accessibility

  • label is required and becomes aria-label. The icon itself is aria-hidden.
  • Same keyboard behavior and focus ring as Button. Loading keeps focus and sets aria-busy.
  • The square target matches the control height (32/40/48 comfortable), never smaller than 24px.

Content guidelines

  • Labels are verb plus object in sentence case: "Copy token name", "Close dialog".
  • Use the same label in the Tooltip so what users see and hear match.

From the code Generated from the component, not editable here.

Anatomy and tokens

Read from packages/react/src/components/IconButton/IconButton.module.css at build time. Every value is a token: open one to see its alias chain in both themes.

1 own tokens52 from Button0 semantic or component, change with theme and brand1 from the shared scales

From Button

IconButton reuses the stylesheet of Button, so it also paints with these 52 tokens. Changing them changes both.

Motion and interaction

IconButton animates on hover and press. Try it in the preview at the top.

WhenWhat changesDurationEasing
HoverBackgroundmotion.duration.instant75 msmotion.easing.standardsettles in place
PressBackgroundmotion.duration.instant75 msmotion.easing.standardsettles in place

With reduced motion turned on, every change happens at once.

From the code Generated from the component, not editable here.

Props

Parsed from the TypeScript types in packages/react/src/components/IconButton/IconButton.tsx, so this table cannot drift from the code. It also accepts every native <button> attribute except children, aria-label.

PropTypeDefaultDescription
iconrequiredLucideIconnoneLucide icon component.
labelrequiredstringnoneAccessible name, required: there is no visible text. Say the action, not the icon ("Delete token", not "Trash").
variant'primary' | 'secondary' | 'ghost' | 'danger' | 'inverse''ghost'Default `ghost`: icon buttons usually live in toolbars and rows. `inverse` on strong surfaces.
sizeButtonSize'md'No description in the code yet.
loadingbooleanfalseNo description in the code yet.
pressedbooleannoneMakes the button a toggle: sets `aria-pressed` and shows the selected look when true. Leave unset otherwise.

Playground

Change the props and see the real IconButton update. Controls are generated from the TypeScript props; nothing here changes the system.

Code for these props
<IconButton label="Edit token" />

Workbench

For contributors: every state with the accessibility panel, in the component workbench (Storybook). The stories double as visual test fixtures; the guidance on this page is the user documentation (open IconButton in Storybook).

Embed Storybook stories here (4)

Loads from https://bridge-storybook.floriangouloubi.com (set STORYBOOK_URL at build time). If Storybook is not running, the frames stay empty.

Default

Secondary

Loading

AllStates

From the code Generated from the component, not editable here.

Changelog

  • New

    Missing pieces now include a library component restyled from outside with tokens only: CSS on a class the component carries, often on a state selector such as [aria-pressed='true'], or a token-only inline style tied to its pressed prop, reads "IconButton: restyled when pressed" with what changed (fill (icon) currentColor) and a restyle mark that sets it apart from hand-picked values

    v1.0.0, Nov 11, 2026

  • Fix

    Component specs count height and width as the content box (a bordered table cell is its height plus its border), the Figma build draws an empty sized slot at its padding instead of 100px, and stories reach every Figma variant: a disabled control on IconButton, Input, Select, Combobox and Textarea, and Figma variant stories for AccordionItem, MenuItem, MenuCheckboxItem, MenuSubmenu and TableEmpty

    v1.0.0, Nov 11, 2026

  • Fix

    Adds the generated component-specs.json (run npm run specs) for Button, IconButton, Badge, Tag, Input and Card, read by the DS Bridge Figma plugin to pull them as component sets

    v1.0.0, Nov 11, 2026

  • Fix

    Studio Components, "Edit tokens" now opens Studio Tokens on ?component=<slug>: exactly the tokens that component's CSS module reads, across every collection, with a removable "Used by IconButton" chip in the chip row

    v1.0.0, Nov 11, 2026

All release notes