svgfusion 1.8.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +124 -20
- package/dist/index.d.mts +12 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +49 -34
- package/dist/index.mjs +52 -37
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -893,7 +893,8 @@ var ReactGenerator = class extends ComponentGenerator {
|
|
|
893
893
|
"title?: string;",
|
|
894
894
|
"titleId?: string;",
|
|
895
895
|
"desc?: string;",
|
|
896
|
-
"descId?: string;"
|
|
896
|
+
"descId?: string;",
|
|
897
|
+
"size?: string;"
|
|
897
898
|
];
|
|
898
899
|
const colorProps = this.generateColorProps(colorMappings);
|
|
899
900
|
if (colorProps) {
|
|
@@ -919,6 +920,7 @@ var ReactGenerator = class extends ComponentGenerator {
|
|
|
919
920
|
"titleId: PropTypes.string,",
|
|
920
921
|
"desc: PropTypes.string,",
|
|
921
922
|
"descId: PropTypes.string,",
|
|
923
|
+
"size: PropTypes.string,",
|
|
922
924
|
"className: PropTypes.string,",
|
|
923
925
|
"style: PropTypes.object,",
|
|
924
926
|
"width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),",
|
|
@@ -941,40 +943,55 @@ var ReactGenerator = class extends ComponentGenerator {
|
|
|
941
943
|
generateComponent(result) {
|
|
942
944
|
const componentName = this.getComponentName();
|
|
943
945
|
const { colorMappings, metadata } = result;
|
|
944
|
-
const customProps = ["title", "titleId", "desc", "descId"];
|
|
946
|
+
const customProps = ["title", "titleId", "desc", "descId", "size"];
|
|
945
947
|
const colorProps = colorMappings.map((m) => m.variableName);
|
|
946
948
|
const colorClassProps = colorMappings.map((m) => `${m.variableName}Class`);
|
|
947
949
|
const allCustomProps = [...customProps, ...colorProps, ...colorClassProps];
|
|
948
950
|
if (metadata.features.includes("fixed-stroke-width")) {
|
|
949
951
|
allCustomProps.push("isFixedStrokeWidth");
|
|
950
952
|
}
|
|
953
|
+
const colorDefaults = this.generateColorDefaults(colorMappings);
|
|
954
|
+
const sizeDefault = 'size = "20"';
|
|
955
|
+
const allDefaults = [sizeDefault, colorDefaults].filter(Boolean).join(", ");
|
|
956
|
+
const defaultPropsString = allDefaults ? `, ${allDefaults}` : "";
|
|
951
957
|
const customPropsDestructure = `{ ${allCustomProps.join(
|
|
952
958
|
", "
|
|
953
|
-
)}, ...svgProps }`;
|
|
959
|
+
)}${defaultPropsString}, ...svgProps }`;
|
|
960
|
+
const rootAttributes = this.generateSvgAttributes(result.ast);
|
|
954
961
|
const titleElement = "{title ? <title id={titleId}>{title}</title> : null}";
|
|
955
962
|
const descElement = "{desc ? <desc id={descId}>{desc}</desc> : null}";
|
|
956
963
|
if (this.reactOptions.typescript) {
|
|
957
964
|
const propsType = `${componentName}Props`;
|
|
958
965
|
const refType = this.reactOptions.forwardRef ? `, ref: Ref<SVGSVGElement>` : "";
|
|
959
966
|
const childrenJsx = result.ast.root.children.map((child) => this.elementToJsx(child, 1)).join("\n");
|
|
960
|
-
return `const ${componentName} = (${customPropsDestructure}: ${propsType}${refType}) =>
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
967
|
+
return `const ${componentName} = (${customPropsDestructure}: ${propsType}${refType}) => {
|
|
968
|
+
const computedSize = size ? { width: size, height: size } : {};
|
|
969
|
+
|
|
970
|
+
return (
|
|
971
|
+
<svg
|
|
972
|
+
${this.reactOptions.forwardRef ? "ref={ref}\n " : ""}${rootAttributes}
|
|
973
|
+
{...computedSize}
|
|
974
|
+
{...svgProps}
|
|
975
|
+
>
|
|
976
|
+
${titleElement}
|
|
977
|
+
${descElement}
|
|
966
978
|
${childrenJsx}
|
|
967
|
-
|
|
968
|
-
)
|
|
979
|
+
</svg>
|
|
980
|
+
);
|
|
981
|
+
};`;
|
|
969
982
|
} else {
|
|
970
983
|
const childrenJsx = result.ast.root.children.map((child) => this.elementToJsx(child, 1)).join("\n");
|
|
971
|
-
return `const ${componentName} = (${customPropsDestructure}) =>
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
984
|
+
return `const ${componentName} = (${customPropsDestructure}) => {
|
|
985
|
+
const computedSize = size ? { width: size, height: size } : {};
|
|
986
|
+
|
|
987
|
+
return (
|
|
988
|
+
<svg ${rootAttributes}{...computedSize} {...svgProps}>
|
|
989
|
+
${titleElement}
|
|
990
|
+
${descElement}
|
|
975
991
|
${childrenJsx}
|
|
976
|
-
|
|
977
|
-
)
|
|
992
|
+
</svg>
|
|
993
|
+
);
|
|
994
|
+
};`;
|
|
978
995
|
}
|
|
979
996
|
}
|
|
980
997
|
/**
|
|
@@ -1028,6 +1045,76 @@ ${childrenJsx}
|
|
|
1028
1045
|
}
|
|
1029
1046
|
return deps;
|
|
1030
1047
|
}
|
|
1048
|
+
/**
|
|
1049
|
+
* Generate SVG root attributes
|
|
1050
|
+
*/
|
|
1051
|
+
generateSvgAttributes(ast) {
|
|
1052
|
+
const attributes = [];
|
|
1053
|
+
const viewBox = ast.root.attributes?.viewBox || ast.viewBox;
|
|
1054
|
+
if (viewBox) {
|
|
1055
|
+
attributes.push(`viewBox="${viewBox}"`);
|
|
1056
|
+
}
|
|
1057
|
+
const xmlns = ast.root.attributes?.xmlns || ast.namespace;
|
|
1058
|
+
if (xmlns) {
|
|
1059
|
+
attributes.push(`xmlns="${xmlns}"`);
|
|
1060
|
+
}
|
|
1061
|
+
if (!viewBox) {
|
|
1062
|
+
const width = ast.root.attributes?.width || ast.width;
|
|
1063
|
+
const height = ast.root.attributes?.height || ast.height;
|
|
1064
|
+
if (width) {
|
|
1065
|
+
attributes.push(`width="${width}"`);
|
|
1066
|
+
}
|
|
1067
|
+
if (height) {
|
|
1068
|
+
attributes.push(`height="${height}"`);
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
return attributes.length > 0 ? attributes.join("\n ") + "\n " : "";
|
|
1072
|
+
}
|
|
1073
|
+
/**
|
|
1074
|
+
* Override to add color class logic for React
|
|
1075
|
+
*/
|
|
1076
|
+
elementToJsx(element, depth = 0) {
|
|
1077
|
+
const indent = " ".repeat(depth + 1);
|
|
1078
|
+
const { tag, attributes, children, content } = element;
|
|
1079
|
+
const jsxAttributes = this.attributesToJsxWithClasses(attributes);
|
|
1080
|
+
const attributeString = jsxAttributes.length > 0 ? " " + jsxAttributes.join(" ") : "";
|
|
1081
|
+
if (children.length === 0 && !content) {
|
|
1082
|
+
return `${indent}<${tag}${attributeString} />`;
|
|
1083
|
+
}
|
|
1084
|
+
let result = `${indent}<${tag}${attributeString}>`;
|
|
1085
|
+
if (content) {
|
|
1086
|
+
result += content;
|
|
1087
|
+
}
|
|
1088
|
+
if (children.length > 0) {
|
|
1089
|
+
result += "\n";
|
|
1090
|
+
result += children.map((child) => this.elementToJsx(child, depth + 1)).join("\n");
|
|
1091
|
+
result += "\n" + indent;
|
|
1092
|
+
}
|
|
1093
|
+
result += `</${tag}>`;
|
|
1094
|
+
return result;
|
|
1095
|
+
}
|
|
1096
|
+
/**
|
|
1097
|
+
* Convert attributes to JSX with color class logic
|
|
1098
|
+
*/
|
|
1099
|
+
attributesToJsxWithClasses(attributes) {
|
|
1100
|
+
const jsxAttributes = [];
|
|
1101
|
+
Object.entries(attributes).forEach(([key, value]) => {
|
|
1102
|
+
const jsxKey = this.convertAttributeName(key);
|
|
1103
|
+
if ((key === "fill" || key === "stroke") && value.startsWith("{") && value.endsWith("}")) {
|
|
1104
|
+
const colorVar = value.slice(1, -1);
|
|
1105
|
+
jsxAttributes.push(`${jsxKey}=${value}`);
|
|
1106
|
+
const classVar = `${colorVar}Class`;
|
|
1107
|
+
jsxAttributes.push(`className={${classVar}}`);
|
|
1108
|
+
} else {
|
|
1109
|
+
if (value.startsWith("{") && value.endsWith("}")) {
|
|
1110
|
+
jsxAttributes.push(`${jsxKey}=${value}`);
|
|
1111
|
+
} else {
|
|
1112
|
+
jsxAttributes.push(`${jsxKey}="${value}"`);
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
});
|
|
1116
|
+
return jsxAttributes;
|
|
1117
|
+
}
|
|
1031
1118
|
};
|
|
1032
1119
|
|
|
1033
1120
|
// src/generators/vue.ts
|
|
@@ -1098,7 +1185,7 @@ ${style}
|
|
|
1098
1185
|
generateTemplate(result) {
|
|
1099
1186
|
const { ast } = result;
|
|
1100
1187
|
const childrenJsx = ast.root.children.map((child) => this.elementToVueTemplate(child, 2)).join("\n");
|
|
1101
|
-
return ` <svg v-bind="$attrs">
|
|
1188
|
+
return ` <svg v-bind="$attrs" :width="props.size || undefined" :height="props.size || undefined">
|
|
1102
1189
|
<title v-if="props.title" :id="props.titleId">{{ props.title }}</title>
|
|
1103
1190
|
<desc v-if="props.desc" :id="props.descId">{{ props.desc }}</desc>
|
|
1104
1191
|
${childrenJsx}
|
|
@@ -1110,8 +1197,20 @@ ${childrenJsx}
|
|
|
1110
1197
|
elementToVueTemplate(element, depth = 0) {
|
|
1111
1198
|
const indent = " ".repeat(depth);
|
|
1112
1199
|
const { tag, attributes, children, content } = element;
|
|
1113
|
-
const vueAttributes =
|
|
1114
|
-
|
|
1200
|
+
const vueAttributes = [];
|
|
1201
|
+
Object.entries(attributes).forEach(([key, value]) => {
|
|
1202
|
+
if (value.startsWith("{") && value.endsWith("}")) {
|
|
1203
|
+
const variableName = value.slice(1, -1);
|
|
1204
|
+
vueAttributes.push(`:${key}="props.${variableName}"`);
|
|
1205
|
+
if (key === "fill" || key === "stroke") {
|
|
1206
|
+
const classVar = `${variableName}Class`;
|
|
1207
|
+
vueAttributes.push(`:class="props.${classVar}"`);
|
|
1208
|
+
}
|
|
1209
|
+
} else {
|
|
1210
|
+
vueAttributes.push(`${key}="${value}"`);
|
|
1211
|
+
}
|
|
1212
|
+
});
|
|
1213
|
+
const attributeString = vueAttributes.length > 0 ? " " + vueAttributes.join(" ") : "";
|
|
1115
1214
|
if (children.length === 0 && !content) {
|
|
1116
1215
|
return `${indent}<${tag}${attributeString} />`;
|
|
1117
1216
|
}
|
|
@@ -1151,6 +1250,7 @@ ${childrenJsx}
|
|
|
1151
1250
|
lines.push(" titleId?: string;");
|
|
1152
1251
|
lines.push(" desc?: string;");
|
|
1153
1252
|
lines.push(" descId?: string;");
|
|
1253
|
+
lines.push(" size?: string;");
|
|
1154
1254
|
const colorProps = this.generateColorPropsInterface(colorMappings);
|
|
1155
1255
|
if (colorProps) {
|
|
1156
1256
|
lines.push(colorProps);
|
|
@@ -1171,6 +1271,10 @@ ${childrenJsx}
|
|
|
1171
1271
|
lines.push(" style: { type: Object, default: undefined },");
|
|
1172
1272
|
lines.push(" width: { type: [String, Number], default: undefined },");
|
|
1173
1273
|
lines.push(" height: { type: [String, Number], default: undefined },");
|
|
1274
|
+
lines.push(' size: { type: String, default: "20" },');
|
|
1275
|
+
}
|
|
1276
|
+
if (this.vueOptions.typescript) {
|
|
1277
|
+
lines.push(' size: "20",');
|
|
1174
1278
|
}
|
|
1175
1279
|
colorMappings.forEach((mapping) => {
|
|
1176
1280
|
const propName = mapping.variableName;
|
package/dist/index.d.mts
CHANGED
|
@@ -264,6 +264,18 @@ declare class ReactGenerator extends ComponentGenerator {
|
|
|
264
264
|
* Get list of dependencies
|
|
265
265
|
*/
|
|
266
266
|
private getDependencies;
|
|
267
|
+
/**
|
|
268
|
+
* Generate SVG root attributes
|
|
269
|
+
*/
|
|
270
|
+
private generateSvgAttributes;
|
|
271
|
+
/**
|
|
272
|
+
* Override to add color class logic for React
|
|
273
|
+
*/
|
|
274
|
+
protected elementToJsx(element: SVGElement, depth?: number): string;
|
|
275
|
+
/**
|
|
276
|
+
* Convert attributes to JSX with color class logic
|
|
277
|
+
*/
|
|
278
|
+
private attributesToJsxWithClasses;
|
|
267
279
|
}
|
|
268
280
|
|
|
269
281
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -264,6 +264,18 @@ declare class ReactGenerator extends ComponentGenerator {
|
|
|
264
264
|
* Get list of dependencies
|
|
265
265
|
*/
|
|
266
266
|
private getDependencies;
|
|
267
|
+
/**
|
|
268
|
+
* Generate SVG root attributes
|
|
269
|
+
*/
|
|
270
|
+
private generateSvgAttributes;
|
|
271
|
+
/**
|
|
272
|
+
* Override to add color class logic for React
|
|
273
|
+
*/
|
|
274
|
+
protected elementToJsx(element: SVGElement, depth?: number): string;
|
|
275
|
+
/**
|
|
276
|
+
* Convert attributes to JSX with color class logic
|
|
277
|
+
*/
|
|
278
|
+
private attributesToJsxWithClasses;
|
|
267
279
|
}
|
|
268
280
|
|
|
269
281
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1,38 +1,53 @@
|
|
|
1
|
-
'use strict';var svgo=require('svgo'),promises=require('fs/promises'),path=require('path'),fs=require('fs');var
|
|
2
|
-
`)}};var
|
|
1
|
+
'use strict';var svgo=require('svgo'),promises=require('fs/promises'),path=require('path'),fs=require('fs');var b=class{parse(e){let t=this.cleanSvgContent(e),r=this.parseElement(t);return {root:r,viewBox:r.attributes.viewBox,width:r.attributes.width,height:r.attributes.height,namespace:r.attributes.xmlns}}extractColors(e){let t=[];return this.traverseElements(e.root,r=>{r.attributes.fill&&this.isValidColor(r.attributes.fill)&&t.push({value:r.attributes.fill,type:"fill",element:r,attribute:"fill"}),r.attributes.stroke&&this.isValidColor(r.attributes.stroke)&&t.push({value:r.attributes.stroke,type:"stroke",element:r,attribute:"stroke"}),r.attributes["stop-color"]&&this.isValidColor(r.attributes["stop-color"])&&t.push({value:r.attributes["stop-color"],type:"stop-color",element:r,attribute:"stop-color"});}),t}cleanSvgContent(e){return e.replace(/<\?xml[^>]*\?>/gi,"").replace(/<!--[\s\S]*?-->/g,"").trim()}parseElement(e){let t=e.match(/<svg([^>]*)>/i);if(!t)throw new Error("Invalid SVG: No svg element found");let r=this.parseAttributes(t[1]),s=this.parseChildren(e);return {tag:"svg",attributes:r,children:s}}parseAttributes(e){let t={},r=/(\w+(?:-\w+)*)=["']([^"']*)["']/g,s;for(;(s=r.exec(e))!==null;)t[s[1]]=s[2];return t}parseChildren(e){let t=[],r=e.match(/<svg[^>]*>(.*)<\/svg>/is);if(!r||!r[1])return t;let s=r[1],o=/<(\w+(?::\w+)?)([^>]*?)(?:\s*\/\s*>|>(.*?)<\/\1\s*>)/gs,i;for(;(i=o.exec(s))!==null;){let[,a,l,c]=i,p=this.parseAttributes(l),u={tag:a,attributes:p,children:[]};c!==void 0&&(c.includes("<")?u.children=this.parseNestedElements(c):c.trim()&&(u.content=c.trim())),t.push(u);}return t}parseNestedElements(e){let t=[],r=/<(\w+(?::\w+)?)([^>]*?)(?:\s*\/\s*>|>(.*?)<\/\1\s*>)/gs,s;for(;(s=r.exec(e))!==null;){let[,o,i,a]=s,l=this.parseAttributes(i),c={tag:o,attributes:l,children:[]};a!==void 0&&(a.includes("<")?c.children=this.parseNestedElements(a):a.trim()&&(c.content=a.trim())),t.push(c);}return t}traverseElements(e,t){t(e),e.children.forEach(r=>this.traverseElements(r,t));}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 S=class{options;constructor(e={}){this.options={preserveOriginalNames:e.preserveOriginalNames??false,generateClasses:e.generateClasses??true,colorPrefix:e.colorPrefix??"color"};}extractColors(e){let t=[];this.traverseElement(e,t);let r=new Map;return t.forEach(s=>{this.isValidColor(s.value)&&r.set(s.value,s);}),Array.from(r.values()).sort((s,o)=>s.value.localeCompare(o.value))}apply(e){let t=this.extractColors(e),r=this.generateColorMappings(t),s=this.replaceColorsWithVariables(e,r);return {mappings:r,processedElement:s,originalColors:t.map(o=>o.value)}}generateColorMappings(e){return e.map((t,r)=>({originalColor:t.value,variableName:r===0?this.options.colorPrefix:`${this.options.colorPrefix}${r+1}`,type:t.type}))}replaceColorsWithVariables(e,t){let r=new Map(t.map(s=>[s.originalColor,s.variableName]));return this.transformElement(e,s=>{let o={...s.attributes};return o.fill&&r.has(o.fill)&&(o.fill=`{${r.get(o.fill)}}`),o.stroke&&r.has(o.stroke)&&(o.stroke=`{${r.get(o.stroke)}}`),o["stop-color"]&&r.has(o["stop-color"])&&(o["stop-color"]=`{${r.get(o["stop-color"])}}`),{...s,attributes:o}})}traverseElement(e,t){e.attributes.fill&&t.push({value:e.attributes.fill,type:"fill",element:e,attribute:"fill"}),e.attributes.stroke&&t.push({value:e.attributes.stroke,type:"stroke",element:e,attribute:"stroke"}),e.attributes["stop-color"]&&t.push({value:e.attributes["stop-color"],type:"stop-color",element:e,attribute:"stop-color"}),e.children.forEach(r=>this.traverseElement(r,t));}transformElement(e,t){let r=t(e);return {...r,children:r.children.map(s=>this.transformElement(s,t))}}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())}};var E=class{options;constructor(e={}){this.options={preserveExisting:e.preserveExisting??true,onlyIfStrokePresent:e.onlyIfStrokePresent??true};}apply(e){let t=0;return {processedElement:this.transformElement(e,s=>this.shouldAddVectorEffect(s)?(t++,{...s,attributes:{...s.attributes,"vector-effect":"non-scaling-stroke"}}):s),elementsModified:t}}shouldAddVectorEffect(e){return this.options.preserveExisting&&e.attributes["vector-effect"]||this.options.onlyIfStrokePresent&&!(e.attributes.stroke&&e.attributes.stroke!=="none"&&e.attributes.stroke!=="transparent")?false:["path","line","polyline","polygon","rect","circle","ellipse"].includes(e.tag)}transformElement(e,t){let r=t(e);return {...r,children:r.children.map(s=>this.transformElement(s,t))}}};var w=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 t=[];if(e.tag!=="svg")return {processedElement:e,attributesAdded:t};let r={...e.attributes};return this.options.addRole&&(!this.options.preserveExisting||!r.role)&&(r.role=this.options.defaultRole,t.push("role")),this.options.addAriaHidden&&(!this.options.preserveExisting||!r["aria-hidden"])&&(r["aria-hidden"]="true",t.push("aria-hidden")),this.options.addTitle&&t.push("title-support"),this.options.addDesc&&t.push("desc-support"),this.options.addTitle&&this.options.addDesc&&(!this.options.preserveExisting||!r["aria-labelledby"])?(r["aria-labelledby"]="{titleId} {descId}",t.push("aria-labelledby")):this.options.addTitle&&(!this.options.preserveExisting||!r["aria-labelledby"])&&(r["aria-labelledby"]="{titleId}",t.push("aria-labelledby")),{processedElement:{...e,attributes:r},attributesAdded:t}}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 t=[];return e==="react"?(this.options.addDesc&&t.push("{desc ? <desc id={descId}>{desc}</desc> : null}"),this.options.addTitle&&t.push("{title ? <title id={titleId}>{title}</title> : null}")):(this.options.addDesc&&t.push('<desc v-if="desc" :id="descId">{{ desc }}</desc>'),this.options.addTitle&&t.push('<title v-if="title" :id="titleId">{{ title }}</title>')),t.join(`
|
|
2
|
+
`)}};var V=class{transform(e,t={}){let{optimize:r=true,splitColors:s=false,fixedStrokeWidth:o=false,accessibility:i=true,removeComments:a=true,removeDuplicates:l=true,minifyPaths:c=false}=t,p=this.deepCloneAst(e),u=[],h=[];return r&&(this.applyOptimizations(p,{removeComments:a,removeDuplicates:l,minifyPaths:c&&!s}),u.push("optimization")),s&&(h=this.applySplitColors(p),u.push("split-colors")),o&&(this.applyFixedStrokeWidth(p),u.push("fixed-stroke-width")),i&&(this.applyAccessibility(p),u.push("accessibility")),{ast:p,colorMappings:h,metadata:{originalColors:h.map(x=>x.originalColor),optimizationApplied:r,features:u}}}applySplitColors(e){let r=new S({generateClasses:true,colorPrefix:"color"}).apply(e.root);return e.root=r.processedElement,r.mappings}applyFixedStrokeWidth(e){let r=new E({onlyIfStrokePresent:true,preserveExisting:true}).apply(e.root);e.root=r.processedElement;}applyAccessibility(e){let r=new w({addRole:true,addTitle:true,addDesc:true,defaultRole:"img",preserveExisting:true}).apply(e.root);e.root=r.processedElement;}applyOptimizations(e,t){t.removeDuplicates&&this.removeDuplicateElements(e),t.minifyPaths&&this.minifyPaths(e),this.removeEmptyGroups(e);}removeDuplicateElements(e){}minifyPaths(e){this.traverseElements(e.root,t=>{t.tag==="path"&&t.attributes.d&&(t.attributes.d=t.attributes.d.replace(/\s+/g," ").replace(/([MLHVCSQTAZ])\s+/gi,"$1").trim());});}removeEmptyGroups(e){let t=r=>(r.children=r.children.filter(t),!(r.tag==="g"&&r.children.length===0&&!r.content));e.root.children=e.root.children.filter(t);}traverseElements(e,t){t(e),e.children.forEach(r=>this.traverseElements(r,t));}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(t=>this.deepCloneElement(t))}}};var v=class{options;constructor(e={}){this.options={typescript:true,memo:true,forwardRef:true,exportDefault:true,componentName:"Icon",includeTypes:true,...e};}astToJsx(e){return this.elementToJsx(e.root,0)}elementToJsx(e,t=0){let r=" ".repeat(t+1),{tag:s,attributes:o,children:i,content:a}=e,l=this.attributesToJsx(o),c=l.length>0?" "+l.join(" "):"";if(i.length===0&&!a)return `${r}<${s}${c} />`;let p=`${r}<${s}${c}>`;return a&&(p+=a),i.length>0&&(p+=`
|
|
3
3
|
`,p+=i.map(u=>this.elementToJsx(u,t+1)).join(`
|
|
4
4
|
`),p+=`
|
|
5
5
|
`+r),p+=`</${s}>`,p}attributesToJsx(e){return Object.entries(e).map(([t,r])=>{let s=this.convertAttributeName(t);return r.startsWith("{")&&r.endsWith("}")?`${s}=${r}`:`${s}="${r}"`})}convertAttributeName(e){let t={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,(r,s)=>s.toUpperCase()):t[e]||e}generateColorProps(e){return e.length===0?"":e.map(t=>{let r=t.variableName,s=`${r}Class`;return this.options.typescript?` ${r}?: string;
|
|
6
6
|
${s}?: string;`:` ${r}: PropTypes.string,
|
|
7
7
|
${s}: PropTypes.string,`}).join(`
|
|
8
|
-
`)}generateColorDefaults(e){return e.length===0?"":e.map(t=>{let r=t.variableName,s=t.originalColor;return `${r} = "${s}"`}).join(", ")}getComponentName(){return this.options.componentName}generateFilename(e,t){return `${e}.${t}`}sanitizeComponentName(e){return e.replace(/[^a-zA-Z0-9_$]/g,"").replace(/^[0-9]/,"_$&")}};var
|
|
8
|
+
`)}generateColorDefaults(e){return e.length===0?"":e.map(t=>{let r=t.variableName,s=t.originalColor;return `${r} = "${s}"`}).join(", ")}getComponentName(){return this.options.componentName}generateFilename(e,t){return `${e}.${t}`}sanitizeComponentName(e){return e.replace(/[^a-zA-Z0-9_$]/g,"").replace(/^[0-9]/,"_$&")}};var R=class extends v{reactOptions;constructor(e={}){super(e),this.reactOptions={...this.options,memo:e.memo??true,forwardRef:e.forwardRef??true,propTypes:e.propTypes??false,defaultProps:e.defaultProps??false,namedExport:e.namedExport??false};}generate(e){let t=this.getComponentName(),{colorMappings:r,metadata:s}=e,o=this.generateImports(),i=this.generateInterfaces(r,s.features),a=this.generateComponent(e),l=this.generateExports(t),c=[o,i,a,l].filter(Boolean).join(`
|
|
9
9
|
|
|
10
|
-
`),p=this.reactOptions.typescript?"tsx":"jsx",u=this.generateFilename(t,p);return {code:
|
|
11
|
-
`)}generateInterfaces(e,t){return !this.reactOptions.typescript&&!this.reactOptions.propTypes?"":this.reactOptions.typescript?this.generateTypeScriptInterface(e,t):this.generatePropTypes(e,t)}generateTypeScriptInterface(e,t){let r=["title?: string;","titleId?: string;","desc?: string;","descId?: string;"],s=this.generateColorProps(e);return s&&r.push(s),t.includes("fixed-stroke-width")&&r.push("isFixedStrokeWidth?: boolean;"),`interface ${this.getComponentName()}Props extends React.SVGProps<SVGSVGElement> {
|
|
10
|
+
`),p=this.reactOptions.typescript?"tsx":"jsx",u=this.generateFilename(t,p);return {code:c,filename:u,componentName:t,dependencies:this.getDependencies()}}generateImports(){let e=[];return this.reactOptions.typescript?(e.push("import * as React from 'react';"),this.reactOptions.forwardRef?e.push("import { Ref, forwardRef, memo } from 'react';"):this.reactOptions.memo&&e.push("import { memo } from 'react';")):(e.push("import React from 'react';"),this.reactOptions.propTypes&&e.push("import PropTypes from 'prop-types';")),e.join(`
|
|
11
|
+
`)}generateInterfaces(e,t){return !this.reactOptions.typescript&&!this.reactOptions.propTypes?"":this.reactOptions.typescript?this.generateTypeScriptInterface(e,t):this.generatePropTypes(e,t)}generateTypeScriptInterface(e,t){let r=["title?: string;","titleId?: string;","desc?: string;","descId?: string;","size?: string;"],s=this.generateColorProps(e);return s&&r.push(s),t.includes("fixed-stroke-width")&&r.push("isFixedStrokeWidth?: boolean;"),`interface ${this.getComponentName()}Props extends React.SVGProps<SVGSVGElement> {
|
|
12
12
|
${r.join(`
|
|
13
13
|
`)}
|
|
14
|
-
}`}generatePropTypes(e,t){let r=this.getComponentName(),s=["title: PropTypes.string,","titleId: PropTypes.string,","desc: PropTypes.string,","descId: PropTypes.string,","className: PropTypes.string,","style: PropTypes.object,","width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),","height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),"],o=this.generateColorProps(e);return o&&s.push(o),t.includes("fixed-stroke-width")&&s.push("isFixedStrokeWidth: PropTypes.bool,"),`${r}.propTypes = {
|
|
14
|
+
}`}generatePropTypes(e,t){let r=this.getComponentName(),s=["title: PropTypes.string,","titleId: PropTypes.string,","desc: PropTypes.string,","descId: PropTypes.string,","size: PropTypes.string,","className: PropTypes.string,","style: PropTypes.object,","width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),","height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),"],o=this.generateColorProps(e);return o&&s.push(o),t.includes("fixed-stroke-width")&&s.push("isFixedStrokeWidth: PropTypes.bool,"),`${r}.propTypes = {
|
|
15
15
|
${s.join(`
|
|
16
16
|
`)}
|
|
17
|
-
};`}generateComponent(e){let t=this.getComponentName(),{colorMappings:r,metadata:s}=e,o=["title","titleId","desc","descId"],i=r.map(
|
|
18
|
-
`);return `const ${t} = (${
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
)
|
|
35
|
-
|
|
17
|
+
};`}generateComponent(e){let t=this.getComponentName(),{colorMappings:r,metadata:s}=e,o=["title","titleId","desc","descId","size"],i=r.map(f=>f.variableName),a=r.map(f=>`${f.variableName}Class`),l=[...o,...i,...a];s.features.includes("fixed-stroke-width")&&l.push("isFixedStrokeWidth");let u=['size = "20"',this.generateColorDefaults(r)].filter(Boolean).join(", "),h=u?`, ${u}`:"",x=`{ ${l.join(", ")}${h}, ...svgProps }`,C=this.generateSvgAttributes(e.ast),y="{title ? <title id={titleId}>{title}</title> : null}",g="{desc ? <desc id={descId}>{desc}</desc> : null}";if(this.reactOptions.typescript){let f=`${t}Props`,d=this.reactOptions.forwardRef?", ref: Ref<SVGSVGElement>":"",D=e.ast.root.children.map(N=>this.elementToJsx(N,1)).join(`
|
|
18
|
+
`);return `const ${t} = (${x}: ${f}${d}) => {
|
|
19
|
+
const computedSize = size ? { width: size, height: size } : {};
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<svg
|
|
23
|
+
${this.reactOptions.forwardRef?`ref={ref}
|
|
24
|
+
`:""}${C}
|
|
25
|
+
{...computedSize}
|
|
26
|
+
{...svgProps}
|
|
27
|
+
>
|
|
28
|
+
${y}
|
|
29
|
+
${g}
|
|
30
|
+
${D}
|
|
31
|
+
</svg>
|
|
32
|
+
);
|
|
33
|
+
};`}else {let f=e.ast.root.children.map(d=>this.elementToJsx(d,1)).join(`
|
|
34
|
+
`);return `const ${t} = (${x}) => {
|
|
35
|
+
const computedSize = size ? { width: size, height: size } : {};
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<svg ${C}{...computedSize} {...svgProps}>
|
|
39
|
+
${y}
|
|
40
|
+
${g}
|
|
41
|
+
${f}
|
|
42
|
+
</svg>
|
|
43
|
+
);
|
|
44
|
+
};`}}generateExports(e){let t=[];return this.reactOptions.forwardRef?(t.push(`const ForwardRef = forwardRef(${e});`),this.reactOptions.memo?(t.push("const Memo = memo(ForwardRef);"),this.reactOptions.exportDefault&&t.push("export default Memo;"),this.reactOptions.namedExport&&t.push(`export { Memo as ${e} };`)):(this.reactOptions.exportDefault&&t.push("export default ForwardRef;"),this.reactOptions.namedExport&&t.push(`export { ForwardRef as ${e} };`))):this.reactOptions.memo?(t.push(`const Memo = memo(${e});`),this.reactOptions.exportDefault&&t.push("export default Memo;"),this.reactOptions.namedExport&&t.push(`export { Memo as ${e} };`)):(this.reactOptions.exportDefault&&t.push(`export default ${e};`),this.reactOptions.namedExport&&t.push(`export { ${e} };`)),t.join(`
|
|
45
|
+
`)}getDependencies(){let e=["react"];return this.reactOptions.propTypes&&e.push("prop-types"),e}generateSvgAttributes(e){let t=[],r=e.root.attributes?.viewBox||e.viewBox;r&&t.push(`viewBox="${r}"`);let s=e.root.attributes?.xmlns||e.namespace;if(s&&t.push(`xmlns="${s}"`),!r){let o=e.root.attributes?.width||e.width,i=e.root.attributes?.height||e.height;o&&t.push(`width="${o}"`),i&&t.push(`height="${i}"`);}return t.length>0?t.join(`
|
|
46
|
+
`)+`
|
|
47
|
+
`:""}elementToJsx(e,t=0){let r=" ".repeat(t+1),{tag:s,attributes:o,children:i,content:a}=e,l=this.attributesToJsxWithClasses(o),c=l.length>0?" "+l.join(" "):"";if(i.length===0&&!a)return `${r}<${s}${c} />`;let p=`${r}<${s}${c}>`;return a&&(p+=a),i.length>0&&(p+=`
|
|
48
|
+
`,p+=i.map(u=>this.elementToJsx(u,t+1)).join(`
|
|
49
|
+
`),p+=`
|
|
50
|
+
`+r),p+=`</${s}>`,p}attributesToJsxWithClasses(e){let t=[];return Object.entries(e).forEach(([r,s])=>{let o=this.convertAttributeName(r);if((r==="fill"||r==="stroke")&&s.startsWith("{")&&s.endsWith("}")){let i=s.slice(1,-1);t.push(`${o}=${s}`);let a=`${i}Class`;t.push(`className={${a}}`);}else s.startsWith("{")&&s.endsWith("}")?t.push(`${o}=${s}`):t.push(`${o}="${s}"`);}),t}};var G=class extends v{vueOptions;constructor(e={}){super(e),this.vueOptions={...this.options,composition:e.composition??true,scriptSetup:e.scriptSetup??true,sfc:e.sfc??true,defineComponent:e.defineComponent??false};}generate(e){let t=this.getComponentName(),r;this.vueOptions.sfc?r=this.generateSFC(e):r=this.generateJSComponent(e);let s=this.vueOptions.sfc?"vue":this.vueOptions.typescript?"ts":"js",o=this.generateFilename(t,s);return {code:r,filename:o,componentName:t,dependencies:this.getDependencies()}}generateSFC(e){let t=this.generateTemplate(e),r=this.generateScript(e),s=this.generateStyle();return `<template>
|
|
36
51
|
${t}
|
|
37
52
|
</template>
|
|
38
53
|
|
|
@@ -44,20 +59,20 @@ ${this.vueOptions.scriptSetup?`defineOptions({ inheritAttrs: false });
|
|
|
44
59
|
|
|
45
60
|
${s?`<style scoped>
|
|
46
61
|
${s}
|
|
47
|
-
</style>`:""}`}generateJSComponent(e){return this.vueOptions.composition?this.generateCompositionAPI(e):this.generateOptionsAPI(e)}generateTemplate(e){let{ast:t}=e;return ` <svg v-bind="$attrs">
|
|
62
|
+
</style>`:""}`}generateJSComponent(e){return this.vueOptions.composition?this.generateCompositionAPI(e):this.generateOptionsAPI(e)}generateTemplate(e){let{ast:t}=e;return ` <svg v-bind="$attrs" :width="props.size || undefined" :height="props.size || undefined">
|
|
48
63
|
<title v-if="props.title" :id="props.titleId">{{ props.title }}</title>
|
|
49
64
|
<desc v-if="props.desc" :id="props.descId">{{ props.desc }}</desc>
|
|
50
65
|
${t.root.children.map(s=>this.elementToVueTemplate(s,2)).join(`
|
|
51
66
|
`)}
|
|
52
|
-
</svg>`}elementToVueTemplate(e,t=0){let r=" ".repeat(t),{tag:s,attributes:o,children:i,content:a}=e,
|
|
67
|
+
</svg>`}elementToVueTemplate(e,t=0){let r=" ".repeat(t),{tag:s,attributes:o,children:i,content:a}=e,l=[];Object.entries(o).forEach(([u,h])=>{if(h.startsWith("{")&&h.endsWith("}")){let x=h.slice(1,-1);if(l.push(`:${u}="props.${x}"`),u==="fill"||u==="stroke"){let C=`${x}Class`;l.push(`:class="props.${C}"`);}}else l.push(`${u}="${h}"`);});let c=l.length>0?" "+l.join(" "):"";if(i.length===0&&!a)return `${r}<${s}${c} />`;let p=`${r}<${s}${c}>`;return a&&(p+=a),i.length>0&&(p+=`
|
|
53
68
|
`,p+=i.map(u=>this.elementToVueTemplate(u,t+1)).join(`
|
|
54
69
|
`),p+=`
|
|
55
|
-
`+r),p+=`</${s}>`,p}generateScript(e){return this.vueOptions.scriptSetup?this.generateScriptSetup(e):this.vueOptions.composition?this.generateCompositionAPI(e):this.generateOptionsAPI(e)}generateScriptSetup(e){let{colorMappings:t,metadata:r}=e,s=[];if(this.vueOptions.typescript){s.push("interface Props extends SVGAttributes {"),s.push(" title?: string;"),s.push(" titleId?: string;"),s.push(" desc?: string;"),s.push(" descId?: string;");let o=this.generateColorPropsInterface(t);o&&s.push(o),r.features.includes("fixed-stroke-width")&&s.push(" isFixedStrokeWidth?: boolean;"),s.push("}"),s.push(""),s.push("const props = withDefaults(defineProps<Props>(), {");}else s.push("const props = defineProps({"),s.push(" title: { type: String, default: undefined },"),s.push(" titleId: { type: String, default: undefined },"),s.push(" desc: { type: String, default: undefined },"),s.push(" descId: { type: String, default: undefined },"),s.push(" class: { type: String, default: undefined },"),s.push(" style: { type: Object, default: undefined },"),s.push(" width: { type: [String, Number], default: undefined },"),s.push(" height: { type: [String, Number], default: undefined },");return t.forEach(o=>{let i=o.variableName,a=o.originalColor,
|
|
56
|
-
`)}generateCompositionAPI(e){let{colorMappings:t,metadata:r}=e,s=this.getComponentName(),o=[];return o.push("import { defineComponent } from 'vue';"),o.push(""),o.push("export default defineComponent({"),o.push(` name: '${s}',`),o.push(" props: {"),o.push(" title: { type: String, default: undefined },"),o.push(" titleId: { type: String, default: undefined },"),o.push(" desc: { type: String, default: undefined },"),o.push(" descId: { type: String, default: undefined },"),o.push(" class: { type: String, default: undefined },"),o.push(" style: { type: Object, default: undefined },"),o.push(" width: { type: [String, Number], default: undefined },"),o.push(" height: { type: [String, Number], default: undefined },"),t.forEach(i=>{let a=i.variableName,
|
|
57
|
-
`)}generateOptionsAPI(e){let{colorMappings:t,metadata:r}=e,s=this.getComponentName(),o=[];return o.push("export default {"),o.push(` name: '${s}',`),o.push(" props: {"),o.push(" title: { type: String, default: undefined },"),o.push(" titleId: { type: String, default: undefined },"),o.push(" desc: { type: String, default: undefined },"),o.push(" descId: { type: String, default: undefined },"),o.push(" class: { type: String, default: undefined },"),o.push(" style: { type: Object, default: undefined },"),o.push(" width: { type: [String, Number], default: undefined },"),o.push(" height: { type: [String, Number], default: undefined },"),t.forEach(i=>{let a=i.variableName,
|
|
70
|
+
`+r),p+=`</${s}>`,p}generateScript(e){return this.vueOptions.scriptSetup?this.generateScriptSetup(e):this.vueOptions.composition?this.generateCompositionAPI(e):this.generateOptionsAPI(e)}generateScriptSetup(e){let{colorMappings:t,metadata:r}=e,s=[];if(this.vueOptions.typescript){s.push("interface Props extends SVGAttributes {"),s.push(" title?: string;"),s.push(" titleId?: string;"),s.push(" desc?: string;"),s.push(" descId?: string;"),s.push(" size?: string;");let o=this.generateColorPropsInterface(t);o&&s.push(o),r.features.includes("fixed-stroke-width")&&s.push(" isFixedStrokeWidth?: boolean;"),s.push("}"),s.push(""),s.push("const props = withDefaults(defineProps<Props>(), {");}else s.push("const props = defineProps({"),s.push(" title: { type: String, default: undefined },"),s.push(" titleId: { type: String, default: undefined },"),s.push(" desc: { type: String, default: undefined },"),s.push(" descId: { type: String, default: undefined },"),s.push(" class: { type: String, default: undefined },"),s.push(" style: { type: Object, default: undefined },"),s.push(" width: { type: [String, Number], default: undefined },"),s.push(" height: { type: [String, Number], default: undefined },"),s.push(' size: { type: String, default: "20" },');return this.vueOptions.typescript&&s.push(' size: "20",'),t.forEach(o=>{let i=o.variableName,a=o.originalColor,l=`${i}Class`;this.vueOptions.typescript?(s.push(` ${i}: '${a}',`),s.push(` ${l}: undefined,`)):(s.push(` ${i}: { type: String, default: '${a}' },`),s.push(` ${l}: { type: String, default: undefined },`));}),r.features.includes("fixed-stroke-width")&&(this.vueOptions.typescript?s.push(" isFixedStrokeWidth: false,"):s.push(" isFixedStrokeWidth: { type: Boolean, default: false },")),s.push("});"),s.join(`
|
|
71
|
+
`)}generateCompositionAPI(e){let{colorMappings:t,metadata:r}=e,s=this.getComponentName(),o=[];return o.push("import { defineComponent } from 'vue';"),o.push(""),o.push("export default defineComponent({"),o.push(` name: '${s}',`),o.push(" props: {"),o.push(" title: { type: String, default: undefined },"),o.push(" titleId: { type: String, default: undefined },"),o.push(" desc: { type: String, default: undefined },"),o.push(" descId: { type: String, default: undefined },"),o.push(" class: { type: String, default: undefined },"),o.push(" style: { type: Object, default: undefined },"),o.push(" width: { type: [String, Number], default: undefined },"),o.push(" height: { type: [String, Number], default: undefined },"),t.forEach(i=>{let a=i.variableName,l=i.originalColor,c=`${a}Class`;o.push(` ${a}: { type: String, default: '${l}' },`),o.push(` ${c}: { type: String, default: undefined },`);}),r.features.includes("fixed-stroke-width")&&o.push(" isFixedStrokeWidth: { type: Boolean, default: false },"),o.push(" },"),o.push(" setup() {"),o.push(" return {};"),o.push(" },"),o.push("});"),o.join(`
|
|
72
|
+
`)}generateOptionsAPI(e){let{colorMappings:t,metadata:r}=e,s=this.getComponentName(),o=[];return o.push("export default {"),o.push(` name: '${s}',`),o.push(" props: {"),o.push(" title: { type: String, default: undefined },"),o.push(" titleId: { type: String, default: undefined },"),o.push(" desc: { type: String, default: undefined },"),o.push(" descId: { type: String, default: undefined },"),o.push(" class: { type: String, default: undefined },"),o.push(" style: { type: Object, default: undefined },"),o.push(" width: { type: [String, Number], default: undefined },"),o.push(" height: { type: [String, Number], default: undefined },"),t.forEach(i=>{let a=i.variableName,l=i.originalColor,c=`${a}Class`;o.push(` ${a}: { type: String, default: '${l}' },`),o.push(` ${c}: { type: String, default: undefined },`);}),r.features.includes("fixed-stroke-width")&&o.push(" isFixedStrokeWidth: { type: Boolean, default: false },"),o.push(" },"),o.push("};"),o.join(`
|
|
58
73
|
`)}generateStyle(){return ""}generateColorPropsInterface(e){return e.length===0?"":e.map(t=>{let r=t.variableName,s=`${r}Class`;return ` ${r}?: string;
|
|
59
74
|
${s}?: string;`}).join(`
|
|
60
|
-
`)}getDependencies(){return ["vue"]}};var
|
|
75
|
+
`)}getDependencies(){return ["vue"]}};var O=class{parser;transformer;constructor(){this.parser=new b,this.transformer=new V;}convert(e,t){try{let r=this.parser.parse(e),s=this.transformer.transform(r,t.transformation),o;return t.framework==="react"?o=new R(t.generator):o=new G(t.generator),{...o.generate(s),metadata:s.metadata}}catch(r){throw new Error(`SVG conversion failed: ${r instanceof Error?r.message:String(r)}`)}}extractColors(e){let t=this.parser.parse(e),r=this.parser.extractColors(t);return Array.from(new Set(r.map(s=>s.value))).sort()}validate(e){let t=[];try{let r=this.parser.parse(e);r.root||t.push("No root SVG element found"),!r.viewBox&&!r.width&&!r.height&&t.push("SVG should have viewBox or width/height attributes");}catch(r){t.push(r instanceof Error?r.message:String(r));}return {valid:t.length===0,errors:t}}};async function j(n,e={}){return new O().convert(n,{...e,framework:"react"})}async function z(n,e={}){return new O().convert(n,{...e,framework:"vue"})}var B={plugins:[{name:"preset-default",params:{overrides:{removeViewBox:false,removeTitle:false,removeDesc:false,removeUselessStrokeAndFill:false,convertColors:{currentColor:true,names2hex:true,rgb2hex:true,shorthex:true,shortname:true}}}},"removeDimensions","cleanupNumericValues"]};function J(n,e=B){try{return svgo.optimize(n,e).data}catch(t){throw new Error(`Failed to optimize SVG: ${t}`)}}function q(n){let e=[{name:"preset-default",params:{overrides:{removeViewBox:!n.removeViewBox,removeTitle:!n.removeTitle,removeDesc:!n.removeDesc,removeUselessStrokeAndFill:!n.preserveClasses,convertColors:n.preserveColors?false:{currentColor:true,names2hex:true,rgb2hex:true,shorthex:true,shortname:true}}}},"cleanupNumericValues"];return n.removeDimensions!==false&&e.push("removeDimensions"),{plugins:e}}async function X(n){try{return await promises.readFile(n,"utf-8")}catch(e){throw new Error(`Failed to read SVG file: ${n}. ${e}`)}}async function Y(n,e){try{await M(path.dirname(n)),await promises.writeFile(n,e,"utf-8");}catch(t){throw new Error(`Failed to write SVG file: ${n}. ${t}`)}}async function ee(n,e){try{await M(path.dirname(n)),await promises.writeFile(n,e,"utf-8");}catch(t){throw new Error(`Failed to write component file: ${n}. ${t}`)}}async function F(n,e=false){try{let t=await promises.readdir(n),r=[];for(let s of t){let o=path.join(n,s),i=await promises.stat(o);if(i.isDirectory()&&e){let a=await F(o,e);r.push(...a);}else i.isFile()&&path.extname(s).toLowerCase()===".svg"&&r.push(o);}return r}catch(t){throw new Error(`Failed to read directory: ${n}. ${t}`)}}async function M(n){fs.existsSync(n)||await promises.mkdir(n,{recursive:true});}var $=n=>n.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*[a-z]*|[A-Z]|[0-9]+[a-z]*/g)?.map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join("")||"";function te(n){let e=n.replace(/\.svg$/i,"");return e=re(e),$(e)}function re(n){let e=n.toLowerCase().replace(/[^a-zA-Z0-9]/g," ");return e=e.replace(/\s+/g," ").trim(),e}function se(n){return $(n.replace(/[^a-zA-Z0-9]/g," "))}function oe(n,e,t){let r=e?$(e):"",s=t?$(t):"",o=$(n);return `${r}${o}${s}`}function ne(n,e){let{format:t,exportType:r,typescript:s}=e,o=[...n].sort((i,a)=>i.componentName.localeCompare(a.componentName));return r==="default"?ae(o):ie(o,t,s)}function ie(n,e,t){let r="";r+=`// Auto-generated index file for tree-shaking
|
|
61
76
|
`,r+=`// This file exports all components for optimal bundling
|
|
62
77
|
|
|
63
78
|
`;for(let s of n){let o=T(s.filename);r+=`export { default as ${s.componentName} } from './${o}';
|
|
@@ -67,7 +82,7 @@ ${t.root.children.map(s=>this.elementToVueTemplate(s,2)).join(`
|
|
|
67
82
|
`,r+=`export type IconComponents = {
|
|
68
83
|
`;for(let s of n)r+=` ${s.componentName}: IconComponent;
|
|
69
84
|
`;r+=`};
|
|
70
|
-
`;}return r}function
|
|
85
|
+
`;}return r}function ae(n,e,t){let r="";r+=`// Auto-generated index file
|
|
71
86
|
`,r+=`// Warning: Default exports are less tree-shakeable
|
|
72
87
|
|
|
73
88
|
`;for(let s of n){let o=T(s.filename);r+=`import ${s.componentName} from './${o}';
|
|
@@ -78,7 +93,7 @@ export default {
|
|
|
78
93
|
`,r+=`
|
|
79
94
|
// Individual exports for flexibility
|
|
80
95
|
`;for(let s of n)r+=`export { default as ${s.componentName} } from './${T(s.filename)}';
|
|
81
|
-
`;return r}function T(n){return n.replace(/\.(tsx?|jsx?|vue)$/,"")}function I(n){let e=new Set,t=new Set,r=new Set,s=new Set,o=[/fill="([^"]*?)"/g,/fill='([^']*?)'/g,/fill:\s*([^;}\s]+)/g],i=[/stroke="([^"]*?)"/g,/stroke='([^']*?)'/g,/stroke:\s*([^;}\s]+)/g],a=[/stop-color="([^"]*?)"/g,/stop-color='([^']*?)'/g,/stop-color:\s*([^;}\s]+)/g];o.forEach(
|
|
96
|
+
`;return r}function T(n){return n.replace(/\.(tsx?|jsx?|vue)$/,"")}function I(n){let e=new Set,t=new Set,r=new Set,s=new Set,o=[/fill="([^"]*?)"/g,/fill='([^']*?)'/g,/fill:\s*([^;}\s]+)/g],i=[/stroke="([^"]*?)"/g,/stroke='([^']*?)'/g,/stroke:\s*([^;}\s]+)/g],a=[/stop-color="([^"]*?)"/g,/stop-color='([^']*?)'/g,/stop-color:\s*([^;}\s]+)/g];o.forEach(g=>{let f;for(;(f=g.exec(n))!==null;){let d=f[1].trim();A(d)&&(e.add(d),s.add(d));}}),i.forEach(g=>{let f;for(;(f=g.exec(n))!==null;){let d=f[1].trim();A(d)&&(t.add(d),s.add(d));}}),a.forEach(g=>{let f;for(;(f=g.exec(n))!==null;){let d=f[1].trim();A(d)&&(r.add(d),s.add(d));}});let l=Array.from(e).sort(),c=Array.from(t).sort(),p=Array.from(r).sort(),u=Array.from(s).sort(),h=new Map,x=new Map,C=new Map,y=new Map;return u.forEach((g,f)=>{let d=f===0?"color":`color${f+1}`;y.set(g,d),l.includes(g)&&h.set(g,d),c.includes(g)&&x.set(g,d),p.includes(g)&&C.set(g,d);}),{colors:u,colorMap:y,fillColors:l,strokeColors:c,gradientColors:p,fillColorMap:h,strokeColorMap:x,gradientColorMap:C}}function le(n){let e=I(n),t=new Map,r=/<(path|circle|rect|ellipse|line|polyline|polygon)[^>]*>/g,s;for(;(s=r.exec(n))!==null;){let o=s[0],i=o.match(/d="([^"]*?)"/),a=o.match(/fill="([^"]*?)"/);if(i&&a){let l=i[1].substring(0,50),c=a[1],p=e.colorMap.get(c);p&&t.set(l,p);}}return {colorInfo:e,elementColorMap:t}}function pe(n,e,t){let r=n,s=t==="react"?/(<path[^>]*d="([^"]{1,50})[^"]*"[^>]*fill=){[^}]*currentColor[^}]*}([^>]*>)/g:/(<path[^>]*d="([^"]{1,50})[^"]*"[^>]*fill=)"currentColor"([^>]*>)/g;return r=r.replace(s,(o,i,a,l)=>{let c=e.get(a);return c?t==="react"?`${i}{${c}}${l}`:`${i}"${c}"${l}`:o}),r}function ce(n,e){return n.length===0?"":n.map((r,s)=>{let o=s===0?"color":`color${s+1}`,i=`${o}Class`;return e==="react"?` ${o}?: string;
|
|
82
97
|
${i}?: string;`:` ${o}: { type: String, default: 'currentColor' },
|
|
83
98
|
${i}: { type: String, default: '' },`}).join(`
|
|
84
|
-
`)}function
|
|
99
|
+
`)}function A(n){return !n||n==="none"||n==="transparent"||n==="currentColor"?false:/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/.test(n)||/^rgba?\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*(?:,\s*[\d.]+\s*)?\)$/.test(n)||/^hsla?\(\s*\d+\s*,\s*\d+%\s*,\s*\d+%\s*(?:,\s*[\d.]+\s*)?\)$/.test(n)?true:["red","green","blue","yellow","orange","purple","pink","brown","black","white","gray","grey","cyan","magenta","lime","maroon","navy","olive","silver","teal","aqua","fuchsia"].includes(n.toLowerCase())}exports.AccessibilityFeature=w;exports.ColorSplittingFeature=S;exports.ComponentGenerator=v;exports.ReactGenerator=R;exports.SVGFusion=O;exports.SVGParser=b;exports.SVGTransformer=V;exports.StrokeFixingFeature=E;exports.VueGenerator=G;exports.convertToReact=j;exports.convertToVue=z;exports.createSvgoConfig=q;exports.extractColors=I;exports.extractColorsWithElementMapping=le;exports.formatComponentName=oe;exports.generateColorProps=ce;exports.generateIndexFile=ne;exports.optimizeSvg=J;exports.pascalCase=$;exports.readSvgDirectory=F;exports.readSvgFile=X;exports.replaceCurrentColorWithVariables=pe;exports.sanitizeComponentName=se;exports.svgToComponentName=te;exports.writeComponentFile=ee;exports.writeSvgFile=Y;
|
package/dist/index.mjs
CHANGED
|
@@ -1,38 +1,53 @@
|
|
|
1
|
-
import {optimize}from'svgo';import {readFile,writeFile,readdir,stat,mkdir}from'fs/promises';import {dirname,join,extname}from'path';import {existsSync}from'fs';var S=class{parse(e){let t=this.cleanSvgContent(e),r=this.parseElement(t);return {root:r,viewBox:r.attributes.viewBox,width:r.attributes.width,height:r.attributes.height,namespace:r.attributes.xmlns}}extractColors(e){let t=[];return this.traverseElements(e.root,r=>{r.attributes.fill&&this.isValidColor(r.attributes.fill)&&t.push({value:r.attributes.fill,type:"fill",element:r,attribute:"fill"}),r.attributes.stroke&&this.isValidColor(r.attributes.stroke)&&t.push({value:r.attributes.stroke,type:"stroke",element:r,attribute:"stroke"}),r.attributes["stop-color"]&&this.isValidColor(r.attributes["stop-color"])&&t.push({value:r.attributes["stop-color"],type:"stop-color",element:r,attribute:"stop-color"});}),t}cleanSvgContent(e){return e.replace(/<\?xml[^>]*\?>/gi,"").replace(/<!--[\s\S]*?-->/g,"").trim()}parseElement(e){let t=e.match(/<svg([^>]*)>/i);if(!t)throw new Error("Invalid SVG: No svg element found");let r=this.parseAttributes(t[1]),s=this.parseChildren(e);return {tag:"svg",attributes:r,children:s}}parseAttributes(e){let t={},r=/(\w+(?:-\w+)*)=["']([^"']*)["']/g,s;for(;(s=r.exec(e))!==null;)t[s[1]]=s[2];return t}parseChildren(e){let t=[],r=e.match(/<svg[^>]*>(.*)<\/svg>/is);if(!r||!r[1])return t;let s=r[1],o=/<(\w+(?::\w+)?)([^>]*?)(?:\s*\/\s*>|>(.*?)<\/\1\s*>)/gs,i;for(;(i=o.exec(s))!==null;){let[,a,c
|
|
2
|
-
`)}};var
|
|
1
|
+
import {optimize}from'svgo';import {readFile,writeFile,readdir,stat,mkdir}from'fs/promises';import {dirname,join,extname}from'path';import {existsSync}from'fs';var S=class{parse(e){let t=this.cleanSvgContent(e),r=this.parseElement(t);return {root:r,viewBox:r.attributes.viewBox,width:r.attributes.width,height:r.attributes.height,namespace:r.attributes.xmlns}}extractColors(e){let t=[];return this.traverseElements(e.root,r=>{r.attributes.fill&&this.isValidColor(r.attributes.fill)&&t.push({value:r.attributes.fill,type:"fill",element:r,attribute:"fill"}),r.attributes.stroke&&this.isValidColor(r.attributes.stroke)&&t.push({value:r.attributes.stroke,type:"stroke",element:r,attribute:"stroke"}),r.attributes["stop-color"]&&this.isValidColor(r.attributes["stop-color"])&&t.push({value:r.attributes["stop-color"],type:"stop-color",element:r,attribute:"stop-color"});}),t}cleanSvgContent(e){return e.replace(/<\?xml[^>]*\?>/gi,"").replace(/<!--[\s\S]*?-->/g,"").trim()}parseElement(e){let t=e.match(/<svg([^>]*)>/i);if(!t)throw new Error("Invalid SVG: No svg element found");let r=this.parseAttributes(t[1]),s=this.parseChildren(e);return {tag:"svg",attributes:r,children:s}}parseAttributes(e){let t={},r=/(\w+(?:-\w+)*)=["']([^"']*)["']/g,s;for(;(s=r.exec(e))!==null;)t[s[1]]=s[2];return t}parseChildren(e){let t=[],r=e.match(/<svg[^>]*>(.*)<\/svg>/is);if(!r||!r[1])return t;let s=r[1],o=/<(\w+(?::\w+)?)([^>]*?)(?:\s*\/\s*>|>(.*?)<\/\1\s*>)/gs,i;for(;(i=o.exec(s))!==null;){let[,a,l,c]=i,p=this.parseAttributes(l),u={tag:a,attributes:p,children:[]};c!==void 0&&(c.includes("<")?u.children=this.parseNestedElements(c):c.trim()&&(u.content=c.trim())),t.push(u);}return t}parseNestedElements(e){let t=[],r=/<(\w+(?::\w+)?)([^>]*?)(?:\s*\/\s*>|>(.*?)<\/\1\s*>)/gs,s;for(;(s=r.exec(e))!==null;){let[,o,i,a]=s,l=this.parseAttributes(i),c={tag:o,attributes:l,children:[]};a!==void 0&&(a.includes("<")?c.children=this.parseNestedElements(a):a.trim()&&(c.content=a.trim())),t.push(c);}return t}traverseElements(e,t){t(e),e.children.forEach(r=>this.traverseElements(r,t));}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 E=class{options;constructor(e={}){this.options={preserveOriginalNames:e.preserveOriginalNames??false,generateClasses:e.generateClasses??true,colorPrefix:e.colorPrefix??"color"};}extractColors(e){let t=[];this.traverseElement(e,t);let r=new Map;return t.forEach(s=>{this.isValidColor(s.value)&&r.set(s.value,s);}),Array.from(r.values()).sort((s,o)=>s.value.localeCompare(o.value))}apply(e){let t=this.extractColors(e),r=this.generateColorMappings(t),s=this.replaceColorsWithVariables(e,r);return {mappings:r,processedElement:s,originalColors:t.map(o=>o.value)}}generateColorMappings(e){return e.map((t,r)=>({originalColor:t.value,variableName:r===0?this.options.colorPrefix:`${this.options.colorPrefix}${r+1}`,type:t.type}))}replaceColorsWithVariables(e,t){let r=new Map(t.map(s=>[s.originalColor,s.variableName]));return this.transformElement(e,s=>{let o={...s.attributes};return o.fill&&r.has(o.fill)&&(o.fill=`{${r.get(o.fill)}}`),o.stroke&&r.has(o.stroke)&&(o.stroke=`{${r.get(o.stroke)}}`),o["stop-color"]&&r.has(o["stop-color"])&&(o["stop-color"]=`{${r.get(o["stop-color"])}}`),{...s,attributes:o}})}traverseElement(e,t){e.attributes.fill&&t.push({value:e.attributes.fill,type:"fill",element:e,attribute:"fill"}),e.attributes.stroke&&t.push({value:e.attributes.stroke,type:"stroke",element:e,attribute:"stroke"}),e.attributes["stop-color"]&&t.push({value:e.attributes["stop-color"],type:"stop-color",element:e,attribute:"stop-color"}),e.children.forEach(r=>this.traverseElement(r,t));}transformElement(e,t){let r=t(e);return {...r,children:r.children.map(s=>this.transformElement(s,t))}}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())}};var w=class{options;constructor(e={}){this.options={preserveExisting:e.preserveExisting??true,onlyIfStrokePresent:e.onlyIfStrokePresent??true};}apply(e){let t=0;return {processedElement:this.transformElement(e,s=>this.shouldAddVectorEffect(s)?(t++,{...s,attributes:{...s.attributes,"vector-effect":"non-scaling-stroke"}}):s),elementsModified:t}}shouldAddVectorEffect(e){return this.options.preserveExisting&&e.attributes["vector-effect"]||this.options.onlyIfStrokePresent&&!(e.attributes.stroke&&e.attributes.stroke!=="none"&&e.attributes.stroke!=="transparent")?false:["path","line","polyline","polygon","rect","circle","ellipse"].includes(e.tag)}transformElement(e,t){let r=t(e);return {...r,children:r.children.map(s=>this.transformElement(s,t))}}};var V=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 t=[];if(e.tag!=="svg")return {processedElement:e,attributesAdded:t};let r={...e.attributes};return this.options.addRole&&(!this.options.preserveExisting||!r.role)&&(r.role=this.options.defaultRole,t.push("role")),this.options.addAriaHidden&&(!this.options.preserveExisting||!r["aria-hidden"])&&(r["aria-hidden"]="true",t.push("aria-hidden")),this.options.addTitle&&t.push("title-support"),this.options.addDesc&&t.push("desc-support"),this.options.addTitle&&this.options.addDesc&&(!this.options.preserveExisting||!r["aria-labelledby"])?(r["aria-labelledby"]="{titleId} {descId}",t.push("aria-labelledby")):this.options.addTitle&&(!this.options.preserveExisting||!r["aria-labelledby"])&&(r["aria-labelledby"]="{titleId}",t.push("aria-labelledby")),{processedElement:{...e,attributes:r},attributesAdded:t}}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 t=[];return e==="react"?(this.options.addDesc&&t.push("{desc ? <desc id={descId}>{desc}</desc> : null}"),this.options.addTitle&&t.push("{title ? <title id={titleId}>{title}</title> : null}")):(this.options.addDesc&&t.push('<desc v-if="desc" :id="descId">{{ desc }}</desc>'),this.options.addTitle&&t.push('<title v-if="title" :id="titleId">{{ title }}</title>')),t.join(`
|
|
2
|
+
`)}};var R=class{transform(e,t={}){let{optimize:r=true,splitColors:s=false,fixedStrokeWidth:o=false,accessibility:i=true,removeComments:a=true,removeDuplicates:l=true,minifyPaths:c=false}=t,p=this.deepCloneAst(e),u=[],x=[];return r&&(this.applyOptimizations(p,{removeComments:a,removeDuplicates:l,minifyPaths:c&&!s}),u.push("optimization")),s&&(x=this.applySplitColors(p),u.push("split-colors")),o&&(this.applyFixedStrokeWidth(p),u.push("fixed-stroke-width")),i&&(this.applyAccessibility(p),u.push("accessibility")),{ast:p,colorMappings:x,metadata:{originalColors:x.map(C=>C.originalColor),optimizationApplied:r,features:u}}}applySplitColors(e){let r=new E({generateClasses:true,colorPrefix:"color"}).apply(e.root);return e.root=r.processedElement,r.mappings}applyFixedStrokeWidth(e){let r=new w({onlyIfStrokePresent:true,preserveExisting:true}).apply(e.root);e.root=r.processedElement;}applyAccessibility(e){let r=new V({addRole:true,addTitle:true,addDesc:true,defaultRole:"img",preserveExisting:true}).apply(e.root);e.root=r.processedElement;}applyOptimizations(e,t){t.removeDuplicates&&this.removeDuplicateElements(e),t.minifyPaths&&this.minifyPaths(e),this.removeEmptyGroups(e);}removeDuplicateElements(e){}minifyPaths(e){this.traverseElements(e.root,t=>{t.tag==="path"&&t.attributes.d&&(t.attributes.d=t.attributes.d.replace(/\s+/g," ").replace(/([MLHVCSQTAZ])\s+/gi,"$1").trim());});}removeEmptyGroups(e){let t=r=>(r.children=r.children.filter(t),!(r.tag==="g"&&r.children.length===0&&!r.content));e.root.children=e.root.children.filter(t);}traverseElements(e,t){t(e),e.children.forEach(r=>this.traverseElements(r,t));}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(t=>this.deepCloneElement(t))}}};var $=class{options;constructor(e={}){this.options={typescript:true,memo:true,forwardRef:true,exportDefault:true,componentName:"Icon",includeTypes:true,...e};}astToJsx(e){return this.elementToJsx(e.root,0)}elementToJsx(e,t=0){let r=" ".repeat(t+1),{tag:s,attributes:o,children:i,content:a}=e,l=this.attributesToJsx(o),c=l.length>0?" "+l.join(" "):"";if(i.length===0&&!a)return `${r}<${s}${c} />`;let p=`${r}<${s}${c}>`;return a&&(p+=a),i.length>0&&(p+=`
|
|
3
3
|
`,p+=i.map(u=>this.elementToJsx(u,t+1)).join(`
|
|
4
4
|
`),p+=`
|
|
5
5
|
`+r),p+=`</${s}>`,p}attributesToJsx(e){return Object.entries(e).map(([t,r])=>{let s=this.convertAttributeName(t);return r.startsWith("{")&&r.endsWith("}")?`${s}=${r}`:`${s}="${r}"`})}convertAttributeName(e){let t={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,(r,s)=>s.toUpperCase()):t[e]||e}generateColorProps(e){return e.length===0?"":e.map(t=>{let r=t.variableName,s=`${r}Class`;return this.options.typescript?` ${r}?: string;
|
|
6
6
|
${s}?: string;`:` ${r}: PropTypes.string,
|
|
7
7
|
${s}: PropTypes.string,`}).join(`
|
|
8
|
-
`)}generateColorDefaults(e){return e.length===0?"":e.map(t=>{let r=t.variableName,s=t.originalColor;return `${r} = "${s}"`}).join(", ")}getComponentName(){return this.options.componentName}generateFilename(e,t){return `${e}.${t}`}sanitizeComponentName(e){return e.replace(/[^a-zA-Z0-9_$]/g,"").replace(/^[0-9]/,"_$&")}};var
|
|
8
|
+
`)}generateColorDefaults(e){return e.length===0?"":e.map(t=>{let r=t.variableName,s=t.originalColor;return `${r} = "${s}"`}).join(", ")}getComponentName(){return this.options.componentName}generateFilename(e,t){return `${e}.${t}`}sanitizeComponentName(e){return e.replace(/[^a-zA-Z0-9_$]/g,"").replace(/^[0-9]/,"_$&")}};var G=class extends ${reactOptions;constructor(e={}){super(e),this.reactOptions={...this.options,memo:e.memo??true,forwardRef:e.forwardRef??true,propTypes:e.propTypes??false,defaultProps:e.defaultProps??false,namedExport:e.namedExport??false};}generate(e){let t=this.getComponentName(),{colorMappings:r,metadata:s}=e,o=this.generateImports(),i=this.generateInterfaces(r,s.features),a=this.generateComponent(e),l=this.generateExports(t),c=[o,i,a,l].filter(Boolean).join(`
|
|
9
9
|
|
|
10
|
-
`),p=this.reactOptions.typescript?"tsx":"jsx",u=this.generateFilename(t,p);return {code:
|
|
11
|
-
`)}generateInterfaces(e,t){return !this.reactOptions.typescript&&!this.reactOptions.propTypes?"":this.reactOptions.typescript?this.generateTypeScriptInterface(e,t):this.generatePropTypes(e,t)}generateTypeScriptInterface(e,t){let r=["title?: string;","titleId?: string;","desc?: string;","descId?: string;"],s=this.generateColorProps(e);return s&&r.push(s),t.includes("fixed-stroke-width")&&r.push("isFixedStrokeWidth?: boolean;"),`interface ${this.getComponentName()}Props extends React.SVGProps<SVGSVGElement> {
|
|
10
|
+
`),p=this.reactOptions.typescript?"tsx":"jsx",u=this.generateFilename(t,p);return {code:c,filename:u,componentName:t,dependencies:this.getDependencies()}}generateImports(){let e=[];return this.reactOptions.typescript?(e.push("import * as React from 'react';"),this.reactOptions.forwardRef?e.push("import { Ref, forwardRef, memo } from 'react';"):this.reactOptions.memo&&e.push("import { memo } from 'react';")):(e.push("import React from 'react';"),this.reactOptions.propTypes&&e.push("import PropTypes from 'prop-types';")),e.join(`
|
|
11
|
+
`)}generateInterfaces(e,t){return !this.reactOptions.typescript&&!this.reactOptions.propTypes?"":this.reactOptions.typescript?this.generateTypeScriptInterface(e,t):this.generatePropTypes(e,t)}generateTypeScriptInterface(e,t){let r=["title?: string;","titleId?: string;","desc?: string;","descId?: string;","size?: string;"],s=this.generateColorProps(e);return s&&r.push(s),t.includes("fixed-stroke-width")&&r.push("isFixedStrokeWidth?: boolean;"),`interface ${this.getComponentName()}Props extends React.SVGProps<SVGSVGElement> {
|
|
12
12
|
${r.join(`
|
|
13
13
|
`)}
|
|
14
|
-
}`}generatePropTypes(e,t){let r=this.getComponentName(),s=["title: PropTypes.string,","titleId: PropTypes.string,","desc: PropTypes.string,","descId: PropTypes.string,","className: PropTypes.string,","style: PropTypes.object,","width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),","height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),"],o=this.generateColorProps(e);return o&&s.push(o),t.includes("fixed-stroke-width")&&s.push("isFixedStrokeWidth: PropTypes.bool,"),`${r}.propTypes = {
|
|
14
|
+
}`}generatePropTypes(e,t){let r=this.getComponentName(),s=["title: PropTypes.string,","titleId: PropTypes.string,","desc: PropTypes.string,","descId: PropTypes.string,","size: PropTypes.string,","className: PropTypes.string,","style: PropTypes.object,","width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),","height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),"],o=this.generateColorProps(e);return o&&s.push(o),t.includes("fixed-stroke-width")&&s.push("isFixedStrokeWidth: PropTypes.bool,"),`${r}.propTypes = {
|
|
15
15
|
${s.join(`
|
|
16
16
|
`)}
|
|
17
|
-
};`}generateComponent(e){let t=this.getComponentName(),{colorMappings:r,metadata:s}=e,o=["title","titleId","desc","descId"],i=r.map(
|
|
18
|
-
`);return `const ${t} = (${
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
)
|
|
35
|
-
|
|
17
|
+
};`}generateComponent(e){let t=this.getComponentName(),{colorMappings:r,metadata:s}=e,o=["title","titleId","desc","descId","size"],i=r.map(f=>f.variableName),a=r.map(f=>`${f.variableName}Class`),l=[...o,...i,...a];s.features.includes("fixed-stroke-width")&&l.push("isFixedStrokeWidth");let u=['size = "20"',this.generateColorDefaults(r)].filter(Boolean).join(", "),x=u?`, ${u}`:"",C=`{ ${l.join(", ")}${x}, ...svgProps }`,v=this.generateSvgAttributes(e.ast),b="{title ? <title id={titleId}>{title}</title> : null}",g="{desc ? <desc id={descId}>{desc}</desc> : null}";if(this.reactOptions.typescript){let f=`${t}Props`,d=this.reactOptions.forwardRef?", ref: Ref<SVGSVGElement>":"",N=e.ast.root.children.map(j=>this.elementToJsx(j,1)).join(`
|
|
18
|
+
`);return `const ${t} = (${C}: ${f}${d}) => {
|
|
19
|
+
const computedSize = size ? { width: size, height: size } : {};
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<svg
|
|
23
|
+
${this.reactOptions.forwardRef?`ref={ref}
|
|
24
|
+
`:""}${v}
|
|
25
|
+
{...computedSize}
|
|
26
|
+
{...svgProps}
|
|
27
|
+
>
|
|
28
|
+
${b}
|
|
29
|
+
${g}
|
|
30
|
+
${N}
|
|
31
|
+
</svg>
|
|
32
|
+
);
|
|
33
|
+
};`}else {let f=e.ast.root.children.map(d=>this.elementToJsx(d,1)).join(`
|
|
34
|
+
`);return `const ${t} = (${C}) => {
|
|
35
|
+
const computedSize = size ? { width: size, height: size } : {};
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<svg ${v}{...computedSize} {...svgProps}>
|
|
39
|
+
${b}
|
|
40
|
+
${g}
|
|
41
|
+
${f}
|
|
42
|
+
</svg>
|
|
43
|
+
);
|
|
44
|
+
};`}}generateExports(e){let t=[];return this.reactOptions.forwardRef?(t.push(`const ForwardRef = forwardRef(${e});`),this.reactOptions.memo?(t.push("const Memo = memo(ForwardRef);"),this.reactOptions.exportDefault&&t.push("export default Memo;"),this.reactOptions.namedExport&&t.push(`export { Memo as ${e} };`)):(this.reactOptions.exportDefault&&t.push("export default ForwardRef;"),this.reactOptions.namedExport&&t.push(`export { ForwardRef as ${e} };`))):this.reactOptions.memo?(t.push(`const Memo = memo(${e});`),this.reactOptions.exportDefault&&t.push("export default Memo;"),this.reactOptions.namedExport&&t.push(`export { Memo as ${e} };`)):(this.reactOptions.exportDefault&&t.push(`export default ${e};`),this.reactOptions.namedExport&&t.push(`export { ${e} };`)),t.join(`
|
|
45
|
+
`)}getDependencies(){let e=["react"];return this.reactOptions.propTypes&&e.push("prop-types"),e}generateSvgAttributes(e){let t=[],r=e.root.attributes?.viewBox||e.viewBox;r&&t.push(`viewBox="${r}"`);let s=e.root.attributes?.xmlns||e.namespace;if(s&&t.push(`xmlns="${s}"`),!r){let o=e.root.attributes?.width||e.width,i=e.root.attributes?.height||e.height;o&&t.push(`width="${o}"`),i&&t.push(`height="${i}"`);}return t.length>0?t.join(`
|
|
46
|
+
`)+`
|
|
47
|
+
`:""}elementToJsx(e,t=0){let r=" ".repeat(t+1),{tag:s,attributes:o,children:i,content:a}=e,l=this.attributesToJsxWithClasses(o),c=l.length>0?" "+l.join(" "):"";if(i.length===0&&!a)return `${r}<${s}${c} />`;let p=`${r}<${s}${c}>`;return a&&(p+=a),i.length>0&&(p+=`
|
|
48
|
+
`,p+=i.map(u=>this.elementToJsx(u,t+1)).join(`
|
|
49
|
+
`),p+=`
|
|
50
|
+
`+r),p+=`</${s}>`,p}attributesToJsxWithClasses(e){let t=[];return Object.entries(e).forEach(([r,s])=>{let o=this.convertAttributeName(r);if((r==="fill"||r==="stroke")&&s.startsWith("{")&&s.endsWith("}")){let i=s.slice(1,-1);t.push(`${o}=${s}`);let a=`${i}Class`;t.push(`className={${a}}`);}else s.startsWith("{")&&s.endsWith("}")?t.push(`${o}=${s}`):t.push(`${o}="${s}"`);}),t}};var O=class extends ${vueOptions;constructor(e={}){super(e),this.vueOptions={...this.options,composition:e.composition??true,scriptSetup:e.scriptSetup??true,sfc:e.sfc??true,defineComponent:e.defineComponent??false};}generate(e){let t=this.getComponentName(),r;this.vueOptions.sfc?r=this.generateSFC(e):r=this.generateJSComponent(e);let s=this.vueOptions.sfc?"vue":this.vueOptions.typescript?"ts":"js",o=this.generateFilename(t,s);return {code:r,filename:o,componentName:t,dependencies:this.getDependencies()}}generateSFC(e){let t=this.generateTemplate(e),r=this.generateScript(e),s=this.generateStyle();return `<template>
|
|
36
51
|
${t}
|
|
37
52
|
</template>
|
|
38
53
|
|
|
@@ -44,41 +59,41 @@ ${this.vueOptions.scriptSetup?`defineOptions({ inheritAttrs: false });
|
|
|
44
59
|
|
|
45
60
|
${s?`<style scoped>
|
|
46
61
|
${s}
|
|
47
|
-
</style>`:""}`}generateJSComponent(e){return this.vueOptions.composition?this.generateCompositionAPI(e):this.generateOptionsAPI(e)}generateTemplate(e){let{ast:t}=e;return ` <svg v-bind="$attrs">
|
|
62
|
+
</style>`:""}`}generateJSComponent(e){return this.vueOptions.composition?this.generateCompositionAPI(e):this.generateOptionsAPI(e)}generateTemplate(e){let{ast:t}=e;return ` <svg v-bind="$attrs" :width="props.size || undefined" :height="props.size || undefined">
|
|
48
63
|
<title v-if="props.title" :id="props.titleId">{{ props.title }}</title>
|
|
49
64
|
<desc v-if="props.desc" :id="props.descId">{{ props.desc }}</desc>
|
|
50
65
|
${t.root.children.map(s=>this.elementToVueTemplate(s,2)).join(`
|
|
51
66
|
`)}
|
|
52
|
-
</svg>`}elementToVueTemplate(e,t=0){let r=" ".repeat(t),{tag:s,attributes:o,children:i,content:a}=e,
|
|
67
|
+
</svg>`}elementToVueTemplate(e,t=0){let r=" ".repeat(t),{tag:s,attributes:o,children:i,content:a}=e,l=[];Object.entries(o).forEach(([u,x])=>{if(x.startsWith("{")&&x.endsWith("}")){let C=x.slice(1,-1);if(l.push(`:${u}="props.${C}"`),u==="fill"||u==="stroke"){let v=`${C}Class`;l.push(`:class="props.${v}"`);}}else l.push(`${u}="${x}"`);});let c=l.length>0?" "+l.join(" "):"";if(i.length===0&&!a)return `${r}<${s}${c} />`;let p=`${r}<${s}${c}>`;return a&&(p+=a),i.length>0&&(p+=`
|
|
53
68
|
`,p+=i.map(u=>this.elementToVueTemplate(u,t+1)).join(`
|
|
54
69
|
`),p+=`
|
|
55
|
-
`+r),p+=`</${s}>`,p}generateScript(e){return this.vueOptions.scriptSetup?this.generateScriptSetup(e):this.vueOptions.composition?this.generateCompositionAPI(e):this.generateOptionsAPI(e)}generateScriptSetup(e){let{colorMappings:t,metadata:r}=e,s=[];if(this.vueOptions.typescript){s.push("interface Props extends SVGAttributes {"),s.push(" title?: string;"),s.push(" titleId?: string;"),s.push(" desc?: string;"),s.push(" descId?: string;");let o=this.generateColorPropsInterface(t);o&&s.push(o),r.features.includes("fixed-stroke-width")&&s.push(" isFixedStrokeWidth?: boolean;"),s.push("}"),s.push(""),s.push("const props = withDefaults(defineProps<Props>(), {");}else s.push("const props = defineProps({"),s.push(" title: { type: String, default: undefined },"),s.push(" titleId: { type: String, default: undefined },"),s.push(" desc: { type: String, default: undefined },"),s.push(" descId: { type: String, default: undefined },"),s.push(" class: { type: String, default: undefined },"),s.push(" style: { type: Object, default: undefined },"),s.push(" width: { type: [String, Number], default: undefined },"),s.push(" height: { type: [String, Number], default: undefined },");return t.forEach(o=>{let i=o.variableName,a=o.originalColor,
|
|
56
|
-
`)}generateCompositionAPI(e){let{colorMappings:t,metadata:r}=e,s=this.getComponentName(),o=[];return o.push("import { defineComponent } from 'vue';"),o.push(""),o.push("export default defineComponent({"),o.push(` name: '${s}',`),o.push(" props: {"),o.push(" title: { type: String, default: undefined },"),o.push(" titleId: { type: String, default: undefined },"),o.push(" desc: { type: String, default: undefined },"),o.push(" descId: { type: String, default: undefined },"),o.push(" class: { type: String, default: undefined },"),o.push(" style: { type: Object, default: undefined },"),o.push(" width: { type: [String, Number], default: undefined },"),o.push(" height: { type: [String, Number], default: undefined },"),t.forEach(i=>{let a=i.variableName,
|
|
57
|
-
`)}generateOptionsAPI(e){let{colorMappings:t,metadata:r}=e,s=this.getComponentName(),o=[];return o.push("export default {"),o.push(` name: '${s}',`),o.push(" props: {"),o.push(" title: { type: String, default: undefined },"),o.push(" titleId: { type: String, default: undefined },"),o.push(" desc: { type: String, default: undefined },"),o.push(" descId: { type: String, default: undefined },"),o.push(" class: { type: String, default: undefined },"),o.push(" style: { type: Object, default: undefined },"),o.push(" width: { type: [String, Number], default: undefined },"),o.push(" height: { type: [String, Number], default: undefined },"),t.forEach(i=>{let a=i.variableName,
|
|
70
|
+
`+r),p+=`</${s}>`,p}generateScript(e){return this.vueOptions.scriptSetup?this.generateScriptSetup(e):this.vueOptions.composition?this.generateCompositionAPI(e):this.generateOptionsAPI(e)}generateScriptSetup(e){let{colorMappings:t,metadata:r}=e,s=[];if(this.vueOptions.typescript){s.push("interface Props extends SVGAttributes {"),s.push(" title?: string;"),s.push(" titleId?: string;"),s.push(" desc?: string;"),s.push(" descId?: string;"),s.push(" size?: string;");let o=this.generateColorPropsInterface(t);o&&s.push(o),r.features.includes("fixed-stroke-width")&&s.push(" isFixedStrokeWidth?: boolean;"),s.push("}"),s.push(""),s.push("const props = withDefaults(defineProps<Props>(), {");}else s.push("const props = defineProps({"),s.push(" title: { type: String, default: undefined },"),s.push(" titleId: { type: String, default: undefined },"),s.push(" desc: { type: String, default: undefined },"),s.push(" descId: { type: String, default: undefined },"),s.push(" class: { type: String, default: undefined },"),s.push(" style: { type: Object, default: undefined },"),s.push(" width: { type: [String, Number], default: undefined },"),s.push(" height: { type: [String, Number], default: undefined },"),s.push(' size: { type: String, default: "20" },');return this.vueOptions.typescript&&s.push(' size: "20",'),t.forEach(o=>{let i=o.variableName,a=o.originalColor,l=`${i}Class`;this.vueOptions.typescript?(s.push(` ${i}: '${a}',`),s.push(` ${l}: undefined,`)):(s.push(` ${i}: { type: String, default: '${a}' },`),s.push(` ${l}: { type: String, default: undefined },`));}),r.features.includes("fixed-stroke-width")&&(this.vueOptions.typescript?s.push(" isFixedStrokeWidth: false,"):s.push(" isFixedStrokeWidth: { type: Boolean, default: false },")),s.push("});"),s.join(`
|
|
71
|
+
`)}generateCompositionAPI(e){let{colorMappings:t,metadata:r}=e,s=this.getComponentName(),o=[];return o.push("import { defineComponent } from 'vue';"),o.push(""),o.push("export default defineComponent({"),o.push(` name: '${s}',`),o.push(" props: {"),o.push(" title: { type: String, default: undefined },"),o.push(" titleId: { type: String, default: undefined },"),o.push(" desc: { type: String, default: undefined },"),o.push(" descId: { type: String, default: undefined },"),o.push(" class: { type: String, default: undefined },"),o.push(" style: { type: Object, default: undefined },"),o.push(" width: { type: [String, Number], default: undefined },"),o.push(" height: { type: [String, Number], default: undefined },"),t.forEach(i=>{let a=i.variableName,l=i.originalColor,c=`${a}Class`;o.push(` ${a}: { type: String, default: '${l}' },`),o.push(` ${c}: { type: String, default: undefined },`);}),r.features.includes("fixed-stroke-width")&&o.push(" isFixedStrokeWidth: { type: Boolean, default: false },"),o.push(" },"),o.push(" setup() {"),o.push(" return {};"),o.push(" },"),o.push("});"),o.join(`
|
|
72
|
+
`)}generateOptionsAPI(e){let{colorMappings:t,metadata:r}=e,s=this.getComponentName(),o=[];return o.push("export default {"),o.push(` name: '${s}',`),o.push(" props: {"),o.push(" title: { type: String, default: undefined },"),o.push(" titleId: { type: String, default: undefined },"),o.push(" desc: { type: String, default: undefined },"),o.push(" descId: { type: String, default: undefined },"),o.push(" class: { type: String, default: undefined },"),o.push(" style: { type: Object, default: undefined },"),o.push(" width: { type: [String, Number], default: undefined },"),o.push(" height: { type: [String, Number], default: undefined },"),t.forEach(i=>{let a=i.variableName,l=i.originalColor,c=`${a}Class`;o.push(` ${a}: { type: String, default: '${l}' },`),o.push(` ${c}: { type: String, default: undefined },`);}),r.features.includes("fixed-stroke-width")&&o.push(" isFixedStrokeWidth: { type: Boolean, default: false },"),o.push(" },"),o.push("};"),o.join(`
|
|
58
73
|
`)}generateStyle(){return ""}generateColorPropsInterface(e){return e.length===0?"":e.map(t=>{let r=t.variableName,s=`${r}Class`;return ` ${r}?: string;
|
|
59
74
|
${s}?: string;`}).join(`
|
|
60
|
-
`)}getDependencies(){return ["vue"]}};var
|
|
75
|
+
`)}getDependencies(){return ["vue"]}};var T=class{parser;transformer;constructor(){this.parser=new S,this.transformer=new R;}convert(e,t){try{let r=this.parser.parse(e),s=this.transformer.transform(r,t.transformation),o;return t.framework==="react"?o=new G(t.generator):o=new O(t.generator),{...o.generate(s),metadata:s.metadata}}catch(r){throw new Error(`SVG conversion failed: ${r instanceof Error?r.message:String(r)}`)}}extractColors(e){let t=this.parser.parse(e),r=this.parser.extractColors(t);return Array.from(new Set(r.map(s=>s.value))).sort()}validate(e){let t=[];try{let r=this.parser.parse(e);r.root||t.push("No root SVG element found"),!r.viewBox&&!r.width&&!r.height&&t.push("SVG should have viewBox or width/height attributes");}catch(r){t.push(r instanceof Error?r.message:String(r));}return {valid:t.length===0,errors:t}}};async function z(n,e={}){return new T().convert(n,{...e,framework:"react"})}async function W(n,e={}){return new T().convert(n,{...e,framework:"vue"})}var J={plugins:[{name:"preset-default",params:{overrides:{removeViewBox:false,removeTitle:false,removeDesc:false,removeUselessStrokeAndFill:false,convertColors:{currentColor:true,names2hex:true,rgb2hex:true,shorthex:true,shortname:true}}}},"removeDimensions","cleanupNumericValues"]};function q(n,e=J){try{return optimize(n,e).data}catch(t){throw new Error(`Failed to optimize SVG: ${t}`)}}function L(n){let e=[{name:"preset-default",params:{overrides:{removeViewBox:!n.removeViewBox,removeTitle:!n.removeTitle,removeDesc:!n.removeDesc,removeUselessStrokeAndFill:!n.preserveClasses,convertColors:n.preserveColors?false:{currentColor:true,names2hex:true,rgb2hex:true,shorthex:true,shortname:true}}}},"cleanupNumericValues"];return n.removeDimensions!==false&&e.push("removeDimensions"),{plugins:e}}async function Y(n){try{return await readFile(n,"utf-8")}catch(e){throw new Error(`Failed to read SVG file: ${n}. ${e}`)}}async function ee(n,e){try{await I(dirname(n)),await writeFile(n,e,"utf-8");}catch(t){throw new Error(`Failed to write SVG file: ${n}. ${t}`)}}async function te(n,e){try{await I(dirname(n)),await writeFile(n,e,"utf-8");}catch(t){throw new Error(`Failed to write component file: ${n}. ${t}`)}}async function M(n,e=false){try{let t=await readdir(n),r=[];for(let s of t){let o=join(n,s),i=await stat(o);if(i.isDirectory()&&e){let a=await M(o,e);r.push(...a);}else i.isFile()&&extname(s).toLowerCase()===".svg"&&r.push(o);}return r}catch(t){throw new Error(`Failed to read directory: ${n}. ${t}`)}}async function I(n){existsSync(n)||await mkdir(n,{recursive:true});}var y=n=>n.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*[a-z]*|[A-Z]|[0-9]+[a-z]*/g)?.map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join("")||"";function re(n){let e=n.replace(/\.svg$/i,"");return e=se(e),y(e)}function se(n){let e=n.toLowerCase().replace(/[^a-zA-Z0-9]/g," ");return e=e.replace(/\s+/g," ").trim(),e}function oe(n){return y(n.replace(/[^a-zA-Z0-9]/g," "))}function ne(n,e,t){let r=e?y(e):"",s=t?y(t):"",o=y(n);return `${r}${o}${s}`}function ie(n,e){let{format:t,exportType:r,typescript:s}=e,o=[...n].sort((i,a)=>i.componentName.localeCompare(a.componentName));return r==="default"?le(o):ae(o,t,s)}function ae(n,e,t){let r="";r+=`// Auto-generated index file for tree-shaking
|
|
61
76
|
`,r+=`// This file exports all components for optimal bundling
|
|
62
77
|
|
|
63
|
-
`;for(let s of n){let o=
|
|
78
|
+
`;for(let s of n){let o=A(s.filename);r+=`export { default as ${s.componentName} } from './${o}';
|
|
64
79
|
`;}if(t&&e==="ts"){r+=`
|
|
65
80
|
// TypeScript component types
|
|
66
81
|
`,r+=`export type IconComponent = React.ComponentType<React.SVGProps<SVGSVGElement>>;
|
|
67
82
|
`,r+=`export type IconComponents = {
|
|
68
83
|
`;for(let s of n)r+=` ${s.componentName}: IconComponent;
|
|
69
84
|
`;r+=`};
|
|
70
|
-
`;}return r}function
|
|
85
|
+
`;}return r}function le(n,e,t){let r="";r+=`// Auto-generated index file
|
|
71
86
|
`,r+=`// Warning: Default exports are less tree-shakeable
|
|
72
87
|
|
|
73
|
-
`;for(let s of n){let o=
|
|
88
|
+
`;for(let s of n){let o=A(s.filename);r+=`import ${s.componentName} from './${o}';
|
|
74
89
|
`;}r+=`
|
|
75
90
|
export default {
|
|
76
91
|
`;for(let s of n)r+=` ${s.componentName},
|
|
77
92
|
`;r+=`};
|
|
78
93
|
`,r+=`
|
|
79
94
|
// Individual exports for flexibility
|
|
80
|
-
`;for(let s of n)r+=`export { default as ${s.componentName} } from './${
|
|
81
|
-
`;return r}function
|
|
95
|
+
`;for(let s of n)r+=`export { default as ${s.componentName} } from './${A(s.filename)}';
|
|
96
|
+
`;return r}function A(n){return n.replace(/\.(tsx?|jsx?|vue)$/,"")}function D(n){let e=new Set,t=new Set,r=new Set,s=new Set,o=[/fill="([^"]*?)"/g,/fill='([^']*?)'/g,/fill:\s*([^;}\s]+)/g],i=[/stroke="([^"]*?)"/g,/stroke='([^']*?)'/g,/stroke:\s*([^;}\s]+)/g],a=[/stop-color="([^"]*?)"/g,/stop-color='([^']*?)'/g,/stop-color:\s*([^;}\s]+)/g];o.forEach(g=>{let f;for(;(f=g.exec(n))!==null;){let d=f[1].trim();k(d)&&(e.add(d),s.add(d));}}),i.forEach(g=>{let f;for(;(f=g.exec(n))!==null;){let d=f[1].trim();k(d)&&(t.add(d),s.add(d));}}),a.forEach(g=>{let f;for(;(f=g.exec(n))!==null;){let d=f[1].trim();k(d)&&(r.add(d),s.add(d));}});let l=Array.from(e).sort(),c=Array.from(t).sort(),p=Array.from(r).sort(),u=Array.from(s).sort(),x=new Map,C=new Map,v=new Map,b=new Map;return u.forEach((g,f)=>{let d=f===0?"color":`color${f+1}`;b.set(g,d),l.includes(g)&&x.set(g,d),c.includes(g)&&C.set(g,d),p.includes(g)&&v.set(g,d);}),{colors:u,colorMap:b,fillColors:l,strokeColors:c,gradientColors:p,fillColorMap:x,strokeColorMap:C,gradientColorMap:v}}function pe(n){let e=D(n),t=new Map,r=/<(path|circle|rect|ellipse|line|polyline|polygon)[^>]*>/g,s;for(;(s=r.exec(n))!==null;){let o=s[0],i=o.match(/d="([^"]*?)"/),a=o.match(/fill="([^"]*?)"/);if(i&&a){let l=i[1].substring(0,50),c=a[1],p=e.colorMap.get(c);p&&t.set(l,p);}}return {colorInfo:e,elementColorMap:t}}function ce(n,e,t){let r=n,s=t==="react"?/(<path[^>]*d="([^"]{1,50})[^"]*"[^>]*fill=){[^}]*currentColor[^}]*}([^>]*>)/g:/(<path[^>]*d="([^"]{1,50})[^"]*"[^>]*fill=)"currentColor"([^>]*>)/g;return r=r.replace(s,(o,i,a,l)=>{let c=e.get(a);return c?t==="react"?`${i}{${c}}${l}`:`${i}"${c}"${l}`:o}),r}function ue(n,e){return n.length===0?"":n.map((r,s)=>{let o=s===0?"color":`color${s+1}`,i=`${o}Class`;return e==="react"?` ${o}?: string;
|
|
82
97
|
${i}?: string;`:` ${o}: { type: String, default: 'currentColor' },
|
|
83
98
|
${i}: { type: String, default: '' },`}).join(`
|
|
84
|
-
`)}function
|
|
99
|
+
`)}function k(n){return !n||n==="none"||n==="transparent"||n==="currentColor"?false:/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/.test(n)||/^rgba?\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*(?:,\s*[\d.]+\s*)?\)$/.test(n)||/^hsla?\(\s*\d+\s*,\s*\d+%\s*,\s*\d+%\s*(?:,\s*[\d.]+\s*)?\)$/.test(n)?true:["red","green","blue","yellow","orange","purple","pink","brown","black","white","gray","grey","cyan","magenta","lime","maroon","navy","olive","silver","teal","aqua","fuchsia"].includes(n.toLowerCase())}export{V as AccessibilityFeature,E as ColorSplittingFeature,$ as ComponentGenerator,G as ReactGenerator,T as SVGFusion,S as SVGParser,R as SVGTransformer,w as StrokeFixingFeature,O as VueGenerator,z as convertToReact,W as convertToVue,L as createSvgoConfig,D as extractColors,pe as extractColorsWithElementMapping,ne as formatComponentName,ue as generateColorProps,ie as generateIndexFile,q as optimizeSvg,y as pascalCase,M as readSvgDirectory,Y as readSvgFile,ce as replaceCurrentColorWithVariables,oe as sanitizeComponentName,re as svgToComponentName,te as writeComponentFile,ee as writeSvgFile};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svgfusion",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "A powerful CLI tool and library that converts SVG files into production-ready React and Vue 3 components with native SVG props inheritance, TypeScript support, and custom SVGFusion engine.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|