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;
|
||||
} else {
|
||||
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') {
|
||||
if (mode === newMode) return;
|
||||
mode = newMode;
|
||||
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();
|
||||
} else {
|
||||
emitGradient();
|
||||
}
|
||||
}
|
||||
|
||||
function clear() {
|
||||
function resetToDefault() {
|
||||
value = '';
|
||||
onchange?.('');
|
||||
}
|
||||
@@ -68,7 +74,9 @@
|
||||
<div class="flex items-center justify-between">
|
||||
<label class="block text-xs font-medium text-gray-600 dark:text-gray-400">{label}</label>
|
||||
{#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}
|
||||
<span class="text-[10px] text-gray-400 dark:text-gray-500">Default</span>
|
||||
{/if}
|
||||
@@ -103,7 +111,7 @@
|
||||
type="text"
|
||||
bind:value={color}
|
||||
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"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -358,37 +358,45 @@
|
||||
<!-- Accent Colors -->
|
||||
<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>
|
||||
<div class="grid grid-cols-2 sm:grid-cols-3 gap-4">
|
||||
<ColorPicker
|
||||
label="Primary"
|
||||
value={getField('primary') || ''}
|
||||
defaultValue={getDefault('primary')}
|
||||
onchange={(v) => setField('primary', v)}
|
||||
/>
|
||||
<ColorPicker
|
||||
label="Primary hover"
|
||||
value={getField('primaryHover') || ''}
|
||||
defaultValue={getDefault('primaryHover')}
|
||||
onchange={(v) => setField('primaryHover', v)}
|
||||
/>
|
||||
<ColorPicker
|
||||
label="Danger"
|
||||
value={getField('danger') || ''}
|
||||
defaultValue={getDefault('danger')}
|
||||
onchange={(v) => setField('danger', v)}
|
||||
/>
|
||||
<ColorPicker
|
||||
label="Danger hover"
|
||||
value={getField('dangerHover') || ''}
|
||||
defaultValue={getDefault('dangerHover')}
|
||||
onchange={(v) => setField('dangerHover', v)}
|
||||
/>
|
||||
<div class="grid grid-cols-2 sm:grid-cols-4 gap-4">
|
||||
<!-- Primary group -->
|
||||
<div class="space-y-3">
|
||||
<ColorPicker
|
||||
label="Primary"
|
||||
value={getField('primary') || ''}
|
||||
defaultValue={getDefault('primary')}
|
||||
onchange={(v) => setField('primary', v)}
|
||||
/>
|
||||
<ColorPicker
|
||||
label="Primary hover"
|
||||
value={getField('primaryHover') || ''}
|
||||
defaultValue={getDefault('primaryHover')}
|
||||
onchange={(v) => setField('primaryHover', v)}
|
||||
/>
|
||||
</div>
|
||||
<!-- Danger group -->
|
||||
<div class="space-y-3">
|
||||
<ColorPicker
|
||||
label="Danger"
|
||||
value={getField('danger') || ''}
|
||||
defaultValue={getDefault('danger')}
|
||||
onchange={(v) => setField('danger', v)}
|
||||
/>
|
||||
<ColorPicker
|
||||
label="Danger hover"
|
||||
value={getField('dangerHover') || ''}
|
||||
defaultValue={getDefault('dangerHover')}
|
||||
onchange={(v) => setField('dangerHover', v)}
|
||||
/>
|
||||
</div>
|
||||
<!-- Success -->
|
||||
<ColorPicker
|
||||
label="Success"
|
||||
value={getField('success') || ''}
|
||||
defaultValue={getDefault('success')}
|
||||
onchange={(v) => setField('success', v)}
|
||||
/>
|
||||
<!-- Warning -->
|
||||
<ColorPicker
|
||||
label="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>
|
||||
<div
|
||||
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 -->
|
||||
<div
|
||||
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>
|
||||
<div class="ml-auto flex gap-1">
|
||||
@@ -421,13 +429,13 @@
|
||||
{#each ['To Do', 'In Progress', 'Done'] as colTitle}
|
||||
<div
|
||||
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>
|
||||
{#each [1, 2] as _}
|
||||
<div
|
||||
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>
|
||||
@@ -437,10 +445,10 @@
|
||||
</div>
|
||||
<!-- Mini button row -->
|
||||
<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('danger') || (activeTab === 'light' ? '#eb5a46' : '#ef4444')};">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-gray-800" style="background: {getField('warning') || (activeTab === 'light' ? '#f2d600' : '#eab308')};">Warning</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') || getDefault('danger')};">Danger</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') || getDefault('warning')};">Warning</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
Reference in New Issue
Block a user