--- import type { HTMLAttributes } from 'astro/types'; import { parse } from 'node-html-parser'; type _ModIcons = | 'chatting' | 'polysprint' | 'vanillahud' | 'overflowanimations' | 'crashpatch' | 'polytime' | 'polyweather' | 'keystrokes'; export type ModIcons = _ModIcons; // bypass for Astro compiler issue https://github.com/withastro/compiler/issues/554#issuecomment-1741702411 type _Icons = | 'chevron-down' | 'download' | 'book-open' | 'link-external' | ModIcons; export type Icons = _Icons; // bypass for Astro compiler issue https://github.com/withastro/compiler/issues/554#issuecomment-1741702411 interface Props extends HTMLAttributes<'svg'> { icon: Icons size?: number | [number, number] } async function getSVG(name: string) { const file = await import(/* @vite-ignore */ `./impl/${name}.svg?raw`); if (!file) throw new Error(`${name} not found`); const content = parse(file.default); const svg = content.querySelector('svg'); if (!svg) throw new Error(`${name} is not a valid SVG`); const { attributes, innerHTML } = svg; return { attributes, innerHTML, }; } const { icon, size, ...attributes } = Astro.props as Props; let svgAttributes = {}; let html = ''; try { const sizeAttributes = () => { if (!size) return {}; if (Array.isArray(size)) { return { width: size[0], height: size[1], }; } return { width: size, height: size, }; }; const { attributes: baseAttributes, innerHTML } = await getSVG(icon); svgAttributes = { ...baseAttributes, ...attributes, ...sizeAttributes(), }; const colorRegex = /(fill|stroke)=\"([^"]*)\"/g; html = innerHTML.replaceAll(colorRegex, '$1="currentColor"'); } catch (err) { // ignored } ---