Icons
Render icons with the semantic Icon API from @infinitibit_gmbh/ui.
Icons
@infinitibit_gmbh/ui ships icons as a single SVG sprite plus a typed Icon
component. You reference icons by semantic name (e.g. close, search) —
you never import an icon library directly.
Setup (once per app)
Icons render from a sprite asset that your app serves, so your bundler controls its hashed URL. Import the sprite as a URL and register it once, before any icon renders (e.g. in your app entry / root):
import spriteUrl from '@infinitibit_gmbh/ui/icons.svg?url';
import { setIconSprite } from '@infinitibit_gmbh/ui/icons';
setIconSprite(spriteUrl);
The ?url suffix is the Vite/TanStack Start convention for "give me the asset's
URL". Other bundlers expose asset URLs differently — use whatever yields the
served URL of @infinitibit_gmbh/ui/icons.svg.
The sprite must be served same-origin (browsers don't load cross-origin
<use> references), so serve it from your app's own assets, not a CDN on
another origin. If no sprite is registered, icons render blank — a dev-mode
console warning points this out.
react >= 18 is a peer dependency.
Rendering an icon
import { Icon } from '@infinitibit_gmbh/ui/icons';
export function Toolbar() {
return (
<button aria-label="Search">
<Icon name="search" title="Search" />
</button>
);
}
name is fully typed — your editor autocompletes the available icons and a typo
is a compile error.
Sizing & color
Icons inherit currentColor and default to 1em square, so they scale with
surrounding text. Override with classes (Tailwind shown) or props:
<Icon name="close" className="size-4 text-red-500" />
<Icon name="close" width={32} height={32} />
Accessibility
- Meaningful icon — pass
title. It renders a<title>androle="img":<Icon name="search" title="Search" /> - Decorative icon (label is elsewhere) — omit
title; it'saria-hiddenautomatically:<button aria-label="Close"><Icon name="close" /></button>
Discovering available icons
import { ICON_NAMES, iconMetadata, type IconName } from '@infinitibit_gmbh/ui/icons';
ICON_NAMES; // readonly array of every icon name
iconMetadata['search']; // { description?, source, viewBox }
Do not import icon libraries directly
Always use the Icon API. Importing @phosphor-icons/* or lucide* directly
defeats the semantic layer (and is blocked by lint inside the design system).
The upstream set backing a given name is an internal detail and may change
without affecting your code. Need an icon that doesn't exist yet? Request it via
the design system (it's added to the curated alias manifest).