Chart Builder: open a snippet in the builder to edit it in place

This commit is contained in:
2026-06-20 12:36:37 +03:00
parent efb5a9bbe0
commit be8cfc402d
16 changed files with 1046 additions and 14 deletions
@@ -25,6 +25,32 @@
Newest first. The at-a-glance build-order tracker is §4; per-item detail is §3. This log is
the quick "where are we" — read it first.
- **2026-06-18 (3C open-in-builder, edit-in-place)** — **the builder became create-and-revise.**
Core: `parseChartSpec` / `parseChartSpecText` (`chart-builder.ts`) — the strict inverse of
`buildChartSpec`, gated by **re-assemble + canonical deep-compare** (ignoring key order,
`$schema`, the injected `mark.tooltip`), so the gate widens for free as the dialect grows and
never lets the builder overwrite a richer spec. `unescapeVegaField` added beside its escape
twin (`rendering.ts`). Save semantics chosen with the user = **edit in place** (not
always-create): `SnippetStore.replaceSnippetSpec` republishes the built spec into both the
snippet's versions (auto names re-derive like publish; user names kept), and
`ChartBuilderStore` gained `editingSnippetId`/`editingSnippetName` + `openForEdit`/`saveEdits`.
Entry point: an **editor-toolbar** _Open in builder_ action (`SpecEditor`), beside _Extract to
Dataset_, shown only when the published spec round-trips _and_ its dataset exists — **hidden
otherwise** (content-gated, like Extract). The modal's primary becomes **Save changes** with an
"Editing _name_" banner; a dedicated `openChartBuilderForEdit` coordinator opener hydrates
before showing the modal so the registry's default `init` can't clobber it. **Data-model edge
(called out, not a bug):** the builder references a dataset by name, so only dataset-referencing
specs hydrate — inline-data snippets (incl. the onboarding gallery) stay Monaco-only. This
reshapes **3B**: builder-openable starters need a paired dataset, so 3B's shape is decided
_after_ this lands (see §3). Spec §06 gained an _Open in builder_ section. **Placement settled
by council:** an initial library metadata-panel placement (beside Duplicate/Delete) tested
undiscoverable; `/council` (NN/g #6 recognition / #4 consistency; Carbon button usage) put it in
the editor toolbar and settled the hidden-vs-disabled question via the toolbar's own precedent —
**content-gated** actions hide (Extract, Open-in-builder), **state-gated** ones disable (Revert,
Config). Recorded as a contract rule in `architecture/10` §5; the parked `ux-second-pass.md` row
is closed. Verified: typecheck + full tests (1089) + eslint + prettier. **Owed:** a visual/manual
pass on the live edit flow (the toolbar action, the "Editing" banner, Save changes).
- **2026-06-13 (guidance: reason over role, not raw type)** — closed a **false-positive class**
in `builderWarnings` (eng-council + council consult). A histogram (bar, binned-Q X, count Y)
tripped "two measures → scatter" because `isMeasureMapping`/`effectiveType` ignored `bin`.
@@ -599,8 +625,8 @@ Phase 2 2A value-or-field channels (Property model) ✓ done
2B field shelf + in-place type cycling ✓ done (field-first + on-chart shelves)
Phase 3 3D entry points & discoverability ✓ done (2026-06-12)
3A intent-first front door (Tier C) ✓ done (2026-06-13); persistent strip
3B starter examples ← next; pairs with 3C
3C open in builder (strict hydration) ← added 2026-06-11; pairs with 3B
3C open in builder (strict hydration) ✓ done (2026-06-18); edit-in-place
3B starter examples ← next; now hydrates via 3C
Marks +rect (Heatmap) ✓ done (2026-06-13)
Phase 4 (gated) theta/facets/styling-overrides/undo/lookup — decide after Phase 3