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
30 changes: 28 additions & 2 deletions configurator/src/App.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts">
import { onMount, untrack } from 'svelte';
import { SlidersHorizontal, Eye } from 'lucide-svelte';
import { SlidersHorizontal, Eye, RotateCcw } from 'lucide-svelte';
import type { PreviewTemplate, SlashedToken } from './types';
import StudioHeader from './components/shell/StudioHeader.svelte';
import SidebarNav from './components/shell/SidebarNav.svelte';
Expand Down Expand Up @@ -58,6 +58,15 @@
// Derived
let overridesCount = $derived(Object.keys(overrides).length);
let domainBadges = $derived(overridesByDomain(overrides));
// Scope the active category's reset to exactly the keys domainOf() would
// badge under this domain — matching against the domain's own pattern list
// directly would over-match, since patterns overlap across domains (e.g.
// layout's "-bg-" also appears in color tokens like --sf-color-bg--active,
// which domainOf() resolves to "colors" by checking that domain first).
let domainOverrideKeys = $derived(
Object.keys(overrides).filter((k) => domainOf(k) === domain)
);
let domainOverridesCount = $derived(domainOverrideKeys.length);
let canUndo = $derived(past.length > 0);
let canRedo = $derived(future.length > 0);

Expand Down Expand Up @@ -144,6 +153,12 @@
setOverrides({});
}

function handleResetDomain() {
const patch: Record<string, null> = {};
for (const k of domainOverrideKeys) patch[k] = null;
handleBulkChange(patch);
Comment thread
qodo-code-review[bot] marked this conversation as resolved.
}

