Icon Registry
@plaud/design ships no icon implementations. It only defines an icon contract
(IconRegistry). Every icon used inside the components is injected by the consumer at the
app entry — design provides no fallback. If the registry is missing or a key is absent, the
affected component throws at render time.
Why this design:
- Icon implementations are decoupled from the component library, so consumers can plug in any
icon source (hand-drawn SVGs,
lucide-react, etc.) - Configure once, globally — swap the whole icon set in a single place
- TypeScript + runtime double validation surfaces missing icons at compile / dev time
Quick start
Inject a registry covering every key at the app root, using DesignProvider (or the lightweight
IconRegistryProvider):
import { DesignProvider } from '@plaud/design'
import type { IconRegistry } from '@plaud/design'
const icons = {
search: MySearchIcon,
calendar: MyCalendarIcon,
// …cover every key of IconRegistry
} satisfies IconRegistry
export const App = () => (
<DesignProvider icons={icons}>
<YourApp />
</DesignProvider>
)
satisfies IconRegistry validates at compile time: a missing key — or an icon component whose
props don't match (e.g. sort must accept sortDirection) — fails the build.
Two providers
| Provider | Capability | When to use |
|---|---|---|
DesignProvider | Theme + overlay host + icon injection (icons required) | Application entry, all-in-one |
IconRegistryProvider | Icon injection only (icons required), no theme management | When theme is owned elsewhere (e.g. this docs site's Docusaurus) |
The contract (IconKey)
Every key of IconRegistry is available via the runtime constant ICON_KEYS:
import { ICON_KEYS } from '@plaud/design'
console.log(ICON_KEYS) // ['infoCircle', 'checkmarkCircle', ...]
Most icons are typed ComponentType<IconProps> (IconProps mirrors native <svg> props).
sort is the exception: it additionally receives sortDirection, so it is typed
ComponentType<SortIconProps>.
Plug in your own icon library
Any source works as long as it satisfies the contract — for example using lucide-react:
import { Search, Calendar, ChevronDown } from 'lucide-react'
import type { IconRegistry } from '@plaud/design'
const icons = {
search: Search,
calendar: Calendar,
chevronDown: ChevronDown,
// …the remaining keys
} satisfies IconRegistry
Reference implementation
This docs site uses a default set sourced from the Figma Design System
(packages/design-site/src/icons/plaud-icon-registry.tsx), injected via IconRegistryProvider
in src/theme/Root.tsx so that every component example below renders its icons:
import { IconRegistryProvider } from '@plaud/design'
import { plaudIconRegistry } from '../icons/plaud-icon-registry'
const Root = ({ children }) => (
<IconRegistryProvider icons={plaudIconRegistry}>{children}</IconRegistryProvider>
)
Consumers can copy plaudIconRegistry as a starting point and replace individual icons as needed.
Validation behavior
- Compile time:
iconsis required onDesignProvider/IconRegistryProvider, andsatisfies IconRegistryguarantees full coverage - Dev time: on mount the provider lists any missing keys via
console.error - Runtime: rendering a component that needs an unprovided icon throws, naming the missing key