Theme Builder: accordion panels across the full config surface, vertical-tab nav, reflective gallery

This commit is contained in:
2026-06-21 17:14:58 +03:00
parent 318a0919c6
commit d76a7a5014
24 changed files with 2420 additions and 845 deletions
@@ -303,13 +303,19 @@ width rather than a variable font's possibly-condensed default instance.
### Structured controls
The builder's panels — Color, Type, Layout, Axes & grid, Legend
(`ColorControls` + `TypeControls`/`LayoutControls`/`AxesControls`/`LegendControls`
on the shared `ThemeFields` field primitives) — are accelerators over the same
`draftConfig`: each reads a value and writes one back through
`CustomThemeStore.mutateDraftConfig(fn)` — the single transform path, which
reparses, reformats, and updates `draftConfig` so the JSON editor and gallery
follow (a parse error disables the controls). The pure transforms live in
The builder's panels — Color, Marks, Type, Title, Layout, Axes & grid, Legend,
Headers, Formats — are accelerators over the same `draftConfig`, one panel per
config domain (each an `XxxControls` component on the shared `ThemeFields`
primitives). `ThemeBuilderModal` holds the single `id → label → Panel` registry
(`THEME_TABS`); panels switch via a **vertical tab list** (APG vertical tabs),
and each panel groups its properties into a **single-expand accordion**
(`ThemeFields` `Accordion` — one section open at a time, each with a set-count
badge so customized sections are scannable while collapsed). Each control reads a
value and writes one back through `CustomThemeStore.mutateDraftConfig(fn)` — the
single transform path, which reparses, reformats, and updates `draftConfig` so
the JSON editor and gallery follow (a parse error disables the controls). The raw
JSON below the panels is the full-power escape hatch for the long tail the
structured controls deliberately omit. The pure transforms live in
`core/theme-controls.ts`: immutable config path get/set, leaf coercion, the
named-scheme catalog (`THEME_SCHEMES`), and `schemeColors` (scheme name → hex
swatches, from the `vega-scale` registry — a focused vega sub-package). A color
@@ -339,8 +345,13 @@ reader announces is unambiguous.
`normalizeRangeSchemes` (core) heals the bare form at the render-resolution
points (`chartConfigForSelection`; the builder gallery) for configs authored or
saved before this was enforced.
- **Do** add a `theme-preview-specs.ts` gallery card for any new color family,
so no control ships without a visible mirror.
- **Do** give every control a visible mirror in the `theme-preview-specs.ts`
gallery, and keep those sample specs on **bare marks** (`mark: 'point'`, not
`{ type: 'point', size: 80 }`): a property hard-coded in a spec overrides the
injected config, making the matching control a no-op in the preview. Mark
styling belongs in the config (a theme), never inline in a card. Default chart
size and tooltips are the unavoidable exceptions — fixed-size swatches, and
hover-only respectively.
### Rules