svger-cli 1.0.3 → 1.0.5

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/builder.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import fs from "fs-extra";
2
2
  import path from "path";
3
3
  import { pascalCase } from "change-case";
4
- import { reactTemplate } from "./templates/ComponentTemplate.js";
5
4
  import { isLocked } from "./lock.js";
6
5
  import { readConfig } from "./config.js";
6
+ import { reactTemplate } from "./templates/ComponentTemplate.js";
7
7
  /**
8
8
  * Converts all SVG files from a source directory into React components and writes them to an output directory.
9
9
  *
@@ -1,12 +1,9 @@
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, }: {
1
+ interface TemplateProps {
6
2
  componentName: string;
7
3
  svgContent: string;
8
4
  defaultWidth?: number;
9
5
  defaultHeight?: number;
10
6
  defaultFill?: string;
11
- defaultStroke?: string;
12
- }): string;
7
+ }
8
+ export declare const reactTemplate: ({ componentName, svgContent, defaultWidth, defaultHeight, defaultFill, }: TemplateProps) => string;
9
+ export {};
@@ -1,45 +1,20 @@
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
25
- let cleaned = svgContent
26
- .replace(/<\?xml.*?\?>/g, "") // remove XML declaration
27
- .replace(/<!DOCTYPE.*?>/g, "") // remove DOCTYPE
28
- .replace(/\r?\n|\r/g, "") // remove newlines
29
- .trim();
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}>`);
36
- return `import * as React from "react";
37
- import type { SVGProps } from "react";
1
+ export const reactTemplate = ({ componentName, svgContent, defaultWidth = 24, defaultHeight = 24, defaultFill = "currentColor", }) => {
2
+ const cleanedSvg = svgContent
3
+ .replace(/style="[^"]*"/g, "")
4
+ .replace(/\s+xmlns:xlink=/g, " xmlnsXlink=");
5
+ return `import type { SVGProps } from "react";
38
6
 
39
- export const ${componentName}: React.FC<SVGProps<SVGSVGElement>> = (props) => (
40
- ${cleaned}
7
+ const ${componentName} = (props: SVGProps<SVGSVGElement>) => (
8
+ ${cleanedSvg
9
+ .replace(/<svg([^>]*)>/, `<svg$1
10
+ width={props.width || ${defaultWidth}}
11
+ height={props.height || ${defaultHeight}}
12
+ fill={props.fill || "${defaultFill}"}
13
+ stroke={props.stroke || "none"}
14
+ className={props.className}
15
+ {...props}>`)}
41
16
  );
42
17
 
43
18
  export default ${componentName};
44
19
  `;
45
- }
20
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svger-cli",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
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",
package/src/builder.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import fs from "fs-extra";
2
2
  import path from "path";
3
3
  import { pascalCase } from "change-case";
4
- import { reactTemplate } from "./templates/ComponentTemplate.js";
5
- import { isLocked } from "./lock.js";
4
+ import { isLocked } from "./lock.js";
6
5
  import { readConfig } from "./config.js";
6
+ import { reactTemplate } from "./templates/ComponentTemplate.js";
7
7
 
8
8
  /**
9
9
  * Converts all SVG files from a source directory into React components and writes them to an output directory.
@@ -1,63 +1,40 @@
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({
6
- componentName,
7
- svgContent,
8
- defaultWidth = 24,
9
- defaultHeight = 24,
10
- defaultFill = "currentColor",
11
- defaultStroke = "none",
12
- }: {
1
+
2
+ interface TemplateProps {
13
3
  componentName: string;
14
4
  svgContent: string;
15
5
  defaultWidth?: number;
16
6
  defaultHeight?: number;
17
7
  defaultFill?: string;
18
- defaultStroke?: string;
19
- }) {
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
37
- let cleaned = svgContent
38
- .replace(/<\?xml.*?\?>/g, "") // remove XML declaration
39
- .replace(/<!DOCTYPE.*?>/g, "") // remove DOCTYPE
40
- .replace(/\r?\n|\r/g, "") // remove newlines
41
- .trim();
42
-
43
- // convert all style="..." to React objects
44
- cleaned = cleaned.replace(/style="([^"]*)"/g, (_, styleContent) => {
45
- return `{...{style: ${JSON.stringify(styleStringToObject(styleContent))}}}`;
46
- });
8
+ }
47
9
 
48
- // inject React props into <svg> tag
49
- cleaned = cleaned.replace(
50
- /<svg([^>]*)>/,
51
- `<svg$1 width={props.width || ${defaultWidth}} height={props.height || ${defaultHeight}} fill={props.fill || "${defaultFill}"} stroke={props.stroke || "${defaultStroke}"} {...props}>`
52
- );
10
+ export const reactTemplate = ({
11
+ componentName,
12
+ svgContent,
13
+ defaultWidth = 24,
14
+ defaultHeight = 24,
15
+ defaultFill = "currentColor",
16
+ }: TemplateProps) => {
17
+
18
+ const cleanedSvg = svgContent
19
+ .replace(/style="[^"]*"/g, "")
20
+ .replace(/\s+xmlns:xlink=/g, " xmlnsXlink=");
53
21
 
54
- return `import * as React from "react";
55
- import type { SVGProps } from "react";
22
+ return `import type { SVGProps } from "react";
56
23
 
57
- export const ${componentName}: React.FC<SVGProps<SVGSVGElement>> = (props) => (
58
- ${cleaned}
24
+ const ${componentName} = (props: SVGProps<SVGSVGElement>) => (
25
+ ${cleanedSvg
26
+ .replace(
27
+ /<svg([^>]*)>/,
28
+ `<svg$1
29
+ width={props.width || ${defaultWidth}}
30
+ height={props.height || ${defaultHeight}}
31
+ fill={props.fill || "${defaultFill}"}
32
+ stroke={props.stroke || "none"}
33
+ className={props.className}
34
+ {...props}>`
35
+ )}
59
36
  );
60
37
 
61
38
  export default ${componentName};
62
39
  `;
63
- }
40
+ };