UNPKG

@obiwanpelosi/vue-icons

Version:

A comprehensive collection of Vue 3 icon components, including multiple icon sets:

122 lines (105 loc) 3.78 kB
import { fileURLToPath } from "url"; import { dirname, join } from "path"; import { readFileSync, readdirSync, writeFileSync, mkdirSync, existsSync, } from "fs"; // In ES modules, __filename and __dirname are not available like in CommonJS // So we need to recreate them using the import.meta.url which gives the URL of the current module // fileURLToPath converts the URL to a file path that we can use const __filename = fileURLToPath(import.meta.url); // dirname extracts the directory path from the file path const __dirname = dirname(__filename); // This line sets the path to the ant-icons directory // Since __dirname is the directory of the current script (scripts folder), // we go up one level (..) to reach the ant-icons root directory // This will be used as the base path for finding icon SVG files and // for creating the output directory for the generated components const cssGgIconsDir = join(__dirname, ".."); const svgDir = join(cssGgIconsDir, "icons"); const outputDir = join(cssGgIconsDir, "components"); // Ensure output directory exists if (!existsSync(outputDir)) { mkdirSync(outputDir, { recursive: true }); } // Clean SVG content and extract viewBox function cleanSvgContent(content: string): { content: string; viewBox: string; } { // Extract viewBox const viewBoxMatch = content.match(/viewBox="([^"]+)"/); const viewBox = viewBoxMatch ? viewBoxMatch[1] : "0 0 24 24"; const cleanedContent = content // Remove XML declaration .replace(/<\?xml.*?\?>/, "") // Remove DOCTYPE .replace(/<!DOCTYPE.*?>/, "") // Remove comments .replace(/<!--.*?-->/g, "") // Remove viewBox attribute .replace(/viewBox="[^"]+"/, "") // Extract the content inside the svg tag .replace(/<svg[^>]*>([^]*?)<\/svg>/, "$1") // Remove newlines and extra spaces .trim(); return { content: cleanedContent, viewBox }; } // Generate components from SVG files function generateComponents(svgDir: string, lib: string) { const svgFiles = readdirSync(svgDir).filter((file: string) => file.endsWith(".svg") ); svgFiles.forEach((svgFile: string) => { const svgContent = readFileSync(join(svgDir, svgFile), "utf-8"); const { content: cleanedSvgContent, viewBox } = cleanSvgContent(svgContent); const componentName = svgFile .replace(".svg", "") .split("-") .map((word: string) => word.charAt(0).toUpperCase() + word.slice(1)) .join(""); const componentFullName = lib + componentName; const vueContent = `<script setup lang="ts"> import BaseIcon, { BaseIconProps } from '@/icons/BaseIcon.vue' import { ref } from 'vue'; const tag = ref("${componentName}"); const props = withDefaults(defineProps<BaseIconProps>(), { size: "1em", color: "currentColor", class: "", style: () => ({}), }); </script> <template> <BaseIcon :size="size" :color="color" :class="props.class" :style="style" viewBox="${viewBox}" > ${cleanedSvgContent} </BaseIcon> </template> `; writeFileSync(join(outputDir, `${componentFullName}.vue`), vueContent); }); return svgFiles; } // Generate components for both variants const iconFiles = generateComponents(svgDir, "Cg"); // Generate index file const indexContent = [ ...iconFiles.map((svgFile: string) => { const componentName = svgFile .replace(".svg", "") .split("-") .map((word: string) => word.charAt(0).toUpperCase() + word.slice(1)) .join(""); return `export { default as Cg${componentName} } from './components/Cg${componentName}.vue'`; }), ].join("\n"); writeFileSync(join(cssGgIconsDir, "index.ts"), indexContent);