<ui-icon>
An SVG icon loader that fetches and caches Phosphor icons on demand.
Use <ui-icon name="…"> for icons from the built-in Phosphor set;
use the src attribute for any other SVG URL.
Prefer <ui-icon> over a plain <img> for icons
because it paints with currentColor, scales with font-size, and supports
offline reuse via the Cache API.
Use a plain <img> instead when the image is photographic or carries
intrinsic dimensions that must not follow the text flow.
| Element | Attributes | Properties | Methods | Events |
|---|---|---|---|---|
<ui-icon> |
name, src, weight (observed — changing one on a
mounted icon swaps the glyph), data-error (set by component on failure:
"missing" | "parse"; cleared when a later load succeeds) |
name, src, weight (each reflects its attribute) |
UiIcon.preload(names, {weight}?), and the overridable statics
UiIcon.icon_url(name, weight) / UiIcon.normalize_svg(svg) |
ui-icon-error (bubbles, detail: {name, url, reason}) |
A named icon resolves to /phosphor-icons/SVGs/<weight>/<name>.svg, with
weight defaulting to regular. Only the regular weight is
vendored, so any other weight value 404s until that weight's SVGs are added
alongside it.
UiIcon.preload(names, {weight}?) fetches icons into the Cache API ahead of use, so a
glyph first needed while offline is already stored. A subclass serves a different icon set by
overriding two statics: icon_url(name, weight) builds the URL from
UiIcon.base, and normalize_svg(svg) post-processes the parsed SVG —
the default fills with currentColor so the host's color paints the
glyph, and thickens Phosphor's hairline strokes.
Use the src attribute for SVGs outside of phosphor-icons.
Sets data-error="missing" on the host and dispatches a bubbling
ui-icon-error event. Default fallback is a red file-x —
override the ui-icon[data-error="missing"]::before rule, which
ui-icon.mjs injects ahead of the page's stylesheets, with a rule of your own.
A transient network failure is not a missing icon: it sets no data-error, fires no
event, and drops the in-memory entry so the next mount retries. An unparseable response sets
data-error="parse" and fires the same event with reason: "parse".
name, src and weight are observed: setting one on a
mounted icon reloads the glyph, so callers repoint an icon in place instead of replacing the
element. A name already in memory swaps without a repaint gap. Swapping away from a 404 also
clears data-error and its red fallback.
All icons (phosphoricons.com). Hover for name, click to copy markup.
Icons are decorative by default: the component sets aria-hidden="true" on the
host automatically, so screen readers skip it (WCAG SC 1.1.1 — Non-text Content).
For a meaningful icon, add aria-label or aria-labelledby
directly on the element — the component will not overwrite an existing label.
<ui-icon> is neither focusable nor interactive. Put keyboard interaction on its surrounding <button> or <a> (WCAG SC 2.1.1 — Keyboard).
ARIA wiring: the shadow root is mode="open" and contains only a
raw <svg>. The SVG itself carries no ARIA role; the host element's
aria-hidden / aria-label propagate through the shadow boundary
because they live on the host (WCAG SC 4.1.2 — Name, Role, Value).
Known limitations: a failed icon exposes no fallback text to assistive
technology — a 404 paints the red file-x glyph and a network failure paints
nothing at all, but neither is announced. Callers that need a guaranteed fallback should supply
aria-label on the host so the label is announced even when the SVG is absent
(naming the icon also suppresses the automatic aria-hidden).
No extra markup needed. aria-hidden is applied automatically.
Add aria-label when a standalone icon conveys information that surrounding text does not explain. For an icon inside a button, name the button as described below.
Icon-only buttons: put the accessible name on the <button>,
not the icon. See Accessibility §Screen reader labels.
<ui-toolbar> — toolbar that commonly hosts icon-only buttons.btn-icon — button variant designed for a single icon