Add support for Astro component

This commit is contained in:
pheralb
2025-04-15 14:21:29 +01:00
parent 0d8e929e4c
commit 021f810e2c
3 changed files with 88 additions and 3 deletions
+52 -3
View File
@@ -20,6 +20,7 @@
import { getSvelteCode } from '@/templates/getSvelteCode';
import { getAngularCode } from '@/templates/getAngularCode';
import { getWebComponent } from '@/templates/getWebComponent';
import { getAstroCode } from '@/templates/getAstroCode';
//Icons:
import ReactIcon from '@/components/icons/reactIcon.svelte';
@@ -27,6 +28,7 @@
import SvelteIcon from '@/components/icons/svelteIcon.svelte';
import AngularIcon from '@/components/icons/angularIcon.svelte';
import WebComponentIcon from '@/components/icons/webComponentIcon.svelte';
import AstroIcon from '@/components/icons/astroIcon.svelte';
// Props:
export let iconSize = 24;
@@ -246,7 +248,7 @@
isLoading = false;
};
// Copy SVG as Standalone Angular component:
// Copy SVG as Web Component:
const convertSvgWebComponent = async () => {
isLoading = true;
optionsOpen = false;
@@ -278,6 +280,37 @@
isLoading = false;
};
// Copy SVG as Astro component:
const convertSvgAstroComponent = async () => {
isLoading = true;
optionsOpen = false;
const svgUrlToCopy = getSvgUrl();
const content = await getSource({
url: svgUrlToCopy
});
if (!content) {
toast.error('Failed to fetch the SVG content', {
duration: 5000
});
isLoading = false;
return;
}
const astroComponentCode = getAstroCode({
svgContent: content
});
await clipboard(astroComponentCode);
toast.success(`Copied as Astro Component`, {
description: `${svgInfo.title} - ${svgInfo.category}`
});
isLoading = false;
};
</script>
<Popover.Root open={optionsOpen} onOpenChange={(isOpen) => (optionsOpen = isOpen)}>
@@ -300,6 +333,9 @@
<div
class="ml-3 flex flex-row space-x-0.5 border-l border-dashed border-neutral-200 pl-3 dark:border-neutral-800"
>
<Tabs.Trigger value="web-component" title="Web Component">
<WebComponentIcon iconSize={21} />
</Tabs.Trigger>
<Tabs.Trigger value="react" title="React">
<ReactIcon iconSize={20} />
</Tabs.Trigger>
@@ -312,8 +348,8 @@
<Tabs.Trigger value="angular" title="Angular">
<AngularIcon iconSize={20} />
</Tabs.Trigger>
<Tabs.Trigger value="web-component" title="Web Component">
<WebComponentIcon iconSize={21} />
<Tabs.Trigger value="astro" title="Astro" class="text-black dark:text-white">
<AstroIcon iconSize={21} />
</Tabs.Trigger>
</div>
</Tabs.List>
@@ -422,6 +458,19 @@
</button>
</section>
</Tabs.Content>
<Tabs.Content value="astro">
<section class="flex flex-col space-y-2">
<button
class={cn(buttonStyles, 'w-full rounded-md')}
title="Copy as Astro Component"
disabled={isLoading}
on:click={() => convertSvgAstroComponent()}
>
<AstroIcon iconSize={18} />
<span>Copy Astro Component</span>
</button>
</section>
</Tabs.Content>
</Tabs.Root>
<div
class="mt-1 flex w-full items-center text-center text-[12px] text-neutral-600 dark:text-neutral-400"
+20
View File
@@ -0,0 +1,20 @@
<script lang="ts">
import type { IconProps } from '@/types/icon';
export let iconSize: IconProps['size'];
</script>
<svg
viewBox="0 0 256 366"
xmlns="http://www.w3.org/2000/svg"
width={iconSize || 16}
height={iconSize || 16}
preserveAspectRatio="xMidYMid"
><path
fill="currentColor"
d="M182.022 9.147c2.982 3.702 4.502 8.697 7.543 18.687L256 246.074a276.467 276.467 0 0 0-79.426-26.891L133.318 73.008a5.63 5.63 0 0 0-10.802.017L79.784 219.11A276.453 276.453 0 0 0 0 246.04L66.76 27.783c3.051-9.972 4.577-14.959 7.559-18.654a24.541 24.541 0 0 1 9.946-7.358C88.67 0 93.885 0 104.314 0h47.683c10.443 0 15.664 0 20.074 1.774a24.545 24.545 0 0 1 9.95 7.373Z"
/><path
fill="#FF5D01"
d="M189.972 256.46c-10.952 9.364-32.812 15.751-57.992 15.751-30.904 0-56.807-9.621-63.68-22.56-2.458 7.415-3.009 15.903-3.009 21.324 0 0-1.619 26.623 16.898 45.14 0-9.615 7.795-17.41 17.41-17.41 16.48 0 16.46 14.378 16.446 26.043l-.001 1.041c0 17.705 10.82 32.883 26.21 39.28a35.685 35.685 0 0 1-3.588-15.647c0-16.886 9.913-23.173 21.435-30.48 9.167-5.814 19.353-12.274 26.372-25.232a47.588 47.588 0 0 0 5.742-22.735c0-5.06-.786-9.938-2.243-14.516Z"
/></svg
>
+16
View File
@@ -0,0 +1,16 @@
interface AstroComponentParams {
svgContent: string;
}
export function getAstroCode({ svgContent }: AstroComponentParams): string {
const cleanedSvg = svgContent
.replace(/\s*(width|height)="[^"]*"/gi, '')
.replace(/\s*(width|height)='[^']*'/gi, '')
.replace(/\s*(width|height)=\{[^}]*\}/gi, '')
.replace(/<svg([^>]*)>/i, (match, attrs) => {
const cleanedAttrs = attrs.replace(/\s*\{?\.\.\.Astro\.props\}?\s*/i, '');
return `<svg ${cleanedAttrs} {...Astro.props}>`;
});
return cleanedSvg.trim();
}