Skip to main content
xriptxr

Icon

Info:Media
21

A functional glyph, or a mark generated from a name, drawn in the current text color.

glyph symbol svg pictogram mark

Live demo

live · @xtyle/astro

Icon

The functional set

chevron-up

chevron-down

chevron-left

chevron-right

chevron-expand

arrow-up

arrow-down

arrow-left

arrow-right

close

check

plus

minus

menu

more-vertical

more-horizontal

search

info

warning

error

success

external-link

maximize

dot

loader

play

pause

stop

skip-forward

skip-back

volume

volume-off

gear

folder

pencil

trash

eye

copy

palette

bookmark

download

Generated marks

A name that carries a spec (a -- grammar) is composed on the fly instead of looked up: primitives placed on a grid, sized, rotated, outlined, or knocked out, colored from the theme's own series so a mark recolors with the theme. See the grammar for the full syntax.

dice 3

dice-3

crest

crest

badge

badge

target

target

framed

framed

spun

spun

check badge

check-badge

search chip

search-chip

pennant

pennant

split

split

The same spec under a different palette via colors. A palette is a set of stops and a mark asks it for N colors, so a ramp-shaped palette (thermal, severity, intensity) is sampled just as happily as a categorical one:

chip chip chip chip chip chip

The primitive library

The library is mostly filled art, not line work: solids you stack into a mark rather than outlines you draw with. Every one takes the layer's color, rotates to any angle, and restretches per axis, so cylinder plus a disc cap is a database and one circle covers every ellipse ratio there is.

Curves & nature

wave

water

swish

blob

lens

leaf

cloud

mountain

sun

flame

drop

Volume

disc

cylinder

cone

half

quarter

wedge

oval

pill

egg

arch

Polygons

triangle

diamond

pentagon

hex

octagon

trapezoid

ramp

squircle

gem

shield

Markers

banner

tag

bubble

chevron

arrow

cross

divider

Stars & seals

star

star4

star6

star8

burst

seal

heart

crescent

bolt

Stacked, they build the marks the flat set can't. A drum with a platter cap is a database; a wavy fill level clipped to a circle is water:

database

cylinder + disc

platters

a stack of discs

sea

water, clipped round

weather

sun behind cloud

spark

seal + star4

hot

flame in flame

Sizing and moving: the layer and the whole mark

A layer sizes with s and moves with x/y. sx/sy then stretch that result on one axis — they layer on s rather than replacing it, so s50-sx200 reads as "half size, then twice as wide" and a primitive stretches out of its authored proportion without the library shipping a shape per ratio.

round

circle

wide

-sx150-sy60

tall

-sx55

band

-sy220

lean

-sx60-r20

layered

-s50-sx200

The finish carries the same two dials for the whole composite: ---s/---sx/---sy resize it and ---mx/---my move it, both wrapping the outline and shadow so a finished mark travels as one piece. ---center measures the ink the mark actually leaves standing and re-centers that, so a composition assembled off-center needs no hand-tuning of every layer — and because a knockout is the tool that carves ink rather than ink itself, a carved mark centers on what survives the carve, not on the shape that is no longer all there:

plain

no finish

inset

---s70

nudged

---mx14--my-14

squat

---sy70

corner

off-center

centered

---center

bitten

carved, off-center

seated

carved + ---center

A mark that carries its own palette

A palette reaches a mark from two places, and the narrower one wins. colors sets it on the control; a ---ps-{palette} finish pins it in the name, so the mark is self-contained and colors the same wherever it lands. The flag validates against the shipped palette list, so every name below works with no parser change. All six icons sit under the same colors="accents" control:

chip

no ps · inherits accents

chip

---ps-skittles

chip

---ps-thermal

chip

---ps-statuses

chip

---ps-severity

chip

---ps-intensity

A pc override still beats the pinned palette for the one slot it names, so a mark can pin the crayon box and then force a single slot to a theme token:

