Foundations

Icons

One glyph language and one sizing model, across every platform.

Icons are SVGs in swsh-assets/icons/, drawn on one grid and filled with currentColor. The Icon primitive centers each glyph in its size box. Import each icon from its own module so a screen only bundles what it renders.

text.primary
text.muted
accent.default
text.inverse on fill.inverse
import { useSwshdTheme } from "swshd/ThemeProvider";
import IconCheck from "swshd/icons/IconCheck";

const { colors } = useSwshdTheme();
<IconCheck size={20} color={colors.text.primary} />

Search the manifest, choose a size and color, then inspect the selected glyph and its public import.

Size
Color
124 of 124

The Check glyph at the preview sizes used by the Icons story.

12
16
20
24
32
48

PhotoStack expanded over the grid; callouts use the authored icon specification.

Grid
20 × 20
Live area
1–19
Stroke
2.25
Chevron
2.5

Grid and live area

20 × 20 grid; live area 1–19.

Line weight

Straight strokes 2.25, chevrons 2.5; round caps and joins.

Dot

4 unit diameter.

Gap

1.125 units between forms.

Corner radius

3.5 unit corner radius.

Negation slash

2.125–17.875 diagonal; 1.125 unit gap.

Icons use currentColor only, except AppleAppStoreBadge, GooglePlayBadge, FullIMessage, FullInstagram, Microsoft, WhatsApp.

Icons carry no accessible name of their own. Give icon-only controls an accessible label; ButtonRoot requires accessibilityLabel when iconOnly is set.

Announced as “Mark album as complete”
<ButtonRoot
  iconOnly
  accessibilityLabel="Mark album as complete"
  onPress={onPress}
>
  <ButtonIcon Icon={IconCheck} />
</ButtonRoot>
  1. Draw or export the SVG on the shared grid; normalize an export with bun fix-icons --path <export dir>.
  2. Place the file in packages/swsh-assets/icons/.
  3. Run bun validate and fix grid, alignment, or line-weight errors.
  4. Run bun codegen to scaffold the icon module and refresh the catalog.