From fd4bc396401b08835780ed99831761c738c5bede Mon Sep 17 00:00:00 2001 From: Kiro Agent <244629292+kiro-agent@users.noreply.github.com> Date: Wed, 19 Aug 2026 23:53:51 +0000 Subject: [PATCH] feat(configurator): turn the Misc grab-bag into a coherent "System" panel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Misc read as a junk drawer. Rename it to "System" and give it structure without scattering controls across other panels. - Rename Misc → "System" (nav, panel heading, Home, command palette, Changes). - Add an overview line and area headers grouping the sections: Layering, Text & selection, Sizing, Links & caret, Icons, Media, Device & forms. - Reclassify the `safe` namespace → misc: safe-area insets are a device/system concern and their control already lives here, so this makes the badge/Reset match where they're edited (they were classified to Layout but never had a Layout control). One classifier, no mismatch. - Drop the stale "focus ring" mention from the preview note (it moved to Accessibility earlier). domains.test adds safe-area → misc. check, lint, curation, 286 unit tests and shell e2e pass; screenshot + e2e verified the renamed, area-grouped panel and that safe-area + z-index both count under System. --- configurator/src/App.svelte | 23 ++++++++----- .../src/components/CommandPalette.svelte | 14 ++++++-- .../src/components/panels/ChangesPanel.svelte | 2 +- .../src/components/panels/HomePanel.svelte | 2 +- .../src/components/panels/MiscPanel.svelte | 34 +++++++++++++++++-- .../src/components/shell/SidebarNav.svelte | 2 +- configurator/src/data/domain-map.json | 3 +- configurator/tests-e2e/shell.spec.js | 2 +- configurator/tests/domains.test.ts | 5 +++ 9 files changed, 68 insertions(+), 19 deletions(-) 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');