♻️ Create `CopySvg` component for copying SVG

This commit is contained in:
pheralb 2024-04-09 16:23:31 +01:00
parent daab73eb58
commit d4bee93474
2 changed files with 105 additions and 100 deletions

View 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>

View File

@ -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