mirror of
https://github.com/shadoll/sLogos.git
synced 2026-02-04 11:03:24 +00:00
Enhance theme handling and color selection for logos; add utility functions for theme-based color retrieval and improve debug logging across components.
This commit is contained in:
@@ -73,6 +73,7 @@ button:hover {
|
|||||||
font-size: 0.95em;
|
font-size: 0.95em;
|
||||||
border-right: 1px solid var(--color-border, #ddd);
|
border-right: 1px solid var(--color-border, #ddd);
|
||||||
transition: background 0.2s, color 0.2s;
|
transition: background 0.2s, color 0.2s;
|
||||||
|
text-wrap: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.copy-btn:last-child,
|
.copy-btn:last-child,
|
||||||
|
|||||||
@@ -71,6 +71,11 @@
|
|||||||
return matchesSearch && matchesTags;
|
return matchesSearch && matchesTags;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Compute the effective theme for children
|
||||||
|
$: effectiveTheme = theme === 'system'
|
||||||
|
? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')
|
||||||
|
: theme;
|
||||||
|
|
||||||
function setGridView() {
|
function setGridView() {
|
||||||
console.log('Setting view mode to: grid');
|
console.log('Setting view mode to: grid');
|
||||||
viewMode = 'grid';
|
viewMode = 'grid';
|
||||||
@@ -257,6 +262,7 @@
|
|||||||
logos={filteredLogos}
|
logos={filteredLogos}
|
||||||
onCopy={copyUrl}
|
onCopy={copyUrl}
|
||||||
onDownload={downloadLogo}
|
onDownload={downloadLogo}
|
||||||
|
theme={effectiveTheme}
|
||||||
/>
|
/>
|
||||||
{:else}
|
{:else}
|
||||||
<LogoList
|
<LogoList
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
export let path;
|
export let path;
|
||||||
export let color;
|
export let color;
|
||||||
export let colorConfig = { target: 'path', attribute: 'fill' };
|
export let colorConfig = { target: 'path', attribute: 'fill' };
|
||||||
|
export let alt;
|
||||||
|
|
||||||
let svgHtml = '';
|
let svgHtml = '';
|
||||||
|
|
||||||
@@ -54,18 +55,17 @@
|
|||||||
// Legacy: force a single attribute
|
// Legacy: force a single attribute
|
||||||
el.setAttribute(colorConfig.attribute, color);
|
el.setAttribute(colorConfig.attribute, color);
|
||||||
} else {
|
} else {
|
||||||
// Only set fill if no stroke attribute exists, and vice versa
|
// Always override fill and stroke unless they are 'none'
|
||||||
const hasFill = el.hasAttribute('fill');
|
if (el.hasAttribute('fill') && el.getAttribute('fill') !== 'none') {
|
||||||
const hasStroke = el.hasAttribute('stroke');
|
|
||||||
if (hasFill && !hasStroke && el.getAttribute('fill') !== 'none') {
|
|
||||||
el.setAttribute('fill', color);
|
el.setAttribute('fill', color);
|
||||||
} else if (hasStroke && !hasFill && el.getAttribute('stroke') !== 'none') {
|
}
|
||||||
|
if (el.hasAttribute('stroke') && el.getAttribute('stroke') !== 'none') {
|
||||||
el.setAttribute('stroke', color);
|
el.setAttribute('stroke', color);
|
||||||
} else if (!hasFill && !hasStroke) {
|
}
|
||||||
|
if (!el.hasAttribute('fill') && !el.hasAttribute('stroke')) {
|
||||||
// If neither, prefer fill
|
// If neither, prefer fill
|
||||||
el.setAttribute('fill', color);
|
el.setAttribute('fill', color);
|
||||||
}
|
}
|
||||||
// If both fill and stroke exist, do not override either
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
svgHtml = doc.documentElement.outerHTML;
|
svgHtml = doc.documentElement.outerHTML;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
export let logo;
|
export let logo;
|
||||||
|
export let onCopy;
|
||||||
export let onDownload;
|
export let onDownload;
|
||||||
|
|
||||||
// Download menu state
|
// Download menu state
|
||||||
@@ -209,7 +210,7 @@
|
|||||||
|
|
||||||
function handleDownloadJpgClick(e) {
|
function handleDownloadJpgClick(e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
console.log('Download JPG clicked', logo);
|
// ...existing code...
|
||||||
try {
|
try {
|
||||||
downloadJpg(logo);
|
downloadJpg(logo);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -284,36 +285,13 @@
|
|||||||
margin-right: 0.5em;
|
margin-right: 0.5em;
|
||||||
}
|
}
|
||||||
.copy-btn {
|
.copy-btn {
|
||||||
background: var(--secondary-color, #2c3e50);
|
|
||||||
color: #fff;
|
|
||||||
font-weight: 500;
|
|
||||||
letter-spacing: 0.02em;
|
|
||||||
min-width: 4em;
|
min-width: 4em;
|
||||||
border-radius: 6px 0 0 6px;
|
border-radius: 6px 0 0 6px;
|
||||||
margin: 0;
|
|
||||||
padding: 0.4em 1em;
|
|
||||||
font-size: 0.95em;
|
|
||||||
border: none;
|
border: none;
|
||||||
transition: background 0.2s, color 0.2s;
|
|
||||||
}
|
|
||||||
.copy-btn:focus,
|
|
||||||
.copy-btn:hover {
|
|
||||||
background: #222;
|
|
||||||
color: #fff;
|
|
||||||
outline: none;
|
|
||||||
}
|
}
|
||||||
.download-btn {
|
.download-btn {
|
||||||
background: #27ae60;
|
|
||||||
color: #fff;
|
|
||||||
font-weight: 500;
|
|
||||||
letter-spacing: 0.02em;
|
|
||||||
min-width: 4em;
|
|
||||||
border-radius: 6px 0 0 6px;
|
border-radius: 6px 0 0 6px;
|
||||||
margin: 0;
|
|
||||||
padding: 0.4em 1em;
|
|
||||||
font-size: 0.95em;
|
|
||||||
border: none;
|
border: none;
|
||||||
transition: background 0.2s, color 0.2s;
|
|
||||||
}
|
}
|
||||||
.download-btn:focus,
|
.download-btn:focus,
|
||||||
.download-btn:hover {
|
.download-btn:hover {
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
import LogoModal from './LogoModal.svelte';
|
import LogoModal from './LogoModal.svelte';
|
||||||
import LogoActions from './LogoActions.svelte';
|
import LogoActions from './LogoActions.svelte';
|
||||||
import InlineSvg from './InlineSvg.svelte';
|
import InlineSvg from './InlineSvg.svelte';
|
||||||
import { onMount } from 'svelte';
|
import { onMount, onDestroy } from 'svelte';
|
||||||
|
import { getDefaultLogoColor, getThemeColor } from '../utils/colorTheme.js';
|
||||||
|
|
||||||
export let logos = [];
|
export let logos = [];
|
||||||
export let onCopy;
|
export let onCopy;
|
||||||
@@ -24,6 +25,22 @@
|
|||||||
return logo.format && logo.format.toLowerCase() === 'svg';
|
return logo.format && logo.format.toLowerCase() === 'svg';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export let theme;
|
||||||
|
$: getLogoThemeColor = logo => getDefaultLogoColor(logo.colors, theme);
|
||||||
|
|
||||||
|
// Improved debug logging for color and theme for each logo
|
||||||
|
$: {
|
||||||
|
if (logos && logos.length) {
|
||||||
|
logos.forEach(logo => {
|
||||||
|
if (logo.colors) {
|
||||||
|
const themeColor = getDefaultLogoColor(logo.colors, theme);
|
||||||
|
const fallbackColor = getThemeColor(logo.colors, theme);
|
||||||
|
const activeColor = logo._activeColor || themeColor;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Inline SVG logic for color switching
|
// Inline SVG logic for color switching
|
||||||
let svgCache = {};
|
let svgCache = {};
|
||||||
|
|
||||||
@@ -36,7 +53,7 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<LogoModal show={showModal} logo={selectedLogo} on:close={closeModal} />
|
<LogoModal show={showModal} logo={selectedLogo} theme={theme} on:close={closeModal} />
|
||||||
|
|
||||||
<div class="logo-grid">
|
<div class="logo-grid">
|
||||||
{#each logos as logo}
|
{#each logos as logo}
|
||||||
@@ -50,12 +67,14 @@
|
|||||||
style="cursor:pointer;"
|
style="cursor:pointer;"
|
||||||
>
|
>
|
||||||
{#if isSvgLogo(logo)}
|
{#if isSvgLogo(logo)}
|
||||||
<InlineSvg
|
{#key theme + (logo._activeColor || '')}
|
||||||
path={logo.path}
|
<InlineSvg
|
||||||
color={logo.colors ? (logo._activeColor || logo.colors[0].value) : undefined}
|
path={logo.path}
|
||||||
colorConfig={logo.colors ? logo.colorConfig : undefined}
|
color={logo.colors ? (logo._activeColor || getLogoThemeColor(logo)) : undefined}
|
||||||
alt={logo.name}
|
colorConfig={logo.colors ? logo.colorConfig : undefined}
|
||||||
/>
|
alt={logo.name}
|
||||||
|
/>
|
||||||
|
{/key}
|
||||||
{:else}
|
{:else}
|
||||||
<img src={logo.path} alt={logo.name} />
|
<img src={logo.path} alt={logo.name} />
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
import LogoModal from './LogoModal.svelte';
|
import LogoModal from './LogoModal.svelte';
|
||||||
import LogoActions from './LogoActions.svelte';
|
import LogoActions from './LogoActions.svelte';
|
||||||
import InlineSvg from './InlineSvg.svelte';
|
import InlineSvg from './InlineSvg.svelte';
|
||||||
|
import { getThemeColor, getDefaultLogoColor } from '../utils/colorTheme.js';
|
||||||
|
import { onMount, onDestroy } from 'svelte';
|
||||||
|
|
||||||
export let logos = [];
|
export let logos = [];
|
||||||
export let onCopy;
|
export let onCopy;
|
||||||
@@ -10,6 +12,8 @@
|
|||||||
let showModal = false;
|
let showModal = false;
|
||||||
let selectedLogo = null;
|
let selectedLogo = null;
|
||||||
|
|
||||||
|
let theme = getTheme();
|
||||||
|
|
||||||
function openPreview(logo) {
|
function openPreview(logo) {
|
||||||
selectedLogo = logo;
|
selectedLogo = logo;
|
||||||
showModal = true;
|
showModal = true;
|
||||||
@@ -23,6 +27,41 @@
|
|||||||
return logo.format && logo.format.toLowerCase() === 'svg';
|
return logo.format && logo.format.toLowerCase() === 'svg';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getTheme() {
|
||||||
|
if (typeof window !== 'undefined' && window.matchMedia) {
|
||||||
|
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
||||||
|
}
|
||||||
|
return 'light';
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleThemeChange(e) {
|
||||||
|
theme = e.matches ? 'dark' : 'light';
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
const mql = window.matchMedia('(prefers-color-scheme: dark)');
|
||||||
|
mql.addEventListener('change', handleThemeChange);
|
||||||
|
});
|
||||||
|
|
||||||
|
onDestroy(() => {
|
||||||
|
const mql = window.matchMedia('(prefers-color-scheme: dark)');
|
||||||
|
mql.removeEventListener('change', handleThemeChange);
|
||||||
|
});
|
||||||
|
|
||||||
|
$: getLogoThemeColor = logo => getDefaultLogoColor(logo.colors, theme);
|
||||||
|
|
||||||
|
// Debug logging for color and theme
|
||||||
|
$: {
|
||||||
|
if (logos && logos.length) {
|
||||||
|
logos.forEach(logo => {
|
||||||
|
if (logo.colors) {
|
||||||
|
const themeColor = getDefaultLogoColor(logo.colors, theme);
|
||||||
|
const activeColor = logo._activeColor || themeColor;
|
||||||
|
console.log('[LogoList] Logo:', logo.name, '| Theme:', theme, '| Theme color:', themeColor, '| Active color:', activeColor);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<LogoModal show={showModal} logo={selectedLogo} on:close={closeModal} />
|
<LogoModal show={showModal} logo={selectedLogo} on:close={closeModal} />
|
||||||
@@ -41,7 +80,7 @@
|
|||||||
{#if isSvgLogo(logo)}
|
{#if isSvgLogo(logo)}
|
||||||
<InlineSvg
|
<InlineSvg
|
||||||
path={logo.path}
|
path={logo.path}
|
||||||
color={logo.colors ? (logo._activeColor || logo.colors[0].value) : undefined}
|
color={logo.colors ? (logo._activeColor || getLogoThemeColor(logo)) : undefined}
|
||||||
colorConfig={logo.colors ? logo.colorConfig : undefined}
|
colorConfig={logo.colors ? logo.colorConfig : undefined}
|
||||||
alt={logo.name}
|
alt={logo.name}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { onMount, onDestroy, createEventDispatcher } from 'svelte';
|
import { onMount, onDestroy, createEventDispatcher } from 'svelte';
|
||||||
import InlineSvg from './InlineSvg.svelte';
|
import InlineSvg from './InlineSvg.svelte';
|
||||||
|
import { getDefaultLogoColor, getThemeColor } from '../utils/colorTheme.js';
|
||||||
|
|
||||||
export let show = false;
|
export let show = false;
|
||||||
export let logo = null;
|
export let logo = null;
|
||||||
@@ -21,6 +22,19 @@
|
|||||||
return logo && logo.format && logo.format.toLowerCase() === 'svg';
|
return logo && logo.format && logo.format.toLowerCase() === 'svg';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Always use $theme directly, do not cache in a function
|
||||||
|
export let theme;
|
||||||
|
$: getLogoThemeColor = logo => getDefaultLogoColor(logo.colors, theme);
|
||||||
|
|
||||||
|
// Improved debug logging for color and theme
|
||||||
|
$: {
|
||||||
|
if (logo && logo.colors) {
|
||||||
|
const themeColor = getDefaultLogoColor(logo.colors, theme);
|
||||||
|
const fallbackColor = getThemeColor(logo.colors, theme);
|
||||||
|
const activeColor = logo._activeColor || themeColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
document.addEventListener('keydown', handleKeydown);
|
document.addEventListener('keydown', handleKeydown);
|
||||||
});
|
});
|
||||||
@@ -30,11 +44,12 @@
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if show && logo}
|
<div class="modal-backdrop"
|
||||||
<div class="modal-backdrop"
|
style="display: {show && logo ? 'flex' : 'none'}"
|
||||||
role="dialog"
|
role="dialog"
|
||||||
aria-modal="true"
|
aria-modal="true"
|
||||||
>
|
>
|
||||||
|
{#if logo}
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h2>{logo.name}</h2>
|
<h2>{logo.name}</h2>
|
||||||
@@ -52,7 +67,7 @@
|
|||||||
{#if isSvgLogo(logo)}
|
{#if isSvgLogo(logo)}
|
||||||
<InlineSvg
|
<InlineSvg
|
||||||
path={logo.path}
|
path={logo.path}
|
||||||
color={logo.colors ? (logo._activeColor || logo.colors[0].value) : undefined}
|
color={logo.colors ? (logo._activeColor || getLogoThemeColor(logo)) : undefined}
|
||||||
colorConfig={logo.colors ? logo.colorConfig : undefined}
|
colorConfig={logo.colors ? logo.colorConfig : undefined}
|
||||||
alt={logo.name}
|
alt={logo.name}
|
||||||
/>
|
/>
|
||||||
@@ -88,8 +103,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{/if}
|
||||||
{/if}
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
:global(.modal-backdrop) {
|
:global(.modal-backdrop) {
|
||||||
@@ -134,6 +149,12 @@
|
|||||||
border: none;
|
border: none;
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
color: var(--color-text, #222);
|
||||||
|
transition: color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-btn:hover {
|
||||||
|
color: var(--color-accent, #4f8cff);
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-body img {
|
.modal-body img {
|
||||||
|
|||||||
19
src/utils/colorTheme.js
Normal file
19
src/utils/colorTheme.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
// Utility to pick the logo color for the current theme using the "theme" key only
|
||||||
|
export function getDefaultLogoColor(colors, theme = 'light') {
|
||||||
|
if (!colors || colors.length === 0) return undefined;
|
||||||
|
// Use the color with the matching theme key if present
|
||||||
|
const match = colors.find(c => c.theme === theme);
|
||||||
|
if (match) return match.value;
|
||||||
|
// Fallback: do not colorize (undefined)
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Utility to select the color with the matching theme key from the colors array
|
||||||
|
export function getThemeColor(colors, theme = 'light') {
|
||||||
|
if (!colors || colors.length === 0) return undefined;
|
||||||
|
// Try to find a color with the matching theme key
|
||||||
|
const match = colors.find(c => c.theme === theme);
|
||||||
|
if (match) return match.value;
|
||||||
|
// Fallback: pick the first color
|
||||||
|
return colors[0].value;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user