Settings & Rendering
When to Use
Defining configurable per-icon properties (size, color, decorative role) and producing the right output markup.
Pattern: Setting Schema
settings:
size:
title: "Size"
description: "Icon edge in px"
type: integer
default: 24
minimum: 8
maximum: 96
multipleOf: 4
color:
title: "Color"
type: string
format: color # forces color-picker widget
decorative:
title: "Decorative only"
type: boolean
default: false
variant:
title: "Variant"
type: string
enum: ["solid", "outline"]
alt:
title: "Alt text"
description: "Leave blank for decorative icons"
type: string
default: ""
Decision: which settings to declare
| Need | Setting | Type |
|---|---|---|
| Editor controls icon size | size |
integer with min/max/multipleOf |
| Editor recolors icons inline | color |
string with format: color |
| Differentiate decorative vs meaningful icons (a11y) | decorative |
boolean |
| Multi-style packs (solid/outline/duotone) | variant |
string with enum |
| Custom CSS class on output | class |
string (free-form) |
| Accessible label for content icons | ariaLabel or alt |
string |
Decision: Output Format Choice
| Extractor | Default output | Pros | Cons |
|---|---|---|---|
| svg / svg_sprite | Inline <svg> |
CSS-styleable, animatable, accessible | larger HTML |
| path | <img> |
cacheable, fewer DOM nodes | not inline-styleable |
| font | <i>/<span> whose glyph comes from CSS content: |
tiny HTML, CSS-color | less semantic, font-loading dependency, needs a paired library |
Pattern: Accessibility
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="{{ attributes.viewBox|default('0 0 24 24') }}"
width="{{ size|default(24) }}" height="{{ size|default(24) }}"
{% if decorative %}aria-hidden="true" role="presentation"
{% else %}role="img" aria-label="{{ ariaLabel|default(alt|default(icon_id)) }}"{% endif %}>
{{ content|raw }}
</svg>
Site builders pick decorative: true for purely visual icons (chevrons, checkmarks next to label text); leave it false and provide ariaLabel for icons that carry meaning on their own.
Common Mistakes
- Wrong: no
decorativeorariaLabelsetting → Right: declare them so editors can comply with WCAG; without them every icon gets the same default a11y - Wrong: hardcoding
width/heightin the template without honoring asizesetting → Right: reference{{ size|default(...) }}so editors can resize - Wrong: using
format: colorwith a non-CSS-color string default → Right: default to a valid color value or the form widget breaks