Published · Updated · v0.6.5 · MIT License · Source: icon.md
Icon
Icon is the Gelium-only primitive for trusted inline SVG glyphs. Use icons when a control or a message needs a small, themeable graphic that ships with the server render. All icons are resolved server-side as trusted template.HTML markup — icon markup must never be built from user input.
Guidance
When to use
Use icons when a control or a message needs a small, themeable graphic that ships with the server render.
When not to use
Do not use an icon where text alone is clearer. Never make an icon the only signal: decorative icons must sit next to visible text, and meaningful icons must be named by visible text. Never build icon markup from user input — glyphs are trusted, server-resolved markup.
Usability
- The shared
.ui-iconclass gives every icon consistent 24 px sizing and acurrentColorfill so the glyph matches surrounding text automatically. - Icons are resolved server-side as trusted
template.HTMLmarkup; pass only internal glyphs. - Decorative icons must include
aria-hidden="true"andfocusable="false".
Accessibility
- Decorative icons must be
aria-hidden="true"andfocusable="false"and must sit next to visible text or another accessible name. - An icon that carries meaning is named by visible text beside it, never by an
aria-labelalone. - The
currentColorfill keeps icons at the surrounding text's contrast in every theme, including forced-colors mode.
See Choose the right control for the cross-component decision.
Material Symbols set
Gelium UI ships a curated set of Material Symbols (Apache-2.0, from google/material-design-icons) as trusted server-resolved inline SVGs. The set is generated by scripts/copy-icons.mjs into internal/app/icons.go and embedded in the binary — consumers never fetch icon files at runtime, and every glyph is themeable through currentColor.
The curated allowlist (38 glyphs, identical to the ICONS array in scripts/copy-icons.mjs).
add, arrow_back, arrow_downward, arrow_forward, arrow_upward, check,
chevron_left, chevron_right, close, delete, edit, error, home, info, menu,
more_vert, refresh, save, search, settings, warning, person, notifications,
share, star, thumb_up, visibility, visibility_off, lock, send, download,
upload, calendar_today, schedule, more_horiz, add_circle, dark_mode,
light_mode
Each glyph keeps the Material Symbols 960-grid coordinate space (viewBox="0 -960 960 960"); the .ui-icon class owns the rendered size. To add a glyph, extend the ICONS allowlist in scripts/copy-icons.mjs, rebuild, and let the contract test verify the new row carries aria-hidden, focusable="false", and currentColor.
The .ui-icon utility
The shared .ui-icon class gives every icon consistent 24 px sizing, a fixed flex size, and a currentColor fill. The glyph matches surrounding text automatically.
Accessibility contract
Decorative icons must be aria-hidden="true" and focusable="false" and must sit next to visible text or another accessible name. An icon that carries meaning is named by visible text beside it and never by an aria-label alone. The examples below follow that contract.