fix(configurator): truthful live previews, reorganized typography, usable token rows - #632
Conversation
…abs incl. display Sidebar previews computed their CSS from parseNum(override) with hardcoded fallbacks, so they broke whenever a control stored a var() reference (the default mode for scale-backed dropdowns) and showed panel guesses instead of framework defaults. The panel document already loads the framework token CSS and receives live override injection, so previews now reference the live tokens directly and can never disagree with reality: - Borders: media radius (also fixes its wrong "radius-m" default — the framework default is 0), focus ring, radius steps, border width bars, border sample. - Effects: blur, opacity rows, scrollbar strip. - Misc: touch target, focus ring. - Macros: scrim, surface-bg composite, flow gap. Typography — one system for text and display, as requested: - Per-type styles now covers Body, H1–H6 AND D·S/D·M/D·L with the same tabs and controls; display tabs edit --sf-display-*-line-height and the shared --sf-font-weight-display, with Size pointing at the modular-scale controls. - The live sample and the Scale preview render from the real tokens (var()) with DOM-measured size labels (new TypeSpecimenRow) — no caps, no approximations. - Display type section slims down to scale-level controls; per-size sliders and the duplicate Display weight grid moved into the tabs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013BRVgKfEYocPCHz9KU96FN
…ections Drop the per-size display tabs (unnecessary) and the old scattered section split (Body text / Font weight scale / Display type / Per-type / Modular scale / Scale preview / Advanced typography). All controls are re-sorted by concern into seven complete sections: 1. Fonts — families, Google loader, OpenType axes (numeric, optical sizing, features, variation). 2. Fluid scale — text and display generators with IDENTICAL controls: shared viewport range, each with the same base-size ClampField + modular-ratio block (display's ratio edits the same shared --sf-text-ratio-* tokens the framework derives display sizes from) + scale multiplier, plus the live DOM-measured ramp and the Advanced power knobs. 3. Line heights — leading scale, taper, display line-heights. 4. Letter spacing — the tracking scale. 5. Font weights — the base weight scale and role weights (heading, display, strong, interactive) in one place, all through the shared weight grid. 6. Elements — body + h1–h6 editor (size / line height / weight / tracking / max width) with the live token-driven sample, plus body & prose details (emphasis, code size, wraps, external-link marker/label). 7. Line lengths — per-step max-widths. No tokens gained or lost — every previously editable control is still present, just organized. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013BRVgKfEYocPCHz9KU96FN
…section
Both generators used the same "Base size & ratio" / "Scale multiplier" labels,
distinguished only by a small group header above them — ambiguous when
scanning and in ClampField's title-derived aria-labels. Labels now carry their
own context ("Text base size & ratio", "Display scale multiplier", …), and the
now-redundant Text/Display mini-headers are dropped. Verified this was the
only duplicated control label across all panels.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013BRVgKfEYocPCHz9KU96FN
…dth value The All-tokens / generic token rows squeezed the value control into a narrow right-aligned column (w-28), clipping longer values (clamp()/var() expressions). Restack each row vertically: token name (+ override dot, colour swatch, reset), description, then a full-width value control — the scale dropdown, the text editor and the value display all span the row. The reset affordance becomes a labelled "reset" button consistent with every other control; tests updated accordingly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013BRVgKfEYocPCHz9KU96FN
…idden Nine reset affordances (SliderRow, TokenRow, PowerKnobRow, weight grids, tracking rows, Motion/Misc/Themes inline resets) used a hide-until-hover pattern (sm:opacity-0 + group-hover reveal), so on desktop they were invisible until the exact row was hovered — users reported reset "missing". A reset button only renders when the token IS overridden, so it carries information and should always be visible; drop the opacity dance everywhere. SliderRow's </> raw-CSS toggle loses its hover-hide too — same discoverability problem, same fix. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013BRVgKfEYocPCHz9KU96FN
|
Warning Review limit reached
Next review available in: 47 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughThe configurator updates typography editing, token row layout, live CSS-variable previews, and control visibility styles. A measured ChangesConfigurator UI updates
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile SummaryThis PR fixes four user-reported configurator issues from #631: sidebar previews that broke or lied when a
Confidence Score: 4/5Safe to merge — all changes are confined to the configurator UI with no framework token or CSS source modifications. The live-preview and reset-visibility fixes are mechanical and well-tested. TypographyPanel has two small gaps: the max-width token written by the new Max width input is not tracked by the tab dot indicator or the bulk-reset button, and a required tokens prop remains in the type annotation without being used — both worth tidying but neither breaks existing flows. configurator/src/components/panels/TypographyPanel.svelte — the Elements section reset logic and tab indicator both miss the max-width token, and the unused tokens prop should be cleaned up. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[User adjusts token control] --> B{Control type}
B -->|SliderRow / PowerKnobRow| C[onSet / onChange fires]
B -->|TokenRow scale picker| D[onSet fires with var ref]
B -->|TokenRow text input| E[onBlur to onSet or onReset]
C --> F[App stores override in overrides map]
D --> F
E --> F
F --> G[Panel injects CSS override]
G --> H[Preview element reads var token with fallback]
H --> I{Preview type}
I -->|TypeSpecimenRow| J[ResizeObserver measures DOM font-size]
J --> K[Displays real rem value]
I -->|Sidebar swatch or border or shadow| L[CSS var resolves in live document]
L --> M[Preview reflects actual rendered output]
F --> N{Token overridden?}
N -->|Yes| O[Reset button visible unconditionally]
N -->|No| P[Reset button absent]
O --> Q[User clicks reset, override cleared]
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A[User adjusts token control] --> B{Control type}
B -->|SliderRow / PowerKnobRow| C[onSet / onChange fires]
B -->|TokenRow scale picker| D[onSet fires with var ref]
B -->|TokenRow text input| E[onBlur to onSet or onReset]
C --> F[App stores override in overrides map]
D --> F
E --> F
F --> G[Panel injects CSS override]
G --> H[Preview element reads var token with fallback]
H --> I{Preview type}
I -->|TypeSpecimenRow| J[ResizeObserver measures DOM font-size]
J --> K[Displays real rem value]
I -->|Sidebar swatch or border or shadow| L[CSS var resolves in live document]
L --> M[Preview reflects actual rendered output]
F --> N{Token overridden?}
N -->|Yes| O[Reset button visible unconditionally]
N -->|No| P[Reset button absent]
O --> Q[User clicks reset, override cleared]
|
| @@ -488,370 +732,102 @@ | |||
| >reset {activeLevel.label}</button> | |||
| {/if} | |||
There was a problem hiding this comment.
Max-width overrides invisible to reset button and tab indicator
The "Max width" input (lines 706–720) writes --sf-h*-max-width overrides, but neither the per-level tab indicator dot (line 608) nor the "reset {label}" bulk-reset button (lines 724–733) check for that token. Concretely: if a user sets only a max-width on H1, the tab dot won't appear, the reset button won't render, and even when other H1 overrides are also active and the reset button is shown, clicking it leaves --sf-h1-max-width still set.
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@configurator/src/components/inputs/TokenRow.svelte`:
- Around line 64-70: Add a token-specific accessible label to the reset button
rendered by TokenRow’s isOverridden block, using the existing shortName value so
it identifies which token on the row will be reset while preserving the visible
“reset” text and onReset behavior.
In `@configurator/src/components/inputs/TypeSpecimenRow.svelte`:
- Around line 16-21: Update the rem conversion in TypeSpecimenRow.svelte to
divide by the computed font size of document.documentElement rather than the
hardcoded 16, while preserving the existing measured font-size behavior from the
$effect and measure function.
In `@configurator/src/components/panels/TypographyPanel.svelte`:
- Around line 366-397: Associate each text input in TypographyPanel, including
the “Font features,” “Variation,” “External marker,” and “External label”
inputs, with an accessible name. Use unique matching id and label for attributes
or equivalent aria-label attributes, while preserving the existing input
behavior and reset controls.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: ccbc7336-543e-452f-affb-41603f0d4f02
📒 Files selected for processing (12)
configurator/src/components/inputs/PowerKnobRow.svelteconfigurator/src/components/inputs/SliderRow.svelteconfigurator/src/components/inputs/TokenRow.svelteconfigurator/src/components/inputs/TypeSpecimenRow.svelteconfigurator/src/components/panels/BordersPanel.svelteconfigurator/src/components/panels/EffectsPanel.svelteconfigurator/src/components/panels/MacrosPanel.svelteconfigurator/src/components/panels/MiscPanel.svelteconfigurator/src/components/panels/MotionPanel.svelteconfigurator/src/components/panels/ThemesPanel.svelteconfigurator/src/components/panels/TypographyPanel.svelteconfigurator/tests-components/token-editing.test.js
Greptile:
- Elements section: the per-level tab dot and the "reset {label}" bulk reset
now track --sf-h{n}-max-width alongside size/line-height/weight/tracking,
so a max-width-only override is indicated and actually cleared.
- Drop the required-but-unused tokens prop (and its type import) from
TypographyPanel — the panel builds its type data statically.
CodeRabbit:
- TokenRow reset gets a token-specific aria-label (`Reset {shortName}`).
- TypeSpecimenRow converts px→rem using the document root's computed
font-size instead of a hardcoded 16.
- Every plain text input in TypographyPanel (font features, variation, Google
font, external link marker/label, per-level and per-step max-widths) gets an
accessible name.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013BRVgKfEYocPCHz9KU96FN
The previous commit removed TypographyPanel's unused tokens prop but left the caller passing it, which svelte-check (CI's Configurator tests gate) rejects. Verified locally with npm run check: 0 errors. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013BRVgKfEYocPCHz9KU96FN
Summary
Follow-up to #631 addressing user-reported issues in the configurator: broken/lying sidebar previews, an inconsistent typography category, clipped token-value inputs, and invisible reset buttons.
var()previews everywhere. Sidebar previews computed CSS fromparseNum(override)with hardcoded fallbacks, so they broke whenever a control stored avar()reference (the default for scale-backed dropdowns — e.g. Global media radius showed nothing when pickingradius-xl) and showed panel guesses instead of framework defaults. The panel document already loads the framework token CSS plus live override injection, so previews now reference live tokens directly (Borders, Effects, Misc, Macros). Also fixes media radius advertisingradius-mas its default when the framework default is0.--sf-text-ratio-*tokens + scale multiplier), a live DOM-measured ramp (TypeSpecimenRow), and unique self-describing labels ("Text scale multiplier" vs "Display scale multiplier"). Per-size display tabs were dropped as unnecessary; no token gained or lost an editor.clamp()/var()values are no longer clipped by the old narrow right-aligned field.sm:opacity-0+ group-hover) and looked missing on desktop; a reset only renders when a token is overridden, so it now shows unconditionally (SliderRow's</>toggle likewise).Type
Checklist
feat:,fix:,docs:, …) — enforced by commitlintnpm run lint:csspasses (stylelint) — no CSS source touched (configurator-only)npm run buildrebuildsdist/(bundles are git-ignored; CI rebuilds and stamps headers)npm testpasses (unit + Playwright e2e) — configurator suite 189/189, plus browser smoke of every changed panelnpm run check:version) — n/a, no version files touchedcore/*.css,optional/*.css, ortoken-registry.jsonchanged (npm run check:llm-guide) — n/a, framework untouchednpm run check:macros,check:registry,audit:check) — n/aCHANGELOG.mdupdated under## [Unreleased](for user-facing changes) — configurator-internal UI changesNotes
Browser-verified with Playwright against the built app: media-radius preview reacts to a
var()pick (0px → 16px onradius-xl), both fluid-scale generators render identically with unique labels, the scale ramp shows real DOM-measured sizes, the full-width token editor fits a 312-charclamp()expression, and reset buttons haveopacity: 1without hovering. Two component tests updated for the relabelled reset affordance (✕→reset).🤖 Generated with Claude Code
https://claude.ai/code/session_013BRVgKfEYocPCHz9KU96FN
Generated by Claude Code
Summary by CodeRabbit
New Features
Improvements