svger-cli 1.0.2 → 1.0.4
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/README.md
CHANGED
|
@@ -118,4 +118,4 @@ Cleans output folder at the end if needed.
|
|
|
118
118
|
|
|
119
119
|
Acknowledgements
|
|
120
120
|
|
|
121
|
-
This project was implemented by Faeze
|
|
121
|
+
This project was implemented by Faeze Mohades, following the ADR authored by Navid Rezadoost and based on the TDR prepared by Ehsan Jafari. Their guidance and documentation on SVG integration methods in React were instrumental in shaping the design and functionality of the svger-cli CLI.
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
export declare function reactTemplate({ componentName, svgContent, defaultWidth, defaultHeight, defaultFill, }: {
|
|
1
|
+
export declare function reactTemplate({ componentName, svgContent, defaultWidth, defaultHeight, defaultFill, defaultStroke, }: {
|
|
2
2
|
componentName: string;
|
|
3
3
|
svgContent: string;
|
|
4
4
|
defaultWidth?: number;
|
|
5
5
|
defaultHeight?: number;
|
|
6
6
|
defaultFill?: string;
|
|
7
|
+
defaultStroke?: string;
|
|
7
8
|
}): string;
|
|
@@ -1,29 +1,37 @@
|
|
|
1
|
-
export function reactTemplate({ componentName, svgContent, defaultWidth = 24, defaultHeight = 24, defaultFill = "currentColor", }) {
|
|
2
|
-
//
|
|
1
|
+
export function reactTemplate({ componentName, svgContent, defaultWidth = 24, defaultHeight = 24, defaultFill = "currentColor", defaultStroke = "none", }) {
|
|
2
|
+
// convert style string to React object
|
|
3
|
+
function styleStringToObject(style) {
|
|
4
|
+
const obj = {};
|
|
5
|
+
style.split(";").forEach((pair) => {
|
|
6
|
+
if (!pair.trim())
|
|
7
|
+
return;
|
|
8
|
+
const [key, value] = pair.split(":");
|
|
9
|
+
if (!key || value === undefined)
|
|
10
|
+
return;
|
|
11
|
+
const camelKey = key.trim().replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
12
|
+
let v = value.trim();
|
|
13
|
+
if (!isNaN(Number(v)))
|
|
14
|
+
v = Number(v);
|
|
15
|
+
obj[camelKey] = v;
|
|
16
|
+
});
|
|
17
|
+
return obj;
|
|
18
|
+
}
|
|
19
|
+
// clean SVG
|
|
3
20
|
let cleaned = svgContent
|
|
4
21
|
.replace(/<\?xml.*?\?>/g, "")
|
|
5
22
|
.replace(/<!DOCTYPE.*?>/g, "")
|
|
6
23
|
.replace(/\r?\n|\r/g, "")
|
|
7
|
-
.replace(/\s*style="[^"]*"/g, "") // حذف style inline
|
|
8
|
-
.replace(/\s*(class|id)=["'][^"']*["']/g, "") // حذف class/id
|
|
9
24
|
.trim();
|
|
10
|
-
//
|
|
11
|
-
cleaned = cleaned.replace(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
className={props.className}
|
|
17
|
-
{...props}>`);
|
|
25
|
+
// fix style attributes
|
|
26
|
+
cleaned = cleaned.replace(/style="([^"]*)"/g, (_, styleContent) => {
|
|
27
|
+
return `style={${JSON.stringify(styleStringToObject(styleContent))}}`;
|
|
28
|
+
});
|
|
29
|
+
// fix svg tag
|
|
30
|
+
cleaned = cleaned.replace(/<svg([^>]*)>/, `<svg$1 width={props.width || ${defaultWidth}} height={props.height || ${defaultHeight}} fill={props.fill || "${defaultFill}"} stroke={props.stroke || "${defaultStroke}"} xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" {...props}>`);
|
|
18
31
|
return `import * as React from "react";
|
|
19
32
|
import type { SVGProps } from "react";
|
|
20
33
|
|
|
21
|
-
export const ${componentName}: React.FC<SVGProps<SVGSVGElement>> = (
|
|
22
|
-
width = ${defaultWidth},
|
|
23
|
-
height = ${defaultHeight},
|
|
24
|
-
fill = "${defaultFill}",
|
|
25
|
-
...props
|
|
26
|
-
}) => (
|
|
34
|
+
export const ${componentName}: React.FC<SVGProps<SVGSVGElement>> = (props) => (
|
|
27
35
|
${cleaned}
|
|
28
36
|
);
|
|
29
37
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svger-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "CLI and runtime for converting SVGs to React components with watch support",
|
|
5
5
|
"main": "dist/cli.js",
|
|
6
6
|
"type": "module",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"cli",
|
|
18
18
|
"components"
|
|
19
19
|
],
|
|
20
|
-
"author": "faeze
|
|
20
|
+
"author": "faeze mohades",
|
|
21
21
|
"license": "MIT",
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"change-case": "^5.4.4",
|
|
@@ -4,43 +4,52 @@ export function reactTemplate({
|
|
|
4
4
|
defaultWidth = 24,
|
|
5
5
|
defaultHeight = 24,
|
|
6
6
|
defaultFill = "currentColor",
|
|
7
|
+
defaultStroke = "none",
|
|
7
8
|
}: {
|
|
8
9
|
componentName: string;
|
|
9
10
|
svgContent: string;
|
|
10
11
|
defaultWidth?: number;
|
|
11
12
|
defaultHeight?: number;
|
|
12
13
|
defaultFill?: string;
|
|
14
|
+
defaultStroke?: string;
|
|
13
15
|
}) {
|
|
14
|
-
//
|
|
16
|
+
// convert style string to React object
|
|
17
|
+
function styleStringToObject(style: string) {
|
|
18
|
+
const obj: Record<string, string | number> = {};
|
|
19
|
+
style.split(";").forEach((pair) => {
|
|
20
|
+
if (!pair.trim()) return;
|
|
21
|
+
const [key, value] = pair.split(":");
|
|
22
|
+
if (!key || value === undefined) return;
|
|
23
|
+
const camelKey = key.trim().replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
24
|
+
let v: string | number = value.trim();
|
|
25
|
+
if (!isNaN(Number(v))) v = Number(v);
|
|
26
|
+
obj[camelKey] = v;
|
|
27
|
+
});
|
|
28
|
+
return obj;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// clean SVG
|
|
15
32
|
let cleaned = svgContent
|
|
16
33
|
.replace(/<\?xml.*?\?>/g, "")
|
|
17
34
|
.replace(/<!DOCTYPE.*?>/g, "")
|
|
18
35
|
.replace(/\r?\n|\r/g, "")
|
|
19
|
-
.replace(/\s*style="[^"]*"/g, "") // حذف style inline
|
|
20
|
-
.replace(/\s*(class|id)=["'][^"']*["']/g, "") // حذف class/id
|
|
21
36
|
.trim();
|
|
22
37
|
|
|
23
|
-
//
|
|
38
|
+
// fix style attributes
|
|
39
|
+
cleaned = cleaned.replace(/style="([^"]*)"/g, (_, styleContent) => {
|
|
40
|
+
return `style={${JSON.stringify(styleStringToObject(styleContent))}}`;
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// fix svg tag
|
|
24
44
|
cleaned = cleaned.replace(
|
|
25
45
|
/<svg([^>]*)>/,
|
|
26
|
-
`<svg$1
|
|
27
|
-
width={width}
|
|
28
|
-
height={height}
|
|
29
|
-
fill={fill}
|
|
30
|
-
stroke={props.stroke || "none"}
|
|
31
|
-
className={props.className}
|
|
32
|
-
{...props}>`
|
|
46
|
+
`<svg$1 width={props.width || ${defaultWidth}} height={props.height || ${defaultHeight}} fill={props.fill || "${defaultFill}"} stroke={props.stroke || "${defaultStroke}"} xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" {...props}>`
|
|
33
47
|
);
|
|
34
48
|
|
|
35
49
|
return `import * as React from "react";
|
|
36
50
|
import type { SVGProps } from "react";
|
|
37
51
|
|
|
38
|
-
export const ${componentName}: React.FC<SVGProps<SVGSVGElement>> = (
|
|
39
|
-
width = ${defaultWidth},
|
|
40
|
-
height = ${defaultHeight},
|
|
41
|
-
fill = "${defaultFill}",
|
|
42
|
-
...props
|
|
43
|
-
}) => (
|
|
52
|
+
export const ${componentName}: React.FC<SVGProps<SVGSVGElement>> = (props) => (
|
|
44
53
|
${cleaned}
|
|
45
54
|
);
|
|
46
55
|
|