Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 6 additions & 14 deletions configurator/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,6 @@
// Transient feedback after an import (the old flow failed silently).
let importStatus = $state<string | null>(null);
let importStatusTimer: ReturnType<typeof setTimeout> | 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");
Expand Down Expand Up @@ -340,7 +329,7 @@
<div class={`shrink-0 ${mobileView === "preview" ? "hidden md:flex" : "flex"}`}>
<SidebarNav
activeId={domain}
onSelect={(d) => { navigateTo(d); }}
onSelect={(d) => { domain = d; }}
overridesByDomain={domainBadges}
/>
</div>
Expand Down Expand Up @@ -378,7 +367,7 @@
onReset={handleReset}
onBulkChange={handleBulkChange}
onApplyTheme={handleApplyTheme}
onSelectDomain={(d) => { navigateTo(d); }}
onSelectDomain={(d) => { domain = d; }}
onResetAll={handleResetAll}
/>
</div>
Expand Down Expand Up @@ -412,7 +401,10 @@
tokens={ALL_TOKENS}
{overrides}
onNavigate={(d, token) => {
navigateTo(d, token);
domain = d;
if (token) { focusNonce += 1; focusRequest = { token, nonce: focusNonce }; }
// On mobile, deep-linking into a token means we want the controls side.
mobileView = "controls";
}}
onClose={() => { showPalette = false; }}
/>
Expand Down
14 changes: 3 additions & 11 deletions configurator/src/components/CommandPalette.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,11 @@

// Navigation destinations — makes this a real command palette (jump to any
// panel/tool), not just a token search.
const NAV_ALIASES: Record<string, string[]> = {
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, terms: [id, ...(NAV_ALIASES[id] ?? [])] }));
].map((id) => ({ id, label: DOMAIN_LABELS[id] ?? id }));

type Result =
| { kind: "nav"; id: string; label: string }
Expand All @@ -44,9 +38,7 @@
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) || n.terms.some((term) => term.includes(q))
) : NAV)
const nav: Result[] = (q ? NAV.filter((n) => n.label.toLowerCase().includes(q)) : NAV)
.map((n) => ({ kind: "nav", id: n.id, label: n.label }));

const tokenMatches: Result[] = [];
Expand Down Expand Up @@ -110,7 +102,7 @@
<div class="px-4 py-8 text-center text-[11px] text-slate-400 dark:text-slate-600">No matches for "{query}"</div>
{:else}
{#each results as r, i (r.kind === "nav" ? `nav:${r.id}` : `tok:${r.token.name}`)}
{#if i === 0 && navCount > 0}
{#if i === 0}
<div class="px-4 pt-2 pb-1 text-[8px] font-bold uppercase tracking-widest text-slate-400 dark:text-slate-600">Go to</div>
{/if}
{#if r.kind === "token" && i === navCount}
Expand Down
41 changes: 28 additions & 13 deletions configurator/src/components/panels/ComponentsPanel.svelte
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<script lang="ts">
import { Eye } from '@lucide/svelte';
import SliderRow from '../inputs/SliderRow.svelte';
import Section from '../inputs/Section.svelte';
import { SPACE_SCALE, RADIUS_SCALE, BORDER_WIDTH_SCALE, SIZE_SCALE, type VarOption } from '../../lib/variableScales';
Expand Down Expand Up @@ -190,9 +191,15 @@

<!-- BUTTON -->
<Section title="Button (.sf-btn)" bind:open={showButton}>
<!-- Preview pickers — local state only, not overrides -->
<div class="space-y-2">
<div class="text-[9px] text-slate-500">Variant (preview only)</div>
<!-- Preview setup — local state only, never written to overrides. Fenced
and labelled so it's unmistakable these pickers don't export. -->
<div class="rounded-xl border border-dashed border-indigo-500/25 bg-indigo-500/[0.03] dark:bg-indigo-400/[0.04] p-2.5 space-y-2">
<div class="flex items-center gap-1.5">
<Eye class="w-3 h-3 text-indigo-500/70 shrink-0" />
<span class="text-[9px] font-bold uppercase tracking-wider text-indigo-600/80 dark:text-indigo-300/80">Preview setup</span>
<span class="text-[8px] font-semibold text-slate-500 bg-black/5 dark:bg-white/8 rounded px-1 py-px">not exported</span>
</div>
<div class="text-[9px] text-slate-500">Variant</div>
<div class="flex flex-wrap gap-1">
{#each BTN_VARIANTS as v (v)}
<button
Expand Down Expand Up @@ -395,16 +402,24 @@

<!-- CARD -->
<Section title="Card (.sf-card)" bind:open={showCard}>
<div class="flex items-center gap-3">
<label class="flex items-center gap-1.5 text-[9px] text-slate-500 cursor-pointer">
<input type="checkbox" bind:checked={cardBordered} class="cursor-pointer" /> bordered
</label>
<label class="flex items-center gap-1.5 text-[9px] text-slate-500 cursor-pointer">
<input type="checkbox" bind:checked={cardElevated} class="cursor-pointer" /> elevated
</label>
<label class="flex items-center gap-1.5 text-[9px] text-slate-500 cursor-pointer">
<input type="checkbox" bind:checked={cardInteractive} class="cursor-pointer" /> interactive
</label>
<!-- Preview setup — local state only, never written to overrides. -->
<div class="rounded-xl border border-dashed border-indigo-500/25 bg-indigo-500/[0.03] dark:bg-indigo-400/[0.04] p-2.5 space-y-2">
<div class="flex items-center gap-1.5">
<Eye class="w-3 h-3 text-indigo-500/70 shrink-0" />
<span class="text-[9px] font-bold uppercase tracking-wider text-indigo-600/80 dark:text-indigo-300/80">Preview setup</span>
<span class="text-[8px] font-semibold text-slate-500 bg-black/5 dark:bg-white/8 rounded px-1 py-px">not exported</span>
</div>
<div class="flex items-center gap-3">
<label class="flex items-center gap-1.5 text-[9px] text-slate-500 cursor-pointer">
<input type="checkbox" bind:checked={cardBordered} class="cursor-pointer" /> bordered
</label>
<label class="flex items-center gap-1.5 text-[9px] text-slate-500 cursor-pointer">
<input type="checkbox" bind:checked={cardElevated} class="cursor-pointer" /> elevated
</label>
<label class="flex items-center gap-1.5 text-[9px] text-slate-500 cursor-pointer">
<input type="checkbox" bind:checked={cardInteractive} class="cursor-pointer" /> interactive
</label>
</div>
</div>

<!-- Live preview — real .sf-card + subcomponents, realistic composition.
Expand Down