Icon
Preview appears after the next Storybook update.
<Icon />When to use
Use it for
- Next to a label, to help people scan: a menu item, a tab, a status line, a table cell.
- Inside your own controls, at size sm (16), the size the system uses in controls.
- In navigation at size md (20), so the side nav reads at a glance.
- Any Lucide glyph: pass the component itself, for example icon={GitBranch} imported from lucide-react.
Not for
- As the only content of a button: use IconButton, which requires a label and sizes the hit area.
- Inside Button or Badge when they place the icon for you: Button takes iconStart and iconEnd, Badge takes icon.
- Emoji or Unicode glyphs standing in for icons: the system uses one family, Lucide.
- Illustrations or logos: Icon draws 24px grid line icons only.
Do and don't
Every example is rendered with the real component, so it always matches what ships.
Pair the icon with text
The word carries the meaning and the icon helps people find it. The icon stays hidden from screen readers, so the label is read once.
Pick the size from the token scale
xs 12, sm 16, md 20, lg 24. The stroke stays at icon.stroke on every size, so icons keep the weight of the text.
Give a label when the icon stands alone and means something
With label, Icon becomes role="img" with that accessible name. Say what it means ("Merged"), not what it shows ("Purple circle").
Set a color or a size by hand
Icon inherits currentColor and takes its size from the icon size tokens. A hard-coded width or color drifts from the theme and the density.
Rely on the icon alone to say a status
Color and shape are not enough for everyone. Put the status in words next to it, or use Badge.
Accessibility
- Without label, the icon gets aria-hidden="true": screen readers skip it and read the text next to it.
- With label, it gets role="img" and aria-label, so it is announced as an image with that name.
- focusable="false" keeps the SVG out of the tab order. Make the parent control focusable, never the icon.
- The icon inherits the text color, so it gets the same contrast as the label it sits next to.
Content guidelines
- A label names the meaning in sentence case: "Merged", "Opens in a new tab".
- Do not add "icon" or "image" to the label: screen readers already announce the role.
From the code Generated from the component, not editable here.
Anatomy and tokens
Read from packages/react/src/components/Icon/Icon.module.css at build time. Every value is a token: open one to see its alias chain in both themes.
- The SVG, stroke width from icon.stroke
.icon - Size xs, 12px (icon.size.xs)
.xs - Size sm, 16px (icon.size.sm), the default
.sm - Size md, 20px (icon.size.md)
.md - Size lg, 24px (icon.size.lg)
.lg
Motion and interaction
Icon does not animate.
From the code Generated from the component, not editable here.
Props
Parsed from the TypeScript types in packages/react/src/components/Icon/Icon.tsx, so this table cannot drift from the code.
| Prop | Type | Default | Description |
|---|---|---|---|
iconrequired | LucideIcon | none | A Lucide icon component, for example `import { GitBranch } from 'lucide-react'`. |
size | 'xs' | 'sm' | 'md' | 'lg' | 'sm' | Token size: xs 12, sm 16, md 20, lg 24. Default `sm`, the size used inside controls. |
label | string | none | Accessible name. Omit for decorative icons next to text (they are hidden from assistive tech). |
Playground
Change the props and see the real Icon update. Controls are generated from the TypeScript props; nothing here changes the system.
<Icon size="xs" />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 Icon 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
Large
WithLabel
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
- New
Component specs describe swappable parts:
swapon icon parts (default icon from the docs preview or the AllStates story) and on full-bleed compound content (Card body: text or media slot),slotsper variant, and file-levelicons(normalized Lucide SVGs read fromlucide-react),iconStyleandslotssectionsv1.0.0, Nov 11, 2026
- Fix
Measured only: a frame bigger than its children plus its padding on an axis its parent does not size keeps its measured size (a 48 px button around a 16 px icon, a 24 px label row around a 16 px label), read from the boxes when the measure did not mark it as sized
v1.0.0, Nov 11, 2026
- Fix
Figma plugin: updating a component no longer adds its icon swap property again (Badge showed Icon2 and Icon3 after Update all)
v1.0.0, Nov 11, 2026
- Fix
Measured only, for any design system pulled from its Storybook: a part the measure gives as SVG (
MeasuredSpec.vectors, an icon, a check mark) is drawn as vectors instead of an empty frame, and a positioned part (a pseudo-element knob) follows its offset in each variantv1.0.0, Nov 11, 2026
- Fix
Figma plugin: the BOOLEAN of a swappable part is named "Show icon" ("Show icon start"), as Figma kits do, so the swap keeps the plain name "Icon" instead of the "Icon2" Figma gave it
v1.0.0, Nov 11, 2026
- Fix
The Bridge connector shows as Bridge with the Bridge mark: the MCP server's initialize answer carries
title: "Bridge",websiteUrlandicons(MCP 2025-11-25 Implementation, PNG 192 and 512 plus the SVG), and the site servesfavicon.ico(16, 32, 48),apple-touch-icon.png,icon-192.png,icon-512.pngand asite.webmanifestnamed Bridge, linked from every page headv1.0.0, Nov 11, 2026
- Fix
Usage guidance for Icon
v1.0.0, Nov 11, 2026
- Fix
Usage guidance for Icon and VisuallyHidden, drafted by Claude from their code and marked for review
v1.0.0, Nov 11, 2026
- Fix
Regenerates
component-specs.jsonwith icon and content slot swaps and the icons sectionv1.0.0, Nov 11, 2026
- Fix
Being built: a library request for a component the library has now shows that component's real Library preview in List, Grid and Board (the same stage as Library > Components cards, now one shared component), instead of the generic component icon
v1.0.0, Nov 11, 2026