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
|
-
|
|
12
|
-
}
|
|
7
|
+
}
|
|
8
|
+
export declare const reactTemplate: ({ componentName, svgContent, defaultWidth, defaultHeight, defaultFill, }: TemplateProps) => string;
|
|
9
|
+
export {};
|
|
@@ -1,45 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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
|
-
|
|
40
|
-
${
|
|
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
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 {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
|
55
|
-
import type { SVGProps } from "react";
|
|
22
|
+
return `import type { SVGProps } from "react";
|
|
56
23
|
|
|
57
|
-
|
|
58
|
-
${
|
|
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
|
+
};
|