A stateless, themeable wrapper around a slotted <svg>. Takes care of sizing, theme-aware colour, and accessibility so consumers only need to provide SVG paths.
<x-icon size="md" color="primary" label="Save">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M5 13l4 4L19 7" />
</svg>
</x-icon>
| Attribute | Values | Default | Description |
|---|---|---|---|
size | sm | md | lg | xl | positive integer (px) | md | Square box size. Tokens map to sm=16, md=20, lg=24, xl=32. |
color | inherit | primary | secondary | tertiary | success | warning | danger | muted | inherit | Maps to theme tokens. inherit rides the parent's currentColor. |
label | string | — | When set and non-empty, the icon is announced with role="img" aria-label. When absent or empty, the icon is decorative (aria-hidden="true"). |
| Property | Type | Reflects attribute |
|---|---|---|
size | string | size |
color | string | color |
label | string | label |
No events, no public methods.
| Slot | Description |
|---|---|
| (default slot) | Exactly one <svg> element supplied by the caller. |
| Part | Description |
|---|---|
box | Sized <span> that wraps the slot |
| Variable | Default | Description |
|---|---|---|
--x-icon-size | 20px | Square size of the icon box (set inline from size) |
--x-icon-color | currentColor | Resolved colour value (set inline from color) |
Host CSS always applies color: var(--x-icon-color, currentColor) so the slotted SVG's fill="currentColor" / stroke="currentColor" picks it up automatically.
For color to take effect — including the default inherit / currentColor behaviour — your SVG paths must use currentColor:
<svg viewBox="0 0 24 24" fill="currentColor">
<path d="…" />
</svg>
or for stroked icons:
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="…" />
</svg>
This is the same convention used by every mainstream icon library (Lucide, Heroicons, Material, Phosphor, Tabler). Icons with hard-coded colours will render but ignore the color attribute.
label is absent (or empty), the host gets aria-hidden="true" and no role. Screen readers skip it.label="…" is set, the host gets role="img" and aria-label="<label>", and aria-hidden is removed. The icon is announced as an image with the given name.label — decorative is a valid and common case.<x-icon size="sm"><svg>...</svg></x-icon>
<x-icon size="md"><svg>...</svg></x-icon>
<x-icon size="lg"><svg>...</svg></x-icon>
<x-icon size="xl"><svg>...</svg></x-icon>
<x-icon size="48"><svg>...</svg></x-icon>
<x-icon color="primary"><svg>...</svg></x-icon>
<x-icon color="danger"><svg>...</svg></x-icon>
<x-icon color="muted"><svg>...</svg></x-icon>
<button style="color: hotpink">
<x-icon><svg>...</svg></x-icon>
Delete
</button>
The icon will render in hot pink because color defaults to inherit.
<x-icon label="Save document"><svg>...</svg></x-icon>
[:x-icon {:size "lg" :color "primary" :label "Save"}
[:svg {:viewBox "0 0 24 24" :fill "currentColor"}
[:path {:d "M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"}]]]
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |