Icons
Lucide icons, their sizes and how to place them in components.
The library and every Zenox app use Lucide through lucide-react, a peer
dependency of the package.
import { BellIcon } from "lucide-react"
Naming
Import the Icon-suffixed name (Trash2Icon, not Trash2). It is the same component, and the
suffix makes it obvious in JSX that the element is an icon.
Size
Components size their icons. Inside a button, menu item, badge or input group, an icon without
a size-* class takes the size the component sets (16px in a default button, 12px in a badge).
Give an icon a size only outside a component:
| Context | Class |
|---|---|
| Next to body text, in a dense row | size-3.5 |
| Default | size-4 |
| Page title icon | size-5 |
| Empty states | the Empty media slot sizes it |
Placement in buttons
Mark the icon with data-icon="inline-start" or data-icon="inline-end". The button tightens
its padding on that side so the label stays optically centered.
<Button>
<PlusIcon data-icon="inline-start" />
New alert
</Button>
Accessibility
- An icon next to visible text is decorative. Lucide icons render
aria-hiddenby default. - An icon-only button needs an
aria-labelthat says what the button does (“Delete alert”), not what the icon shows (“Trash”). - Do not convey state with an icon alone: pair it with text or a tooltip.
Brand marks
The Zenox and Tellyu marks are components, not icons. See Brand.