Skip to main content
xriptxr

Theme Card

Info:Content
20

A preview of a theme, drawn as a small fake of a themed UI.

theme card preview thumbnail fake algorithm invocation picker palette

Live demo

live · @xtyle/astro

ThemeCard

Every blessed algorithm, previewed

Each card derives its invocation and paints the result rather than applying it. The drawing is a fake: a small simulated interface in the theme's own colors, which reads a palette faster than a list of hex values.

Seeded invocations, and both schemes

A card takes the same invocation inputs as a scope, so an accent seed or a pinned scheme previews exactly what a scope would apply.

Selectable

interactive makes each card a real button that emits select. This is the seam a theme picker sits on.

Chosen: Default

Theme Card derives an invocation exactly the way <xtyle-theme-scope> does — a named algorithm plus its knobs and token constraints — but paints the result instead of applying it, so a theme can be shown without the page having to wear it. What it draws is a fake: a small simulated interface in the theme's own colors, with a surface, a title, a row of swatches, a filled button, and the status dots.

A fake reads a palette faster than a list of hex values does, because it shows the colors doing the job they were derived for. The whole drawing lives in the component's fill, so a mod can redraw the fake into whatever preview an app wants — a different mock, more swatches, a type specimen — without touching the element. interactive turns the card into a real button that emits select, which is what a theme picker listens to; selected marks the current one. A bad invocation shows its error on the card rather than a blank frame.

When to use

How this component composes with the rest of the set.

Lay a grid of them out to let someone choose a theme by eye rather than by name.
Pair with <xtyle-theme-scope>: the card previews an invocation, the scope applies the one that was chosen.
Listen for select to drive the choice; the event carries the card's name, algorithm, and scheme.
Override the component.theme-card fill to redraw the fake when an app wants a different preview.

Props

7 props, straight from the manifest.

PropTypeDefaultBindingsDescription
algorithm string xtyle-default
html svelte astro
The id of the algorithm to invoke.
name string —
html svelte astro
The theme's display name, shown under the preview and used in the accessible name.
scheme "light" | "dark"
light dark
—
html svelte astro
Pins the previewed scheme, re-deriving inverted when the algorithm's native mode is the other one.
knobs Knobs —
html svelte astro
The algorithm's own dials, as an object in the framework bindings and JSON in the HTML attribute.
constraints Constraints —
html svelte astro
Direct token overrides applied over the derivation.
interactive boolean false
html svelte astro
Render as a button that emits select when chosen.
selected boolean false
html svelte astro
Mark this card as the chosen one; sets aria-pressed on the interactive card.

Events

What the component emits, and what rides along on event.detail. The name in the first column is the one addEventListener takes.

EventDetailBindingsDescription
select —
html svelte astro
The card was activated.
xtyle:theme-card { theme }
html astro
The card's theme was chosen, carrying the whole invocation.

Appearance

States

interactive

.xtyle-theme-card--interactive

The card is a button and can be chosen.

selected

.xtyle-theme-card--selected

The card is the currently chosen theme.

error

.xtyle-theme-card--error

The invocation could not be derived; the card shows why instead of a blank frame.

Anatomy

The named parts that make up the component. Created from script it renders a shadow root, where a ::part() handle is reachable from your own stylesheet and the class beside it is internal. Upgraded over server-rendered markup it renders light DOM, where the class is the handle.

card

Success:::part(card) .xtyle-theme-card

The card itself; a <button> under interactive, a grouped <span> otherwise.

preview

Success:::part(preview) .xtyle-theme-card__preview

The fake: an inline SVG of a themed interface, drawn from the derived register.

name

Success:::part(name) .xtyle-theme-card__name

The theme's display name.

meta

Success:::part(meta) .xtyle-theme-card__meta

The algorithm and the scheme the derivation landed on.

Tokens & coverage

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

Success:fully covered 20/20 consumed tokens produced default register: 311 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 --bg-1 --border-thick --border-thin --danger --duration-fast --ease-standard --fg-0 --fg-2 --font-sans --leading-tight --line --line-2 --radius-md --ring --space-1 --space-2 --text-sm --text-xs --weight-medium

Accessibility

The host's aria-label / aria-labelledby names the inner role="group" card, ahead of the component's own naming; aria-labelledby ids are read from the host's own tree.
Under forced-colors: active a selected card draws a Highlight outline, since the mode forces its accent border to the same color as every other card's.
Under interactive the card is a real <button> with aria-pressed, so it is reachable, announced, and operable from the keyboard.
The fake is decorative (aria-hidden); the card's accessible name carries the theme's name, algorithm, and scheme instead.
A static card is a labelled group rather than a control, so it is never a focus stop that does nothing.
The focus ring is the shared --ring token, consistent with every other control.

Code

Previews, a seeded invocation, and a selectable row

Cards previewing the blessed algorithms, one seeded and pinned light, and an interactive row that reports what was chosen.

<!-- A preview of an algorithm's default theme -->
<xtyle-theme-card algorithm="xtyle-quiet" name="Quiet"></xtyle-theme-card>

<!-- A seeded invocation, pinned light -->
<xtyle-theme-card
	name="Grape"
	scheme="light"
	constraints='{"--accent":"#7c5cff"}'
></xtyle-theme-card>

<!-- Selectable: emits `select` for a picker to listen to -->
<xtyle-theme-card algorithm="xtyle-loud" name="Loud" interactive selected></xtyle-theme-card>