Add ADR for component editor configuration overhaul - #146
Merged
jordanwallwork merged 7 commits intoJul 20, 2026
Conversation
Capture the decisions from the editor review and design interview: capability-driven property groups, schema normalization without migration, unset-first nullable properties, edit-session undo batching, unit-aware length inputs, dual config-panel prototypes, mobile bottom sheet, and phased canvas/workflow features. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GTSHG3qL5K7qrWx4GXPLkn
Implements Phase 1 of ADR-0001 — invisible foundations for the component editor configuration overhaul, with no intended UI redesign. D3 Schema normalization: one Border and one Background model across all element types. Removed ShapeBorder (shapes use the unified border) and text's flat backgroundColor (text uses Background). Renamed grid per-cell styling to cellBackground/cellBorder so it can't be confused with the grid element's own background/border. No migration (pre-release). D4 Unset-first defaults: new effectiveDefaults.ts is the single source of truth for what an unset property means; the element factory (and the AddElementPopover path) stop stamping cosmetic defaults, so new elements are nearly-empty objects. Renderers resolve unset values through the module instead of scattered `|| fallback`. D7 Store edit-sessions: templateStore.updateElement takes a session key; consecutive same-key updates collapse into one undo step, sealed on blur/pointer-up, key change, selection change, or any structural op. The bespoke saveToHistory/updateElementWithoutHistory workarounds for text content and drag/resize/rotation are removed; updates stay live so the canvas previews continuously. D8 Unit-aware lengths: DimensionInput accepts number|string directly (number = px), and gap, font size, and shape/grid border widths join the already unit-aware position/padding/border controls. Canvas drag/resize preserve an element's existing unit (mm stays mm) via writeBackInExistingUnit. Adds tests at the store public-API seam (edit-sessions, move/duplicate), the effective-defaults resolver, and the unit write-back helper. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RmQAu3SECs47Yza2UYyyWR
DimensionInput now accepts number|string directly, so the per-control number->px string adapters in PositionControls, PaddingControls, BorderConfig, and BaseElementConfig are dead weight. Pass stored length values straight through; the object-radius guards are preserved. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RmQAu3SECs47Yza2UYyyWR
Introduces a strongly-typed Dimension working type ({ unit, value } with
px/mm/percent constructors) and consolidates the length parsing/formatting
that was smeared across utils.ts, DimensionInput, and writeBackInExistingUnit
into one pure, well-tested module (dimension.ts).
Storage stays number|string (the serialized convention is unchanged): the
module parses at the boundary (toDimension) and serializes back (toStored),
so Dimension is a domain type, not a schema change. dimensionValue /
dimensionToPx / writeBackInExistingUnit are reimplemented on top of it with
their existing contracts and tests intact.
Two intentional improvements fall out of the seam:
- px canonicalizes to a plain number on serialize (DimensionInput no longer
emits "10px" strings; onchange widened to number|string|undefined).
- toPx requires an explicit reference for %, so percentage->px can't do
silent wrong math.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RmQAu3SECs47Yza2UYyyWR
Implements Phase 2 of ADR-0001: the config panel is now driven by a capability registry, with both UX prototypes coexisting behind a dev toggle for the owner to evaluate (D5 decision gate — neither deleted). Capability registry (capabilities.ts): declarative element-type -> property group matrix (iterator = identity only). Group model (groupModel.ts): readShared/MIXED, fieldState, set-indicator + summary helpers. All pure and tested. Shared group controls (_components/config-groups/): Identity, Position, Size, Layout, Typography, Background, Border, Effects — each rendering only the sub-controls meaningful for the element type, with unset placeholders (from effectiveDefaults), a reset (x) to clear to undefined, and Mixed-value plumbing (dormant until Phase 3 multi-select). Type-specific pinned fields per element type preserve merge fields, font tracking, markdown, conditional visibility. Previously render-only properties now have editing UI (D3): opacity slider and a multi-shadow list editor (Effects); background image with URL/filename/merge-field source + size/repeat/position (Background); margin and overflow (Layout); z-index and rotation (Position); min/max width/height (Size). Two prototypes behind a dev toggle (?panel=a|b or header switch): AccordionPanel (collapsible groups, pinned identity/type-specific, set-dot + summary headers, remembered open state) and TabRailPanel (vertical glyph tab rail, per-tab set dots, remembered active tab). GroupConfigHost binds both to the store with edit-sessions and read-only guards; empty state when nothing selected. Mobile: BottomSheet with peek/half/full snap points hosts the panel so the canvas stays visible; structure tree stays a drawer. Component-test infra: @testing-library/svelte + jsdom (per-file docblock; node stays default), $app mocks. Adds 52 tests (pure + component). Old per-type configuration components remain on disk pending the owner's prototype decision and cleanup. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RmQAu3SECs47Yza2UYyyWR
Adds a third panel prototype behind the dev toggle, refining Variant B per owner feedback: the vertical tab rail is now sticky and all granted group sections render in one long scrollable list. The active tab tracks which section is in view (IntersectionObserver scroll-spy) and clicking a tab scrolls to its section. Selectable via ?panel=c or the C header button. The rail markup mirrors Variant B (already covered by tests); the scroll-spy depends on a real layout engine + IntersectionObserver, so it is validated by live evaluation rather than a jsdom unit test. Guarded so the component degrades gracefully where IntersectionObserver is unavailable. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RmQAu3SECs47Yza2UYyyWR
D5 decision gate resolved: the owner chose Variant A (collapsible accordion groups). Removes the two losing prototypes (Variant B tab rail, Variant C scroll-spy rail) and the dev toggle; GroupConfigHost now renders the accordion directly. panelPrefs drops the variant/active-tab machinery, keeping only the remembered accordion open-state. Also deletes the now-unused per-type configuration components (Container/Text/Image/Shape/Grid/Iterator/BaseElementConfig) superseded by the capability-driven group controls. ComponentConfig (root/component settings) and PlaceholderModal (used by the new image type-specific fields) are retained. Records the decision in ADR-0001. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RmQAu3SECs47Yza2UYyyWR
|
This was referenced Jul 19, 2026
Closed
Editor overhaul 10: Panel prototype A — collapsible groups with set-indicators + variant toggle
#136
Closed
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Capture the decisions from the editor review and design interview:
capability-driven property groups, schema normalization without migration,
unset-first nullable properties, edit-session undo batching, unit-aware
length inputs, dual config-panel prototypes, mobile bottom sheet, and
phased canvas/workflow features.
Co-Authored-By: Claude Fable 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01GTSHG3qL5K7qrWx4GXPLkn