Icon
The icon primitive across Ecology. It inlines the Lucide SVGs it needs (no icon dependency), inherits color via currentColor, and maps to five sizes — xs=14, sm=16, md=20, lg=24, xl=28.
Preview
<EsaIcon name="star" size="md" /> Sizes
Three sizes map to fixed pixel boxes via the --icon-size-* tokens.
<EsaIcon name="star" size="xs" />
<EsaIcon name="star" size="sm" />
<EsaIcon name="star" size="md" />
<EsaIcon name="star" size="lg" />
<EsaIcon name="star" size="xl" /> Color
Icons inherit currentColor, so they take the text color of their context — set color on a wrapper to tint them.
<span style="color: var(--color-content-brand)"><EsaIcon name="circle-check" size="lg" /></span>
<span style="color: var(--color-content-utility-warning)"><EsaIcon name="triangle-alert" size="lg" /></span>
<span style="color: var(--color-content-utility-danger)"><EsaIcon name="circle-x" size="lg" /></span>
<span style="color: var(--color-content-utility-info)"><EsaIcon name="info" size="lg" /></span> Gallery
The icons currently inlined in the lookup. Add entries to esa-icon.astro as new components need them.
home settings plus x check chevron-down chevron-up chevron-left chevron-right chevrons-left chevrons-right search filter arrow-left arrow-right arrow-up arrow-down circle-alert circle-check circle-x info eye pencil trash-2 copy download upload external-link calendar user users star loader menu bell triangle-alert save circle-question-mark API
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | required | Lucide icon name (kebab-case), e.g. "chevron-down". Resolved against the inlined Lucide lookup; an unknown name renders an empty glyph. |
size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' | Icon size — xs=14, sm=16, md=20, lg=24, xl=28. |
label | string | — | Accessible label. When provided the icon becomes role="img"; when omitted the icon is decorative (aria-hidden). |
paths | string | — | Inner SVG markup (the <path>/<circle>… children, no <svg> wrapper) for a glyph not in the built-in registry. Lets a consumer supply brand- or feature-specific icons without forking this component — used as the fallback when `name` is unknown. |
Accessibility
- Decorative (default): no
label→ the icon isaria-hidden="true"and skipped by screen readers. - Meaningful: pass
label→ the icon getsrole="img"+aria-label, e.g. . - The inner
<svg>isfocusable="false"to keep it out of the tab order in legacy browsers.
Theming surface
Every public token this component reads, extracted from its source at build time,
split by blast radius: the hooks that belong to this component,
then the shared and system tokens it consumes alongside everything else. The
Resolves to column walks each token's real lineage —
component → semantic → primitive → raw value — so you
can see exactly where re-pointing it lands. A spoke re-skins by overriding these in
its theme-<slug>.css; component internals are never edited. No
hook for what you need? File it with /request-lego.
Wired to this component
None. This component has no hooks of its own — it themes entirely through the shared tokens below, so every override here also moves its siblings.
Shared tokens it reads
Owned by a family or by the semantic layer. Still overridable — but scope the
override (esa-foo { --form-border-color: … }) unless you mean to move
everything that reads it. Reach says what else that is.
| Token | Reach | Resolves to |
|---|---|---|
--icon-size-lg | primitive every component | 24px |
--icon-size-md | primitive every component | 20px |
--icon-size-sm | primitive every component | 16px |
--icon-size-xl | primitive every component | 28px |
--icon-size-xs | primitive every component | 14px |