svger-cli 1.0.2 → 1.0.3

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 Mohadespor, 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.
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,12 @@
1
- export declare function reactTemplate({ componentName, svgContent, defaultWidth, defaultHeight, defaultFill, }: {
1
+ /**
2
+ * Generates a React functional component string from an SVG file's content,
3
+ * safely converting any inline `style="..."` to React-compatible object.
4
+ */
5
+ export declare function reactTemplate({ componentName, svgContent, defaultWidth, defaultHeight, defaultFill, defaultStroke, }: {
2
6
  componentName: string;
3
7
  svgContent: string;
4
8
  defaultWidth?: number;
5
9
  defaultHeight?: number;
6
10
  defaultFill?: string;
11
+ defaultStroke?: string;
7
12
  }): string;
@@ -1,29 +1,42 @@
1
- export function reactTemplate({ componentName, svgContent, defaultWidth = 24, defaultHeight = 24, defaultFill = "currentColor", }) {
2
- // پاکسازی XML/DOCTYPE و style inline و class/id
1
+ /**
2
+ * Generates a React functional component string from an SVG file's content,
3
+ * safely converting any inline `style="..."` to React-compatible object.
4
+ */
5
+ export function reactTemplate({ componentName, svgContent, defaultWidth = 24, defaultHeight = 24, defaultFill = "currentColor", defaultStroke = "none", }) {
6
+ // helper: convert inline style string to JS object
7
+ function styleStringToObject(style) {
8
+ const obj = {};
9
+ style.split(";").forEach((pair) => {
10
+ if (!pair.trim())
11
+ return;
12
+ const [key, value] = pair.split(":");
13
+ if (!key || value === undefined)
14
+ return;
15
+ // convert kebab-case to camelCase
16
+ const camelKey = key.trim().replace(/-([a-z])/g, (_, c) => c.toUpperCase());
17
+ let v = value.trim();
18
+ if (!isNaN(Number(v)))
19
+ v = Number(v);
20
+ obj[camelKey] = v;
21
+ });
22
+ return obj;
23
+ }
24
+ // clean SVG content
3
25
  let cleaned = svgContent
4
- .replace(/<\?xml.*?\?>/g, "")
5
- .replace(/<!DOCTYPE.*?>/g, "")
6
- .replace(/\r?\n|\r/g, "")
7
- .replace(/\s*style="[^"]*"/g, "") // حذف style inline
8
- .replace(/\s*(class|id)=["'][^"']*["']/g, "") // حذف class/id
26
+ .replace(/<\?xml.*?\?>/g, "") // remove XML declaration
27
+ .replace(/<!DOCTYPE.*?>/g, "") // remove DOCTYPE
28
+ .replace(/\r?\n|\r/g, "") // remove newlines
9
29
  .trim();
10
- // تبدیل attribute svg به props-react compatible
11
- cleaned = cleaned.replace(/<svg([^>]*)>/, `<svg$1
12
- width={width}
13
- height={height}
14
- fill={fill}
15
- stroke={props.stroke || "none"}
16
- className={props.className}
17
- {...props}>`);
30
+ // convert all style="..." to React objects
31
+ cleaned = cleaned.replace(/style="([^"]*)"/g, (_, styleContent) => {
32
+ return `{...{style: ${JSON.stringify(styleStringToObject(styleContent))}}}`;
33
+ });
34
+ // inject React props into <svg> tag
35
+ cleaned = cleaned.replace(/<svg([^>]*)>/, `<svg$1 width={props.width || ${defaultWidth}} height={props.height || ${defaultHeight}} fill={props.fill || "${defaultFill}"} stroke={props.stroke || "${defaultStroke}"} {...props}>`);
18
36
  return `import * as React from "react";
19
37
  import type { SVGProps } from "react";
20
38
 
21
- export const ${componentName}: React.FC<SVGProps<SVGSVGElement>> = ({
22
- width = ${defaultWidth},
23
- height = ${defaultHeight},
24
- fill = "${defaultFill}",
25
- ...props
26
- }) => (
39
+ export const ${componentName}: React.FC<SVGProps<SVGSVGElement>> = (props) => (
27
40
  ${cleaned}
28
41
  );
29
42
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svger-cli",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
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 mohadespoor",
20
+ "author": "faeze mohades",
21
21
  "license": "MIT",
22
22
  "dependencies": {
23
23
  "change-case": "^5.4.4",
@@ -1,46 +1,60 @@
1
+ /**
2
+ * Generates a React functional component string from an SVG file's content,
3
+ * safely converting any inline `style="..."` to React-compatible object.
4
+ */
1
5
  export function reactTemplate({
2
6
  componentName,
3
7
  svgContent,
4
8
  defaultWidth = 24,
5
9
  defaultHeight = 24,
6
10
  defaultFill = "currentColor",
11
+ defaultStroke = "none",
7
12
  }: {
8
13
  componentName: string;
9
14
  svgContent: string;
10
15
  defaultWidth?: number;
11
16
  defaultHeight?: number;
12
17
  defaultFill?: string;
18
+ defaultStroke?: string;
13
19
  }) {
14
- // پاکسازی XML/DOCTYPE و style inline و class/id
20
+ // helper: convert inline style string to JS object
21
+ function styleStringToObject(style: string) {
22
+ const obj: Record<string, string | number> = {};
23
+ style.split(";").forEach((pair) => {
24
+ if (!pair.trim()) return;
25
+ const [key, value] = pair.split(":");
26
+ if (!key || value === undefined) return;
27
+ // convert kebab-case to camelCase
28
+ const camelKey = key.trim().replace(/-([a-z])/g, (_, c) => c.toUpperCase());
29
+ let v: string | number = value.trim();
30
+ if (!isNaN(Number(v))) v = Number(v);
31
+ obj[camelKey] = v;
32
+ });
33
+ return obj;
34
+ }
35
+
36
+ // clean SVG content
15
37
  let cleaned = svgContent
16
- .replace(/<\?xml.*?\?>/g, "")
17
- .replace(/<!DOCTYPE.*?>/g, "")
18
- .replace(/\r?\n|\r/g, "")
19
- .replace(/\s*style="[^"]*"/g, "") // حذف style inline
20
- .replace(/\s*(class|id)=["'][^"']*["']/g, "") // حذف class/id
38
+ .replace(/<\?xml.*?\?>/g, "") // remove XML declaration
39
+ .replace(/<!DOCTYPE.*?>/g, "") // remove DOCTYPE
40
+ .replace(/\r?\n|\r/g, "") // remove newlines
21
41
  .trim();
22
42
 
23
- // تبدیل attribute svg به props-react compatible
43
+ // convert all style="..." to React objects
44
+ cleaned = cleaned.replace(/style="([^"]*)"/g, (_, styleContent) => {
45
+ return `{...{style: ${JSON.stringify(styleStringToObject(styleContent))}}}`;
46
+ });
47
+
48
+ // inject React props into <svg> tag
24
49
  cleaned = cleaned.replace(
25
50
  /<svg([^>]*)>/,
26
- `<svg$1
27
- width={width}
28
- height={height}
29
- fill={fill}
30
- stroke={props.stroke || "none"}
31
- className={props.className}
32
- {...props}>`
51
+ `<svg$1 width={props.width || ${defaultWidth}} height={props.height || ${defaultHeight}} fill={props.fill || "${defaultFill}"} stroke={props.stroke || "${defaultStroke}"} {...props}>`
33
52
  );
34
53
 
35
54
  return `import * as React from "react";
36
55
  import type { SVGProps } from "react";
37
56
 
38
- export const ${componentName}: React.FC<SVGProps<SVGSVGElement>> = ({
39
- width = ${defaultWidth},
40
- height = ${defaultHeight},
41
- fill = "${defaultFill}",
42
- ...props
43
- }) => (
57
+ export const ${componentName}: React.FC<SVGProps<SVGSVGElement>> = (props) => (
44
58
  ${cleaned}
45
59
  );
46
60