heat

---ps-thermal

heat

---ps-thermal--pc1-accent

swatch

---ps-skittles

swatch

---ps-skittles--pc5-fg

Text marks

The letter primitive typesets a glyph as a mark (--letter-A), so a monogram or initial composes like any other primitive: colored, framed, outlined, scaled. It draws in an indexed font slot (-f0 sans, -f1 display, -f2 mono), and a ---f finish swaps a slot for another theme font. A named web font renders only where it's loaded; theme-token fonts always work.

letter AA

letter A

display QQ

display Q

mono 77

mono 7

badged AA

badged A

framed NN

framed N

outlined RR

outlined R

Web fonts, on request

A ---f finish can name a web font (---f1-lobster). The engine gates the family on its character set, which is what keeps an untrusted icon name from smuggling a quote or an angle bracket into the URL it builds. Hand it the Google Fonts list with useGoogleFontCatalogue — as the icon builder does — and it also gets exact: a typo reads as a typo instead of rendering in a silent fallback, and ibm+plex+mono resolves to the real IBM Plex Mono rather than a mis-cased guess that 404s. These marks render in the theme's display font until you load the family.

lobster LL

Lobster

monoton 88

Monoton

bungee BB

Bungee

symbolsN

Noto Sans Symbols

Not loaded

Nothing is fetched until you click. Your browser asks fonts.googleapis.com for the font directly, which tells Google your IP address. An export does not have this problem: embedFontsInSvg bakes the face into the SVG, subsetted to just the glyphs the mark draws, so the file renders correctly on a machine that has never heard of the font.

Sizes

Tones

With no tone an icon inherits the surrounding text color; a tone tints it to a semantic role or named hue.

Spin

The loader glyph with spin is a lightweight busy indicator.

In controls

Transport controls

The media-transport glyphs (play, pause, stop, skip-back, skip-forward) drop into a run bar or a player the same way any glyph does, so a run / execute / start-stop control renders in one voice.

Inline

Press the to search, then to confirm or to dismiss.

Icon renders one glyph from a small functional set (chevrons, arrows, close, check, the status marks, a spinner, the menu dots, and the media-transport family: play, pause, stop, skip-forward, skip-back) as inline SVG. It carries no color of its own: the glyph is drawn in currentColor, so it inherits the text color around it and matches the derived theme with nothing to wire.

It sizes off the surrounding type by default, so an icon set beside a word lines up with it; size steps it in fixed em for a standalone glyph. An optional tone tints it to a semantic role or named hue, spin turns it into a loading affordance, and a label promotes it from decorative to a named image for assistive tech. Beyond the lookup, a name can carry a spec: a terse grammar (shield--star-s45-c1) the engine parses into a layered mark and composes on the fly, placing primitives on a grid, sizing (uniformly with s, then stretched per axis by sx/sy layered on top of it), rotating, outlining, or knocking them out, and coloring them from one of the theme's own palettes via colors so a generated mark recolors with the theme (a ---ps-{palette} finish pins the palette in the name instead, so a mark carries its own). The library it draws from is mostly filled art rather than line work — curves and volumes and polygons you stack, so a cylinder capped with a disc is a database and a water level under a wave is the sea — and the finish resizes (---s/---sx/---sy), moves (---mx/---my), and re-centers (---center) the whole composite. A parametric letter primitive typesets a glyph as a mark (--letter-A) in an indexed theme font slot (f0 sans, f1 display, f2 mono) that a ---f finish can swap for another theme font or a named web font. Lookup for the common glyph, generation for everything else, one element for both.

When to use

How this component composes with the rest of the set.

