Compute modular-scale derived tokens in JS and improve ratio UI - #457
Conversation
Syncs configurator UI fixes that were made in the SLASHED-Plugins repo back to the framework source so they survive future sync-core.mjs runs. Changes ported from plugin commits (c6b0c8a..HEAD in admin-app/src/): - ClampField: redesign modular scale ratio to independent mobile/desktop selectors + always-visible custom inputs; remove shared activeRatioValue and onRatioPreset props - SliderRow: fix raw input clearing while typing; keep raw mode visible while editing; reset on blur when empty instead of on every keystroke - BordersPanel / SpacingPanel / TypographyPanel: drop activeRatioValue + onRatioPreset call-sites after ClampField API change; fix parseFloat returning 0 for falsy values (use explicit isNaN guard) - persistence: fix derived/ov merge order in injectLivePreview so user overrides win; add same-origin guard to wpSave REST URL Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0124dAf4BHiKD1uESapMZdnK
…rder/motion Ports all configurator-side changes from SLASHED-Plugins PR #109 to the framework so they survive future sync-core.mjs runs. persistence.ts — full computeDerivedOverrides() engine (exported): - Adds radius/border/motion derived-token computation alongside existing text/space logic (RADIUS_STEPS, BORDER_WIDTH_STEPS, DURATION_STEPS) - injectLivePreview() now injects derived tokens as unlayered :root CSS so scale knobs are reflected immediately without waiting for a save PreviewPanel.svelte — withDerivedOverrides() applied in all three preview CSS injection paths (buildIframeHTML + both live-update calls) so preview iframes reflect scale knobs immediately App.svelte — untrack() wraps lastSavedOverrides initialiser to avoid spurious dirty-state on mount CommandPalette.svelte — tabindex="-1" on dialog root for keyboard focus ColorInput.svelte — replace autofocus with tick()+bind:this $effect to avoid SSR warnings and race conditions on re-mount SliderRow.svelte — init rawDraft as '' instead of currentRaw to prevent stale value flashing before the sync $effect runs ShadowsPanel.svelte — aria-label on glow toggle button Not ported (plugin-specific): AppOverlay.svelte changes, class-css-generator.php Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0124dAf4BHiKD1uESapMZdnK
|
Warning Review limit reached
Next review available in: 18 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 (11)
✨ 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 |
PR Summary by QodoCompute modular-scale derived tokens in JS and improve ratio UI
AI Description
Diagram
High-Level Assessment
Files changed (11)
|
Code Review by Qodo
Context used✅ Compliance rules (platform):
6 rules 1.
|
- computeDerivedOverrides now accepts { reduceMotion } option; when true,
all --sf-duration-* tokens are skipped so unlayered :root CSS does not
override the framework's @media (prefers-reduced-motion: reduce) rules
that live inside @layer slashed.overrides
- injectLivePreview and PreviewPanel.withDerivedOverrides both read
window.matchMedia("(prefers-reduced-motion: reduce)").matches and pass it
- --sf-radius-pill is now var(--sf-radius-full) instead of a hardcoded 9999px
value, so a fine-tune override on --sf-radius-full propagates correctly
- --sf-radius-outer is now calc(var(--sf-radius-m) + var(--sf-component-pad))
instead of a scale-baked pixel value, mirroring the framework token graph
Co-Authored-By: Claude <noreply@anthropic.com>
Summary
This PR adds server-side computation of modular-scale derived tokens (text sizes, spacing, radius, borders, motion) in JavaScript, injecting them as unlayered CSS to override hardcoded framework defaults. It also refactors the modular-scale ratio UI to support independent mobile/desktop ratios with always-visible custom inputs alongside preset selectors.
Key Changes
Derived Token Computation (
persistence.ts)computeDerivedOverrides()function pre-computes all derived tokens (e.g.,--sf-text-s,--sf-space-l) from source tokens using the samefluidClamp()formula the CSS framework uses:rootCSS, which beats any@layerdeclaration, ensuring accurate live preview even when legacy WP settings emit hardcoded clamp valuesgetNum()(safe number parsing),fmt()(precision formatting),fluidClamp()(mirrors CSS formula)Live Preview & Save Integration
injectLivePreview()now includes derived tokens alongside source tokenswpSave()validates REST URL is same-origin before POST to prevent CSRFPreviewPanel.svelteapplies derived overrides when rendering preview iframesModular-Scale Ratio UI (
ClaimField.svelte)activeRatioValue,onRatioPresetprops)ratioMin) and desktop (ratioMax) each have their own preset dropdown + always-visible custom number inputactiveRatioMin,activeRatioMaxderived values) so each breakpoint highlights independentlySupporting Changes
SliderRow.svelte: Improved raw mode UX — shows raw input when editing even if not a CSS expression; clears override on blur if input is emptyColorInput.svelte: Fixed autofocus usingtick()to ensure DOM is ready before focusTypographyPanel.svelte&SpacingPanel.svelte: RemovedactiveRatioderived value andonRatioPresetcallback; updatedClampFieldprop usageBordersPanel.svelte: FixedparseFloat()fallback to useisNaN()check instead of falsy coercionCommandPalette.svelte: Addedtabindex="-1"to dialog for better accessibilityShadowsPanel.svelte: Added missingaria-labelto glow toggle buttonApp.svelte: Wrapped initiallastSavedOverridesinuntrack()to prevent spurious change detectionImplementation Details
:rootlevel without@layer, ensuring they override any framework defaults or legacy hardcoded values inside@layer slashed.overridesfmt()strips trailing zeros and handles edge cases (empty string, negative zero) to produce clean CSS valuesfluidClamp()applies the scale factor to both min/max bounds before computing the clamp, matching the framework's CSS formula exactlyhttps://claude.ai/code/session_0124dAf4BHiKD1uESapMZdnK