svger-cli 1.0.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/.svg-lock ADDED
@@ -0,0 +1 @@
1
+ []
package/README.md ADDED
@@ -0,0 +1,121 @@
1
+ svger-cli CLI Commands Reference
2
+
3
+ Version: 1.0.0
4
+ Purpose: Convert SVGs into React components with configurable defaults, watch mode, and selective rebuilding.
5
+
6
+ 1. Build Command
7
+ Command Example
8
+ svger-cli build [options] svger-cli build --src ./src/assets/svg --out ./src/components/icons
9
+
10
+ What It Does
11
+
12
+ Converts every .svg in the source folder into a React component.
13
+
14
+ Applies default width, height, fill, and style rules from .svgconfig.json if present.
15
+
16
+ Skips locked files.
17
+
18
+ Generates component names based on PascalCase (configurable).
19
+
20
+ 2. Watch Command
21
+ Command Example
22
+ svger-cli watch [options] svger-cli watch --src ./src/assets/svg --out ./src/components/icons
23
+
24
+ What It Does
25
+
26
+ Continuously monitors the source folder for new, updated, or deleted SVG files.
27
+
28
+ Automatically rebuilds React components for added or modified files.
29
+
30
+ Deletes components if SVG files are removed.
31
+
32
+ Skips locked files.
33
+
34
+ Ideal for development with frequent SVG updates.
35
+
36
+ 3. Generate Command
37
+ Command Example
38
+ svger-cli generate <svgFile> [options] svger-cli generate ./src/assets/svg/heart.svg --out ./src/components/icons
39
+
40
+ What It Does
41
+
42
+ Converts a specific SVG file into a React component.
43
+
44
+ Useful for adding a single icon to an existing collection.
45
+
46
+ Honors default configuration values.
47
+
48
+ 4. Lock Command
49
+ Command Example
50
+ svger-cli lock <svgFile> [options] svger-cli lock ./src/assets/svg/logo.svg
51
+
52
+ What It Does
53
+
54
+ Marks one or more SVG files as locked.
55
+
56
+ Locked files are skipped during build or watch operations.
57
+
58
+ Ensures that branded or protected icons remain unchanged.
59
+
60
+ 5. Unlock Command
61
+ Command Example
62
+ svger-cli unlock <svgFile> [options] svger-cli unlock ./src/assets/svg/logo.svg
63
+
64
+ What It Does
65
+
66
+ Removes files from the locked state.
67
+
68
+ Locked files can now be rebuilt normally.
69
+
70
+ 6. Config Command
71
+ Command Example
72
+ svger-cli config [options] svger-cli config --init or svger-cli config --set defaultWidth=32
73
+
74
+ What It Does
75
+
76
+ Creates or modifies .svgconfig.json for default build settings.
77
+
78
+ --init — creates a new configuration file.
79
+
80
+ --set <key=value> — updates configuration properties like source, output, defaultWidth, defaultHeight, defaultFill, etc.
81
+
82
+ --show — displays current configuration.
83
+
84
+ 7. Clean Command
85
+ Command Example
86
+ svger-cli clean --out <folder> svger-cli clean --out ./src/components/icons
87
+
88
+ What It Does
89
+
90
+ Deletes all previously generated React component files in the specified output folder.
91
+
92
+ Useful for rebuilding everything from scratch.
93
+
94
+ 8. Full One-Line Command (Bash / PowerShell / Mac / Linux)
95
+ svger-cli config --init && \
96
+ svger-cli config --set source=./src/assets/svg && \
97
+ svger-cli config --set output=./src/components/icons && \
98
+ svger-cli config --set defaultWidth=24 && \
99
+ svger-cli config --set defaultHeight=24 && \
100
+ svger-cli config --set defaultFill=currentColor && \
101
+ svger-cli lock ./src/assets/svg/logo.svg && \
102
+ svger-cli build ./src/assets/svg ./src/components/icons && \
103
+ svger-cli generate ./src/assets/svg/new-icon.svg ./src/components/icons && \
104
+ svger-cli unlock ./src/assets/svg/logo.svg && \
105
+ svger-cli watch ./src/assets/svg ./src/components/icons && \
106
+ svger-cli clean ./src/components/icons
107
+
108
+
109
+ What It Does
110
+
111
+ Initializes configuration, sets defaults, locks specific icons.
112
+
113
+ Builds all SVGs, generates a new one, unlocks, and starts watch mode.
114
+
115
+ Cleans output folder at the end if needed.
116
+
117
+
118
+
119
+ Acknowledgements
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.
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import("../dist/cli.js");
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Converts all SVG files from a source directory into React components and writes them to an output directory.
3
+ *
4
+ * @param {Object} config - Configuration object.
5
+ * @param {string} config.src - Path to the source folder containing SVG files.
6
+ * @param {string} config.out - Path to the output folder where React components will be generated.
7
+ * @returns {Promise<void>} Resolves when all SVGs have been processed.
8
+ */
9
+ export declare function buildAll(config: {
10
+ src: string;
11
+ out: string;
12
+ }): Promise<void>;
13
+ /**
14
+ * Generates a single React component from an SVG file.
15
+ *
16
+ * @param {Object} params - Parameters object.
17
+ * @param {string} params.svgFile - Path to the SVG file to be converted.
18
+ * @param {string} params.outDir - Path to the output folder for the generated component.
19
+ * @returns {Promise<void>} Resolves when the SVG has been converted.
20
+ */
21
+ export declare function generateSVG({ svgFile, outDir, }: {
22
+ svgFile: string;
23
+ outDir: string;
24
+ }): Promise<void>;
@@ -0,0 +1,83 @@
1
+ import fs from "fs-extra";
2
+ import path from "path";
3
+ import { pascalCase } from "change-case";
4
+ import { reactTemplate } from "./templates/ComponentTemplate.js";
5
+ import { isLocked } from "./lock.js";
6
+ import { readConfig } from "./config.js";
7
+ /**
8
+ * Converts all SVG files from a source directory into React components and writes them to an output directory.
9
+ *
10
+ * @param {Object} config - Configuration object.
11
+ * @param {string} config.src - Path to the source folder containing SVG files.
12
+ * @param {string} config.out - Path to the output folder where React components will be generated.
13
+ * @returns {Promise<void>} Resolves when all SVGs have been processed.
14
+ */
15
+ export async function buildAll(config) {
16
+ const svgConfig = readConfig();
17
+ const srcDir = path.resolve(config.src);
18
+ const outDir = path.resolve(config.out);
19
+ if (!fs.existsSync(srcDir)) {
20
+ console.error("❌ Source folder not found:", srcDir);
21
+ process.exit(1);
22
+ }
23
+ await fs.ensureDir(outDir);
24
+ const files = (await fs.readdir(srcDir)).filter(f => f.endsWith(".svg"));
25
+ if (!files.length) {
26
+ console.log("⚠️ No SVG files found in", srcDir);
27
+ return;
28
+ }
29
+ for (const file of files) {
30
+ const svgPath = path.join(srcDir, file);
31
+ if (isLocked(svgPath)) {
32
+ console.log(`⚠️ Skipped locked file: ${file}`);
33
+ continue;
34
+ }
35
+ const svgContent = await fs.readFile(svgPath, "utf-8");
36
+ const componentName = pascalCase(file.replace(".svg", ""));
37
+ const componentCode = reactTemplate({
38
+ componentName,
39
+ svgContent,
40
+ defaultWidth: svgConfig.defaultWidth,
41
+ defaultHeight: svgConfig.defaultHeight,
42
+ defaultFill: svgConfig.defaultFill,
43
+ });
44
+ const outFile = path.join(outDir, `${componentName}.tsx`);
45
+ await fs.writeFile(outFile, componentCode, "utf-8");
46
+ console.log(`✅ Generated: ${componentName}.tsx`);
47
+ }
48
+ console.log("🎉 All SVGs have been converted successfully!");
49
+ }
50
+ /**
51
+ * Generates a single React component from an SVG file.
52
+ *
53
+ * @param {Object} params - Parameters object.
54
+ * @param {string} params.svgFile - Path to the SVG file to be converted.
55
+ * @param {string} params.outDir - Path to the output folder for the generated component.
56
+ * @returns {Promise<void>} Resolves when the SVG has been converted.
57
+ */
58
+ export async function generateSVG({ svgFile, outDir, }) {
59
+ const svgConfig = readConfig();
60
+ const filePath = path.resolve(svgFile);
61
+ if (isLocked(filePath)) {
62
+ console.log(`⚠️ Skipped locked file: ${path.basename(svgFile)}`);
63
+ return;
64
+ }
65
+ if (!fs.existsSync(filePath)) {
66
+ console.error("❌ SVG file not found:", filePath);
67
+ process.exit(1);
68
+ }
69
+ const svgContent = await fs.readFile(filePath, "utf-8");
70
+ const componentName = pascalCase(path.basename(svgFile, ".svg"));
71
+ const componentCode = reactTemplate({
72
+ componentName,
73
+ svgContent,
74
+ defaultWidth: svgConfig.defaultWidth,
75
+ defaultHeight: svgConfig.defaultHeight,
76
+ defaultFill: svgConfig.defaultFill,
77
+ });
78
+ const outputFolder = path.resolve(outDir);
79
+ await fs.ensureDir(outputFolder);
80
+ const outFile = path.join(outputFolder, `${componentName}.tsx`);
81
+ await fs.writeFile(outFile, componentCode, "utf-8");
82
+ console.log(`✅ Generated: ${componentName}.tsx`);
83
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Cleans the specified output directory by removing all files and folders inside it.
3
+ * Typically used to clear previously generated SVG React components before a new build.
4
+ *
5
+ * @param {string} outDir - Path to the output directory to be cleaned.
6
+ * @returns {Promise<void>} Resolves when the directory has been emptied.
7
+ */
8
+ export declare function clean(outDir: string): Promise<void>;
package/dist/clean.js ADDED
@@ -0,0 +1,18 @@
1
+ import fs from "fs-extra";
2
+ import path from "path";
3
+ /**
4
+ * Cleans the specified output directory by removing all files and folders inside it.
5
+ * Typically used to clear previously generated SVG React components before a new build.
6
+ *
7
+ * @param {string} outDir - Path to the output directory to be cleaned.
8
+ * @returns {Promise<void>} Resolves when the directory has been emptied.
9
+ */
10
+ export async function clean(outDir) {
11
+ const targetDir = path.resolve(outDir);
12
+ if (!fs.existsSync(targetDir)) {
13
+ console.log(`⚠️ Directory not found: ${targetDir}`);
14
+ return;
15
+ }
16
+ await fs.emptyDir(targetDir);
17
+ console.log(`🧹 Cleaned all generated SVG components in: ${targetDir}`);
18
+ }
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,124 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import { buildAll, generateSVG } from "./builder.js";
4
+ import { lockFiles, unlockFiles } from "./lock.js";
5
+ import { initConfig, setConfig, showConfig } from "./config.js";
6
+ import { watchSVGs } from "./watch.js";
7
+ import { clean } from "./clean.js";
8
+ const program = new Command();
9
+ /**
10
+ * svger-cli CLI
11
+ * Custom SVG to React component converter.
12
+ */
13
+ program
14
+ .name("svger-cli")
15
+ .description("Custom SVG to React component converter")
16
+ .version("1.0.0");
17
+ // -------- Build Command --------
18
+ /**
19
+ * Build all SVGs from a source folder to an output folder.
20
+ *
21
+ * @param {string} src - Source folder containing SVG files.
22
+ * @param {string} out - Output folder for generated React components.
23
+ */
24
+ program
25
+ .command("build <src> <out>")
26
+ .description("Build all SVGs from source to output")
27
+ .action(async (src, out) => {
28
+ console.log("🛠️ Building SVGs...");
29
+ console.log("Source:", src);
30
+ console.log("Output:", out);
31
+ await buildAll({ src, out });
32
+ });
33
+ // -------- Watch Command --------
34
+ /**
35
+ * Watch a source folder and rebuild SVGs automatically on changes.
36
+ *
37
+ * @param {string} src - Source folder to watch.
38
+ * @param {string} out - Output folder for generated components.
39
+ */
40
+ program
41
+ .command("watch <src> <out>")
42
+ .description("Watch source folder and rebuild SVGs automatically")
43
+ .action((src, out) => {
44
+ console.log("🚀 Starting watch mode...");
45
+ watchSVGs({ src, out });
46
+ });
47
+ // -------- Generate Single SVG --------
48
+ /**
49
+ * Generate a React component from a single SVG file.
50
+ *
51
+ * @param {string} svgFile - Path to the SVG file.
52
+ * @param {string} out - Output folder for the generated component.
53
+ */
54
+ program
55
+ .command("generate <svgFile> <out>")
56
+ .description("Convert a single SVG file into a React component")
57
+ .action(async (svgFile, out) => {
58
+ await generateSVG({ svgFile, outDir: out });
59
+ });
60
+ // -------- Lock / Unlock --------
61
+ /**
62
+ * Lock one or more SVG files to prevent accidental overwrites.
63
+ *
64
+ * @param {string[]} files - Paths to SVG files to lock.
65
+ */
66
+ program
67
+ .command("lock <files...>")
68
+ .description("Lock one or more SVG files")
69
+ .action((files) => lockFiles(files));
70
+ /**
71
+ * Unlock one or more SVG files to allow modifications.
72
+ *
73
+ * @param {string[]} files - Paths to SVG files to unlock.
74
+ */
75
+ program
76
+ .command("unlock <files...>")
77
+ .description("Unlock one or more SVG files")
78
+ .action((files) => unlockFiles(files));
79
+ // -------- Config --------
80
+ /**
81
+ * Manage svger-cli configuration.
82
+ *
83
+ * Options:
84
+ * --init: Create default .svgconfig.json
85
+ * --set key=value: Set a configuration value
86
+ * --show: Show current configuration
87
+ *
88
+ * @param {Object} opts - CLI options
89
+ */
90
+ program
91
+ .command("config")
92
+ .description("Manage svger-cli configuration")
93
+ .option("--init", "Create default .svgconfig.json")
94
+ .option("--set <keyValue>", "Set config key=value")
95
+ .option("--show", "Show current config")
96
+ .action((opts) => {
97
+ if (opts.init)
98
+ return initConfig();
99
+ if (opts.set) {
100
+ const [key, value] = opts.set.split("=");
101
+ if (!key || value === undefined) {
102
+ console.error("❌ Invalid format. Use key=value");
103
+ process.exit(1);
104
+ }
105
+ const parsedValue = !isNaN(Number(value)) ? Number(value) : value;
106
+ return setConfig(key, parsedValue);
107
+ }
108
+ if (opts.show)
109
+ return showConfig();
110
+ console.log("❌ No option provided. Use --init, --set, or --show");
111
+ });
112
+ // -------- Clean Command --------
113
+ /**
114
+ * Remove all generated SVG React components from an output folder.
115
+ *
116
+ * @param {string} out - Output folder to clean.
117
+ */
118
+ program
119
+ .command("clean <out>")
120
+ .description("Remove all generated SVG React components from output folder")
121
+ .action(async (out) => {
122
+ await clean(out);
123
+ });
124
+ program.parse();
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Read the current svger-cli configuration.
3
+ *
4
+ * @returns {Record<string, any>} Configuration object. Returns an empty object if no config file exists.
5
+ */
6
+ export declare function readConfig(): Record<string, any>;
7
+ /**
8
+ * Write a configuration object to the config file.
9
+ *
10
+ * @param {Record<string, any>} config - Configuration object to write.
11
+ */
12
+ export declare function writeConfig(config: Record<string, any>): void;
13
+ /**
14
+ * Initialize the svger-cli configuration with default values.
15
+ * If a config file already exists, this function will not overwrite it.
16
+ */
17
+ export declare function initConfig(): void;
18
+ /**
19
+ * Set a specific configuration key to a new value.
20
+ *
21
+ * @param {string} key - The config key to set.
22
+ * @param {any} value - The value to assign to the key.
23
+ */
24
+ export declare function setConfig(key: string, value: any): void;
25
+ /**
26
+ * Display the current configuration in the console.
27
+ */
28
+ export declare function showConfig(): void;
package/dist/config.js ADDED
@@ -0,0 +1,74 @@
1
+ import fs from "fs-extra";
2
+ import path from "path";
3
+ const CONFIG_FILE = ".svgconfig.json";
4
+ /**
5
+ * Get the absolute path to the configuration file.
6
+ *
7
+ * @returns {string} Absolute path to .svgconfig.json
8
+ */
9
+ function getConfigPath() {
10
+ return path.resolve(CONFIG_FILE);
11
+ }
12
+ /**
13
+ * Read the current svger-cli configuration.
14
+ *
15
+ * @returns {Record<string, any>} Configuration object. Returns an empty object if no config file exists.
16
+ */
17
+ export function readConfig() {
18
+ if (!fs.existsSync(getConfigPath()))
19
+ return {};
20
+ return fs.readJSONSync(getConfigPath());
21
+ }
22
+ /**
23
+ * Write a configuration object to the config file.
24
+ *
25
+ * @param {Record<string, any>} config - Configuration object to write.
26
+ */
27
+ export function writeConfig(config) {
28
+ fs.writeJSONSync(getConfigPath(), config, { spaces: 2 });
29
+ }
30
+ /**
31
+ * Initialize the svger-cli configuration with default values.
32
+ * If a config file already exists, this function will not overwrite it.
33
+ */
34
+ export function initConfig() {
35
+ if (fs.existsSync(getConfigPath())) {
36
+ console.log("⚠️ Config file already exists:", getConfigPath());
37
+ return;
38
+ }
39
+ const defaultConfig = {
40
+ source: "./src/assets/svg",
41
+ output: "./src/components/icons",
42
+ watch: false,
43
+ defaultWidth: 24,
44
+ defaultHeight: 24,
45
+ defaultFill: "currentColor",
46
+ exclude: [],
47
+ styleRules: {
48
+ fill: "inherit",
49
+ stroke: "none",
50
+ },
51
+ };
52
+ writeConfig(defaultConfig);
53
+ console.log("✅ Config file created:", getConfigPath());
54
+ }
55
+ /**
56
+ * Set a specific configuration key to a new value.
57
+ *
58
+ * @param {string} key - The config key to set.
59
+ * @param {any} value - The value to assign to the key.
60
+ */
61
+ export function setConfig(key, value) {
62
+ const config = readConfig();
63
+ config[key] = value;
64
+ writeConfig(config);
65
+ console.log(`✅ Set config ${key}=${value}`);
66
+ }
67
+ /**
68
+ * Display the current configuration in the console.
69
+ */
70
+ export function showConfig() {
71
+ const config = readConfig();
72
+ console.log("📄 Current Config:");
73
+ console.log(JSON.stringify(config, null, 2));
74
+ }
package/dist/lock.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Lock one or more SVG files to prevent them from being processed.
3
+ *
4
+ * @param {string[]} files - Paths to SVG files to lock.
5
+ */
6
+ export declare function lockFiles(files: string[]): void;
7
+ /**
8
+ * Unlock one or more SVG files, allowing them to be processed again.
9
+ *
10
+ * @param {string[]} files - Paths to SVG files to unlock.
11
+ */
12
+ export declare function unlockFiles(files: string[]): void;
13
+ /**
14
+ * Check if a specific SVG file is locked.
15
+ *
16
+ * @param {string} file - Path to the SVG file to check.
17
+ * @returns {boolean} True if the file is locked, false otherwise.
18
+ */
19
+ export declare function isLocked(file: string): boolean;
package/dist/lock.js ADDED
@@ -0,0 +1,69 @@
1
+ import fs from "fs-extra";
2
+ import path from "path";
3
+ const LOCK_FILE = ".svg-lock";
4
+ /**
5
+ * Get the absolute path to the lock file.
6
+ *
7
+ * @returns {string} Absolute path to .svg-lock
8
+ */
9
+ function getLockFilePath() {
10
+ return path.resolve(LOCK_FILE);
11
+ }
12
+ /**
13
+ * Read the current locked SVG files from the lock file.
14
+ *
15
+ * @returns {string[]} Array of locked SVG file names.
16
+ */
17
+ function readLockFile() {
18
+ if (!fs.existsSync(getLockFilePath()))
19
+ return [];
20
+ try {
21
+ const data = fs.readFileSync(getLockFilePath(), "utf-8");
22
+ return JSON.parse(data);
23
+ }
24
+ catch (e) {
25
+ return [];
26
+ }
27
+ }
28
+ /**
29
+ * Write the list of locked SVG files to the lock file.
30
+ *
31
+ * @param {string[]} files - Array of SVG file names to lock.
32
+ */
33
+ function writeLockFile(files) {
34
+ fs.writeFileSync(getLockFilePath(), JSON.stringify(files, null, 2), "utf-8");
35
+ }
36
+ /**
37
+ * Lock one or more SVG files to prevent them from being processed.
38
+ *
39
+ * @param {string[]} files - Paths to SVG files to lock.
40
+ */
41
+ export function lockFiles(files) {
42
+ const fileNames = files.map(f => path.basename(f));
43
+ const current = readLockFile();
44
+ const newFiles = Array.from(new Set([...current, ...fileNames]));
45
+ writeLockFile(newFiles);
46
+ console.log(`🔒 Locked files: ${newFiles.join(", ")}`);
47
+ }
48
+ /**
49
+ * Unlock one or more SVG files, allowing them to be processed again.
50
+ *
51
+ * @param {string[]} files - Paths to SVG files to unlock.
52
+ */
53
+ export function unlockFiles(files) {
54
+ const fileNames = files.map(f => path.basename(f));
55
+ const current = readLockFile();
56
+ const remaining = current.filter(f => !fileNames.includes(f));
57
+ writeLockFile(remaining);
58
+ console.log(`🔓 Unlocked files: ${fileNames.join(", ")}`);
59
+ }
60
+ /**
61
+ * Check if a specific SVG file is locked.
62
+ *
63
+ * @param {string} file - Path to the SVG file to check.
64
+ * @returns {boolean} True if the file is locked, false otherwise.
65
+ */
66
+ export function isLocked(file) {
67
+ const current = readLockFile();
68
+ return current.includes(path.basename(file));
69
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Generates a React functional component string from an SVG file's content.
3
+ *
4
+ * This template replaces XML/DOCTYPE declarations, cleans up formatting,
5
+ * and injects React props (`width`, `height`, `fill`, and any others via `...props`)
6
+ * directly into the root `<svg>` tag.
7
+ *
8
+ * @param {Object} params - Template generation parameters.
9
+ * @param {string} params.componentName - The name of the generated React component.
10
+ * @param {string} params.svgContent - The raw SVG markup to transform into a React component.
11
+ * @param {number} [params.defaultWidth=24] - Default width of the SVG (used if none is provided via props).
12
+ * @param {number} [params.defaultHeight=24] - Default height of the SVG (used if none is provided via props).
13
+ * @param {string} [params.defaultFill="currentColor"] - Default fill color of the SVG.
14
+ *
15
+ * @returns {string} The complete TypeScript React component code as a string.
16
+ *
17
+ * @example
18
+ * const svg = '<svg viewBox="0 0 24 24"><path d="M0 0h24v24H0z"/></svg>';
19
+ * const componentCode = reactTemplate({
20
+ * componentName: "MyIcon",
21
+ * svgContent: svg,
22
+ * defaultWidth: 32,
23
+ * defaultHeight: 32,
24
+ * });
25
+ *
26
+ * // Result: a ready-to-write .tsx file containing a typed React component
27
+ * console.log(componentCode);
28
+ */
29
+ export declare function reactTemplate({ componentName, svgContent, defaultWidth, defaultHeight, defaultFill, }: {
30
+ componentName: string;
31
+ svgContent: string;
32
+ defaultWidth?: number;
33
+ defaultHeight?: number;
34
+ defaultFill?: string;
35
+ }): string;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Generates a React functional component string from an SVG file's content.
3
+ *
4
+ * This template replaces XML/DOCTYPE declarations, cleans up formatting,
5
+ * and injects React props (`width`, `height`, `fill`, and any others via `...props`)
6
+ * directly into the root `<svg>` tag.
7
+ *
8
+ * @param {Object} params - Template generation parameters.
9
+ * @param {string} params.componentName - The name of the generated React component.
10
+ * @param {string} params.svgContent - The raw SVG markup to transform into a React component.
11
+ * @param {number} [params.defaultWidth=24] - Default width of the SVG (used if none is provided via props).
12
+ * @param {number} [params.defaultHeight=24] - Default height of the SVG (used if none is provided via props).
13
+ * @param {string} [params.defaultFill="currentColor"] - Default fill color of the SVG.
14
+ *
15
+ * @returns {string} The complete TypeScript React component code as a string.
16
+ *
17
+ * @example
18
+ * const svg = '<svg viewBox="0 0 24 24"><path d="M0 0h24v24H0z"/></svg>';
19
+ * const componentCode = reactTemplate({
20
+ * componentName: "MyIcon",
21
+ * svgContent: svg,
22
+ * defaultWidth: 32,
23
+ * defaultHeight: 32,
24
+ * });
25
+ *
26
+ * // Result: a ready-to-write .tsx file containing a typed React component
27
+ * console.log(componentCode);
28
+ */
29
+ export function reactTemplate({ componentName, svgContent, defaultWidth = 24, defaultHeight = 24, defaultFill = "currentColor", }) {
30
+ const cleaned = svgContent
31
+ .replace(/<\?xml.*?\?>/g, "") // Remove XML declarations
32
+ .replace(/<!DOCTYPE.*?>/g, "") // Remove DOCTYPE lines
33
+ .replace(/\r?\n|\r/g, "") // Remove newlines
34
+ .trim();
35
+ return `import * as React from "react";
36
+
37
+ export const ${componentName}: React.FC<React.SVGProps<SVGSVGElement>> = ({
38
+ width = ${defaultWidth},
39
+ height = ${defaultHeight},
40
+ fill = "${defaultFill}",
41
+ ...props
42
+ }) => (
43
+ ${cleaned.replace(/<svg/, `<svg width={width} height={height} fill={fill} {...props}`)}
44
+ );
45
+
46
+ export default ${componentName};
47
+ `;
48
+ }