<arc-icon> Overview
Guidelines
When to use
- Provide a label for icons that convey meaning (e.g., status indicators, action icons)
- Omit the label for purely decorative icons so they are hidden from screen readers
- Use the size prop rather than CSS overrides to maintain consistent icon dimensions
- Register custom icons via the iconRegistry before first render
- Use currentColor inheritance by setting color on the parent element
When not to use
- Pass unsanitized SVG strings from user input — while the component strips scripts, defense in depth is wise
- Use the xl size for inline text icons; sm or md integrates better with body copy
- Set both a name and slot content simultaneously — the name lookup takes precedence
- Rely on the icon alone to communicate critical information; pair with visible text
- Hardcode fill or stroke colors in registered SVGs — use currentColor so they adapt to context
Features
- Per-icon lazy loading — only icons you use are fetched (~500 bytes each), 0KB upfront
- Two built-in icon packs: Phosphor (1,500+ filled) and Lucide (1,900+ stroke-based)
- One-line library switching via iconRegistry.use() or <arc-icon-library>
- Custom icon registration — merge your own SVGs on top of any library (renders instantly)
- Five size presets: xs (12px), sm (16px), md (20px), lg (24px), xl (32px)
- Inherits color via currentColor for natural parent-driven styling
- Slot fallback when no registry name matches, allowing inline SVG passthrough
- Accessible role switching: role="img" with label, role="presentation" without
- XSS-safe: strips <script> tags and on* event handlers from SVG content
Preview
Usage
<!-- Basic usage (Phosphor is the default library) -->
<arc-icon name="star" size="sm"></arc-icon>
<arc-icon name="heart" size="md"></arc-icon>
<arc-icon name="gear" size="lg"></arc-icon>
<!-- Accessible icon with label -->
<arc-icon name="warning" size="md" label="Warning"></arc-icon>
<!-- Switch to Lucide globally -->
<arc-icon-library name="lucide"></arc-icon-library> import { iconRegistry } from '@arclux/arc-ui';
// Switch all icons to Lucide
iconRegistry.use('lucide');
// List all available icon names (async — loads manifest lazily)
const names = await iconRegistry.list(); // active library
const phosphor = await iconRegistry.list('phosphor'); // specific library
// Register custom icons (merged on top of active library)
iconRegistry.set({
'my-logo': '<svg viewBox="0 0 24 24">...</svg>',
});
// Look up an icon by name (async — loads single icon lazily)
const svg = await iconRegistry.get('star'); // returns SVG string or null import { Icon } from '@arclux/arc-ui-react';
<Icon name="star" size="sm" />
<Icon name="heart" size="md" />
<Icon name="gear" size="lg" label="Settings" /> <script setup>
import { Icon } from '@arclux/arc-ui-vue';
</script>
<template>
<Icon name="star" size="sm"></Icon>
<Icon name="heart" size="md"></Icon>
<Icon name="gear" size="lg"></Icon>
</template> <script>
import { Icon } from '@arclux/arc-ui-svelte';
</script>
<Icon name="star" size="sm"></Icon>
<Icon name="heart" size="md"></Icon>
<Icon name="gear" size="lg"></Icon> import { Component } from '@angular/core';
import { Icon } from '@arclux/arc-ui-angular';
@Component({
imports: [Icon],
template: `
<Icon name="star" size="sm"></Icon>
<Icon name="heart" size="md"></Icon>
<Icon name="gear" size="lg"></Icon>
`,
})
export class MyComponent {} import { Icon } from '@arclux/arc-ui-solid';
<Icon name="star" size="sm"></Icon>
<Icon name="heart" size="md"></Icon>
<Icon name="gear" size="lg"></Icon> import { Icon } from '@arclux/arc-ui-preact';
<Icon name="star" size="sm"></Icon>
<Icon name="heart" size="md"></Icon>
<Icon name="gear" size="lg"></Icon> <!-- Auto-generated by @arclux/prism — do not edit manually -->
<!-- arc-icon — requires icon.css + base.css (or arc-ui.css) -->
<span class="arc-icon">
<span
class="icon"
role="presentation"
aria-label="Label"
aria-hidden="true"
>
</span>
</span> <!-- Auto-generated by @arclux/prism — do not edit manually -->
<!-- arc-icon — self-contained, no external CSS needed -->
<span class="arc-icon" style="display: inline-flex; align-items: center; justify-content: center; color: currentColor; vertical-align: middle">
<span
style="display: flex; align-items: center; justify-content: center; width: 100%; height: 100%"
role="presentation"
aria-label="Label"
aria-hidden="true"
>
</span>
</span> API
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | '' | Icon name to look up in the icon registry. When provided, renders the matching SVG. When empty, falls back to slotted content. |
size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'sm' | Icon dimensions: `xs` (12px), `sm` (16px), `md` (20px), `lg` (24px), `xl` (32px). |
label | string | '' | Accessibility label. When provided, sets `role="img"` and `aria-label`. When empty, sets `role="presentation"` and `aria-hidden="true"`. |
See Also
- Icon Button Compact button that renders an icon with optional text label, supporting ghost, secondary, and primary variants.
- Badge Compact pill-shaped label for status indicators, category tags, and notification counts. Three color variants let you encode meaning at a glance across dashboards, tables, and card layouts.