From f1d4a28e9d8d7019c35ea73cebf245e055f8b917 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 18 Jul 2026 20:00:56 +0000 Subject: [PATCH 1/7] fix(configurator): live var() previews everywhere; unified per-type tabs incl. display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Claude-Session: https://claude.ai/code/session_013BRVgKfEYocPCHz9KU96FN --- .../components/inputs/TypeSpecimenRow.svelte | 39 ++++ .../src/components/panels/BordersPanel.svelte | 23 +-- .../src/components/panels/EffectsPanel.svelte | 14 +- .../src/components/panels/MacrosPanel.svelte | 6 +- .../src/components/panels/MiscPanel.svelte | 8 +- .../components/panels/TypographyPanel.svelte | 184 +++++++----------- 6 files changed, 134 insertions(+), 140 deletions(-) create mode 100644 configurator/src/components/inputs/TypeSpecimenRow.svelte diff --git a/configurator/src/components/inputs/TypeSpecimenRow.svelte b/configurator/src/components/inputs/TypeSpecimenRow.svelte new file mode 100644 index 00000000..f7b38eb2 --- /dev/null +++ b/configurator/src/components/inputs/TypeSpecimenRow.svelte @@ -0,0 +1,39 @@ + + +
+ {label} + Aa + {px ? `${(px / 16).toFixed(2)}rem` : ""} +
diff --git a/configurator/src/components/panels/BordersPanel.svelte b/configurator/src/components/panels/BordersPanel.svelte index acb20af2..0c1e54b7 100644 --- a/configurator/src/components/panels/BordersPanel.svelte +++ b/configurator/src/components/panels/BordersPanel.svelte @@ -14,7 +14,6 @@ const BORDER_STYLES = ["solid", "dashed", "dotted"]; const RADIUS_STEPS = ["xs", "s", "m", "l", "xl", "2xl", "full"]; - const BASE_RADII: Record = { xs: 2, s: 4, m: 8, l: 12, xl: 16, "2xl": 24, full: 9999 }; const RADIUS_FINE: Array<{ step: string; name: string; default: number; max: number; step_size: number; rawDefault: string }> = [ { step: "xs", name: "--sf-radius-xs", default: 2, max: 16, step_size: 0.5, rawDefault: "calc(2px * var(--sf-radius-scale))" }, @@ -50,7 +49,6 @@ return isNaN(v) ? fallback : v; } - let radiusScale = $derived(parseNum(overrides["--sf-radius-scale"], 1)); let borderScale = $derived(parseNum(overrides["--sf-border-scale"], 1)); let focusWidth = $derived(parseNum(overrides["--sf-focus-ring-width"], 2, "px")); let focusOffset = $derived(parseNum(overrides["--sf-focus-ring-offset"], 2, "px")); @@ -130,14 +128,11 @@
{#each [1, 2, 3, 4] as base (base)}
- {base}px → + width-{base}
- - {(base * borderScale).toFixed(1)}px -
{/each}
@@ -178,11 +173,11 @@
Border sample
- {(1 * borderScale).toFixed(1)}px · {borderStyle} + width-1 · {borderStyle}
@@ -258,7 +253,7 @@
Focus preview
@@ -316,12 +311,10 @@
{#each RADIUS_STEPS as step (step)} - {@const base = BASE_RADII[step] ?? 6} - {@const computed = step === "full" ? 9999 : base * radiusScale}
{step}
@@ -345,7 +338,7 @@ overridden={"--sf-media-radius" in overrides} onChange={(v) => onSet("--sf-media-radius", `${v}rem`)} onReset={() => onReset("--sf-media-radius")} - rawDefault="var(--sf-radius-m)" + rawDefault="0" variableOptions={RADIUS_SCALE} currentRaw={overrides["--sf-media-radius"]} onRawSet={(v) => onSet("--sf-media-radius", v)} @@ -353,7 +346,7 @@
diff --git a/configurator/src/components/panels/EffectsPanel.svelte b/configurator/src/components/panels/EffectsPanel.svelte index 27d19086..58d5487c 100644 --- a/configurator/src/components/panels/EffectsPanel.svelte +++ b/configurator/src/components/panels/EffectsPanel.svelte @@ -59,7 +59,7 @@
{blur}px
@@ -94,13 +94,13 @@
{#each [ - { label: "muted", val: opacityMuted }, - { label: "disabled", val: opacityDisabled }, - { label: "pending", val: pendingOpacity }, + { label: "muted", token: "--sf-opacity-muted", val: opacityMuted }, + { label: "disabled", token: "--sf-opacity-disabled", val: opacityDisabled }, + { label: "pending", token: "--sf-state-pending-opacity", val: pendingOpacity }, ] as row (row.label)}
{row.label} -
+
{row.val}
{/each} @@ -129,8 +129,8 @@ {/each}
-
-
+
+
Scrollbar preview
diff --git a/configurator/src/components/panels/MacrosPanel.svelte b/configurator/src/components/panels/MacrosPanel.svelte index aa7134fa..122aeb61 100644 --- a/configurator/src/components/panels/MacrosPanel.svelte +++ b/configurator/src/components/panels/MacrosPanel.svelte @@ -131,7 +131,7 @@ currentRaw={overrides["--sf-flow-space"]} onRawSet={(v) => onSet("--sf-flow-space", v)} /> -
+
{#each [0, 1, 2] as i (i)}
{/each} @@ -228,7 +228,7 @@
-
+
Caption over scrim
.sf-surface-bg preview
diff --git a/configurator/src/components/panels/MiscPanel.svelte b/configurator/src/components/panels/MiscPanel.svelte index 424f14d1..e0c66989 100644 --- a/configurator/src/components/panels/MiscPanel.svelte +++ b/configurator/src/components/panels/MiscPanel.svelte @@ -88,10 +88,8 @@
- {touchTarget}px -
+ style={`width: var(--sf-touch-target, 2.75rem); height: var(--sf-touch-target, 2.75rem)`} + >

Minimum interactive area — ensures accessibility on touch devices.

@@ -240,7 +238,7 @@
Focus ring · {focusRingStyle}
diff --git a/configurator/src/components/panels/TypographyPanel.svelte b/configurator/src/components/panels/TypographyPanel.svelte index c47741be..6655b4c1 100644 --- a/configurator/src/components/panels/TypographyPanel.svelte +++ b/configurator/src/components/panels/TypographyPanel.svelte @@ -6,6 +6,7 @@ import RangeWithNumber from '../inputs/RangeWithNumber.svelte'; import ClampField from '../inputs/ClampField.svelte'; import Section from '../inputs/Section.svelte'; + import TypeSpecimenRow from '../inputs/TypeSpecimenRow.svelte'; import { themeState } from '../../lib/theme.svelte'; //