IconButton
Preview appears after the next Storybook update.
<IconButton />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.
Name the action, not the picture
label="Delete token" is what a screen reader says. "Trash" describes the drawing, not what happens.
Pair with a Tooltip showing the same label
Sighted mouse users get the name on hover; keyboard users get it on focus.
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.
- Square container (layout from Button)
.iconButton
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.
| When | What changes | Duration | Easing |
|---|---|---|---|
| Hover | Background | motion.duration.instant75 ms | motion.easing.standardsettles in place |
| Press | Background | motion.duration.instant75 ms | motion.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.
| Prop | Type | Default | Description |
|---|---|---|---|
iconrequired | LucideIcon | none | Lucide icon component. |
labelrequired | string | none | Accessible 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. |
size | ButtonSize | 'md' | No description in the code yet. |
loading | boolean | false | No description in the code yet. |
pressed | boolean | none | Makes 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.
<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 itspressedprop, reads "IconButton: restyled when pressed" with what changed (fill (icon) currentColor) and arestylemark that sets it apart from hand-picked valuesv1.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(runnpm run specs) for Button, IconButton, Badge, Tag, Input and Card, read by the DS Bridge Figma plugin to pull them as component setsv1.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 rowv1.0.0, Nov 11, 2026