From 1dbd22d42e0d64c2f6dbfcdbe256c0f86653f7c6 Mon Sep 17 00:00:00 2001 From: Kevin Midboe Date: Wed, 11 Mar 2026 00:03:47 +0100 Subject: [PATCH] Icon System Infrastructure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add icon conversion tooling and new icon library - Add icon-converter.mjs script to transform SVG files into Vue components - Converts kebab-case filenames to PascalCase (e.g., clipboard-text.svg → IconClipboardText.vue) - Wraps SVG content in proper Vue template structure - Sets width/height to 100% for consistent sizing - Add 38 new icon components for future use (IconHelm, IconMailboxFull, IconCheck, IconWarning, IconClipboardText, IconExpandVertical, IconShrinkVertical, and more) --- scripts/convert-svg-to-vue.mjs | 70 ++++++++++++++++++++++++++++++ scripts/icon-converter.js | 63 +++++++++++++++++++++++++++ src/icons/IconBooks.vue | 7 +++ src/icons/IconBox.vue | 7 +++ src/icons/IconChart.vue | 7 +++ src/icons/IconCheck.vue | 6 +++ src/icons/IconChristmasTree.vue | 7 +++ src/icons/IconClapboardPlay.vue | 8 ++++ src/icons/IconClipboardText.vue | 8 ++++ src/icons/IconCross.vue | 6 +++ src/icons/IconCrown.vue | 11 +++++ src/icons/IconDisposal.vue | 10 +++++ src/icons/IconEarth.vue | 6 +++ src/icons/IconEasterEgg.vue | 8 ++++ src/icons/IconExit.vue | 7 +++ src/icons/IconExpandHorizontal.vue | 7 +++ src/icons/IconExpandVertical.vue | 7 +++ src/icons/IconFilm.vue | 6 +++ src/icons/IconFingerprint.vue | 8 ++++ src/icons/IconFlag3.vue | 6 +++ src/icons/IconGhost.vue | 9 ++++ src/icons/IconHalloween.vue | 9 ++++ src/icons/IconMailboxEmpty.vue | 7 +++ src/icons/IconMailboxFull.vue | 6 +++ src/icons/IconMedalEmpty.vue | 6 +++ src/icons/IconPaperPlane.vue | 6 +++ src/icons/IconPlanet.vue | 6 +++ src/icons/IconPodium.vue | 9 ++++ src/icons/IconPuzzle.vue | 6 +++ src/icons/IconReel.vue | 11 +++++ src/icons/IconShrinkHorizontal.vue | 7 +++ src/icons/IconShrinkVertical.vue | 7 +++ src/icons/IconSine.vue | 6 +++ src/icons/IconSnowman.vue | 11 +++++ src/icons/IconStop2.vue | 7 +++ src/icons/IconSyncGear.vue | 10 +++++ src/icons/IconTelescope.vue | 6 +++ src/icons/IconTicket.vue | 7 +++ src/icons/IconUnlink2.vue | 13 ++++++ src/icons/IconWarning.vue | 9 ++++ src/icons/IconWitchHat.vue | 6 +++ 41 files changed, 429 insertions(+) create mode 100644 scripts/convert-svg-to-vue.mjs create mode 100644 scripts/icon-converter.js create mode 100644 src/icons/IconBooks.vue create mode 100644 src/icons/IconBox.vue create mode 100644 src/icons/IconChart.vue create mode 100644 src/icons/IconCheck.vue create mode 100644 src/icons/IconChristmasTree.vue create mode 100644 src/icons/IconClapboardPlay.vue create mode 100644 src/icons/IconClipboardText.vue create mode 100644 src/icons/IconCross.vue create mode 100644 src/icons/IconCrown.vue create mode 100644 src/icons/IconDisposal.vue create mode 100644 src/icons/IconEarth.vue create mode 100644 src/icons/IconEasterEgg.vue create mode 100644 src/icons/IconExit.vue create mode 100644 src/icons/IconExpandHorizontal.vue create mode 100644 src/icons/IconExpandVertical.vue create mode 100644 src/icons/IconFilm.vue create mode 100644 src/icons/IconFingerprint.vue create mode 100644 src/icons/IconFlag3.vue create mode 100644 src/icons/IconGhost.vue create mode 100644 src/icons/IconHalloween.vue create mode 100644 src/icons/IconMailboxEmpty.vue create mode 100644 src/icons/IconMailboxFull.vue create mode 100644 src/icons/IconMedalEmpty.vue create mode 100644 src/icons/IconPaperPlane.vue create mode 100644 src/icons/IconPlanet.vue create mode 100644 src/icons/IconPodium.vue create mode 100644 src/icons/IconPuzzle.vue create mode 100644 src/icons/IconReel.vue create mode 100644 src/icons/IconShrinkHorizontal.vue create mode 100644 src/icons/IconShrinkVertical.vue create mode 100644 src/icons/IconSine.vue create mode 100644 src/icons/IconSnowman.vue create mode 100644 src/icons/IconStop2.vue create mode 100644 src/icons/IconSyncGear.vue create mode 100644 src/icons/IconTelescope.vue create mode 100644 src/icons/IconTicket.vue create mode 100644 src/icons/IconUnlink2.vue create mode 100644 src/icons/IconWarning.vue create mode 100644 src/icons/IconWitchHat.vue diff --git a/scripts/convert-svg-to-vue.mjs b/scripts/convert-svg-to-vue.mjs new file mode 100644 index 0000000..afdea76 --- /dev/null +++ b/scripts/convert-svg-to-vue.mjs @@ -0,0 +1,70 @@ +#!/usr/bin/env node +/** + * Usage: node convert-svg-to-svelte.js [inputDir] [outputDir] + * Defaults: svgs src/icons + */ +import fs from "fs"; +import path from "path"; + +const INPUT_DIR = process.argv[2] || "svgs"; +const OUTPUT_DIR = process.argv[3] || "src/icons"; + +if (!fs.existsSync(OUTPUT_DIR)) fs.mkdirSync(OUTPUT_DIR, { recursive: true }); + +function processSvg(svgContent) { + // Strip XML/DOCTYPE + let out = svgContent + .replace(/<\?xml[\s\S]*?\?>\s*/i, "") + .replace(/\s*/i, ""); + + // Remove ALL comments + out = out.replace(/\s*/g, ""); + + // Remove with any whitespace between tags + out = out.replace(/\s*<\/g>\s*/gi, ""); + + // Ensure only width="100%" height="100%" on the tag + out = out.replace(/]*>/i, match => { + let tag = match + .replace(/\s+(width|height)\s*=\s*"[^"]*"/gi, "") + .replace(/\s+(width|height)\s*=\s*'[^']*'/gi, ""); + return tag.replace(/>$/, ' width="100%" height="100%">'); + }); + + // Prepend the single license comment + out = + "\n" + + out.replace(/^\s+/, ""); + + // Wrap with