Icon
Icon renders a Lucide glyph without a network dependency. Choose a verified registry name for common
symbols; pass icon only when the glyph is absent, and decide whether it is decoration or meaningful content.
Examples
Curated registry
Registry names are kebab-case and intentionally finite, so common icons stay tree-shakable. An
unknown name renders nothing and warns during development rather than guessing at a symbol.
Size and accessible label
Use 16px inline and 24px for emphasis. Without title, an Icon is decorative; give it a title
only when the glyph carries information that is absent from nearby text.
When to use
Use an Icon to reinforce a nearby label or to supply the visual content of an IconButton.
For a glyph outside the registry, the icon prop accepts a Lucide component and takes precedence over name.
Reach for something else when:
- The control has no visible text — use IconButton and give its required
labela clear action name. - The symbol must be a logo or product mark — use the approved brand asset.
- A status needs words as well as a color — use Badge or an explicit text label.
Accessibility
- Without
title, Icon emitsaria-hidden="true"; use this for decorative glyphs beside visible text. - With
title, it emitsrole="img"andaria-labelwith that exact title. Keep it concise and avoid repeating adjacent text such as “Search” beside a search icon. - An Icon inside IconButton is normally decorative. The button's
label, not the glyph title, supplies the control's accessible name. - A bare Icon is not interactive or focusable. Put it inside a semantic link or button when it triggers something.
Props
| Name | Type | Required | Description |
|---|---|---|---|
name | IconName | — | Curated registry key in kebab-case, e.g. `"arrow-right"`, `"search"`, `"layout-dashboard"`. |
icon | LucideIcon | — | Escape hatch (D-03): a lucide-react component. Wins over `name` when both are given. |
size | number | — | Side length in px. Default `20` (16 inline, 24 for emphasis). |
color | string | — | CSS color. Defaults to `currentColor` (lucide's native default — D-06). |
title | string | — | Accessible label. With it the icon is `role="img"`; without it the icon is decorative. |
className | string | — | |
style | CSSProperties | — |
Plain HTML
Icon renders an SVG. The React component also emits .lyra-icon as a targeting hook, but no stylesheet
rule ships for it, so plain HTML needs no Lyra class:
<svg
aria-hidden="true"
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
>
<path d="m9 18 6-6-6-6" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"></path>
</svg>
<svg role="img" aria-label="Featured project" width="24" height="24" viewBox="0 0 24 24"></svg>