/// Media
Icon
Sizing wrapper that scales any inline SVG icon to a token box.
import { Icon } from "@protocore/pds";Basics
Wrap any SVG icon child — lucide-react here. The wrapper sets font-size, and because the icon draws at 1em it takes the box size. Icons are decorative by default (aria-hidden).
Sizes
Four boxes tuned to the type scale: sm 14, md 16 (default), lg 20, xl 24. Match the icon size to the text or control it sits beside.
Decorative vs. labelled
Set label when the icon carries meaning on its own — it becomes role="img" with an accessible name. Omit label for icons that merely decorate adjacent text; they are hidden from assistive tech so the label isn't announced twice.
Deploy
When to use it
Icon is a *sizing primitive*, not an icon set — the PDS ships no glyphs of its own. Bring your own SVG (lucide-react in these docs) and wrap it so it snaps to the token scale and inherits currentColor. Use Icon for inline, non-interactive glyphs: a leading mark on a list row, a status affordance beside text. If the glyph is clickable, use IconButton (it owns the hit target, focus ring, and required aria-label). Component slots like Button's startIcon already size their icons — you don't need to wrap those.
Usage
Do
- Give the icon an accessible `label` whenever it conveys information not present in nearby text.
- Leave `label` off for purely decorative icons so screen readers skip them.
- Let the icon inherit color via `currentColor` from its container.
- Size icons to the adjacent text or control using the four presets.
Don't
- Don't use Icon for clickable glyphs — that's IconButton, which supplies the hit target and focus ring.
- Don't hardcode width/height on the SVG; the wrapper's `font-size` does the scaling.
- Don't double-wrap icons that a component slot (e.g. `startIcon`) already sizes.
- Don't rely on an unlabelled icon as the only signal of state or meaning.
Accessibility
- Decorative icons (no `label`) render `aria-hidden` so they are never announced.
- Passing `label` promotes the wrapper to `role="img"` with `aria-label`, giving the glyph an accessible name.
- Icon is not focusable and has no interactive behavior — for keyboard operability wrap the glyph in a Button or IconButton.
- Color contrast still applies: labelled informational icons must meet non-text contrast against their background.
Icon props
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | The SVG icon element to size (drawn at 1em). |
className | string | — | |
label | string | — | Accessible label. When set the icon becomes `role="img"`; omit it for decorative icons (then `aria-hidden`). |
size | enum | md | Box + font-size: sm 14 · md 16 · lg 20 · xl 24. |
style | CSSProperties | — |