Implement fit-mode rendering contract with container sizing and pane re-fit

This commit is contained in:
2026-06-05 10:45:41 +03:00
parent f4253f50ca
commit 411bfbc6c2
13 changed files with 552 additions and 73 deletions
+34 -4
View File
@@ -174,7 +174,7 @@ set to Plex Mono explicitly since it can't read the CSS token.
---
## M2 · Editor robustness
## M2 · Editor robustness ✅ (done)
**Goal:** the editor becomes trustworthy — draft vs published, schema-aware
assistance, and the fit-mode rendering contract.
@@ -185,7 +185,9 @@ assistance, and the fit-mode rendering contract.
Vega-Lite `"container"`), recursing into layered/concat/child specs (spec §04
Rendering Contract, step 2).
- `vega-lite-schema.ts` — provide the Vega-Lite JSON schema for Monaco's
validation/autocomplete (mine vega-editor for sourcing/versioning the schema).
validation/autocomplete. _Delivered early in M1.5 as
`infrastructure/monaco-schema.ts` (bundled schema, offline, `markdownDescription`
hover docs); no further work needed in M2._
**App**
@@ -210,6 +212,30 @@ assistance, and the fit-mode rendering contract.
- Invalid spec shows inline error; autocomplete suggests Vega-Lite properties.
- Each fit mode resizes the chart as specified; choice survives reload.
**Verified:** `typecheck` + `test` (83 passing — `rendering` fit-mode incl.
nested layer/concat/facet specs, `SnippetStore` draft/publish/revert/editorView,
`settings-store` `previewFitMode` round-trip) + `build` (PWA, 41 precache
entries) + `eslint` clean. Implementation notes: editing now writes the
**draft** only (`commitDraft` no longer touches `spec`); `publish`/`revert` live
in `SnippetStore`, with a `bufferEpoch` counter so programmatic buffer reloads
(select/create/revert) refresh Monaco without fighting the cursor mid-typing.
The Draft/Published view is a store-level `editorView`; the published view is
read-only and the preview renders whichever version is shown (`selectShownText`).
The editor (§03E) and preview (§04) share one render error via a small
`PreviewStore`. `previewFitMode` was pulled into `AppStore` + the settings
adapter, hydrated/persisted by a new `orchestration/preferences.ts` mirroring the
theme slice. Publish/Revert **success toasts** stay deferred to M6 (TODO
breadcrumbs at the call sites), matching the existing delete-toast convention.
Fit-mode rendering needed a layout fix: vega-embed brands the embed host with its
own `.vega-embed { display: inline-block }` (injected at runtime, wins the
cascade), which shrink-wrapped the host so `width: "container"` collapsed (Height
survived only via the old `min-height: 100%`). Fix: embed into a static-class
inner host (React never reconciles its className, so Vega's runtime classes
survive) inside a React-owned frame that carries the fit-sizing class via
two-class selectors that out-specify `.vega-embed`. All four fit modes
user-verified in the running app.
---
## M3 · Datasets
@@ -329,8 +355,12 @@ the reference.
**Goal:** the workspace feels finished and meets §10.
- **Panes:** drag-resize handles with min widths; per-pane show/hide toggle strip;
widths + visibility persist (§01A, §09D).
- **Panes:** ~~drag-resize handles with min widths; widths persist~~ ✅ **pulled
forward after M2** (coupled to the preview's container sizing — see
[arch 05 §8](architecture/05-rendering-theming-preview.md)). Side panes carry
remembered widths, the editor flexes between them, widths persist to
`astrolabe:ux-prefs`. **Remaining:** per-pane show/hide **toggle strip** +
visibility persist + proportional redistribution on hide (§01A, §09D).
- **Routing:** URL hash view-state (`#snippet-<id>`, `#datasets/...`) with Back/Forward;
restore on load (§01E). _(see [Architecture 04 · Routing & Events](architecture/04-routing-and-events.md))_
- **Shortcuts:** Cmd/Ctrl+Shift+N / +K / +S / +, / Esc via a single key router