The <dsgn-icon> component renders one SVG icon inside a 24×24 viewBox. Give
it an icon either as a Lit template (icon) or by name (icon-name), and it
inherits its color from currentColor — so it takes the color of whatever
contains it.
Usage
<dsgn-icon icon-name="check" size="md" label="Complete"></dsgn-icon>
Import the component module in your application entrypoint:
import '@ds-gn/ui/icon';
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| size | 'sm' | 'md' | 'lg' | 'xl' |
'lg' |
Icon size: sm 16px, md 20px, lg 24px, xl 32px. |
| icon-name | IconName | '' |
'' |
Icon to render, by name. Requires the icon registry (see below). |
| icon | SVGTemplateResult |
undefined |
Icon as a Lit template. Property-only (no attribute); wins over icon-name. |
| label | string |
'' |
Accessible label. When set, the icon is announced; when empty, it is decorative. |
| surface | 'light' | 'dark' |
'light' |
Semantic token surface to use. |
icon-name is the attribute name; the matching JavaScript property is
iconName.
The icon has no variant prop — color comes from the surrounding text color.
Set it with CSS, or use a component that supplies one, such as
<dsgn-feature-item>’s colored icon badge.
Slots
The component renders its own <svg> and takes no slotted content.
Methods
| Method | Description |
|---|---|
Icon.registerIcons(registry) |
Static. Adds icons to the shared name registry. Merges with anything registered earlier. |
Two ways to supply an icon
icon-name is markup, so it survives a CMS or a copy-paste — but names resolve
through a registry you populate once at app entry:
import { Icon } from '@ds-gn/ui/icon';
import * as icons from '@ds-gn/ui/icon/icons';
const { iconNames, ...registry } = icons;
Icon.registerIcons(registry); // or just the ones you use, to keep the bundle small
<dsgn-icon icon-name="arrowRight"></dsgn-icon>
Custom icons work the same way — any SVGTemplateResult keyed by name:
import { svg } from 'lit';
import { Icon } from '@ds-gn/ui/icon';
Icon.registerIcons({ myIcon: svg`<path d="M4 12h16" />` });
icon takes a Lit template instead. It needs no registry and tree-shakes to the
one icon you import, but it can only be set from JavaScript:
import { arrowRight } from '@ds-gn/ui/icon/icons';
html`<dsgn-icon .icon=${arrowRight}></dsgn-icon>`;
If both are set, icon wins. The name list is exported as iconNames from
@ds-gn/ui/icon/icons.
Examples
Sizes
<dsgn-icon icon-name="check" size="sm"></dsgn-icon>
<dsgn-icon icon-name="check" size="md"></dsgn-icon>
<dsgn-icon icon-name="check" size="lg"></dsgn-icon>
<dsgn-icon icon-name="check" size="xl"></dsgn-icon>
Coloring an icon
<span style="color: var(--color-brand)">
<dsgn-icon icon-name="circleCheck"></dsgn-icon>
</span>
Labeled versus decorative
<!-- Announced as an image named "Warning" -->
<dsgn-icon icon-name="triangleAlert" label="Warning"></dsgn-icon>
<!-- Decorative: hidden from assistive technology -->
<dsgn-icon icon-name="triangleAlert"></dsgn-icon>
Accessibility
An icon with no label renders role="presentation" and aria-hidden="true",
which is the right default next to visible text. Set label only when the icon
is the sole carrier of meaning — an icon-only control should instead get its
name from the control (for example <dsgn-button>’s aria-label), so the name
is not announced twice.