Icon inventory
The generated list of every semantic icon role in the system and the lucide glyph it currently resolves to, so a swap is one mapping rather than a search.
Overview
Most design systems cannot answer the question "which icons does this system rely on?" The glyphs are imported one by one in whichever component happens to need them, and the only way to find out is to grep.
opsinjs answers it for the half of the set that is mapped, and this page is where the rest is specified. The design is that a component asks for the icon for status: urgent, for category: sleep, for action: dismiss. Each of those is a role, and a single mapping resolves each role to a lucide name.
No generator emits icon data yet: scripts/build-registry.mts reads the
catalogue and the component sources and has no icon step, so running it will not
fill this table. What exists instead is described below, in prose, with the file
that holds it.
Nothing on this site types a measured number by hand, so an ungenerated table shows this rather than an example.
The status half of the mapping is live. CLINICAL_STATUS_META[level].icon
in lib/status.ts names the lucide glyph for each of the four levels and for
unknown, and lib/status.ts ships inside every implemented registry
item. StatusPill, RangeBar and ScoreDial each keep a local binding from
that name to a component and assert in development that the two agree, so the
four shapes cannot drift apart from the four words.
The other halves are not mapped. Category, data-state, action and provenance roles have no table, and eight built components import their glyphs from lucide directly as a result. That is a debt this page records, not a design: a direct import is invisible to this table, to the contrast audit and to anybody swapping the icon set.
What is fixed now is the shape of the whole set, and the shape is what makes the rest possible: swapping a glyph is one line, auditing the whole set is one table, and a product that wants its own icon library replaces the mapping rather than editing components.
The browsable version, where you can search and copy, is at /icons; this page is the reference form of the same data.
How it works
Roles are grouped by what they do, and the grouping is not cosmetic. Each group has different rules.
Category roles. One per health category. These are semantic: the glyph is carrying which part of someone's health a surface is about, because colour cannot. They are the roles most likely to be customised by a product with its own categories, and the mapping is where that happens. See Theming → Category palettes.
Status roles. One per clinical status level. Always accompanied by colour and a word; never used alone. The set is deliberately closed, because an extra status glyph is an extra status level that the system does not have.
Data-state roles. Empty, error and stale each have a glyph. Loading does not, because a skeleton is not an icon.
Action roles. Dismiss, expand, add, edit, back, more. The mundane majority.
Provenance roles. Where a reading came from: entered by hand, from a device, imported. These matter more than they look. See Data provenance and device accuracy.
Each row carries four things: the role, the lucide glyph it resolves to, what it is used by, and its default accessible name where it can appear alone. The fourth column is the one that stops icon-only controls shipping unnamed.
Where the set is constrained. Everything on Health glyphs is excluded from the mapping by rule, not by convention. A role may not resolve to a symbol that implies clinical authority, and the generator is where that could be checked mechanically.
Using it
Reference the role, never the glyph, wherever a role exists. For status,
that means resolving through CLINICAL_STATUS_META[level].icon rather than
choosing a lucide component yourself. For the roles with no mapping yet, keep the
glyph in one place per role rather than at each call site, so that the eventual
mapping is a move rather than a hunt.
Check the accessible-name column before shipping an icon-only control. If the role has no default name, the control needs one written for it, describing the action rather than the picture.
Do not add a role for a one-off. A role exists because more than one place needs the concept. A single screen wanting a specific glyph is a component detail; a single screen wanting a new concept is a design question that predates the icon.
Use this page to review coherence. Icons chosen one at a time drift: two roles end up with near-identical glyphs, or one group is drawn from a different visual family. Seeing the whole set in one table is the only reliable way to notice.
Tokens
The role mapping is meant to be emitted as machine-readable JSON beside the
catalogue, so an agent generating an interface can resolve a role without
guessing at a glyph name. See
Machine-readable schemas. That step
has not been added to scripts/build-registry.mts, so the only machine-readable
half today is CLINICAL_STATUS_META, which travels with every implemented item.
Sizes and alignment come from the type and space scales, not from here.
scripts/build-registry.mts has no icon step, so there is no emitted role map to
link to. An agent that needs a status glyph today reads lib/status.ts, which
ships with the component.
Nothing on this site types a measured number by hand, so an ungenerated table shows this rather than an example.
Accessibility impact
- The accessible-name column is the point of the table. Icon-only controls without names are the most common accessibility defect involving icons, and the fix is to make the name part of the definition rather than something each component invents.
- A closed status set is an accessibility property. Four levels with four glyphs is learnable; nine glyphs across a product is not, and the readers who suffer most are those with cognitive disabilities and low digital confidence.
- Every meaningful glyph is measured for non-text contrast against the surfaces it appears on, under WCAG 2.2 SC 1.4.11, in both themes. The measured results appear on Contrast conformance.
- Icons are checked under CVD simulation as shapes, not colours. Two status glyphs that differ only by hue are two glyphs that are the same glyph for a large group of readers. The audit is on Colour independence.
Related
- Health glyphs says what may never enter this mapping and why.
- Sizing and alignment shows how these glyphs are sized and set beside text.
- Iconography has the four rules that govern the whole set.
Iconography
One icon library, roles rather than filenames, and the rule that an icon never carries status on its own in a system whose category axis is glyph-driven.
Health glyphs
The medical symbols opsinjs will not use, because an app that borrows the visual language of clinical authority is claiming something it has not earned.