mirror of
https://github.com/shadoll/sLogos.git
synced 2025-12-20 06:30:00 +00:00
Refactor logo management components: remove LogoModal, add Actions and Grid components, enhance List and Preview components with improved theme handling and SVG support.
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import LogoGrid from './components/LogoGrid.svelte';
|
import Grid from './components/Grid.svelte';
|
||||||
import LogoList from './components/LogoList.svelte';
|
import List from './components/List.svelte';
|
||||||
|
|
||||||
let viewMode = 'grid'; // 'grid' or 'list'
|
let viewMode = 'grid'; // 'grid' or 'list'
|
||||||
let searchQuery = '';
|
let searchQuery = '';
|
||||||
@@ -261,14 +261,14 @@
|
|||||||
|
|
||||||
<div class="logos-container">
|
<div class="logos-container">
|
||||||
{#if viewMode === 'grid'}
|
{#if viewMode === 'grid'}
|
||||||
<LogoGrid
|
<Grid
|
||||||
logos={filteredLogos}
|
logos={filteredLogos}
|
||||||
onCopy={copyUrl}
|
onCopy={copyUrl}
|
||||||
onDownload={downloadLogo}
|
onDownload={downloadLogo}
|
||||||
theme={effectiveTheme}
|
theme={effectiveTheme}
|
||||||
/>
|
/>
|
||||||
{:else}
|
{:else}
|
||||||
<LogoList
|
<List
|
||||||
logos={filteredLogos}
|
logos={filteredLogos}
|
||||||
onCopy={copyUrl}
|
onCopy={copyUrl}
|
||||||
onDownload={downloadLogo}
|
onDownload={downloadLogo}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import LogoModal from './LogoModal.svelte';
|
import Preview from './Preview.svelte';
|
||||||
import LogoActions from './LogoActions.svelte';
|
import Actions from './Actions.svelte';
|
||||||
import InlineSvg from './InlineSvg.svelte';
|
import InlineSvg from './InlineSvg.svelte';
|
||||||
import { onMount, onDestroy } from 'svelte';
|
import { onMount, onDestroy } from 'svelte';
|
||||||
import { getDefaultLogoColor, getThemeColor } from '../utils/colorTheme.js';
|
import { getDefaultLogoColor, getThemeColor } from '../utils/colorTheme.js';
|
||||||
@@ -53,7 +53,7 @@ $: getLogoThemeColor = logo => getDefaultLogoColor(logo.colors, theme);
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<LogoModal show={showModal} logo={selectedLogo} theme={theme} on:close={closeModal} />
|
<Preview 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}
|
||||||
@@ -115,7 +115,7 @@ $: getLogoThemeColor = logo => getDefaultLogoColor(logo.colors, theme);
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="logo-actions">
|
<div class="logo-actions">
|
||||||
<LogoActions {logo} {onCopy} {onDownload} />
|
<Actions {logo} {onCopy} {onDownload} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
<script>
|
<script>
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from "svelte";
|
||||||
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;
|
export const alt = "";
|
||||||
|
|
||||||
let svgHtml = '';
|
let svgHtml = "";
|
||||||
|
|
||||||
async function fetchAndColorSvg() {
|
async function fetchAndColorSvg() {
|
||||||
const res = await fetch(path);
|
const res = await fetch(path);
|
||||||
@@ -17,10 +17,10 @@
|
|||||||
}
|
}
|
||||||
// Parse and update color only if user selected
|
// Parse and update color only if user selected
|
||||||
const parser = new DOMParser();
|
const parser = new DOMParser();
|
||||||
const doc = parser.parseFromString(text, 'image/svg+xml');
|
const doc = parser.parseFromString(text, "image/svg+xml");
|
||||||
// 1. Parse <style> rules and apply as inline attributes before removing <style>
|
// 1. Parse <style> rules and apply as inline attributes before removing <style>
|
||||||
const styleEls = Array.from(doc.querySelectorAll('style'));
|
const styleEls = Array.from(doc.querySelectorAll("style"));
|
||||||
styleEls.forEach(styleEl => {
|
styleEls.forEach((styleEl) => {
|
||||||
const css = styleEl.textContent;
|
const css = styleEl.textContent;
|
||||||
// Only handle simple .class { ... } rules
|
// Only handle simple .class { ... } rules
|
||||||
const regex = /\.([\w-]+)\s*{([^}]*)}/g;
|
const regex = /\.([\w-]+)\s*{([^}]*)}/g;
|
||||||
@@ -29,19 +29,22 @@
|
|||||||
const className = match[1];
|
const className = match[1];
|
||||||
const rules = match[2];
|
const rules = match[2];
|
||||||
// Find all elements with this class
|
// Find all elements with this class
|
||||||
doc.querySelectorAll('.' + className).forEach(el => {
|
doc.querySelectorAll("." + className).forEach((el) => {
|
||||||
rules.split(';').forEach(rule => {
|
rules.split(";").forEach((rule) => {
|
||||||
const [prop, value] = rule.split(':').map(s => s && s.trim());
|
const [prop, value] = rule.split(":").map((s) => s && s.trim());
|
||||||
if (prop && value) {
|
if (prop && value) {
|
||||||
// Apply all style properties, not just fill/stroke
|
// Apply all style properties, not just fill/stroke
|
||||||
el.setAttribute(prop.replace(/-([a-z])/g, g => g[1].toUpperCase()), value);
|
el.setAttribute(
|
||||||
|
prop.replace(/-([a-z])/g, (g) => g[1].toUpperCase()),
|
||||||
|
value,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Remove all <style> elements
|
// Remove all <style> elements
|
||||||
styleEls.forEach(styleEl => styleEl.remove());
|
styleEls.forEach((styleEl) => styleEl.remove());
|
||||||
let targets;
|
let targets;
|
||||||
if (colorConfig.selector) {
|
if (colorConfig.selector) {
|
||||||
targets = doc.querySelectorAll(colorConfig.selector);
|
targets = doc.querySelectorAll(colorConfig.selector);
|
||||||
@@ -50,21 +53,21 @@
|
|||||||
} else {
|
} else {
|
||||||
targets = [];
|
targets = [];
|
||||||
}
|
}
|
||||||
targets.forEach(el => {
|
targets.forEach((el) => {
|
||||||
if (colorConfig.attribute) {
|
if (colorConfig.attribute) {
|
||||||
// Legacy: force a single attribute
|
// Legacy: force a single attribute
|
||||||
el.setAttribute(colorConfig.attribute, color);
|
el.setAttribute(colorConfig.attribute, color);
|
||||||
} else {
|
} else {
|
||||||
// Always override fill and stroke unless they are 'none'
|
// Always override fill and stroke unless they are 'none'
|
||||||
if (el.hasAttribute('fill') && el.getAttribute('fill') !== 'none') {
|
if (el.hasAttribute("fill") && el.getAttribute("fill") !== "none") {
|
||||||
el.setAttribute('fill', color);
|
el.setAttribute("fill", color);
|
||||||
}
|
}
|
||||||
if (el.hasAttribute('stroke') && el.getAttribute('stroke') !== 'none') {
|
if (el.hasAttribute("stroke") && el.getAttribute("stroke") !== "none") {
|
||||||
el.setAttribute('stroke', color);
|
el.setAttribute("stroke", color);
|
||||||
}
|
}
|
||||||
if (!el.hasAttribute('fill') && !el.hasAttribute('stroke')) {
|
if (!el.hasAttribute("fill") && !el.hasAttribute("stroke")) {
|
||||||
// If neither, prefer fill
|
// If neither, prefer fill
|
||||||
el.setAttribute('fill', color);
|
el.setAttribute("fill", color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import LogoModal from './LogoModal.svelte';
|
import Preview from './Preview.svelte';
|
||||||
import LogoActions from './LogoActions.svelte';
|
import Actions from './Actions.svelte';
|
||||||
import InlineSvg from './InlineSvg.svelte';
|
import InlineSvg from './InlineSvg.svelte';
|
||||||
import { getThemeColor, getDefaultLogoColor } from '../utils/colorTheme.js';
|
import { getThemeColor, getDefaultLogoColor } from '../utils/colorTheme.js';
|
||||||
import { onMount, onDestroy } from 'svelte';
|
import { onMount, onDestroy } from 'svelte';
|
||||||
@@ -64,7 +64,7 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<LogoModal show={showModal} logo={selectedLogo} on:close={closeModal} />
|
<Preview show={showModal} logo={selectedLogo} on:close={closeModal} />
|
||||||
|
|
||||||
<div class="logo-list">
|
<div class="logo-list">
|
||||||
{#each logos as logo}
|
{#each logos as logo}
|
||||||
@@ -77,8 +77,7 @@
|
|||||||
on:keydown={(e) => (e.key === 'Enter' || e.key === ' ') && openPreview(logo)}
|
on:keydown={(e) => (e.key === 'Enter' || e.key === ' ') && openPreview(logo)}
|
||||||
style="cursor:pointer;"
|
style="cursor:pointer;"
|
||||||
>
|
>
|
||||||
{#if isSvgLogo(logo)}
|
{#if isSvgLogo(logo)} <InlineSvg
|
||||||
<InlineSvg
|
|
||||||
path={logo.path}
|
path={logo.path}
|
||||||
color={logo.colors ? (logo._activeColor || getLogoThemeColor(logo)) : undefined}
|
color={logo.colors ? (logo._activeColor || getLogoThemeColor(logo)) : undefined}
|
||||||
colorConfig={logo.colors ? logo.colorConfig : undefined}
|
colorConfig={logo.colors ? logo.colorConfig : undefined}
|
||||||
@@ -125,7 +124,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="logo-actions">
|
<div class="logo-actions">
|
||||||
<LogoActions {logo} {onCopy} {onDownload} />
|
<Actions {logo} {onCopy} {onDownload} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
Reference in New Issue
Block a user