diff --git a/configurator/src/App.svelte b/configurator/src/App.svelte index 72c0820f..a53099f8 100644 --- a/configurator/src/App.svelte +++ b/configurator/src/App.svelte @@ -21,7 +21,7 @@ const DOMAIN_LABELS: Record = { home: "Home", colors: "Colors", typography: "Typography", spacing: "Spacing", layout: "Layout", borders: "Shape", depth: "Depth", motion: "Motion", - macros: "Macros", misc: "Misc", components: "Components", + macros: "Macros", misc: "System", components: "Components", changes: "Changes", themes: "Presets", wcag: "Accessibility", setup: "Install & export", cheatsheet: "Reference", }; @@ -59,6 +59,17 @@ // Transient feedback after an import (the old flow failed silently). let importStatus = $state(null); let importStatusTimer: ReturnType | null = null; + + function navigateTo(domainId: string, token?: string) { + domain = domainId; + if (token) { + focusNonce += 1; + focusRequest = { token, nonce: focusNonce }; + } else { + focusRequest = null; + } + mobileView = "controls"; + } // On narrow screens the controls panel and the live preview can't both fit, so // we show one at a time and let the user fold between them (desktop shows both). let mobileView = $state<"controls" | "preview">("controls"); @@ -342,7 +353,7 @@
{ domain = d; focusRequest = null; }} + onSelect={(d) => { navigateTo(d); }} overridesByDomain={domainBadges} />
@@ -382,7 +393,7 @@ onReset={handleReset} onBulkChange={handleBulkChange} onApplyTheme={handleApplyTheme} - onSelectDomain={(d) => { domain = d; focusRequest = null; }} + onSelectDomain={(d) => { navigateTo(d); }} onResetAll={handleResetAll} /> @@ -420,11 +431,7 @@ tokens={ALL_TOKENS} {overrides} 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"; + navigateTo(d, token); }} onClose={() => { showPalette = false; }} /> diff --git a/configurator/src/components/CommandPalette.svelte b/configurator/src/components/CommandPalette.svelte index bbd9c555..5b6c3684 100644 --- a/configurator/src/components/CommandPalette.svelte +++ b/configurator/src/components/CommandPalette.svelte @@ -17,18 +17,24 @@ const DOMAIN_LABELS: Record = { home: "Home", colors: "Colors", typography: "Typography", spacing: "Spacing", layout: "Layout", borders: "Shape", depth: "Depth", motion: "Motion", - macros: "Macros", misc: "Misc", components: "Components", + macros: "Macros", misc: "System", components: "Components", changes: "Changes", wcag: "Accessibility", themes: "Presets", setup: "Install & export", cheatsheet: "Reference", }; // Navigation destinations — makes this a real command palette (jump to any // panel/tool), not just a token search. + const NAV_ALIASES: Record = { + borders: ["border", "radius", "shape"], shadows: ["shadow", "depth"], + effects: ["effect"], wcag: ["accessibility", "contrast"], + themes: ["theme", "preset"], setup: ["install", "export"], + cheatsheet: ["reference", "classes"], misc: ["system"], + }; const NAV = [ "home", "colors", "typography", "spacing", "borders", "motion", "layout", "depth", "macros", "components", "misc", "changes", "wcag", "themes", "setup", "cheatsheet", - ].map((id) => ({ id, label: DOMAIN_LABELS[id] ?? id })); + ].map((id) => ({ id, label: DOMAIN_LABELS[id] ?? id, terms: [id, ...(NAV_ALIASES[id] ?? [])] })); type Result = | { kind: "nav"; id: string; label: string } @@ -38,7 +44,9 @@ const q = query.trim().toLowerCase(); // Navigation matches (all destinations when empty, so the palette is useful // before typing). - const nav: Result[] = (q ? NAV.filter((n) => n.label.toLowerCase().includes(q)) : NAV) + const nav: Result[] = (q ? NAV.filter((n) => + n.label.toLowerCase().includes(q) || n.terms.some((term) => term.includes(q)) + ) : NAV) .map((n) => ({ kind: "nav", id: n.id, label: n.label })); const tokenMatches: Result[] = []; diff --git a/configurator/src/components/panels/ChangesPanel.svelte b/configurator/src/components/panels/ChangesPanel.svelte index 5c3d991b..f8208100 100644 --- a/configurator/src/components/panels/ChangesPanel.svelte +++ b/configurator/src/components/panels/ChangesPanel.svelte @@ -18,7 +18,7 @@ const DOMAIN_LABEL: Record = { colors: "Colors", typography: "Typography", spacing: "Spacing", layout: "Layout", borders: "Shape", depth: "Depth", motion: "Motion", - macros: "Macros", components: "Components", misc: "Misc", + macros: "Macros", components: "Components", misc: "System", }; let summary = $derived(summarizeChanges(tokens, overrides)); diff --git a/configurator/src/components/panels/HomePanel.svelte b/configurator/src/components/panels/HomePanel.svelte index 5913d5fe..b9419e5a 100644 --- a/configurator/src/components/panels/HomePanel.svelte +++ b/configurator/src/components/panels/HomePanel.svelte @@ -34,7 +34,7 @@ { id: "depth", icon: Layers, label: "Depth", desc: "Shadows, glow, blur & opacity" }, { id: "macros", icon: Blocks, label: "Macros", desc: "Flow, prose, aspect & scrim" }, { id: "components", icon: Component, label: "Components", desc: "Button & card component tokens" }, - { id: "misc", icon: Puzzle, label: "Misc", desc: "Z-index & remaining tokens" }, + { id: "misc", icon: Puzzle, label: "System", desc: "Layering, sizing, media, selection" }, ], }, { diff --git a/configurator/src/components/panels/MiscPanel.svelte b/configurator/src/components/panels/MiscPanel.svelte index a281fbf1..f03008a2 100644 --- a/configurator/src/components/panels/MiscPanel.svelte +++ b/configurator/src/components/panels/MiscPanel.svelte @@ -57,8 +57,24 @@
- + + + +
+

