|
44 | 44 | { 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 }, |
45 | 45 | { 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 }, |
46 | 46 | { 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 }, |
48 | 54 | ]; |
49 | 55 |
|
50 | 56 | const CARD_TOKENS: Array<{ label: string; token: string; unit: string; min: number; max: number; step: number; default: number; rawDefault: string; variableOptions: VarOption[] }> = [ |
|
55 | 61 | { 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 }, |
56 | 62 | ]; |
57 | 63 |
|
| 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 | +
|
58 | 80 | let showButton = $state(false); |
59 | 81 | let showCard = $state(false); |
60 | 82 |
|
|
236 | 258 | </div> |
237 | 259 |
|
238 | 260 | <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> |
239 | 267 | {#each BUTTON_TOKENS as t (t.token)} |
240 | 268 | <SliderRow |
241 | 269 | label={t.label} value={getVal(t)} min={t.min} max={t.max} step={t.step} unit={t.unit} |
|
248 | 276 | currentRaw={overrides[t.token]} |
249 | 277 | onRawSet={(v) => onSet(t.token, v)} |
250 | 278 | /> |
| 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} |
251 | 282 | {/each} |
252 | 283 |
|
253 | 284 | <div> |
|
265 | 296 | >{step}</button> |
266 | 297 | {/each} |
267 | 298 | </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} |
268 | 302 | </div> |
269 | 303 |
|
270 | 304 | <div> |
|
284 | 318 | {/each} |
285 | 319 | </div> |
286 | 320 | </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} |
287 | 328 | </div> |
288 | 329 | {/if} |
289 | 330 | </section> |
|
0 commit comments