feat(studio+components): typed enum fields, palette-prefilled colors, string lists - #85
Conversation
…list rows - closed-set stringly-typed fields become real Rust enums (stepper orientation, chart funnel direction, cursor style and path easing — serde values identical; unknown strings now fail the typed parse as blocking validate errors instead of silent fallbacks; path_easing loses its silent ease_in_out catch-all, the one behavior break, no repo example affected; cursor_style flagged as unconsumed by the painter). The schema-driven inspector renders exact-variant selects automatically - chart::DEFAULT_PALETTE goes pub; an empty chart colors list shows an 'engine palette' hint and + Add color prefills the 8 colors the canvas actually renders (pure palette_prefill map, extensible) - StringList kind for non-color string arrays (axes, categories) with per-entry inputs; third list control triggers the rule of three: generic ListRows shell (render-prop items) now backs ColorRows, NumberList and StringList; radar_data joins the structured-data exclusions
Diagnosis of 'cannot modify the chart color' on the round-6 build: - data path exonerated by a new integration test that drives the exact button writes through apply_optimistic on the real promo scenario (nested scene->div->card->chart pointer) and asserts red pixels appear in the re-rendered frame - the fragile link was the prefill's on_add callback forwarded through two prop layers; replaced by a pure, tested next_entries_on_add(current, add_value, prefill) consumed directly by ListRows with the palette as data — one code path for all three list kinds, empty-list gating evaluated at click time (immune to panel memoization) - UX trap proven by a dedicated assertion: the prefill write renders a canvas strictly identical to the default palette, so a user who clicks Add sees no change until editing a swatch — hint reinforced to 'engine palette — click + to edit' - NumberList/StringList empty-add covered (exactly one seeded entry, no lost clicks)
LeadcodeDev
commented
Jul 19, 2026
Follow-up commit after live-testing feedback (« je ne peux pas modifier la couleur du graph de gauche »): the data path is pixel-proven innocent (new integration test drives the exact button writes through the optimistic pipeline on the real promo scenario and asserts red pixels in the re-rendered frame). The fragile UI link — the prefill callback forwarded through two prop layers — is replaced by a pure, tested |
- the export status leaves the topbar (its unbounded spans were overlapping the centered title) for a floating toast at the canvas's bottom-right: live progress, success auto-dismissed after ~6s (guarded against a new export starting meanwhile), persistent error with close; remaining topbar center occupants verified bounded (Saving…, ellipsized write_error) - css_effective_default table (each entry sourced: painter, taffy, CSS spec, builder) + per-component typography defaults (text 48 / terminal-codeblock 14, unknown tag stays a placeholder rather than a wrong number) + engine placeholders (auto/none/–) route through css_row_value(raw, tag, prop) -> (shown, is_default): the raw always wins, cleared controls fall back visually to the default state; applied to both curated rows (opacity slider shows 1.0, Position preselects static) and generic registry rows, with the same dimmed default dot as the Properties section
LeadcodeDev
commented
Jul 19, 2026
Round 7 (2 more commits): the export status moves to a bottom-right canvas toast (live progress / auto-dismissed success / persistent error) — its unbounded topbar spans were what overlapped the centered title, and the remaining center occupants are verified bounded. And every CSS control now shows the engine's effective default (sourced table: opacity 1.0, position static, padding 0, per-component font sizes…; placeholders auto/none where no default is displayable) with the same dimmed default marker as Properties — same philosophy as the show_value fix: the inspector can no longer contradict the render. 413 tests green. |
Closes#84 — user iteration round 6 (chart inspector screenshot).
stepper.orientation,chart.direction(funnel),cursor.cursor_style,cursor.path_easingbecome real Rust enums — JSON values identical, the inspector derives exact-variant selects automatically, andvalidatenow rejects invalid values as blocking typed-parse errors (feat(cli): validate rm-* and JSON component attributes at validation time #33 philosophy). Disclosed behavior break:path_easingloses its silent ease-in-out catch-all (exotic values now fail to load — no repo example affected; all three example scenarios re-validated green, including the user's promo drift). Side finding:cursor_styleis declared but unconsumed by the painter — flagged for implement-or-deprecate.chart::DEFAULT_PALETTEexposed; an emptycolorslist shows a dimmed "engine palette" hint and + Add color prefills the 8 palette colors the canvas actually renders, written typed through the optimistic pipeline.axes/categoriesbecome per-entry string-input lists;radar_data(chart data) joins the structured-data exclusions. Third list control → rule of three applied: a genericListRowsshell (render-prop items) now backs ColorRows, NumberList and the new StringList.Tests: 5 new (string-list/exclusion detection, exact palette prefill, exact enum variants, negative unknown-enum parse) + corpus entries for every converted field. 408 total, all green; the three example scenarios validate green.
Verify:
cargo check -p rustmotion-studio✓ ·cargo test --workspace→ 408 passed ✓ ·cargo fmt --check✓ · clippy gated ≤1 ✓ · 3×rustmotion validate✓