Icon
πDark Mode Compatible
A flexible icon component that provides uniform SVG rendering with semantic sizing and coloring based on design tokens.
Overviewβ
Use Icon when you needβ¦
- Consistent icon rendering with semantic sizing (xs, sm, md, lg, xl)
- Semantic colors that adapt to light and dark themes
- Lucide React icon library integration with string-based API
- Accessibility support (title for screen readers, aria-hidden for decorative)
- Polymorphic rendering via
asprop - Token-based design values that automatically adapt to themes
Live demoInteractive
Anatomyβ
The Icon component is a container element with an SVG icon inside.
ββββββββββββββββββββββββββββββββββββββββββββ
β Icon Container (as="span") β
β ββββββββββββββββββββββββββββββββββββββ β
β β size: xs/sm/md/lg/xl β β
β β color: semantic token β β
β β β β
β β ββββββββββββββββββββββββββ β β
β β β SVG Icon β β β
β β β (Lucide React) β β β
β β ββββββββββββββββββββββββββ β β
β ββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββ
Component Structure:
- Container: Inline-flex wrapper (default
span, customizable viaasprop) - Size: Fixed dimensions using design tokens
- Color: Semantic text color tokens
- SVG: Lucide React icon component
Usageβ
Import the component:
import { Icon } from '@grasdouble/lufa_design-system';
Basic usageβ
src/App.tsx
import { Icon } from '@grasdouble/lufa_design-system';
function App() {
return (
<>
<Icon name="user" />
<Icon name="check" size="lg" color="success" />
<Icon name="alert-circle" color="error" title="Error notification" />
<button>
<Icon name="plus" size="sm" />
<span>Add Item</span>
</button>
</>
);
}
Propsβ
| Prop | Type | Default | Description |
|---|---|---|---|
name | IconName | Required | Icon name from Lucide React library |
as | 'span' | 'div' | 'i' | 'span' | HTML element to render as container |
size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' | Size variant (dimensions) |
color | 'currentColor' | 'primary' | 'secondary' | 'success' | 'error' | 'warning' | 'info' | 'muted' | 'currentColor' | Color variant using semantic tokens |
title | string | undefined | Accessible title for screen readers (makes icon non-decorative) |
className | string | undefined | Additional CSS classes |
Also supports all standard HTML attributes for the underlying container element (for example id, role, aria-*, data-*, style, and event handlers).
Accessibilityβ
Icons are non-interactive by default. Provide a title when the icon conveys meaning on its own.
import { Icon } from '@grasdouble/lufa_design-system';
export function IconButtons() {
return (
<>
<button>
<Icon name="trash" size="sm" color="error" title="Delete item" />
</button>
<button>
<Icon name="download" size="sm" />
<span>Download</span>
</button>
</>
);
}
- Use
titlefor icon-only buttons and meaningful standalone icons. - Omit
titlewhen the icon is purely decorative and has adjacent text. - Keep sufficient color contrast for status icons and muted tones.
Theming & Tokensβ
Icon size and color map to semantic tokens:
- Sizes:
xs(16px),sm(20px),md(24px),lg(32px),xl(40px) - Colors:
currentColor,primary,secondary,success,error,warning,info,muted
import { Icon } from '@grasdouble/lufa_design-system';
export function TokenColorExample() {
return <Icon name="check-circle" color="success" />;
}
Do / Donβtβ
Do
- Use
currentColorfor icons that should inherit parent text color - Provide
titlefor icon-only interactive elements - Match icon size to adjacent text size
- Use semantic colors for status and feedback
- Keep icon usage consistent across similar actions
Don't
- Omit
titleon icon-only buttons - Hard-code icon colors with
stylewhen tokens work - Overuse
xlsize outside hero or focal contexts - Mix multiple icon libraries in the same interface
- Rely on color alone to convey meaning
Related Componentsβ
- Button - Interactive button component that can include icons
- Badge - Small UI element for labels and counts
- Text - Typography primitive often paired with icons
- Stack - Layout primitive for arranging icons with spacing
- Box - Layout primitive for icon containers