function handleUndo() {
if (past.length === 0) return;
const previous = past[past.length - 1];
Expand Down Expand Up @@ -296,10 +311,21 @@
100% of the whole row and overflow past it), fixed 360px on desktop -->
<div class={`flex-1 min-w-0 md:flex-none md:w-[360px] bg-[#0c0c15] border-r border-white/8 flex-col min-h-0 ${mobileView === "preview" ? "hidden md:flex" : "flex"}`}>
<!-- Panel heading -->
<div class="h-9 flex items-center px-4 border-b border-white/6 shrink-0">
<div class="h-9 flex items-center px-4 border-b border-white/6 shrink-0 gap-2">
<span data-testid="panel-heading" class="text-[11px] font-bold text-slate-300 uppercase tracking-widest flex-1">
{DOMAIN_LABELS[domain] ?? domain}
</span>
{#if domainOverridesCount > 0}
<button
onclick={handleResetDomain}
data-testid="reset-category"
title={`Reset ${domainOverridesCount} override${domainOverridesCount !== 1 ? "s" : ""} in ${DOMAIN_LABELS[domain] ?? domain}`}
class="flex items-center gap-1 px-1.5 py-0.5 rounded-md text-[9px] font-bold text-slate-500 hover:text-rose-400 hover:bg-rose-500/10 transition-colors cursor-pointer shrink-0"
>
<RotateCcw class="w-3 h-3" />
Reset {domainOverridesCount}
</button>
{/if}
</div>
<!-- Scrollable panel content -->
<div class="flex-1 min-h-0 flex flex-col overflow-hidden">
Expand Down
25 changes: 6 additions & 19 deletions configurator/src/components/DomainPanel.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts">
import { SlidersHorizontal, List } from 'lucide-svelte';
import type { SlashedToken } from '../types';
import { DOMAIN_PATTERNS } from '../lib/domains';
import { DOMAIN_PATTERNS, domainOf } from '../lib/domains';
import HomePanel from './panels/HomePanel.svelte';
import ColorsPanel from './panels/ColorsPanel.svelte';
import TypographyPanel from './panels/TypographyPanel.svelte';
Expand Down Expand Up @@ -46,26 +46,13 @@

let patterns = $derived(DOMAIN_PATTERNS[domain] ?? [domain]);

// Uses domainOf() rather than the raw patterns list so this badge always
// agrees with App.svelte's "Reset N" count — matching against a single
// domain's patterns in isolation over-counts where patterns overlap (e.g.
// layout's "-bg-" also appears in color tokens like --sf-color-bg--active).
let domainOverridesInTokenTab = $derived(
tokens.filter((t) =>
patterns.some((p) => t.name.includes(p)) && t.name in overrides
).length
tokens.filter((t) => domainOf(t.name) === domain && t.name in overrides).length
);

// Count overrides belonging to this domain for the reset button
let domainOverridesCount = $derived(
Object.keys(overrides).filter((k) =>
patterns.some((p) => k.includes(p))
).length
);

function handleDomainReset() {
const patch: Record<string, null> = {};
for (const k of Object.keys(overrides)) {
if (patterns.some((p) => k.includes(p))) patch[k] = null;
}
onBulkChange(patch);
}
</script>

{#if NO_CONTROLS_TAB.has(domain)}
Expand Down
2 changes: 1 addition & 1 deletion configurator/src/components/inputs/PowerKnobRow.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
{#if isOverridden}
<button
onclick={handleReset}
class="text-[9px] text-slate-500 hover:text-rose-400 transition-colors cursor-pointer opacity-0 group-hover:opacity-100"
class="text-[9px] text-slate-500 hover:text-rose-400 transition-colors cursor-pointer opacity-100 sm:opacity-0 sm:group-hover:opacity-100 sm:group-focus-within:opacity-100 focus:opacity-100"
>
reset
</button>
Expand Down
4 changes: 2 additions & 2 deletions configurator/src/components/inputs/SliderRow.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,14 @@
class={`text-[9px] font-mono cursor-pointer transition-all px-0.5 ${
showRaw
? 'text-indigo-400'
: 'opacity-0 group-hover:opacity-100 text-slate-500 hover:text-indigo-400'
: 'opacity-100 sm:opacity-0 sm:group-hover:opacity-100 sm:group-focus-within:opacity-100 focus:opacity-100 text-slate-500 hover:text-indigo-400'
}`}
>&lt;/&gt;</button>
{/if}
{#if overridden}
<button
onclick={onReset}
class="text-[9px] text-slate-500 hover:text-rose-400 cursor-pointer opacity-0 group-hover:opacity-100 transition-colors"
class="text-[9px] text-slate-500 hover:text-rose-400 cursor-pointer opacity-100 sm:opacity-0 sm:group-hover:opacity-100 sm:group-focus-within:opacity-100 focus:opacity-100 transition-colors"
>reset</button>
{/if}
</div>
Expand Down
2 changes: 1 addition & 1 deletion configurator/src/components/inputs/TokenRow.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
{#if isOverridden}
<button
onclick={onReset}
class="text-[9px] text-slate-600 hover:text-rose-400 transition-colors cursor-pointer opacity-0 group-hover:opacity-100 shrink-0"
class="text-[9px] text-slate-600 hover:text-rose-400 transition-colors cursor-pointer opacity-100 sm:opacity-0 sm:group-hover:opacity-100 sm:group-focus-within:opacity-100 focus:opacity-100 shrink-0"
>
</button>
Expand Down
2 changes: 1 addition & 1 deletion configurator/src/components/panels/MiscPanel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@
<div class="flex items-center justify-between mb-1.5">
<span class="text-[11px] font-semibold text-slate-200">Underline thickness</span>
{#if "--sf-link-underline-thickness" in overrides}
<button onclick={() => onReset("--sf-link-underline-thickness")} class="text-[9px] text-slate-500 hover:text-rose-400 cursor-pointer opacity-0 group-hover:opacity-100">reset</button>
<button onclick={() => onReset("--sf-link-underline-thickness")} class="text-[9px] text-slate-500 hover:text-rose-400 cursor-pointer opacity-100 sm:opacity-0 sm:group-hover:opacity-100 sm:group-focus-within:opacity-100 focus:opacity-100">reset</button>
{/if}
</div>
<div class="flex gap-1">
Expand Down
2 changes: 1 addition & 1 deletion configurator/src/components/panels/MotionPanel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@
<div class="flex items-center justify-between mb-1.5">
<span class="text-[11px] font-semibold text-slate-200">Stagger base</span>
{#if STAGGER_TOKENS.some(t => t in overrides)}
<button onclick={resetStagger} class="text-[9px] text-slate-500 hover:text-rose-400 cursor-pointer opacity-0 group-hover:opacity-100">reset</button>
<button onclick={resetStagger} class="text-[9px] text-slate-500 hover:text-rose-400 cursor-pointer opacity-100 sm:opacity-0 sm:group-hover:opacity-100 sm:group-focus-within:opacity-100 focus:opacity-100">reset</button>
{/if}
</div>
<SliderRow
Expand Down
8 changes: 4 additions & 4 deletions configurator/src/components/panels/TypographyPanel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@
<div class="flex items-center justify-between mb-1.5">
<span class="text-[11px] font-semibold text-slate-200">{row.label} weight</span>
{#if isOverridden}
<button onclick={() => onReset(row.tokenName)} class="text-[9px] text-slate-500 hover:text-rose-400 cursor-pointer opacity-0 group-hover:opacity-100 transition-colors">reset</button>
<button onclick={() => onReset(row.tokenName)} class="text-[9px] text-slate-500 hover:text-rose-400 cursor-pointer opacity-100 sm:opacity-0 sm:group-hover:opacity-100 sm:group-focus-within:opacity-100 focus:opacity-100 transition-colors">reset</button>
{/if}
</div>
<div class="flex gap-1">
Expand Down Expand Up @@ -615,7 +615,7 @@
<div class="flex items-center justify-between mb-1">
<span class="text-[10px] font-semibold text-slate-200">{row.label}</span>
{#if row.token in overrides}
<button onclick={() => onReset(row.token)} class="text-[9px] text-slate-500 hover:text-rose-400 cursor-pointer opacity-0 group-hover:opacity-100">reset</button>
<button onclick={() => onReset(row.token)} class="text-[9px] text-slate-500 hover:text-rose-400 cursor-pointer opacity-100 sm:opacity-0 sm:group-hover:opacity-100 sm:group-focus-within:opacity-100 focus:opacity-100">reset</button>
{/if}
</div>
<div class="flex gap-1">
Expand Down Expand Up @@ -692,7 +692,7 @@
<div class="flex items-center justify-between mb-1.5">
<span class="text-[11px] font-semibold text-slate-200">{row.label} weight</span>
{#if isOverridden}
<button onclick={() => onReset(row.tokenName)} class="text-[9px] text-slate-500 hover:text-rose-400 cursor-pointer opacity-0 group-hover:opacity-100 transition-colors">reset</button>
<button onclick={() => onReset(row.tokenName)} class="text-[9px] text-slate-500 hover:text-rose-400 cursor-pointer opacity-100 sm:opacity-0 sm:group-hover:opacity-100 sm:group-focus-within:opacity-100 focus:opacity-100 transition-colors">reset</button>
{/if}
</div>
<div class="flex gap-1">
Expand Down Expand Up @@ -796,7 +796,7 @@
<div class="flex items-center justify-between mb-1">
<span class="text-[10px] font-semibold text-slate-200">{t.label}</span>
{#if t.token in overrides}
<button onclick={() => onReset(t.token)} class="text-[9px] text-slate-500 hover:text-rose-400 cursor-pointer opacity-0 group-hover:opacity-100">reset</button>
<button onclick={() => onReset(t.token)} class="text-[9px] text-slate-500 hover:text-rose-400 cursor-pointer opacity-100 sm:opacity-0 sm:group-hover:opacity-100 sm:group-focus-within:opacity-100 focus:opacity-100">reset</button>
{/if}
</div>
<RangeWithNumber
Expand Down