Icon
Draws the components' icons, and any Lucide icon you add, with no Angular icon package.
import { … } from '@inlaylab/ivorie/icon'- arrow-left
- arrow-right
- check
- chevron-down
- chevron-left
- chevron-right
- chevron-up
- chevrons-left
- chevrons-right
- chevrons-up-down
- circle-alert
- circle-check
- ellipsis
- grip-vertical
- info
- loader-circle
- minus
- panel-left
- search
- triangle-alert
- x
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { ICONS, IconName, IvIcon } from '@inlaylab/ivorie/icon';
@Component({
selector: 'demo-icon',
imports: [IvIcon],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<ul class="grid grid-cols-3 gap-3 sm:grid-cols-6">
@for (name of names; track name) {
<li class="text-muted-foreground flex flex-col items-center gap-2 rounded-md border p-3 text-xs">
<svg [ivIcon]="name" class="text-foreground size-5"></svg>
{{ name }}
</li>
}
</ul>
`,
})
export default class IconDemo {
readonly names = Object.keys(ICONS) as IconName[];
}
Installation
npx ivorie add iconimport { … } from '@inlaylab/ivorie/icon'The components draw their icons with IvIcon. The shapes come from Lucide, so you install nothing for them.
Usage
import { IvIcon } from '@inlaylab/ivorie/icon';<svg ivIcon="chevron-down" class="size-4"></svg>The names shown above are built in.
Examples
Any Lucide icon
Install the plain lucide package and pass the icon to ivIcon. It is typed, and the build keeps only the icons you import.
npm i lucideimport { House } from 'lucide';
// in the component: protected readonly House = House;<svg [ivIcon]="House" class="size-4"></svg>import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IvButton } from '@inlaylab/ivorie/button';
import { IvIcon } from '@inlaylab/ivorie/icon';
import { Bell, House, Settings } from 'lucide';
@Component({
selector: 'demo-icon-lucide',
imports: [IvIcon, IvButton],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div class="flex gap-2">
<button ivButton variant="outline" size="icon" aria-label="Home"><svg [ivIcon]="House"></svg></button>
<button ivButton variant="outline" size="icon" aria-label="Notifications"><svg [ivIcon]="Bell"></svg></button>
<button ivButton variant="outline" size="icon" aria-label="Settings"><svg [ivIcon]="Settings"></svg></button>
</div>
`,
})
export default class IconLucideDemo {
protected readonly House = House;
protected readonly Bell = Bell;
protected readonly Settings = Settings;
}
Icon library
The components draw Lucide by default. To draw Tabler, Phosphor, Hugeicons or Remix, provide that library's set once:
import { provideIvIcons } from '@inlaylab/ivorie/icon';
import { COMPONENT_ICONS } from '@inlaylab/ivorie/icons/tabler';
providers: [provideIvIcons(COMPONENT_ICONS)]Each set holds only the 18 icons the components use. For your own icons, use <ng-icon> from ng-icons with the same library. npx ivorie migrate icons switches them for you. Size an <ng-icon> with its size input (size="1rem") or the font size, and color it from its parent. A size-* or text-* class on the <ng-icon> itself does not apply.
Why not @lucide/angular
@lucide/angular is one 10 MB file. ng serve does not tree-shake packages, so the browser loads all of it on every reload. The plain lucide package is icon data only (about 1 MB for every icon) and fits IvIcon as is.
shadcn/ui for React imports icons from lucide-react in each component. Ivorie keeps the same Lucide look without that cost.
API
svg[ivIcon]
| Name | Type | Default | Description |
|---|---|---|---|
ivIcon |
IconName | IconData | IconNode |
required | A built-in name, IconData, or a Lucide IconNode such as House from lucide. |
size |
number |
24 |
Width and height in px. A size-* class wins over it. |
Also exported: ICONS (the built-in shapes), IconName, IconNode (the same shape as Lucide's), IconData, IconSvg, IconSet, LUCIDE_ICONS, LUCIDE_SVG, IV_ICONS and provideIvIcons(set).
[ivIconShape]
Internal to IvIcon: ivIconShape binds one shape's attributes. Exported only because IvIcon uses it.
Only shape and drawing attributes are drawn. Event handler (on*) and href attributes in icon data never reach the page.
Accessibility
Icons are decorative: aria-hidden="true". Give the button or link its own label, for example aria-label="Close".