Skip to content

0010 Components, versions, variants and style templates

  • Status: accepted (2026-10-29)
  • Components. Every element type is a component (@astrolabe/components, ComponentManifest, ComponentDefinition), graded or not, so blocks such as images and callouts fit the same model. Tags stay astl-*. The built-ins are listed once, in definitions.ts, elements.ts, editors.ts and manifests.ts.
  • Versions. manifest.version is the element format version, written as v in every view. A breaking change bumps it and adds ComponentDefinition.migrations[n] (source n to n + 1); players keep rendering every older view version, because stored views are immutable.
  • Variants. manifest.variants { default, values } (or null) and the public variant attribute derived from it (variantAttribute). A variant changes presentation and student-side behaviour only (a resizable gap, a select with a search box), never grading: every variant of a source grades the same. The engine validates the value like any enum, elements render it, the authoring kit offers it. Adding a variant is not breaking; removing one or changing the default is.
  • Style templates. StyleTemplate (core style.ts): a named, versioned look made of token overrides (all themes, then light and dark) and ::part() declarations per component tag. Hosts register templates (trusted, like their own CSS); exercises refer to them by name with style-template on <astl-doc> or on a component. The closest wins: component, then document, then the player's default. Templates never apply in the hc theme or under forced colours, and built-in templates are contrast-checked in light and dark.
  • Author-written CSS inside exercises stays out until there is a CSS sanitiser.

A new built-in touches its folder and four list lines. Looks are chosen per exercise or per component without forking components, and accessibility themes always win. Templates cannot restyle internals that a component does not expose as a part.

  • Amended 2026-10-29: the built-in looks are playful and notebook next to the default look (no template); calm is dropped, and elements.ts lists lazy elements (0011, Looks).