Skip to content
Protocore Design Systemv1.6.9

/// Media

Icon

Sizing wrapper that scales any inline SVG icon to a token box.

import { Icon } from "@protocore/pds";
View as Markdown

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

PropTypeDefaultDescription
childrenReactNodeThe SVG icon element to size (drawn at 1em).
classNamestring
labelstringAccessible label. When set the icon becomes `role="img"`; omit it for decorative icons (then `aria-hidden`).
sizeenummdBox + font-size: sm 14 · md 16 · lg 20 · xl 24.
styleCSSProperties

Related

  • IconButtonA square, icon-only action control — Button's affordances with a required aria-label.
  • AvatarSquare user image with a mono-initials fallback.
  • LogoThe Protocore faceted-core mark, with an optional mono wordmark.
  • ButtonThe system action control — mono uppercase label, sharp corners, and a primary fill that inverts on hover.