Skip to content

Icon registry ​

The icon registry stores glyphs by string name. It is exported from the root entry point.

ts
import {
  getIcon,
  hasIcon,
  registerIcon
} from "@jolly-pixel/ui";

@jolly-pixel/ui/elements/icon registers these names on a shared 24 by 24 SVG grid:

chevron, settings, close, plus, revert, drag, lock, eye, search, check, info, and warning. plus carries the lime tone; the others have none.

Register a Lit SVG glyph ​

ts
import { svg } from "lit";
import { registerIcon } from "@jolly-pixel/ui";

registerIcon("cube", svg`
  <path
    d="m12 3 7 4v8l-7 4-7-4V7l7-4Z"
    fill="none"
    stroke="currentColor"
    stroke-width="2"
    stroke-linejoin="round"
  />
`);
ts
registerIcon(
  name: string,
  glyph: IconGlyph,
  options?: RegisterIconOptions
): void

IconGlyph accepts a Lit SVGTemplateResult or a markup string. Registering an existing name replaces its glyph. Register custom icons before rendering them; registry changes do not request updates from existing jolly-icon elements.

Glyphs use a 24 by 24 view box unless they are registered with viewBox. currentColor makes strokes and fills follow the surrounding text color.

Illustrated glyphs ​

A glyph can be a full-colour illustration drawn on its own grid. Pass the grid as viewBox and keep the literal colours:

ts
registerIcon("image", `
  <rect x="5" y="11" width="54" height="42" rx="5" fill="#7fd3ff" />
  <circle cx="45" cy="23" r="5.5" fill="#ffd23f" />
`, { viewBox: "0 0 64 64" });

Literal colours ignore tones, on-fill and --jolly-icon-tone-strength, and stay as drawn under forced colours, like an image. Register an illustrated glyph without a tone.

ts
iconViewBox(name: IconName): string

iconViewBox() returns the registered view box, or DEFAULT_ICON_VIEW_BOX ("0 0 24 24") for a glyph registered without one and for an unknown name.

Tones ​

A glyph opts into colour with two classes and a default tone:

ts
registerIcon("cube", svg`
  <path class="tone-fill" d="m12 3 7 4v8l-7 4-7-4V7l7-4Z" />
  <path
    d="m12 3 7 4v8l-7 4-7-4V7l7-4Z"
    fill="none"
    stroke="currentColor"
    stroke-width="2"
  />
`, { tone: "violet" });
  • tone-fill fills a closed shape with the tone, under the outline.

  • tone-ink shifts a currentColor stroke or fill towards the tone, for glyphs with no closed shape.

  • ICON_TONES lists the seven tones. Their tokens are in Theme exports and tokens.

  • A glyph registered without a tone follows currentColor.

  • A pane or dialog whose icon has a tone becomes a toned area.

ts
iconTone(name: IconName): IconTone | null
isIconTone(value: string): value is IconTone

Register a markup string ​

ts
registerIcon(
  "cube",
  '<path d="m12 3 7 4v8l-7 4-7-4V7l7-4Z" />'
);

String glyphs are passed to Lit's unsafeSVG directive. Use this form only for trusted markup shipped with the application. The registry does not sanitize the string.

Read the registry ​

ts
getIcon(name: IconName): SVGTemplateResult | null
hasIcon(name: IconName): boolean

getIcon() returns the stored Lit SVG template or null for an unknown name. hasIcon() tests the same map without retrieving the template.

Use getIcon() when an application owns the surrounding SVG:

ts
import {
  svg,
  type SVGTemplateResult
} from "lit";
import {
  getIcon,
  iconViewBox
} from "@jolly-pixel/ui";

type EditorIconName = "move" | "paint";

function renderEditorIcon(
  name: EditorIconName
): SVGTemplateResult {
  return svg`
    <svg viewBox=${iconViewBox(name)} fill="none" aria-hidden="true">
      ${getIcon(name)}
    </svg>
  `;
}

For standard DOM use, let jolly-icon create the SVG and provide its accessible label.

Types ​

ts
type BuiltinIconName =
  | "chevron" | "close" | "plus" | "revert" | "drag" | "lock"
  | "eye" | "search" | "check" | "info" | "warning" | "settings";
type IconName = BuiltinIconName | (string & {}); // completion for built-ins
type IconGlyph = string | SVGTemplateResult;
type IconTone = typeof ICON_TONES[number];

interface RegisterIconOptions {
  tone?: IconTone;
  viewBox?: string; // default "0 0 24 24"
}