Centrim Design System — a token-first, accessible React component system.
Icons
One icon library, five legal sizes, and a hard requirement that an icon never carries meaning on its own. Icons support labels; they do not replace them unless the control is unmistakable.
What is this?
Lucide React is the only icon source. Sizes come from --size-icon-xs (12px) through --size-icon-xl (32px), and icon-only controls are always rendered through IconButton.
When to use it
- Reinforcing a labelled action or a status
- Compressing a repeated, unmistakable control into a single tap target
- Marking rows, list items and menu entries consistently
How to use it
- Import the icon from lucide-react and size it with an icon-size token
- Match icon size to the control size — small controls take xs, default take sm
- Give icon-only controls an accessible label and a Tooltip
What to avoid
- Custom SVGs, emoji, or a second icon library
- Icons as the only indicator of state or meaning
- Arbitrary pixel sizes such as size-[18px]
Size tokens
Lucide React is the only icon library.
icon-xs
icon-sm
icon-md
icon-lg
icon-xl
Size assignment
| Token | Value | Use with |
|---|---|---|
| --size-icon-xs | 12px | Small buttons, badges, chips, table meta |
| --size-icon-sm | 16px | Default buttons, inputs, menu items, nav links |
| --size-icon-md | 20px | Large controls, section headers, feature rows |
| --size-icon-lg | 24px | Feature callouts, dialog headers |
| --size-icon-xl | 32px | Empty and error states only |
Common actions
Use the same icon for the same action everywhere — recognition is the point.
Icon-only controls
IconButton supplies the accessible name and the 24px minimum target; the Tooltip explains the action.
Rules
Three non-negotiable icon rules
1. Lucide React only. No custom SVGs, no second icon library, no emoji standing in for an icon.
2. Token sizes only. Every icon uses one of the five icon-size tokens, applied through size-(--size-icon-*).
3. Icon-only controls use IconButton and a Tooltip. The label prop gives the control an accessible name; the tooltip gives sighted users the same information. An unfamiliar control without a tooltip is a bug.
Do & don't
Do
- Mark decorative icons aria-hidden when a visible label already names the action.
- Keep icon meaning stable across the product — one icon, one action.
- Pair status icons with status colour so colour is never the only channel.
- Use the xl size only inside empty and error states.
Don't
- Do not put an icon on every button — reserve them for scanning value.
- Do not use an icon-only control for a destructive action outside a repeated row.
- Do not resize an icon with width/height attributes.
- Do not rotate or recolour an icon to invent a new meaning.
Why it is designed this way
Constraining the library and the size set means icons compose predictably with the type scale: a 16px icon always sits on a 16px label, so toolbars and menus align without per-case adjustment. Routing icon-only controls through IconButton is what guarantees the accessible name and the 24px minimum pointer target every time.