Fix ColorPicker solid color issues, add per-field reset, regroup accents
ColorPicker fixes: - Color picker now initializes to default color instead of black when field is cleared/empty - Switching Solid<>Gradient no longer emits black; restores default color when switching back to Solid from a gradient value - No-op guard prevents re-emitting when clicking the already-active mode - Reset button now says "Reset to default" when a default is available - Text input placeholder shows the default value Branding page: - Accent Colors regrouped: Primary+hover and Danger+hover are stacked together, Success and Warning standalone in a 4-column grid - Mini preview fallbacks now use getDefault() helper instead of hardcoded values, keeping them in sync with the defaults map Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -35,7 +35,8 @@
|
|||||||
color = v;
|
color = v;
|
||||||
} else {
|
} else {
|
||||||
mode = 'color';
|
mode = 'color';
|
||||||
color = '#000000';
|
// Show the default color in the picker when no custom value is set
|
||||||
|
color = defaultValue && defaultValue.startsWith('#') ? defaultValue : '#000000';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -50,15 +51,20 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function switchMode(newMode: 'color' | 'gradient') {
|
function switchMode(newMode: 'color' | 'gradient') {
|
||||||
|
if (mode === newMode) return;
|
||||||
mode = newMode;
|
mode = newMode;
|
||||||
if (newMode === 'color') {
|
if (newMode === 'color') {
|
||||||
|
// Restore from default if available, not leftover gradient state
|
||||||
|
if (!value || value.startsWith('linear-gradient') || value.startsWith('radial-gradient')) {
|
||||||
|
color = defaultValue && defaultValue.startsWith('#') ? defaultValue : '#000000';
|
||||||
|
}
|
||||||
emitColor();
|
emitColor();
|
||||||
} else {
|
} else {
|
||||||
emitGradient();
|
emitGradient();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function clear() {
|
function resetToDefault() {
|
||||||
value = '';
|
value = '';
|
||||||
onchange?.('');
|
onchange?.('');
|
||||||
}
|
}
|
||||||
@@ -68,7 +74,9 @@
|
|||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<label class="block text-xs font-medium text-gray-600 dark:text-gray-400">{label}</label>
|
<label class="block text-xs font-medium text-gray-600 dark:text-gray-400">{label}</label>
|
||||||
{#if value}
|
{#if value}
|
||||||
<button onclick={clear} class="text-[10px] text-gray-400 hover:text-gray-600 dark:hover:text-gray-300">Reset</button>
|
<button onclick={resetToDefault} class="text-[10px] text-gray-400 hover:text-gray-600 dark:hover:text-gray-300">
|
||||||
|
{defaultValue ? 'Reset to default' : 'Clear'}
|
||||||
|
</button>
|
||||||
{:else if defaultValue}
|
{:else if defaultValue}
|
||||||
<span class="text-[10px] text-gray-400 dark:text-gray-500">Default</span>
|
<span class="text-[10px] text-gray-400 dark:text-gray-500">Default</span>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -103,7 +111,7 @@
|
|||||||
type="text"
|
type="text"
|
||||||
bind:value={color}
|
bind:value={color}
|
||||||
oninput={emitColor}
|
oninput={emitColor}
|
||||||
placeholder="#000000"
|
placeholder={defaultValue || '#000000'}
|
||||||
class="flex-1 rounded border border-gray-300 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100 px-2 py-1 text-xs font-mono focus:border-[var(--color-primary)] focus:outline-none"
|
class="flex-1 rounded border border-gray-300 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100 px-2 py-1 text-xs font-mono focus:border-[var(--color-primary)] focus:outline-none"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -358,37 +358,45 @@
|
|||||||
<!-- Accent Colors -->
|
<!-- Accent Colors -->
|
||||||
<section class="rounded-xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 p-5">
|
<section class="rounded-xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 p-5">
|
||||||
<h2 class="text-sm font-semibold text-gray-800 dark:text-gray-200 mb-4">Accent Colors</h2>
|
<h2 class="text-sm font-semibold text-gray-800 dark:text-gray-200 mb-4">Accent Colors</h2>
|
||||||
<div class="grid grid-cols-2 sm:grid-cols-3 gap-4">
|
<div class="grid grid-cols-2 sm:grid-cols-4 gap-4">
|
||||||
<ColorPicker
|
<!-- Primary group -->
|
||||||
label="Primary"
|
<div class="space-y-3">
|
||||||
value={getField('primary') || ''}
|
<ColorPicker
|
||||||
defaultValue={getDefault('primary')}
|
label="Primary"
|
||||||
onchange={(v) => setField('primary', v)}
|
value={getField('primary') || ''}
|
||||||
/>
|
defaultValue={getDefault('primary')}
|
||||||
<ColorPicker
|
onchange={(v) => setField('primary', v)}
|
||||||
label="Primary hover"
|
/>
|
||||||
value={getField('primaryHover') || ''}
|
<ColorPicker
|
||||||
defaultValue={getDefault('primaryHover')}
|
label="Primary hover"
|
||||||
onchange={(v) => setField('primaryHover', v)}
|
value={getField('primaryHover') || ''}
|
||||||
/>
|
defaultValue={getDefault('primaryHover')}
|
||||||
<ColorPicker
|
onchange={(v) => setField('primaryHover', v)}
|
||||||
label="Danger"
|
/>
|
||||||
value={getField('danger') || ''}
|
</div>
|
||||||
defaultValue={getDefault('danger')}
|
<!-- Danger group -->
|
||||||
onchange={(v) => setField('danger', v)}
|
<div class="space-y-3">
|
||||||
/>
|
<ColorPicker
|
||||||
<ColorPicker
|
label="Danger"
|
||||||
label="Danger hover"
|
value={getField('danger') || ''}
|
||||||
value={getField('dangerHover') || ''}
|
defaultValue={getDefault('danger')}
|
||||||
defaultValue={getDefault('dangerHover')}
|
onchange={(v) => setField('danger', v)}
|
||||||
onchange={(v) => setField('dangerHover', v)}
|
/>
|
||||||
/>
|
<ColorPicker
|
||||||
|
label="Danger hover"
|
||||||
|
value={getField('dangerHover') || ''}
|
||||||
|
defaultValue={getDefault('dangerHover')}
|
||||||
|
onchange={(v) => setField('dangerHover', v)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<!-- Success -->
|
||||||
<ColorPicker
|
<ColorPicker
|
||||||
label="Success"
|
label="Success"
|
||||||
value={getField('success') || ''}
|
value={getField('success') || ''}
|
||||||
defaultValue={getDefault('success')}
|
defaultValue={getDefault('success')}
|
||||||
onchange={(v) => setField('success', v)}
|
onchange={(v) => setField('success', v)}
|
||||||
/>
|
/>
|
||||||
|
<!-- Warning -->
|
||||||
<ColorPicker
|
<ColorPicker
|
||||||
label="Warning"
|
label="Warning"
|
||||||
value={getField('warning') || ''}
|
value={getField('warning') || ''}
|
||||||
@@ -403,12 +411,12 @@
|
|||||||
<h2 class="text-sm font-semibold text-gray-800 dark:text-gray-200 mb-4">Preview</h2>
|
<h2 class="text-sm font-semibold text-gray-800 dark:text-gray-200 mb-4">Preview</h2>
|
||||||
<div
|
<div
|
||||||
class="rounded-lg overflow-hidden border border-gray-200 dark:border-gray-600"
|
class="rounded-lg overflow-hidden border border-gray-200 dark:border-gray-600"
|
||||||
style="background: {getField('pageBg') || (activeTab === 'light' ? '#f9fafb' : '#030712')}; min-height: 200px;"
|
style="background: {getField('pageBg') || getDefault('pageBg')}; min-height: 200px;"
|
||||||
>
|
>
|
||||||
<!-- Mini nav -->
|
<!-- Mini nav -->
|
||||||
<div
|
<div
|
||||||
class="h-8 flex items-center px-3"
|
class="h-8 flex items-center px-3"
|
||||||
style="background: {getField('navBg') || (activeTab === 'light' ? '#0079bf' : '#3b82f6')};"
|
style="background: {getField('navBg') || getDefault('navBg')};"
|
||||||
>
|
>
|
||||||
<span class="text-white text-xs font-bold">Pounce</span>
|
<span class="text-white text-xs font-bold">Pounce</span>
|
||||||
<div class="ml-auto flex gap-1">
|
<div class="ml-auto flex gap-1">
|
||||||
@@ -421,13 +429,13 @@
|
|||||||
{#each ['To Do', 'In Progress', 'Done'] as colTitle}
|
{#each ['To Do', 'In Progress', 'Done'] as colTitle}
|
||||||
<div
|
<div
|
||||||
class="w-28 rounded-lg p-2"
|
class="w-28 rounded-lg p-2"
|
||||||
style="background: {getField('columnBg') || (activeTab === 'light' ? '#ebecf0' : '#1f2937')}; border: 1px solid {getField('columnBorder') || 'transparent'}; color: {getField('columnText') || 'inherit'}; opacity: {getField('columnOpacity') != null && getField('columnOpacity') !== '' ? getField('columnOpacity') : 1};"
|
style="background: {getField('columnBg') || getDefault('columnBg')}; border: 1px solid {getField('columnBorder') || getDefault('columnBorder')}; color: {getField('columnText') || getDefault('columnText')}; opacity: {getField('columnOpacity') != null && getField('columnOpacity') !== '' ? getField('columnOpacity') : 1};"
|
||||||
>
|
>
|
||||||
<div class="text-[10px] font-semibold mb-1.5" style="color: {getField('columnText') || (activeTab === 'light' ? '#374151' : '#d1d5db')};">{colTitle}</div>
|
<div class="text-[10px] font-semibold mb-1.5" style="color: {getField('columnText') || (activeTab === 'light' ? '#374151' : '#d1d5db')};">{colTitle}</div>
|
||||||
{#each [1, 2] as _}
|
{#each [1, 2] as _}
|
||||||
<div
|
<div
|
||||||
class="mb-1 p-1.5 shadow-sm"
|
class="mb-1 p-1.5 shadow-sm"
|
||||||
style="background: {getField('cardBg') || (activeTab === 'light' ? '#ffffff' : '#374151')}; border: 1px solid {getField('cardBorder') || (activeTab === 'light' ? '#e5e7eb' : '#4b5563')}; border-radius: {getField('cardRadius') || '0.5rem'}; opacity: {getField('cardOpacity') != null && getField('cardOpacity') !== '' ? getField('cardOpacity') : 1};"
|
style="background: {getField('cardBg') || getDefault('cardBg')}; border: 1px solid {getField('cardBorder') || getDefault('cardBorder')}; border-radius: {getField('cardRadius') || '0.5rem'}; opacity: {getField('cardOpacity') != null && getField('cardOpacity') !== '' ? getField('cardOpacity') : 1};"
|
||||||
>
|
>
|
||||||
<div class="h-1.5 rounded" style="background: {getField('cardText') || (activeTab === 'light' ? '#374151' : '#d1d5db')}; width: 60%; opacity: 0.5;"></div>
|
<div class="h-1.5 rounded" style="background: {getField('cardText') || (activeTab === 'light' ? '#374151' : '#d1d5db')}; width: 60%; opacity: 0.5;"></div>
|
||||||
</div>
|
</div>
|
||||||
@@ -437,10 +445,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- Mini button row -->
|
<!-- Mini button row -->
|
||||||
<div class="flex gap-2 px-3 pb-3">
|
<div class="flex gap-2 px-3 pb-3">
|
||||||
<div class="rounded px-2 py-1 text-[10px] text-white" style="background: {getField('primary') || (activeTab === 'light' ? '#0079bf' : '#3b82f6')};">Primary</div>
|
<div class="rounded px-2 py-1 text-[10px] text-white" style="background: {getField('primary') || getDefault('primary')};">Primary</div>
|
||||||
<div class="rounded px-2 py-1 text-[10px] text-white" style="background: {getField('danger') || (activeTab === 'light' ? '#eb5a46' : '#ef4444')};">Danger</div>
|
<div class="rounded px-2 py-1 text-[10px] text-white" style="background: {getField('danger') || getDefault('danger')};">Danger</div>
|
||||||
<div class="rounded px-2 py-1 text-[10px] text-white" style="background: {getField('success') || (activeTab === 'light' ? '#61bd4f' : '#22c55e')};">Success</div>
|
<div class="rounded px-2 py-1 text-[10px] text-white" style="background: {getField('success') || getDefault('success')};">Success</div>
|
||||||
<div class="rounded px-2 py-1 text-[10px] text-gray-800" style="background: {getField('warning') || (activeTab === 'light' ? '#f2d600' : '#eab308')};">Warning</div>
|
<div class="rounded px-2 py-1 text-[10px] text-gray-800" style="background: {getField('warning') || getDefault('warning')};">Warning</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
Reference in New Issue
Block a user