@incodetech/prizma-enterprise-icons
v5.1.0
Published
Prizma Enterprise icons: the iconography library as one React component per drawing (pay per icon, tree-shaking keeps only what you import).
Maintainers
Keywords
Readme
@incodetech/prizma-enterprise-icons
The Prizma Enterprise icon bank, as React components. 289 drawings, one module each, so a consumer pays for the glyphs it imports and nothing else.
import { Button } from '@incodetech/prizma-enterprise-web';
import { PlusIcon, DeleteIcon } from '@incodetech/prizma-enterprise-icons';
<Button icon={PlusIcon}>Add member</Button>
<Button variant="icon" tone="danger" icon={DeleteIcon} aria-label="Delete" />Pass the component, never an element: icon={PlusIcon}, not
icon={<PlusIcon />}. The component that places the glyph is what sizes and
colours it, and it can only do that while it still holds the component.
Where the drawings come from
One source, no second copy: the iconography library at
apps/hub/src/components/view/UIApprovedComponents/icons/<name>.svg, the 267
names in ICONOGRAPHY_SET_GENERIC (apps/hub/src/design-data/iconography-brand.ts).
That is the one set Brand, Enterprise and Core share (owner, 2026-10-07).
src/icons/ is generated from those SVGs by
enterprise/scripts/generate-icons.mjs, which copies each drawing's markup
attribute by attribute. Nothing is retyped, re-framed or re-scaled: the viewBox
is the drawing's own and so are the fills. Run it after the library changes:
node enterprise/scripts/generate-icons.mjs # write the package
node enterprise/scripts/generate-icons.mjs --check # fail if it drifted--check runs inside enterprise/web's test suite, so a drawing that changes
in the library and not here fails a PR.
The three rules
| Rule | Why it is law |
| --- | --- |
| Colour is inherited, always currentColor | The glyph takes the ink of the text around it, so a danger button's icon turns red with its label and nobody has to pass a colour. An icon never names one. |
| No intrinsic size | No width, no height: the consumer sizes it through its own icon slot (Button 14, compact 12, Floating menu 16). A size shipped here would fight every component that places the glyph. |
| One source | The drawings are the iconography library's. Pasting a path or hand drawing a glyph is a defect, not a shortcut. |
| The viewBox is the drawing's own | Copied from the source SVG, never normalized. Re-framing is how a glyph silently stops matching the rest of the set. |
What the type buys you
icon props across the library are typed PrizmaEnterpriseIcon, a brand only
createIcon in this package can produce. A hand written <svg> passed to one
of them is a compile error, not a review comment:
Type 'ReactElement<any, any>' is missing the following properties from type
'PrizmaEnterpriseIcon': iconName, [importedFromPrizmaEnterpriseIcons]Owner's law (Nacim, 2026-10-07): "el boton tiene que consumir solo y unicamente iconos de la libreria, ninguno hardcoded."
Naming a glyph
A drawing is decorative by default: aria-hidden, no role, because almost
every glyph sits beside a label that already says what the action is. Passing
aria-label flips it, so a name never ends up somewhere no screen reader can
reach:
<PlusIcon /> // aria-hidden
<PlusIcon aria-label="Add" /> // role="img", not hiddenSet role or aria-hidden explicitly and your value wins.
Tree-shaking
One module per drawing plus "sideEffects": false is what carries the weight:
the bundler drops whole files. Measured with Rollup against the built dist,
importing two glyphs costs 3.3 kB and importing all 267 costs 488 kB, so a
consumer really does pay per icon.
Every createIcon call also carries a /*#__PURE__*/ annotation. That is the
second guard, for a bundler that concatenates the bank into one module instead
of keeping the files apart: the playground harness did exactly that, and without
the annotation a board went from 341 kB to 584 kB.
There is deliberately no name to component map in this package. A map would reference all 267 modules and defeat both guards at once.
Packaging
Built with plain tsc to dist/, like @incodetech/prizma-enterprise-web. The
manifest carries main and types next to exports because the dashboard runs
TypeScript 4.9 with moduleResolution: Node, which ignores exports entirely
(see enterprise/PUBLISHING.md). The declarations are self-contained: nothing
in them points at a dependency's exports-mapped subpath.
Published since 2026-10-13, at 1.0.0:
npm install @incodetech/prizma-enterprise-iconsIt also arrives on its own with @incodetech/prizma-enterprise-web, which
declares it as a real dependency. enterprise/scripts/pack-smoke.mjs packs
this package with the other two and proves all three install, typecheck and
build in a dashboard-shaped consumer.
