mirror of
https://github.com/KevinMidboe/seasoned.git
synced 2026-03-11 11:55:38 +00:00
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)
71 lines
2.2 KiB
JavaScript
71 lines
2.2 KiB
JavaScript
#!/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(/<!DOCTYPE[\s\S]*?>\s*/i, "");
|
|
|
|
// Remove ALL comments
|
|
out = out.replace(/<!--[\s\S]*?-->\s*/g, "");
|
|
|
|
// Remove <g id="icomoon-ignore"></g> with any whitespace between tags
|
|
out = out.replace(/<g\s+id=(["'])icomoon-ignore\1\s*>\s*<\/g>\s*/gi, "");
|
|
|
|
// Ensure only width="100%" height="100%" on the <svg> tag
|
|
out = out.replace(/<svg\b[^>]*>/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 =
|
|
"<!-- generated by icomoon.io - licensed Lindua icon -->\n" +
|
|
out.replace(/^\s+/, "");
|
|
|
|
// Wrap with <template> tags
|
|
out = "<template>\n" + out + "\n</template>";
|
|
|
|
return out;
|
|
}
|
|
|
|
function convertSvgs(inputDir = INPUT_DIR, outputDir = OUTPUT_DIR) {
|
|
if (!fs.existsSync(inputDir)) {
|
|
console.warn(`Input directory not found: ${inputDir}`);
|
|
return;
|
|
}
|
|
const files = fs
|
|
.readdirSync(inputDir)
|
|
.filter(f => f.toLowerCase().endsWith(".svg"));
|
|
files.forEach(file => {
|
|
const src = path.join(inputDir, file);
|
|
const baseName = file.replace(/\.svg$/i, "");
|
|
// Convert kebab-case to PascalCase (e.g., clipboard-text -> ClipboardText)
|
|
const pascalCase = baseName
|
|
.split("-")
|
|
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
|
|
.join("");
|
|
const destFileName = `Icon${pascalCase}.vue`;
|
|
const dest = path.join(outputDir, destFileName);
|
|
const svgContent = fs.readFileSync(src, "utf8");
|
|
const processed = processSvg(svgContent);
|
|
fs.writeFileSync(dest, processed, "utf8");
|
|
console.log(`Converted: ${file} -> ${path.basename(dest)}`);
|
|
});
|
|
}
|
|
|
|
convertSvgs();
|