Skip to content

Commit 7dd9246

Browse files
committed
fix(configurator): make button size-scale behaviour intuitive
Phase 4 — the buttons/cards config UX. - Correct the Min-height default: it now reads 'size-m (default)' and, when unset, falls through to the per-size scale (--sf-size-* via .sf-btn--xs…xl). The old 'touch-target' (44px) default silently pinned every size to 44px and collapsed the XS–XL scale — the exact trap that made all button sizes look identical. touch-target stays available as an explicit choice in the variable dropdown. - Add a 'Base style — applies to every size' heading + explainer: padding, min-height and label size are global and override the size scale. - Flag each scale-shadowing knob inline ('↕ overrides every size') when it is actually set, including Label size. - Add a 'Reset all button tokens' action. Verified: vite build clean; panel renders with the corrected default and new guidance. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WqrpLiaSZCeouRQ5RNBtsh
1 parent d61c306 commit 7dd9246

1 file changed

Lines changed: 42 additions & 1 deletion

File tree

configurator/src/components/panels/ComponentsPanel.svelte

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,13 @@
4444
{ label: "Padding inline", token: "--sf-btn-padding-inline", unit: "rem", min: 0, max: 2, step: 0.025, default: 1, rawDefault: "var(--sf-space-m)", variableOptions: SPACE_SCALE },
4545
{ label: "Gap (icon+label)", token: "--sf-btn-gap", unit: "rem", min: 0, max: 1, step: 0.0125, default: 0.25, rawDefault: "var(--sf-space-2xs)", variableOptions: SPACE_SCALE },
4646
{ label: "Border width", token: "--sf-btn-border-width", unit: "px", min: 0, max: 4, step: 0.5, default: 1, rawDefault: "var(--sf-border-width-1)", variableOptions: BORDER_WIDTH_SCALE },
47-
{ label: "Min height", token: "--sf-btn-min-height", unit: "rem", min: 1, max: 4, step: 0.125, default: 2.75, rawDefault: "var(--sf-touch-target)", variableOptions: SIZE_SCALE },
47+
// Unset, --sf-btn-min-height falls through to the per-size tier
48+
// (--sf-size-* via .sf-btn--xs…xl), whose base is --sf-size-m (40px) — so
49+
// THAT is the real default, not --sf-touch-target. Presenting touch-target
50+
// (44px) as the default silently pinned every size to 44px and collapsed
51+
// the XS–XL scale. touch-target stays available as an explicit choice via
52+
// the variable dropdown for consumers who want the WCAG AAA target.
53+
{ label: "Min height", token: "--sf-btn-min-height", unit: "rem", min: 1, max: 4, step: 0.125, default: 2.5, rawDefault: "var(--sf-size-m)", variableOptions: SIZE_SCALE },
4854
];
4955
5056
const CARD_TOKENS: Array<{ label: string; token: string; unit: string; min: number; max: number; step: number; default: number; rawDefault: string; variableOptions: VarOption[] }> = [
@@ -55,6 +61,22 @@
5561
{ label: "Media radius", token: "--sf-card-media-radius", unit: "rem", min: 0, max: 2, step: 0.05, default: 0.5, rawDefault: "var(--sf-card-radius, var(--sf-radius-m))", variableOptions: RADIUS_SCALE },
5662
];
5763
64+
// Global knobs that, once set, shadow the per-size scale (.sf-btn--xs…xl) on
65+
// EVERY size — the framework reads the public knob before the size tier. The
66+
// UI flags these so a global tweak that flattens the size scale isn't a
67+
// surprise. (Label size / --sf-btn-font-size behaves the same way.)
68+
const SCALE_SHADOWING = new Set([
69+
"--sf-btn-padding-block",
70+
"--sf-btn-padding-inline",
71+
"--sf-btn-min-height",
72+
]);
73+
74+
function resetButtonTokens() {
75+
for (const k of Object.keys(overrides)) {
76+
if (k.startsWith("--sf-btn-")) onReset(k);
77+
}
78+
}
79+
5880
let showButton = $state(false);
5981
let showCard = $state(false);
6082
@@ -236,6 +258,12 @@
236258
</div>
237259

238260
<div class="mt-2 space-y-2">
261+
<div class="text-[9px] font-bold text-slate-500 uppercase tracking-wider">Base style — applies to every size</div>
262+
<div class="text-[9px] text-slate-500 leading-snug">
263+
Padding, min-height and label size are <b>global</b>: once set they override the
264+
<code class="text-slate-600 dark:text-slate-300">.sf-btn--xs…xl</code> size scale on every button.
265+
Leave them at default to keep the size scale (see it live on the Components preview tab).
266+
</div>
239267
{#each BUTTON_TOKENS as t (t.token)}
240268
<SliderRow
241269
label={t.label} value={getVal(t)} min={t.min} max={t.max} step={t.step} unit={t.unit}
@@ -248,6 +276,9 @@
248276
currentRaw={overrides[t.token]}
249277
onRawSet={(v) => onSet(t.token, v)}
250278
/>
279+
{#if SCALE_SHADOWING.has(t.token) && t.token in overrides}
280+
<div class="text-[9px] text-amber-600 dark:text-amber-400 -mt-1 pl-0.5">↕ overrides every size (.sf-btn--xs…xl)</div>
281+
{/if}
251282
{/each}
252283

253284
<div>
@@ -265,6 +296,9 @@
265296
>{step}</button>
266297
{/each}
267298
</div>
299+
{#if "--sf-btn-font-size" in overrides}
300+
<div class="text-[9px] text-amber-600 dark:text-amber-400 mt-1 pl-0.5">↕ overrides every size (.sf-btn--xs…xl)</div>
301+
{/if}
268302
</div>
269303

270304
<div>
@@ -284,6 +318,13 @@
284318
{/each}
285319
</div>
286320
</div>
321+
322+
{#if Object.keys(overrides).some((k) => k.startsWith("--sf-btn-"))}
323+
<button
324+
onclick={resetButtonTokens}
325+
class="text-[10px] font-semibold text-slate-500 hover:text-slate-700 dark:hover:text-slate-300 underline underline-offset-2 cursor-pointer"
326+
>Reset all button tokens</button>
327+
{/if}
287328
</div>
288329
{/if}
289330
</section>

0 commit comments

Comments
 (0)