Contribute glyphs with registerIcons({ name: body }), or with { body, viewBox, strokeWidth } when the artwork was drawn somewhere other than the roster's 24x24 grid - the registry fits it the way preserveAspectRatio="xMidYMid meet" would, so a 32-grid or 16-pixel-grid mark registers unedited instead of being re-pathed by hand. A second argument carries set-wide defaults, so a pack drawn entirely at one weight says so once.
Size a glyph with the scale or with --xtyle-icon-size, not with width / height. The mark draws at 1em inside the element, so sizing the box leaves a text-sized glyph floating in a large empty one - which half-works, which is what makes it cost time.
Drop an Icon inside a Button before or after the label for an icon-and-text control, or on its own in an icon-only button.
Set an Icon inline in Text at its default size to sit a glyph on the baseline mid-sentence.
Pair tone with a matching status glyph (success + tone="success") for a colored inline indicator.
Use spin on the loader glyph for a lightweight busy indicator where a full Spinner is too much.

Props

7 props, straight from the manifest.

PropTypeDefaultBindingsDescription
name IconName | string
chevron-up chevron-down chevron-left chevron-right chevron-expand arrow-up arrow-down arrow-left arrow-right close check plus minus menu more-vertical more-horizontal search info warning error success external-link maximize dot loader play pause stop skip-forward skip-back volume volume-off gear folder pencil trash eye copy palette bookmark download
html svelte astro
A functional-set glyph name, or a generated-mark spec (a name carrying a -- grammar, e.g. crest--shield-c1--star-s45-cf). A plain name that is neither renders a visible placeholder box.
colors Palette
accents skittles statuses thermal severity intensity
accents
html svelte astro
For a generated mark, the palette its c1c9 color slots draw from (accents, skittles, statuses, thermal, severity, intensity), so one spec re-skins across palettes. A mark that pins its own palette in its name (a ---ps-{palette} finish) overrides this. Ignored for a functional glyph.
size IconSize
xs sm md lg xl
md
html svelte astro
The glyph size, stepping in em off the surrounding text: xs, sm, md, lg, xl. Omit to match the current text size. The scale shares its floor with Button's, so an xs control can hold an xs glyph. When a layout constraint wants an exact figure rather than a step, set --xtyle-icon-size on the host and it wins over whichever step is named.
tone FullTone
accent neutral danger success warn info accent-2 accent-3 accent-4 red orange yellow green blue purple brown pink cyan gray white black
html svelte astro
Tints the glyph to a semantic role (accent, success, danger, …) or a named hue (red … black). Omit to inherit the surrounding currentColor.
label string
html svelte astro
An accessible name. Set it and the icon is exposed as an image with this name; omit it and the icon is decorative and hidden from assistive tech.
spin boolean false
html svelte astro
Continuously rotates the glyph as a loading affordance. Honors prefers-reduced-motion.
static boolean false
astro
Astro only: emit the resolved light-DOM markup but never load the runtime to hydrate it, for a zero-JS glyph or mark. The Svelte and raw-element paths always upgrade, so they carry no equivalent.

Appearance

Sizes

xs

.xtyle-icon--xs

The floor of the scale, matching an xs Button so the smallest control can hold a correctly-sized glyph.

sm

.xtyle-icon--sm

A compact glyph for dense inline hints.

md

default
.xtyle-icon

The default glyph, matching body text.

lg

.xtyle-icon--lg

A prominent glyph for a featured control.

xl

.xtyle-icon--xl

A large glyph for an empty-state or hero mark.

States

spin

.xtyle-icon--spin

Rotates continuously as a loading affordance; suppressed under reduced-motion.

Anatomy

The named parts that make up the component, with their selectors. This one renders light DOM, so the selector is the handle.

icon

.xtyle-icon

The <svg> glyph, drawn in currentColor on a 24×24 grid.

Tokens & coverage

What the component consumes, checked live against what the algorithm produces.

Success:fully covered 21/21 consumed tokens produced default register: 310 tokens

Live coverage check against the xtyle-default register (derive(xtyleDefault, { anchors })coverComponent(manifest, register)). Every token this component consumes must be a key the algorithm produces.

