🐛 Import plugins directly into svgr

This commit is contained in:
pheralb 2024-04-09 23:26:51 +01:00
parent f1db803782
commit 6000cbb6a5
2 changed files with 36 additions and 7 deletions

View File

@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import type { iSVG } from '@/types/svg'; import type { iSVG } from '@/types/svg';
import { ClipboardIcon, CopyIcon, X } from 'lucide-svelte'; import { ClipboardIcon, CopyIcon, Loader, X } from 'lucide-svelte';
import { toast } from 'svelte-sonner'; import { toast } from 'svelte-sonner';
import * as Popover from '@/ui/popover'; import * as Popover from '@/ui/popover';
@ -19,6 +19,7 @@
export let isWordmarkSvg = false; export let isWordmarkSvg = false;
export let svgInfo: iSVG; export let svgInfo: iSVG;
let optionsOpen = false; let optionsOpen = false;
let isLoading = false;
const getSvgUrl = () => { const getSvgUrl = () => {
let svgUrlToCopy; let svgUrlToCopy;
@ -85,20 +86,20 @@
: svgInfo.category; : svgInfo.category;
if (isInFigma) { if (isInFigma) {
toast.success('Ready to paste in Figma!', { toast.success('Ready to paste in Figma', {
description: `${svgInfo.title} - ${category}` description: `${svgInfo.title} - ${category}`
}); });
return; return;
} }
if (isWordmarkSvg) { if (isWordmarkSvg) {
toast.success('Copied wordmark SVG to clipboard!', { toast.success('Copied wordmark SVG to clipboard', {
description: `${svgInfo.title} - ${category}` description: `${svgInfo.title} - ${category}`
}); });
return; return;
} }
toast.success('Copied to clipboard!', { toast.success('Copied to clipboard', {
description: `${svgInfo.title} - ${category}` description: `${svgInfo.title} - ${category}`
}); });
}; };
@ -108,6 +109,8 @@
const svgUrlToCopy = getSvgUrl(); const svgUrlToCopy = getSvgUrl();
optionsOpen = false; optionsOpen = false;
isLoading = true;
try { try {
const title = svgInfo.title.split(' ').join(''); const title = svgInfo.title.split(' ').join('');
const content = (await getSvgContent(svgUrlToCopy, false)) as string; const content = (await getSvgContent(svgUrlToCopy, false)) as string;
@ -120,14 +123,16 @@
}); });
const data = await getCode.json(); const data = await getCode.json();
await navigator.clipboard.writeText(data); await navigator.clipboard.writeText(data);
toast.success('Copied as React component', { toast.success(`Copied as React ${tsx ? 'TSX' : 'JSX'} component`, {
description: `${svgInfo.title}` description: `${svgInfo.title} - ${svgInfo.category}`
}); });
} catch (error) { } catch (error) {
toast.error('Failed to copy as React component', { toast.error('Failed to copy as React component', {
description: `${error}`, description: `${error}`,
duration: 5000 duration: 5000
}); });
} finally {
isLoading = false;
} }
}; };
</script> </script>
@ -138,6 +143,8 @@
> >
{#if optionsOpen} {#if optionsOpen}
<X size={iconSize} strokeWidth={iconStroke} /> <X size={iconSize} strokeWidth={iconStroke} />
{:else if isLoading}
<Loader size={iconSize} strokeWidth={iconStroke} class="animate-spin" />
{:else} {:else}
<CopyIcon size={iconSize} strokeWidth={iconStroke} /> <CopyIcon size={iconSize} strokeWidth={iconStroke} />
{/if} {/if}
@ -154,6 +161,7 @@
<button <button
class={cn(buttonStyles, 'rounded-md w-full')} class={cn(buttonStyles, 'rounded-md w-full')}
title="Copy as React component" title="Copy as React component"
disabled={isLoading}
on:click={() => copyToClipboardAsReactComponent(true)} on:click={() => copyToClipboardAsReactComponent(true)}
> >
<ReactIcon iconSize={18} color="#2563eb" /> <ReactIcon iconSize={18} color="#2563eb" />
@ -162,6 +170,7 @@
<button <button
class={cn(buttonStyles, 'rounded-md w-full')} class={cn(buttonStyles, 'rounded-md w-full')}
title="Copy as React component" title="Copy as React component"
disabled={isLoading}
on:click={() => copyToClipboardAsReactComponent(false)} on:click={() => copyToClipboardAsReactComponent(false)}
> >
<ReactIcon iconSize={18} color="#60a5fa" /> <ReactIcon iconSize={18} color="#60a5fa" />

View File

@ -3,7 +3,27 @@ import type { RequestEvent } from '../$types';
import { transform } from '@svgr/core'; import { transform } from '@svgr/core';
import { json } from '@sveltejs/kit'; import { json } from '@sveltejs/kit';
import { ratelimit } from '@/server/redis';
// SVGR Plugins:
import svgrJSX from '@svgr/plugin-jsx';
export const POST = async ({ request }: RequestEvent) => { export const POST = async ({ request }: RequestEvent) => {
const ip = request.headers.get('x-forwarded-for') ?? '';
const { success, reset } = await ratelimit.limit(ip);
// Error 429 | If rate limit is exceeded:
if (!success) {
const now = Date.now();
const retryAfter = Math.floor((reset - now) / 500);
return new Response('Too Many Requests', {
status: 429,
headers: {
'Retry-After': retryAfter.toString()
}
});
}
try { try {
const body = await request.json(); const body = await request.json();
@ -14,7 +34,7 @@ export const POST = async ({ request }: RequestEvent) => {
const jsCode = await transform( const jsCode = await transform(
svgCode, svgCode,
{ {
plugins: ['@svgr/plugin-jsx'], plugins: [svgrJSX],
icon: true, icon: true,
typescript: typescript typescript: typescript
}, },