+ Low-level system tokens, grouped by area: + Layering, + Text & selection, + Sizing & + Icons, + Media, and + device / forms. +

+
+ + +
Layering
@@ -84,6 +100,8 @@
+
Text & selection
+
@@ -161,6 +179,8 @@
+
Sizing
+

@@ -196,6 +216,8 @@

+
Links & caret
+
@@ -257,6 +279,8 @@
+
Icons
+

@@ -290,6 +314,8 @@

+
Media
+

Default values for .sf-media images and replaced elements.

@@ -328,6 +354,8 @@
+
Device & forms
+

@@ -387,7 +415,7 @@

- Selection colors, caret, links, focus ring, borders and sizes all render in the + Selection colors, caret, links, borders and sizes all render in the live preview (try the Components template). Scroll behavior applies to the page itself and can't be shown in the static canvas. diff --git a/configurator/src/components/shell/SidebarNav.svelte b/configurator/src/components/shell/SidebarNav.svelte index 25ed5700..dc39ad34 100644 --- a/configurator/src/components/shell/SidebarNav.svelte +++ b/configurator/src/components/shell/SidebarNav.svelte @@ -34,7 +34,7 @@ { id: "depth", icon: Layers, label: "Depth" }, { id: "macros", icon: Blocks, label: "Macros" }, { id: "components", icon: Component, label: "Components" }, - { id: "misc", icon: Puzzle, label: "Misc" }, + { id: "misc", icon: Puzzle, label: "System" }, ], }, { diff --git a/configurator/src/data/domain-map.json b/configurator/src/data/domain-map.json index 74c7aead..fc169024 100644 --- a/configurator/src/data/domain-map.json +++ b/configurator/src/data/domain-map.json @@ -49,7 +49,7 @@ "stack": "layout", "header": "layout", "sticky": "layout", - "safe": "layout", + "breakout": "layout", "box": "layout", "bg": "layout", @@ -92,6 +92,7 @@ "size": "misc", "object": "misc", "scrollbar": "misc", + "safe": "misc", "is": "misc", "focus": "wcag", diff --git a/configurator/tests-e2e/shell.spec.js b/configurator/tests-e2e/shell.spec.js index 238900a0..56962f65 100644 --- a/configurator/tests-e2e/shell.spec.js +++ b/configurator/tests-e2e/shell.spec.js @@ -6,7 +6,7 @@ import { watchErrors, gotoClean, navButton } from './helpers.js'; const NAV_LABELS = [ 'Home', 'Colors', 'Typography', 'Spacing', 'Shape', - 'Layout', 'Depth', 'Motion', 'Macros', 'Misc', 'Components', + 'Layout', 'Depth', 'Motion', 'Macros', 'System', 'Components', 'Changes', 'Accessibility', 'Presets', 'Install & export', 'Reference', ]; diff --git a/configurator/tests/domains.test.ts b/configurator/tests/domains.test.ts index 815b874d..b87d17c2 100644 --- a/configurator/tests/domains.test.ts +++ b/configurator/tests/domains.test.ts @@ -47,6 +47,11 @@ describe('domainOf', () => { expect(classifyKnown('--sf-z-modal')).toBe('misc'); }); + test('safe-area insets classify to the System (misc) panel, where they are edited', () => { + expect(domainOf('--sf-safe-top')).toBe('misc'); + expect(domainOf('--sf-safe-bottom')).toBe('misc'); + }); + test('per-token exceptions override their namespace default', () => { // `content` defaults to spacing, but these two are genuinely elsewhere. expect(domainOf('--sf-content-gap')).toBe('spacing');