UNPKG

svgfusion-core

Version:

Core engine and utilities for SVGFusion - the foundation library that powers SVG to component conversion.

52 lines (43 loc) 21.4 kB
import {svgToComponentName}from'svgfusion-utils';export{extractColors,extractColorsWithElementMapping,generateColorProps,generateDefaultColors,replaceColorsWithProps,replaceCurrentColorWithVariables}from'svgfusion-utils';var k=(n=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(n,{get:(e,r)=>(typeof require<"u"?require:e)[r]}):n)(function(n){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+n+'" is not supported')});var f=class{parse(e){let r=this.cleanSvgContent(e),t=this.parseElement(r);return {root:t,viewBox:t.attributes.viewBox,width:t.attributes.width,height:t.attributes.height,namespace:t.attributes.xmlns}}extractColors(e){let r=[];return this.traverseElements(e.root,t=>{t.attributes.fill&&this.isValidColor(t.attributes.fill)&&r.push({value:t.attributes.fill,type:"fill",element:t,attribute:"fill"}),t.attributes.stroke&&this.isValidColor(t.attributes.stroke)&&r.push({value:t.attributes.stroke,type:"stroke",element:t,attribute:"stroke"}),t.attributes["stop-color"]&&this.isValidColor(t.attributes["stop-color"])&&r.push({value:t.attributes["stop-color"],type:"stop-color",element:t,attribute:"stop-color"});}),r}cleanSvgContent(e){return e.replace(/<\?xml[^>]*\?>/gi,"").replace(/<!--[\s\S]*?-->/g,"").trim()}parseElement(e){if(typeof DOMParser<"u"){let t=new DOMParser().parseFromString(e,"image/svg+xml");if(t.querySelector("parsererror"))throw new Error("Invalid SVG: XML parsing failed");let i=t.documentElement;if(i.tagName.toLowerCase()!=="svg")throw new Error("Invalid SVG: No svg element found");return this.convertDOMToSVGElement(i)}try{let t=(typeof k<"u"?k:function(){throw new Error("require not available")}())("jsdom"),{JSDOM:o}=t,s=new o(e,{contentType:"image/svg+xml"}).window.document.documentElement;if(s.tagName.toLowerCase()!=="svg")throw new Error("Invalid SVG: No svg element found");return this.convertDOMToSVGElement(s)}catch{return this.parseElementWithRegex(e)}}convertDOMToSVGElement(e){let r={tag:this.preserveSvgTagCase(e.tagName),attributes:{},children:[]};for(let t=0;t<e.attributes.length;t++){let o=e.attributes[t];r.attributes[o.name]=o.value;}for(let t=0;t<e.children.length;t++){let o=e.children[t];r.children.push(this.convertDOMToSVGElement(o));}return e.children.length===0&&e.textContent?.trim()&&(r.content=e.textContent.trim()),r}parseElementWithRegex(e){let r=e.match(/<svg([^>]*)>/i);if(!r)throw new Error("Invalid SVG: No svg element found");let t=this.parseAttributes(r[1]),o=this.parseChildren(e);return {tag:"svg",attributes:t,children:o}}parseAttributes(e){let r={},t=/(\w+(?:-\w+)*)=["']([^"']*)["']/g,o;for(;(o=t.exec(e))!==null;)r[o[1]]=o[2];return r}parseChildren(e){let r=[],t=e.match(/<svg[^>]*>(.*)<\/svg>/is);if(!t||!t[1])return r;let o=t[1],i=/<(\w+(?::\w+)?)([^>]*?)(?:\s*\/\s*>|>(.*?)<\/\1\s*>)/gs,s;for(;(s=i.exec(o))!==null;){let[,a,c,l]=s,p=this.parseAttributes(c),m={tag:a,attributes:p,children:[]};l!==void 0&&(l.includes("<")?m.children=this.parseNestedElements(l):l.trim()&&(m.content=l.trim())),r.push(m);}return r}parseNestedElements(e){let r=[],t=/<(\w+(?::\w+)?)([^>]*?)(?:\s*\/\s*>|>(.*?)<\/\1\s*>)/gs,o;for(;(o=t.exec(e))!==null;){let[,i,s,a]=o,c=this.parseAttributes(s),l={tag:i,attributes:c,children:[]};a!==void 0&&(a.includes("<")?l.children=this.parseNestedElements(a):a.trim()&&(l.content=a.trim())),r.push(l);}return r}traverseElements(e,r){r(e),e.children.forEach(t=>this.traverseElements(t,r));}preserveSvgTagCase(e){let r=e.toLowerCase();return {clippath:"clipPath",defs:"defs",foreignobject:"foreignObject",lineargradient:"linearGradient",radialgradient:"radialGradient",textpath:"textPath",use:"use",feblend:"feBlend",feflood:"feFlood",fecolormatrix:"feColorMatrix",fecomponenttransfer:"feComponentTransfer",fecomposite:"feComposite",feconvolvematrix:"feConvolveMatrix",fediffuselighting:"feDiffuseLighting",fedisplacementmap:"feDisplacementMap",fedropshadow:"feDropShadow",fegaussianblur:"feGaussianBlur",feimage:"feImage",femerge:"feMerge",femergenode:"feMergeNode",femorphology:"feMorphology",feoffset:"feOffset",fespecularlighting:"feSpecularLighting",fetile:"feTile",feturbulence:"feTurbulence",filter:"filter",g:"g",image:"image",line:"line",marker:"marker",mask:"mask",metadata:"metadata",path:"path",pattern:"pattern",polygon:"polygon",polyline:"polyline",rect:"rect",stop:"stop",svg:"svg",text:"text",tspan:"tspan",view:"view",circle:"circle",ellipse:"ellipse"}[r]||r}isValidColor(e){return !e||e==="none"||e==="transparent"||e==="currentColor"?false:/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/.test(e)||/^rgba?\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*(?:,\s*[\d.]+\s*)?\)$/.test(e)||/^hsla?\(\s*\d+\s*,\s*\d+%\s*,\s*\d+%\s*(?:,\s*[\d.]+\s*)?\)$/.test(e)?true:["red","green","blue","black","white","yellow","cyan","magenta"].includes(e.toLowerCase())}};var h=class{options;constructor(e={}){this.options={preserveOriginalNames:e.preserveOriginalNames??false,generateClasses:e.generateClasses??true,colorPrefix:e.colorPrefix??"color"};}extractColors(e){let r=[];this.traverseElement(e,r);let t=new Map;return r.forEach(o=>{this.isValidColor(o.value)&&t.set(o.value,o);}),Array.from(t.values()).sort((o,i)=>o.value.localeCompare(i.value))}apply(e){let r=this.extractColors(e),t=this.generateColorMappings(r),o=this.replaceColorsWithVariables(e,t);return {mappings:t,processedElement:o,originalColors:r.map(i=>i.value)}}generateColorMappings(e){return e.map((r,t)=>({originalColor:r.value,variableName:t===0?this.options.colorPrefix:`${this.options.colorPrefix}${t+1}`,type:r.type}))}replaceColorsWithVariables(e,r){let t=new Map(r.map(o=>[o.originalColor,o.variableName]));return this.transformElement(e,o=>{let i={...o.attributes};if(i.fill&&t.has(i.fill)&&(i.fill=`{${t.get(i.fill)}}`),i.stroke&&t.has(i.stroke)&&(i.stroke=`{${t.get(i.stroke)}}`),i["stop-color"]&&t.has(i["stop-color"])&&(i["stop-color"]=`{${t.get(i["stop-color"])}}`),i.style){let s=i.style,a=s.match(/fill:\s*([^;]+)/);if(a){let p=a[1].trim();t.has(p)&&(s=s.replace(/fill:\s*[^;]+/,`fill: {${t.get(p)}}`));}let c=s.match(/stroke:\s*([^;]+)/);if(c){let p=c[1].trim();t.has(p)&&(s=s.replace(/stroke:\s*[^;]+/,`stroke: {${t.get(p)}}`));}let l=s.match(/stop-color:\s*([^;]+)/);if(l){let p=l[1].trim();t.has(p)&&(s=s.replace(/stop-color:\s*[^;]+/,`stop-color: {${t.get(p)}}`));}i.style=s;}if(this.isDrawableElement(o.tag)){let s=o.attributes.fill!==void 0&&o.attributes.fill!=="",a=o.attributes.stroke!==void 0&&o.attributes.stroke!=="";s&&!a&&!i.stroke&&(i.stroke="none"),a&&!s&&!i.fill&&(i.fill="none");}return {...o,attributes:i}})}traverseElement(e,r){e.attributes.fill&&r.push({value:e.attributes.fill,type:"fill",element:e,attribute:"fill"}),e.attributes.stroke&&r.push({value:e.attributes.stroke,type:"stroke",element:e,attribute:"stroke"}),e.attributes["stop-color"]&&r.push({value:e.attributes["stop-color"],type:"stop-color",element:e,attribute:"stop-color"}),e.attributes.style&&this.extractColorsFromStyle(e.attributes.style).forEach(o=>{r.push({value:o.value,type:o.type,element:e,attribute:"style"});}),e.children.forEach(t=>this.traverseElement(t,r));}transformElement(e,r){let t=r(e);return {...t,children:t.children.map(o=>this.transformElement(o,r))}}isDrawableElement(e){return ["path","circle","ellipse","line","rect","polygon","polyline","text","tspan","use"].includes(e)}isValidColor(e){return !e||e==="none"||e==="transparent"||e==="currentColor"?false:/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/.test(e)||/^rgba?\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*(?:,\s*[\d.]+\s*)?\)$/.test(e)||/^hsla?\(\s*\d+\s*,\s*\d+%\s*,\s*\d+%\s*(?:,\s*[\d.]+\s*)?\)$/.test(e)?true:["red","green","blue","yellow","orange","purple","pink","brown","black","white","gray","grey","cyan","magenta","lime","navy"].includes(e.toLowerCase())}extractColorsFromStyle(e){let r=[],t=e.match(/fill:\s*([^;]+)/);if(t){let s=t[1].trim();this.isValidColor(s)&&r.push({value:s,type:"fill"});}let o=e.match(/stroke:\s*([^;]+)/);if(o){let s=o[1].trim();this.isValidColor(s)&&r.push({value:s,type:"stroke"});}let i=e.match(/stop-color:\s*([^;]+)/);if(i){let s=i[1].trim();this.isValidColor(s)&&r.push({value:s,type:"stop-color"});}return r}};var v=class{options;constructor(e={}){this.options={preserveExisting:e.preserveExisting??true,onlyIfStrokePresent:e.onlyIfStrokePresent??true};}apply(e){let r=0;return {processedElement:this.transformElement(e,o=>this.shouldAddVectorEffect(o)?(r++,{...o,attributes:{...o.attributes,"vector-effect":"non-scaling-stroke"}}):o),elementsModified:r}}shouldAddVectorEffect(e){return this.options.preserveExisting&&e.attributes["vector-effect"]?false:["path","line","polyline","polygon","rect","circle","ellipse"].includes(e.tag)}transformElement(e,r){let t=r(e);return {...t,children:t.children.map(o=>this.transformElement(o,r))}}};var S=class{options;constructor(e={}){this.options={preserveOriginalNames:e.preserveOriginalNames??false,strokeWidthPrefix:e.strokeWidthPrefix??"strokeWidth",generateClasses:e.generateClasses??true};}extractStrokeWidths(e){let r=[];this.traverseElement(e,r);let t=new Map;return r.forEach(o=>{this.isValidStrokeWidth(o.value)&&t.set(o.value,o);}),Array.from(t.values()).sort((o,i)=>{let s=parseFloat(o.value),a=parseFloat(i.value);return isNaN(s)&&isNaN(a)?o.value.localeCompare(i.value):isNaN(s)?1:isNaN(a)?-1:s-a})}apply(e){let r=this.extractStrokeWidths(e),t=this.generateStrokeWidthMappings(r),o=this.replaceStrokeWidthsWithVariables(e,t);return {mappings:t,processedElement:o,originalStrokeWidths:r.map(i=>i.value)}}traverseElement(e,r){if(e.attributes["stroke-width"]&&r.push({value:e.attributes["stroke-width"],element:e,attribute:"stroke-width"}),e.attributes.style){let t=this.extractStrokeWidthFromStyle(e.attributes.style);t&&r.push({value:t,element:e,attribute:"style",styleProperty:"stroke-width"});}e.children.forEach(t=>this.traverseElement(t,r));}extractStrokeWidthFromStyle(e){let r=e.match(/stroke-width\s*:\s*([^;]+)/);return r?r[1].trim():null}isValidStrokeWidth(e){return e==="inherit"||e==="none"||e==="initial"||e==="unset"||e.includes("var(")||e.includes("calc(")?false:/^[\d.]+(?:px|pt|pc|in|cm|mm|em|rem|ex|ch|vw|vh|vmin|vmax|%)?$/.test(e.trim())}generateStrokeWidthMappings(e){return e.map((r,t)=>({originalStrokeWidth:r.value,variableName:t===0?this.options.strokeWidthPrefix:`${this.options.strokeWidthPrefix}${t+1}`}))}replaceStrokeWidthsWithVariables(e,r){let t=new Map(r.map(o=>[o.originalStrokeWidth,o.variableName]));return this.transformElement(e,o=>{let i={...o.attributes};if(i["stroke-width"]&&t.has(i["stroke-width"])&&(i["stroke-width"]=`{${t.get(i["stroke-width"])}}`),i.style){let s=i.style;t.forEach((a,c)=>{let l=new RegExp(`stroke-width\\s*:\\s*${this.escapeRegExp(c)}`,"g");s=s.replace(l,`stroke-width: {${a}}`);}),i.style=s;}return {...o,attributes:i}})}transformElement(e,r){let t=r(e);return {...t,children:t.children.map(o=>this.transformElement(o,r))}}escapeRegExp(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}};var b=class{options;constructor(e={}){this.options={addRole:e.addRole??true,addAriaHidden:e.addAriaHidden??false,addTitle:e.addTitle??true,addDesc:e.addDesc??true,defaultRole:e.defaultRole??"img",preserveExisting:e.preserveExisting??true};}apply(e){let r=[];if(e.tag!=="svg")return {processedElement:e,attributesAdded:r};let t={...e.attributes};return this.options.addRole&&(!this.options.preserveExisting||!t.role)&&(t.role=this.options.defaultRole,r.push("role")),this.options.addAriaHidden&&(!this.options.preserveExisting||!t["aria-hidden"])&&(t["aria-hidden"]="true",r.push("aria-hidden")),this.options.addTitle&&r.push("title-support"),this.options.addDesc&&r.push("desc-support"),this.options.addTitle&&this.options.addDesc&&(!this.options.preserveExisting||!t["aria-labelledby"])?(t["aria-labelledby"]="{titleId} {descId}",r.push("aria-labelledby")):this.options.addTitle&&(!this.options.preserveExisting||!t["aria-labelledby"])&&(t["aria-labelledby"]="{titleId}",r.push("aria-labelledby")),{processedElement:{...e,attributes:t},attributesAdded:r}}generateProps(){let e=[];return this.options.addTitle&&e.push("title?: string","titleId?: string"),this.options.addDesc&&e.push("desc?: string","descId?: string"),e}generateJSXElements(e){let r=[];return e==="react"?(this.options.addDesc&&r.push("{desc ? <desc id={descId}>{desc}</desc> : null}"),this.options.addTitle&&r.push("{title ? <title id={titleId}>{title}</title> : null}")):(this.options.addDesc&&r.push('<desc v-if="desc" :id="descId">{{ desc }}</desc>'),this.options.addTitle&&r.push('<title v-if="title" :id="titleId">{{ title }}</title>')),r.join(` `)}};var E=class{constructor(e){this.options=e;}apply(e){return this.options.enabled?this.normalizeElements(e):e}normalizeElements(e){return e.map(r=>this.transformElement(r,t=>{let o={...t.attributes};if(this.isDrawableElement(t.tag)){let i=t.attributes.fill!==void 0&&t.attributes.fill!=="",s=t.attributes.stroke!==void 0&&t.attributes.stroke!=="";i&&!s&&(o.stroke="none"),s&&!i&&(o.fill="none");}return {...t,attributes:o}}))}transformElement(e,r){let t=r(e);return t.children&&(t.children=t.children.map(o=>this.transformElement(o,r))),t}isDrawableElement(e){return ["path","circle","ellipse","line","rect","polygon","polyline","text","tspan","use"].includes(e)}};function A(n){let e={tag:n.tag,attributes:{...n.attributes},children:[],content:n.content};return n.tag==="defs"?e.children=n.children.filter(r=>r.tag!=="filter"):e.children=n.children.map(r=>A(r)),e.attributes.filter&&delete e.attributes.filter,e}function N(n,e){return e.removeFilters?{root:A(n.root)}:n}var g=class{transform(e,r={}){let{optimize:t=true,splitColors:o=false,splitStrokeWidths:i=false,fixedStrokeWidth:s=false,normalizeFillStroke:a=false,accessibility:c=true,removeComments:l=true,removeDuplicates:p=true,minifyPaths:m=false,removeFilters:W=false}=r,d=this.deepCloneAst(e),u=[],x=[],y=[];return t&&(this.applyOptimizations(d,{removeComments:l,removeDuplicates:p,minifyPaths:m&&!o}),u.push("optimization")),o&&(x=this.applySplitColors(d),u.push("split-colors")),i&&(y=this.applySplitStrokeWidths(d),u.push("split-stroke-widths")),s&&(this.applyFixedStrokeWidth(d),u.push("fixed-stroke-width")),a&&(this.applyFillStrokeNormalization(d),u.push("normalize-fill-stroke")),c&&(this.applyAccessibility(d),u.push("accessibility")),W&&(d=N(d,{removeFilters:W}),u.push("remove-filters")),{ast:d,colorMappings:x,strokeWidthMappings:y,metadata:{originalColors:x.map(C=>C.originalColor),originalStrokeWidths:y.map(C=>C.originalStrokeWidth),optimizationApplied:t,features:u,hasClassAttributes:this.hasClassAttributes(d)}}}applySplitColors(e){let t=new h({generateClasses:true,colorPrefix:"color"}).apply(e.root);return e.root=t.processedElement,t.mappings}applyFixedStrokeWidth(e){let t=new v({onlyIfStrokePresent:false,preserveExisting:true}).apply(e.root);e.root=t.processedElement;}applyAccessibility(e){let t=new b({addRole:true,addTitle:true,addDesc:true,defaultRole:"img",preserveExisting:true}).apply(e.root);e.root=t.processedElement;}applyFillStrokeNormalization(e){let r=new E({enabled:true});e.root.children=r.apply(e.root.children);}applyOptimizations(e,r){r.removeDuplicates&&this.removeDuplicateElements(e),r.minifyPaths&&this.minifyPaths(e),this.removeEmptyGroups(e);}removeDuplicateElements(e){}minifyPaths(e){this.traverseElements(e.root,r=>{r.tag==="path"&&r.attributes.d&&(r.attributes.d=r.attributes.d.replace(/\s+/g," ").replace(/([MLHVCSQTAZ])\s+/gi,"$1").trim());});}removeEmptyGroups(e){let r=t=>(t.children=t.children.filter(r),!(t.tag==="g"&&t.children.length===0&&!t.content));e.root.children=e.root.children.filter(r);}traverseElements(e,r){r(e),e.children.forEach(t=>this.traverseElements(t,r));}isValidColor(e){return !e||e==="none"||e==="transparent"||e==="currentColor"?false:/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/.test(e)||/^rgba?\(.+\)$/.test(e)||/^hsla?\(.+\)$/.test(e)}deepCloneAst(e){return {...e,root:this.deepCloneElement(e.root)}}deepCloneElement(e){return {...e,attributes:{...e.attributes},children:e.children.map(r=>this.deepCloneElement(r))}}hasClassAttributes(e){let r=t=>t.attributes.class||t.attributes.className?true:t.children.some(o=>r(o));return r(e.root)}applySplitStrokeWidths(e){let t=new S({generateClasses:true,strokeWidthPrefix:"strokeWidth"}).apply(e.root);return e.root=t.processedElement,t.mappings}};var V=class{options;constructor(e={}){this.options={typescript:true,memo:true,forwardRef:true,exportDefault:true,componentName:"Icon",prefix:"",suffix:"",includeTypes:true,...e};}astToJsx(e){return this.elementToJsx(e.root,0)}elementToJsx(e,r=0){let t=" ".repeat(r+1),{tag:o,attributes:i,children:s,content:a}=e,c=this.attributesToJsx(i),l=c.length>0?" "+c.join(" "):"";if(s.length===0&&!a)return `${t}<${o}${l} />`;let p=`${t}<${o}${l}>`;return a&&(p+=a),s.length>0&&(p+=` `,p+=s.map(m=>this.elementToJsx(m,r+1)).join(` `),p+=` `+t),p+=`</${o}>`,p}attributesToJsx(e){return Object.entries(e).map(([r,t])=>{let o=this.convertAttributeName(r);return t.startsWith("{")&&t.endsWith("}")?`${o}=${t}`:`${o}="${t}"`})}convertAttributeName(e){let r={class:"className",for:"htmlFor",tabindex:"tabIndex",readonly:"readOnly",maxlength:"maxLength",cellpadding:"cellPadding",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"};return e.startsWith("aria-")||e.startsWith("data-")?e:e.includes("-")?e.replace(/-([a-z])/g,(t,o)=>o.toUpperCase()):r[e]||e}generateColorProps(e,r=true){return e.length===0?"":e.map(t=>{let o=t.variableName,i=`${o}Class`;if(this.options.typescript){let s=` ${o}?: string;`;return r&&(s+=` ${i}?: string;`),s}else {let s=` ${o}: PropTypes.string,`;return r&&(s+=` ${i}: PropTypes.string,`),s}}).join(` `)}generateColorDefaults(e){return e.length===0?"":e.map(r=>{let t=r.variableName,o=r.originalColor;return `${t} = "${o}"`}).join(", ")}generateStrokeWidthProps(e,r=true){return e.length===0?"":e.map(t=>{let o=t.variableName,i=`${o}Class`;if(this.options.typescript){let s=` ${o}?: string | number;`;return r&&(s+=` ${i}?: string;`),s}else {let s=` ${o}: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),`;return r&&(s+=` ${i}: PropTypes.string,`),s}}).join(` `)}generateStrokeWidthDefaults(e){return e.length===0?"":e.map(r=>{let t=r.variableName,o=r.originalStrokeWidth;return `${t} = "${o}"`}).join(", ")}getComponentName(){return svgToComponentName(this.options.componentName,this.options.prefix,this.options.suffix)}generateFilename(e,r){return `${e}.${r}`}sanitizeComponentName(e){return e.replace(/[^a-zA-Z0-9_$]/g,"").replace(/^[0-9]/,"_$&")}};var G=class{parser;transformer;constructor(){this.parser=new f,this.transformer=new g;}extractColors(e){let r=this.parser.parse(e),t=this.parser.extractColors(r);return Array.from(new Set(t.map(o=>o.value))).sort()}validate(e){let r=[];try{let t=this.parser.parse(e);t.root||r.push("No root SVG element found"),!t.viewBox&&!t.width&&!t.height&&r.push("SVG should have viewBox or width/height attributes");}catch(t){r.push(t instanceof Error?t.message:String(t));}return {valid:r.length===0,errors:r}}async convert(e,r,t){try{let o=this.parser.parse(e),i=this.transformer.transform(o,r.transformation);return {...await new t(r.generator).generate(i),metadata:i.metadata}}catch(o){throw new Error(`SVG conversion failed: ${o instanceof Error?o.message:String(o)}`)}}};function $(n,e){let{format:r,exportType:t,typescript:o}=e,i=[...n].sort((s,a)=>s.componentName.localeCompare(a.componentName));return t==="default"?P(i):M(i,r,o,e.framework)}function M(n,e,r,t){let o="";o+=`// Auto-generated index file for tree-shaking `,o+=`// This file exports all components for optimal bundling `;for(let i of n){let s=w(i.filename,t);o+=`export { default as ${i.componentName} } from './${s}'; `;}if(r&&e==="ts"){o+=` // TypeScript component types `,t==="vue"?o+=`export type IconComponent = any; `:o+=`export type IconComponent = React.ComponentType<React.SVGProps<SVGSVGElement>>; `,o+=`export type IconComponents = { `;for(let i of n)o+=` ${i.componentName}: IconComponent; `;o+=`}; `;}return o}function P(n,e,r){let t="";t+=`w// Auto-generated index file `,t+=`// Warning: Default exports are less tree-shakeable `;for(let o of n){let i=w(o.filename);t+=`import ${o.componentName} from './${i}'; `;}t+=` export default { `;for(let o of n)t+=` ${o.componentName}, `;t+=`}; `,t+=` // Individual exports for flexibility `;for(let o of n)t+=`export { default as ${o.componentName} } from './${w(o.filename)}'; `;return t}function w(n,e){return e==="vue"&&n.endsWith(".vue")?n:n.replace(/\.(tsx?|jsx?|vue)$/,"")}function F(n){let e=n.map(t=>t.componentName).sort(),r=`# Generated Components `;r+=`This directory contains ${n.length} auto-generated components from SVG files. `,r+=`## Usage `,r+=`### Named imports (recommended for tree-shaking) `,r+="```typescript\n",r+=`import { ${e.slice(0,3).join(", ")} } from './index'; `,r+="```\n\n",r+=`### Default import `,r+="```typescript\n",r+=`import * as Icons from './index'; `,r+="```\n\n",r+=`## Available Components `;for(let t of e)r+=`- \`${t}\` `;return r+=` ## Tree-shaking `,r+="This index file is optimized for tree-shaking. When using named imports, ",r+=`bundlers like webpack, Rollup, or Vite will only include the components you actually use. `,r}export{V as ComponentGenerator,G as SVGFusion,f as SVGParser,g as SVGTransformer,$ as generateIndexFile,F as generateReadmeContent};