diff --git a/configurator/src/App.svelte b/configurator/src/App.svelte index d8308f17..72c0820f 100644 --- a/configurator/src/App.svelte +++ b/configurator/src/App.svelte @@ -67,6 +67,16 @@ let previewMotion = $state<"normal" | "slow" | "none">("normal"); let previewTemplate = $state("color"); + // Lifecycle / reference tools have no live visual sample, so the preview used + // to sit there showing an irrelevant Color gallery over half the screen. + // For these the preview is hidden and the panel takes the full width instead. + // (Accessibility keeps the preview — its contrast checker reads the rendered + // colours from the iframe.) + const FULLWIDTH_DOMAINS = new Set(["changes", "themes", "setup", "cheatsheet"]); + let hidePreview = $derived(FULLWIDTH_DOMAINS.has(domain)); + // A tool screen has nothing to fold to, so keep the mobile view on controls. + $effect(() => { if (hidePreview) untrack(() => { mobileView = "controls"; }); }); + // Derived let overridesCount = $derived(Object.keys(overrides).length); let domainBadges = $derived(overridesByDomain(overrides)); @@ -317,11 +327,14 @@ -
- {@render foldToggleButton("controls", SlidersHorizontal, "Controls")} - {@render foldToggleButton("preview", Eye, "Preview")} -
+ visible without scrolling and doesn't compete with the status bar. + Hidden on tool screens, which have no preview to fold to. --> + {#if !hidePreview} +
+ {@render foldToggleButton("controls", SlidersHorizontal, "Controls")} + {@render foldToggleButton("preview", Eye, "Preview")} +
+ {/if}
@@ -329,15 +342,17 @@
{ domain = d; }} + onSelect={(d) => { domain = d; focusRequest = null; }} overridesByDomain={domainBadges} />
- -
+ +
@@ -367,26 +382,30 @@ onReset={handleReset} onBulkChange={handleBulkChange} onApplyTheme={handleApplyTheme} - onSelectDomain={(d) => { domain = d; }} + onSelectDomain={(d) => { domain = d; focusRequest = null; }} onResetAll={handleResetAll} />
- -
- { previewTheme = t; }} - onWidthChange={(w) => { previewWidth = w; }} - onMotionChange={(m) => { previewMotion = m; }} - onTemplateChange={(t) => { previewTemplate = t; }} - /> -
+ + {#if !hidePreview} +
+ { previewTheme = t; }} + onWidthChange={(w) => { previewWidth = w; }} + onMotionChange={(m) => { previewMotion = m; }} + onTemplateChange={(t) => { previewTemplate = t; }} + /> +
+ {/if}
@@ -403,6 +422,7 @@ onNavigate={(d, token) => { domain = d; if (token) { focusNonce += 1; focusRequest = { token, nonce: focusNonce }; } + else focusRequest = null; // On mobile, deep-linking into a token means we want the controls side. mobileView = "controls"; }} diff --git a/configurator/src/components/CommandPalette.svelte b/configurator/src/components/CommandPalette.svelte index 708a5ac1..bbd9c555 100644 --- a/configurator/src/components/CommandPalette.svelte +++ b/configurator/src/components/CommandPalette.svelte @@ -102,7 +102,7 @@
No matches for "{query}"
{:else} {#each results as r, i (r.kind === "nav" ? `nav:${r.id}` : `tok:${r.token.name}`)} - {#if i === 0} + {#if i === 0 && navCount > 0}
Go to
{/if} {#if r.kind === "token" && i === navCount} diff --git a/configurator/src/components/panels/BordersPanel.svelte b/configurator/src/components/panels/BordersPanel.svelte index 52c8bbb9..d7b3e6ec 100644 --- a/configurator/src/components/panels/BordersPanel.svelte +++ b/configurator/src/components/panels/BordersPanel.svelte @@ -5,6 +5,8 @@ import ColorInput from '../inputs/ColorInput.svelte'; import Section from '../inputs/Section.svelte'; import { SPACE_SCALE, RADIUS_SCALE, BORDER_WIDTH_SCALE, type VarOption } from '../../lib/variableScales'; + import ScaleShadowNotice from '../inputs/ScaleShadowNotice.svelte'; + import { scaleShadows } from '../../lib/tokenModel'; let { overrides, onSet, onReset }: { overrides: Record; @@ -56,6 +58,13 @@ let dividerColor = $derived(overrides["--sf-divider-color"] ?? ""); let mediaRadius = $derived(parseNum(overrides["--sf-media-radius"]?.replace("rem",""), 0)); + // Fixed per-step overrides that shadow the radius / border-width scale knobs + // (the same detached-scale state the Type & Spacing panels already warn about; + // generalised here via tokenModel.scaleShadows). + let radiusShadow = $derived(scaleShadows(overrides).find((s) => s.family.id === "radius")?.shadowedSteps ?? []); + let borderShadow = $derived(scaleShadows(overrides).find((s) => s.family.id === "border-width")?.shadowedSteps ?? []); + const clearSteps = (steps: string[]) => steps.forEach(onReset); + function getStyleCurrent(tokenName: string, defaultVal: string): string { return overrides[tokenName] ?? defaultVal; } @@ -98,6 +107,7 @@
+ clearSteps(borderShadow)} />
Radius
+ clearSteps(radiusShadow)} />
diff --git a/configurator/src/components/panels/MotionPanel.svelte b/configurator/src/components/panels/MotionPanel.svelte index a8577fdc..efbdd3c5 100644 --- a/configurator/src/components/panels/MotionPanel.svelte +++ b/configurator/src/components/panels/MotionPanel.svelte @@ -4,6 +4,8 @@ import SliderRow from '../inputs/SliderRow.svelte'; import Toggle from '../inputs/Toggle.svelte'; import Section from '../inputs/Section.svelte'; + import ScaleShadowNotice from '../inputs/ScaleShadowNotice.svelte'; + import { scaleShadows } from '../../lib/tokenModel'; import { themeState } from '../../lib/theme.svelte'; //