mirror of
https://github.com/pheralb/svgl.git
synced 2024-11-10 14:46:54 +08:00
♻️ Create `CopySvg
` component for copying SVG
This commit is contained in:
parent
daab73eb58
commit
d4bee93474
101
src/components/copySvg.svelte
Normal file
101
src/components/copySvg.svelte
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { iSVG } from '@/types/svg';
|
||||||
|
|
||||||
|
import { CopyIcon } from 'lucide-svelte';
|
||||||
|
import { toast } from 'svelte-sonner';
|
||||||
|
|
||||||
|
// Utils:
|
||||||
|
import { MIMETYPE, getSvgContent } from '@/utils/getSvgContent';
|
||||||
|
import { copyToClipboard as figmaCopyToClipboard } from '@/figma/copy-to-clipboard';
|
||||||
|
|
||||||
|
// Props:
|
||||||
|
export let iconSize = 24;
|
||||||
|
export let iconStroke = 2;
|
||||||
|
export let isInFigma = false;
|
||||||
|
export let isWordmarkSvg = false;
|
||||||
|
export let svgInfo: iSVG;
|
||||||
|
|
||||||
|
// Copy SVG to clipboard:
|
||||||
|
const copyToClipboard = async () => {
|
||||||
|
let svgUrlToCopy;
|
||||||
|
const dark = document.documentElement.classList.contains('dark');
|
||||||
|
|
||||||
|
if (isWordmarkSvg) {
|
||||||
|
const svgHasTheme = typeof svgInfo.wordmark !== 'string';
|
||||||
|
if (!svgHasTheme) {
|
||||||
|
svgUrlToCopy =
|
||||||
|
typeof svgInfo.wordmark === 'string'
|
||||||
|
? svgInfo.wordmark
|
||||||
|
: "Something went wrong. Couldn't copy the SVG.";
|
||||||
|
}
|
||||||
|
|
||||||
|
svgUrlToCopy =
|
||||||
|
typeof svgInfo.wordmark !== 'string'
|
||||||
|
? dark
|
||||||
|
? svgInfo.wordmark?.dark
|
||||||
|
: svgInfo.wordmark?.light
|
||||||
|
: svgInfo.wordmark;
|
||||||
|
} else {
|
||||||
|
const svgHasTheme = typeof svgInfo.route !== 'string';
|
||||||
|
if (!svgHasTheme) {
|
||||||
|
svgUrlToCopy =
|
||||||
|
typeof svgInfo.route === 'string'
|
||||||
|
? svgInfo.route
|
||||||
|
: "Something went wrong. Couldn't copy the SVG.";
|
||||||
|
}
|
||||||
|
svgUrlToCopy =
|
||||||
|
typeof svgInfo.route !== 'string'
|
||||||
|
? dark
|
||||||
|
? svgInfo.route.dark
|
||||||
|
: svgInfo.route.light
|
||||||
|
: svgInfo.route;
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
[MIMETYPE]: getSvgContent(svgUrlToCopy, true)
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isInFigma) {
|
||||||
|
const content = (await getSvgContent(svgUrlToCopy, false)) as string;
|
||||||
|
figmaCopyToClipboard(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const clipboardItem = new ClipboardItem(data);
|
||||||
|
await navigator.clipboard.write([clipboardItem]);
|
||||||
|
} catch (error) {
|
||||||
|
const content = (await getSvgContent(svgUrlToCopy, false)) as string;
|
||||||
|
await navigator.clipboard.writeText(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
const category = Array.isArray(svgInfo.category)
|
||||||
|
? svgInfo.category.sort().join(' - ')
|
||||||
|
: svgInfo.category;
|
||||||
|
|
||||||
|
if (isInFigma) {
|
||||||
|
toast.success('Ready to paste in Figma!', {
|
||||||
|
description: `${svgInfo.title} - ${category}`
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isWordmarkSvg) {
|
||||||
|
toast.success('Copied wordmark SVG to clipboard!', {
|
||||||
|
description: `${svgInfo.title} - ${category}`
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
toast.success('Copied to clipboard!', {
|
||||||
|
description: `${svgInfo.title} - ${category}`
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button
|
||||||
|
title={isWordmarkSvg ? 'Copy wordmark SVG to clipboard' : 'Copy SVG to clipboard'}
|
||||||
|
on:click={() => copyToClipboard()}
|
||||||
|
class="flex items-center space-x-2 rounded-md p-2 duration-100 hover:bg-neutral-200 dark:hover:bg-neutral-700/40"
|
||||||
|
>
|
||||||
|
<CopyIcon size={iconSize} strokeWidth={iconStroke} />
|
||||||
|
</button>
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
// Utils:
|
// Utils:
|
||||||
import { cn } from '@/utils/cn';
|
import { cn } from '@/utils/cn';
|
||||||
import { MIMETYPE, getSvgContent } from '@/utils/getSvgContent';
|
import { getSvgContent } from '@/utils/getSvgContent';
|
||||||
|
|
||||||
// Icons:
|
// Icons:
|
||||||
import { CopyIcon, LinkIcon, ChevronsRight, Baseline, Sparkles } from 'lucide-svelte';
|
import { CopyIcon, LinkIcon, ChevronsRight, Baseline, Sparkles } from 'lucide-svelte';
|
||||||
@ -12,11 +12,11 @@
|
|||||||
// Components & styles:
|
// Components & styles:
|
||||||
import CardSpotlight from './cardSpotlight.svelte';
|
import CardSpotlight from './cardSpotlight.svelte';
|
||||||
import DownloadSvg from './downloadSvg.svelte';
|
import DownloadSvg from './downloadSvg.svelte';
|
||||||
|
import CopySvg from './copySvg.svelte';
|
||||||
import { badgeStyles } from '@/ui/styles';
|
import { badgeStyles } from '@/ui/styles';
|
||||||
|
|
||||||
// Figma
|
// Figma
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { copyToClipboard as figmaCopyToClipboard } from '@/figma/copy-to-clipboard';
|
|
||||||
import { insertSVG as figmaInsertSVG } from '@/figma/insert-svg';
|
import { insertSVG as figmaInsertSVG } from '@/figma/insert-svg';
|
||||||
|
|
||||||
// Props:
|
// Props:
|
||||||
@ -31,48 +31,6 @@
|
|||||||
// Wordmark SVG:
|
// Wordmark SVG:
|
||||||
let wordmarkSvg = false;
|
let wordmarkSvg = false;
|
||||||
|
|
||||||
// Copy SVG to clipboard:
|
|
||||||
const copyToClipboard = async (url?: string) => {
|
|
||||||
const data = {
|
|
||||||
[MIMETYPE]: getSvgContent(url, true)
|
|
||||||
};
|
|
||||||
|
|
||||||
if (isInFigma) {
|
|
||||||
const content = (await getSvgContent(url, false)) as string;
|
|
||||||
figmaCopyToClipboard(content);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const clipboardItem = new ClipboardItem(data);
|
|
||||||
await navigator.clipboard.write([clipboardItem]);
|
|
||||||
} catch (error) {
|
|
||||||
const content = (await getSvgContent(url, false)) as string;
|
|
||||||
await navigator.clipboard.writeText(content);
|
|
||||||
}
|
|
||||||
|
|
||||||
const category = Array.isArray(svgInfo.category)
|
|
||||||
? svgInfo.category.sort().join(' - ')
|
|
||||||
: svgInfo.category;
|
|
||||||
|
|
||||||
if (isInFigma) {
|
|
||||||
toast.success('Ready to paste in Figma!', {
|
|
||||||
description: `${svgInfo.title} - ${category}`
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wordmarkSvg) {
|
|
||||||
toast.success('Copied wordmark SVG to clipboard!', {
|
|
||||||
description: `${svgInfo.title} - ${category}`
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
toast.success('Copied to clipboard!', {
|
|
||||||
description: `${svgInfo.title} - ${category}`
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const insertSVG = async (url?: string) => {
|
const insertSVG = async (url?: string) => {
|
||||||
const content = (await getSvgContent(url, false)) as string;
|
const content = (await getSvgContent(url, false)) as string;
|
||||||
figmaInsertSVG(content);
|
figmaInsertSVG(content);
|
||||||
@ -172,63 +130,9 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if wordmarkSvg}
|
{#if wordmarkSvg}
|
||||||
<button
|
<CopySvg {iconSize} {iconStroke} {svgInfo} isInFigma={false} isWordmarkSvg={true} />
|
||||||
title="Copy wordmark SVG to clipboard"
|
|
||||||
on:click={() => {
|
|
||||||
const svgHasTheme = typeof svgInfo.wordmark !== 'string';
|
|
||||||
|
|
||||||
if (!svgHasTheme) {
|
|
||||||
copyToClipboard(
|
|
||||||
typeof svgInfo.wordmark === 'string'
|
|
||||||
? svgInfo.wordmark
|
|
||||||
: "Something went wrong. Couldn't copy the SVG."
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const dark = document.documentElement.classList.contains('dark');
|
|
||||||
|
|
||||||
copyToClipboard(
|
|
||||||
typeof svgInfo.wordmark !== 'string'
|
|
||||||
? dark
|
|
||||||
? svgInfo.wordmark?.dark
|
|
||||||
: svgInfo.wordmark?.light
|
|
||||||
: svgInfo.wordmark
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
class="flex items-center space-x-2 rounded-md p-2 duration-100 hover:bg-neutral-200 dark:hover:bg-neutral-700/40"
|
|
||||||
>
|
|
||||||
<CopyIcon size={iconSize} strokeWidth={iconStroke} />
|
|
||||||
</button>
|
|
||||||
{:else}
|
{:else}
|
||||||
<button
|
<CopySvg {iconSize} {iconStroke} {svgInfo} isInFigma={false} isWordmarkSvg={false} />
|
||||||
title="Copy to clipboard"
|
|
||||||
on:click={() => {
|
|
||||||
const svgHasTheme = typeof svgInfo.route !== 'string';
|
|
||||||
|
|
||||||
if (!svgHasTheme) {
|
|
||||||
copyToClipboard(
|
|
||||||
typeof svgInfo.route === 'string'
|
|
||||||
? svgInfo.route
|
|
||||||
: "Something went wrong. Couldn't copy the SVG."
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const dark = document.documentElement.classList.contains('dark');
|
|
||||||
|
|
||||||
copyToClipboard(
|
|
||||||
typeof svgInfo.route !== 'string'
|
|
||||||
? dark
|
|
||||||
? svgInfo.route.dark
|
|
||||||
: svgInfo.route.light
|
|
||||||
: svgInfo.route
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
class="flex items-center space-x-2 rounded-md p-2 duration-100 hover:bg-neutral-200 dark:hover:bg-neutral-700/40"
|
|
||||||
>
|
|
||||||
<CopyIcon size={iconSize} strokeWidth={iconStroke} />
|
|
||||||
</button>
|
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<DownloadSvg
|
<DownloadSvg
|
||||||
|
Loading…
Reference in New Issue
Block a user