--accent --accent-2 --accent-3 --accent-4 --black --blue --brown --cyan --danger --gray --green --info --neutral --orange --pink --purple --red --success --warn --white --yellow

Accessibility

Decorative by default: with no label the icon is aria-hidden, so an adjacent text label carries the meaning and the icon is not announced twice.
Set label for a standalone icon that conveys meaning on its own (an icon-only button's glyph); it becomes role="img" with the name.
spin honors prefers-reduced-motion, freezing the glyph for users who ask for less motion.

Code

Glyphs and sizes

A few glyphs from the set, and the size steps.

<xtyle-icon name="search"></xtyle-icon>
<xtyle-icon name="check"></xtyle-icon>
<xtyle-icon name="chevron-right"></xtyle-icon>

<xtyle-icon name="menu" size="sm"></xtyle-icon>
<xtyle-icon name="menu" size="lg"></xtyle-icon>

Toned and spinning

A tone colors the glyph; spin turns the loader into a busy indicator.

<xtyle-icon name="success" tone="success"></xtyle-icon>
<xtyle-icon name="warning" tone="warn"></xtyle-icon>
<xtyle-icon name="error" tone="danger"></xtyle-icon>

<xtyle-icon name="loader" spin label="Loading"></xtyle-icon>

Generated marks

A name carrying a spec is composed on the fly: primitives on a grid, sized / rotated / outlined / knocked out, colored from the theme's series via colors.

<!-- a name carrying a spec is composed, not looked up -->
<xtyle-icon name="crest--shield-c1--star-s45-cf" size="xl"></xtyle-icon>

<!-- a functional glyph rides as a charge by its bare name -->
<xtyle-icon name="check-badge--circle-c3--check-s55-cf" size="xl"></xtyle-icon>

<!-- a negative-space die: three pips knocked out of a rounded face -->
<xtyle-icon name="dice-3--square3-c1--dot-p7-s14-ko--dot-s14-ko--dot-p3-s14-ko" size="xl"></xtyle-icon>

<!-- the same spec re-skinned by scheme -->
<xtyle-icon name="chip--hex-c1--dot-s30-c2" colors="statuses" size="xl"></xtyle-icon>

The primitive library

The library is mostly filled art rather than line work: solids you stack into a mark. Curves and nature (wave, water, swish, blob, lens, leaf, cloud, mountain, sun, flame, drop), volume (disc, cylinder, cone, half, quarter, wedge, oval, pill, egg, arch), polygons (pentagon, octagon, trapezoid, ramp, squircle, gem), markers (banner, tag, bubble, chevron, arrow), and stars (star4 / star6 / star8, burst, seal). cylinder is the square-edged oval a database icon is made of: stack a disc cap on one and you have the drum.

<!-- a database: the square-edged oval, capped with flat discs -->
<xtyle-icon name="database--cylinder-c1--disc-y-25-c3--disc-y-2-c2-a70" size="xl"></xtyle-icon>

<!-- water: a wavy fill level, clipped to a circle -->
<xtyle-icon name="sea--circle-cb--water-c1--circle-i-ko" size="xl"></xtyle-icon>

<!-- filled art stacks; there is no line work to line up -->
<xtyle-icon name="weather--sun-c4-x-18-y-16-s70--cloud-cf-s90-y8" size="xl"></xtyle-icon>
<xtyle-icon name="spark--seal-c2--star4-s45-cf" size="xl"></xtyle-icon>

Sizing and moving: the layer and the whole mark

A layer sizes with s and moves with x/y; sx/sy then stretch that result on one axis, layering on s rather than replacing it, so one circle covers every ellipse ratio. The finish carries the same dials for the whole composite — ---s/---sx/---sy resize it and ---mx/---my move it, both wrapping the outline and shadow so a finished mark travels as one piece. ---center re-centers the mark on the ink it actually leaves standing: a knockout is the tool that carves ink rather than ink itself, so a carved mark seats on what survives the carve. The engine can do this anywhere because it measures the primitive geometry statically rather than asking a DOM.

<!-- sx / sy stretch one layer out of its authored proportion, on top of s -->
<xtyle-icon name="wide--circle-c2-sx150-sy60" size="xl"></xtyle-icon>
<xtyle-icon name="layered--circle-c2-s50-sx200" size="xl"></xtyle-icon>

<!-- the finish resizes and moves the WHOLE composite, outline and shadow with it -->
<xtyle-icon name="inset--square1-c1--star-s50-cf---s70" size="xl"></xtyle-icon>
<xtyle-icon name="nudged--square1-c1--star-s50-cf---mx14--my-14" size="xl"></xtyle-icon>

<!-- ---center re-centers on the ink left standing, so a carve moves where the mark sits -->
<xtyle-icon name="centered--star-p1-s40-c1---center" size="xl"></xtyle-icon>
<xtyle-icon name="seated--circle-c1--circle-x50-ko---center" size="xl"></xtyle-icon>

A mark that carries its own palette

The palette reaches a mark from two places and the narrower one wins: colors sets it on the control, a ---ps-{palette} finish pins it in the name. A pinned mark is self-contained, so it colors the same wherever it lands; a pc override still beats the pinned palette for the slot it names.

<!-- the control sets the palette: both marks read the same scheme -->
<xtyle-icon name="chip--hex-c1--dot-s30-c2" colors="skittles" size="xl"></xtyle-icon>

<!-- a ---ps finish pins the palette in the NAME, so it wins over colors="…" -->
<xtyle-icon name="chip--hex-c1--dot-s30-c2---ps-thermal" colors="skittles" size="xl"></xtyle-icon>

<!-- a self-contained mark colors the same wherever it lands, with no control to wire -->
<xtyle-icon name="heat--ring-c1--dot-s28-c9---ps-thermal" size="xl"></xtyle-icon>

<!-- a pc override still beats the pinned scheme, for the one slot it names -->
<xtyle-icon name="chip--hex-c1--dot-s30-c2---ps-skittles--pc1-accent" size="xl"></xtyle-icon>

Text marks

The letter primitive typesets a glyph as a mark, drawn in an indexed theme font slot (f0 sans, f1 display, f2 mono); a ---f finish swaps a slot for another theme font or a named web font. A named family is gated on its character set (letters, digits, spaces, hyphens, under a length cap), which is what keeps an untrusted icon name from carrying a quote or an angle bracket into the url() and the href the family lands in; iconFontImports then hands back ready-made loading code. Install the Google Fonts list with useGoogleFontCatalogue — as xtyle.dev's icon builder does — and the same calls sharpen: canonical casing (ibm+plex+mono becomes the real IBM Plex Mono, not the mis-cased guess that 404s), and an honest "no such family" with a did-you-mean instead of a snippet that quietly loads nothing. loadGoogleFont loads a family for preview, and embedFontsInSvg bakes it into an export (subsetted to the glyphs drawn), so the mark renders in the right face on a machine that has never heard of the font. Both reach Google only when called, since the fetch discloses the visitor's IP address.

<!-- the letter primitive typesets a glyph; -f1 draws it in the display font -->
<xtyle-icon name="initial--letter-A" size="xl"></xtyle-icon>
<xtyle-icon name="mono--letter-7-f2" size="xl"></xtyle-icon>

<!-- a monogram badged, colored, and scaled like any primitive -->
<xtyle-icon name="badge--circle-c1--letter-A-cb-s55" size="xl"></xtyle-icon>

<!-- a ---f finish swaps a slot to a named web font; the mark declares it but does not carry it -->
<xtyle-icon name="mark--letter-Q-f1---f1-noto+sans+symbols" size="xl"></xtyle-icon>

<!-- load it with the snippet iconFontImports() hands you rather than a hand-built URL -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Noto+Sans+Symbols&display=swap">