Skip to content

shutteringv1.0.0

Icons

Two different problems wear the same word. The functional glyphs come from a library; the ones only your product has are drawn — and this is what they are drawn to.

@shuttering/iconsimport { Glyph, GLYPH, checkGlyph } from '@shuttering/icons'

Which problem you have

Conflating these is what makes iconography feel unanswerable.

LayerExampleWho owns it
UI glyphs A library. @phosphor-icons/react already does.
Domain glyphs You. No library can carry a seat, a cascade, a lapsed record.
The marka logo, a faviconDrawn once per venture. Not a set — see @shuttering/error-pages/mark.
Note:

This package ships no art

It holds the geometry, the wrapper and the checker. The glyphs on this page are demonstrations — a roster of glyph names in a shared package is one product’s vocabulary inside everybody’s dependency.

The contract

One weight, one box, one live area. Mixing two stroke weights is the single most legible sign that a set was assembled rather than drawn.

16px
24px
32px
48px
Box0 0 24 24
Stroke1.5 — matched to the vendored set's regular weight
Terminal radius0.75 — derived as stroke ÷ 2, never chosen
Live area3–21
Caps and joinsround
Judge at16px — where sets fall apart

Do: Draw at 24 and judge at 16. Most glyphs render at 16, so a set only ever looked at large is a set whose problems ship.

Don’t: Mix stroke weights across a set — it is the most legible sign a sheet was assembled rather than drawn. checkGlyph fails a file carrying two, and a file declaring none.

Accessibility

Decorative by default, because that is the common case — a glyph beside a label is announced twice if it carries a name.

Seat offeredaria-hiddenrole="img" + aria-label
Warning:

The default runs the other way in most icon sets

A vendored set commonly presets a title, so going decorative means remembering to clear it — which is how a screen reader ends up reading “image” between every label. Glyph hides unless you name it, and applies that treatment after the prop spread so a call site cannot undo it by accident.

Checking art you did not draw

The point of a written contract is a set commissioned from someone outside the repo. checkGlyph says whether the files are drawn to it before they are committed.

off contracta 32-box glyph stroked 2 in red
  • view-boxviewBox is "0 0 32 32", not "0 0 24 24" — the 24 drawing box
  • strokestroke-width is 2, not 1.5 — one weight per set, or the sheet reads as assembled
  • stroke-linecapno stroke-linecap; every glyph declares "round"
  • stroke-linejoinno stroke-linejoin; every glyph declares "round"
  • currentColorliteral colour stroke="red" — a glyph paints in currentColor so one drawing serves every ground
  • live-areax="1", y="1" outside 3–21; a glyph that fills the box sits heavier than its neighbours

Also available as a Vitest matcher — import '@shuttering/icons/vitest', then expect(svg).toBeDrawnToContract() over a directory of delivered files. The checker entry is React-free, so a build script can import it without crossing a client boundary.

API

PropTypeDefaultDescription
children (required)ReactNodeThe drawn shapes, on a 24 box, inside the live area.
labelstringAn accessible name. Omit for a decorative glyph — the common case, and the default.
sizenumber24Rendered box in px. The drawing itself is resolution-independent.

Designed & built by stxkxs — React 19, Tailwind v4, and its own @shuttering/* packages.

Agent surfaces are always-on. Proprietary.

© stxkxs