svgfusion 1.7.0 → 1.8.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/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  **Transform SVG files into production-ready React and Vue 3 components**
7
7
 
8
- A powerful Node.js CLI tool and library that converts SVG files into optimized React and Vue components with complex SVG support, TypeScript integration, and smart optimization for modern development workflows.
8
+ A powerful Node.js CLI tool and library that converts SVG files into optimized React and Vue components with native SVG props inheritance, TypeScript integration, and smart optimization for modern development workflows.
9
9
 
10
10
  [![npm version](https://img.shields.io/npm/v/svgfusion)](https://www.npmjs.com/package/svgfusion)
11
11
  [![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?style=flat&logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
@@ -16,12 +16,22 @@ A powerful Node.js CLI tool and library that converts SVG files into optimized R
16
16
 
17
17
  </div>
18
18
 
19
+ ## What's New in v2.0
20
+
21
+ - **Custom SVGFusion Engine**: Complete rewrite with custom SVG parser replacing SVGR/SVGO
22
+ - **Native SVG Props**: Full React.SVGProps and Vue SVGAttributes support
23
+ - **Enhanced Type Safety**: Better TypeScript integration and type inference
24
+ - **Improved Performance**: Faster processing with streamlined architecture
25
+ - **Better Control**: Fine-grained control over SVG transformations and output
26
+
19
27
  ## Features
20
28
 
29
+ - **Native SVG Props**: Generated components extend React.SVGProps<SVGSVGElement> and Vue SVGAttributes
21
30
  - **Dual Framework Support**: Generate both React and Vue 3 components from the same SVG
31
+ - **Custom Engine**: Built-in SVGFusion engine for reliable SVG parsing and transformation
22
32
  - **Complex SVG Support**: Handles gradients, masks, filters, patterns, and Figma exports
23
33
  - **ID Collision Prevention**: Automatic unique ID generation for complex SVGs
24
- - **Optimized Output**: Built-in SVGO optimization with customizable settings
34
+ - **Optimized Output**: Smart optimization with customizable settings
25
35
  - **Icon Builder Ready**: Perfect for design systems and icon libraries
26
36
  - **TypeScript Ready**: Full TypeScript support with proper type definitions
27
37
  - **Flexible API**: Both CLI and programmatic usage
@@ -30,7 +40,7 @@ A powerful Node.js CLI tool and library that converts SVG files into optimized R
30
40
  - **Zero Configuration**: Works out of the box with sensible defaults
31
41
  - **Simple CLI**: Direct, intuitive command structure without subcommands
32
42
 
33
- ### 🚀 Advanced Features
43
+ ### Advanced Features
34
44
 
35
45
  - **Split Colors Mode**: Extract individual color props for maximum Tailwind CSS compatibility
36
46
  - **Fixed Stroke Width**: Add `vector-effect="non-scaling-stroke"` support for consistent strokes
@@ -72,7 +82,7 @@ pnpm add svgfusion
72
82
 
73
83
  ## CLI Options
74
84
 
75
- <img src="https://i.ibb.co/TD0QP5FC/cli.png" alt="SVGFusion CLI" width="512" >
85
+ <img src="https://i.ibb.co/mfRb84x/cli.png" alt="SVGFusion CLI" width="512" >
76
86
 
77
87
  svgfusion ./icons --output ./components --prefix Icon --suffix Svg
78
88
 
@@ -177,156 +187,163 @@ npx svgfusion ./assets/icons --output ./src/components --split-colors --fixed-st
177
187
  #### Single File Conversion
178
188
 
179
189
  ```typescript
180
- import { convertToReact, convertToVue, readSvgFile } from 'svgfusion';
190
+ import { SVGFusion, readFileSync } from 'svgfusion';
181
191
 
182
- // Read SVG file
183
- const svgContent = await readSvgFile('./icons/star.svg');
192
+ // Create SVGFusion engine instance
193
+ const engine = new SVGFusion();
184
194
 
185
- // React conversion
186
- const reactResult = await convertToReact(svgContent, {
187
- name: 'StarIcon',
188
- typescript: true,
189
- memo: true,
190
- ref: true,
191
- });
195
+ // Read SVG file
196
+ const svgContent = readFileSync('./icons/star.svg', 'utf8');
192
197
 
193
- // Vue conversion
194
- const vueResult = convertToVue(svgContent, {
195
- name: 'StarIcon',
198
+ // React conversion with native SVG props
199
+ const reactResult = engine.convert(svgContent, {
200
+ framework: 'react',
201
+ componentName: 'StarIcon',
196
202
  typescript: true,
197
- scriptSetup: true,
203
+ features: {
204
+ colorSplitting: true,
205
+ strokeFixing: true,
206
+ accessibility: true,
207
+ },
198
208
  });
199
209
 
200
- // Advanced: Split colors for Tailwind CSS
201
- const reactWithColors = await convertToReact(svgContent, {
202
- name: 'StarIcon',
203
- splitColors: true,
204
- isFixedStrokeWidth: true,
210
+ // Vue conversion with native SVG attributes
211
+ const vueResult = engine.convert(svgContent, {
212
+ framework: 'vue',
213
+ componentName: 'StarIcon',
205
214
  typescript: true,
215
+ features: {
216
+ colorSplitting: true,
217
+ strokeFixing: true,
218
+ accessibility: true,
219
+ },
206
220
  });
207
221
 
208
- console.log(reactResult.code); // Generated React component
209
- console.log(vueResult.code); // Generated Vue component
222
+ console.log(reactResult.code); // Generated React component with React.SVGProps
223
+ console.log(vueResult.code); // Generated Vue component with SVGAttributes
210
224
  ```
211
225
 
212
- #### Batch Processing
226
+ #### Batch Processing with CLI
213
227
 
214
228
  ```typescript
215
- import { BatchConverter } from 'svgfusion';
216
-
217
- const batchConverter = new BatchConverter();
229
+ import { processInput } from 'svgfusion/cli';
218
230
 
219
231
  // Convert entire directory
220
- const result = await batchConverter.convertBatch({
221
- inputDir: './icons',
222
- outputDir: './components',
232
+ processInput('./icons', {
233
+ output: './components',
223
234
  framework: 'react',
224
235
  recursive: true,
225
- generateIndex: true,
236
+ index: true,
226
237
  typescript: true,
227
238
  prefix: 'Icon',
228
239
  suffix: 'Component',
229
- indexFormat: 'ts',
230
- exportType: 'named',
231
240
  splitColors: true,
232
- isFixedStrokeWidth: true,
241
+ fixedStrokeWidth: true,
233
242
  });
234
-
235
- // Check results
236
- console.log(`Processed ${result.summary.total} files`);
237
- console.log(`Successful: ${result.summary.successful}`);
238
- console.log(`Failed: ${result.summary.failed}`);
239
-
240
- // Get component names
241
- const componentNames = batchConverter.getComponentNames(result);
242
- console.log('Generated components:', componentNames);
243
-
244
- // Generate summary report
245
- const report = batchConverter.generateSummaryReport(result);
246
- console.log(report);
247
243
  ```
248
244
 
249
245
  ## API Reference
250
246
 
251
- ### `convertToReact(svgContent, options)`
247
+ ### `SVGFusion`
252
248
 
253
- Convert SVG to React component.
249
+ The main engine class for converting SVG content to framework components.
254
250
 
255
- **Options:**
251
+ ```typescript
252
+ import { SVGFusion } from 'svgfusion';
256
253
 
257
- - `name?: string` - Component name (auto-generated from filename if not provided)
258
- - `prefix?: string` - Add prefix to component name
259
- - `suffix?: string` - Add suffix to component name
260
- - `typescript?: boolean` - Generate TypeScript component (default: `true`)
261
- - `memo?: boolean` - Wrap with React.memo (default: `true`)
262
- - `ref?: boolean` - Add forwardRef support (default: `true`)
263
- - `optimize?: boolean` - Apply SVGO optimization (default: `true`)
264
- - `splitColors?: boolean` - Extract individual color props (default: `false`)
265
- - `isFixedStrokeWidth?: boolean` - Add fixed stroke width support (default: `false`)
254
+ const engine = new SVGFusion();
255
+ ```
266
256
 
267
- ### `convertToVue(svgContent, options)`
257
+ #### `convert(svgContent: string, options: SVGFusionOptions): ConversionResult`
268
258
 
269
- Convert SVG to Vue 3 component. **Note: This is a synchronous function.**
259
+ Convert SVG content to React or Vue component.
270
260
 
271
261
  **Options:**
272
262
 
273
- - `name?: string` - Component name (auto-generated from filename if not provided)
274
- - `prefix?: string` - Add prefix to component name
275
- - `suffix?: string` - Add suffix to component name
263
+ - `framework: 'react' | 'vue'` - Target framework
264
+ - `componentName?: string` - Component name (auto-generated from filename if not provided)
276
265
  - `typescript?: boolean` - Generate TypeScript component (default: `true`)
277
- - `scriptSetup?: boolean` - Use script setup syntax (default: `true`)
278
- - `compositionApi?: boolean` - Use Composition API (default: `true`)
279
- - `optimize?: boolean` - Apply SVGO optimization (default: `true`)
280
- - `splitColors?: boolean` - Extract individual color props (default: `false`)
281
- - `isFixedStrokeWidth?: boolean` - Add fixed stroke width support (default: `false`)
266
+ - `features?: FeatureConfig` - Enable/disable transformation features
267
+ - `colorSplitting?: boolean` - Extract individual color props (default: `false`)
268
+ - `strokeFixing?: boolean` - Add fixed stroke width support (default: `false`)
269
+ - `accessibility?: boolean` - Add accessibility enhancements (default: `true`)
282
270
 
283
- ### `BatchConverter`
271
+ **Returns:** `ConversionResult`
284
272
 
285
- Process multiple SVG files in batch operations.
273
+ - `code: string` - Generated component code
274
+ - `framework: string` - Target framework
275
+ - `componentName: string` - Final component name
276
+ - `warnings: string[]` - Any conversion warnings
286
277
 
287
- #### `convertBatch(options: BatchConversionOptions)`
278
+ ### React Components
288
279
 
289
- Convert multiple SVG files to framework components.
280
+ Generated React components automatically extend `React.SVGProps<SVGSVGElement>`, providing:
290
281
 
291
- **Options:**
282
+ - All native SVG element props (onClick, onMouseOver, className, style, etc.)
283
+ - Full TypeScript support with proper type inference
284
+ - Native event handling and accessibility features
292
285
 
293
- - `inputDir: string` - Input directory path
294
- - `outputDir: string` - Output directory path
295
- - `framework?: 'react' | 'vue'` - Target framework (default: 'react')
296
- - `recursive?: boolean` - Recursively scan directories (default: false)
297
- - `extensions?: string[]` - File extensions to process (default: ['.svg'])
298
- - `generateIndex?: boolean` - Generate index file (default: false)
299
- - `indexFormat?: 'ts' | 'js'` - Index file format (default: 'ts')
300
- - `exportType?: 'named' | 'default'` - Export type (default: 'named')
301
- - `prefix?: string` - Add prefix to component names
302
- - `suffix?: string` - Add suffix to component names
303
- - `typescript?: boolean` - Generate TypeScript components (default: true)
304
- - `splitColors?: boolean` - Extract individual color props (default: false)
305
- - `isFixedStrokeWidth?: boolean` - Add fixed stroke width support (default: false)
306
- - All other conversion options from `convertToReact`/`convertToVue`
286
+ ```tsx
287
+ // Generated component signature
288
+ interface StarIconProps extends React.SVGProps<SVGSVGElement> {
289
+ // Custom color props if colorSplitting is enabled
290
+ color1?: string;
291
+ color2?: string;
292
+ }
293
+
294
+ const StarIcon: React.FC<StarIconProps> = props => {
295
+ // Component implementation with native SVG props support
296
+ };
297
+ ```
307
298
 
308
- **Note:** The batch converter automatically validates for duplicate component names and throws an error if conflicts are detected.
299
+ ### Vue Components
309
300
 
310
- **Returns:** `Promise<BatchConversionResult>`
301
+ Generated Vue components extend `SVGAttributes` with `v-bind="$attrs"`, providing:
311
302
 
312
- #### `getComponentNames(results: BatchConversionResult)`
303
+ - All native SVG element attributes
304
+ - Event handlers (onClick, onMouseover, etc.)
305
+ - Full TypeScript support with proper attribute typing
313
306
 
314
- Get array of generated component names from batch results.
307
+ ```vue
308
+ <script setup lang="ts">
309
+ import type { SVGAttributes } from 'vue';
310
+
311
+ interface StarIconProps extends SVGAttributes {
312
+ // Custom color props if colorSplitting is enabled
313
+ color1?: string;
314
+ color2?: string;
315
+ }
315
316
 
316
- #### `generateSummaryReport(results: BatchConversionResult)`
317
+ defineOptions({ inheritAttrs: false });
318
+ </script>
317
319
 
318
- Generate a detailed summary report of the conversion process.
320
+ <template>
321
+ <svg v-bind="$attrs" viewBox="0 0 24 24">
322
+ <!-- SVG content -->
323
+ </svg>
324
+ </template>
325
+ ```
319
326
 
320
- ### `optimizeSvg(svgContent, config?)`
327
+ ### CLI Integration
321
328
 
322
- Optimize SVG content using SVGO. **Note: This is a synchronous function.**
329
+ ```typescript
330
+ import { processInput } from 'svgfusion/cli';
323
331
 
324
- ### File Utilities
332
+ // Process single file or directory
333
+ processInput(inputPath: string, options: CliOptions): void
334
+ ```
325
335
 
326
- - `readSvgFile(filePath)` - Read SVG file (async)
327
- - `writeSvgFile(filePath, content)` - Write SVG file (async)
328
- - `readSvgDirectory(dirPath, recursive?)` - Read SVG files from directory (async)
329
- - `writeComponentFile(filePath, content)` - Write component file (async)
336
+ **CLI Options:**
337
+
338
+ - `output?: string` - Output directory (default: './components')
339
+ - `framework?: 'react' | 'vue'` - Target framework (default: 'react')
340
+ - `typescript?: boolean` - Generate TypeScript files (default: true)
341
+ - `recursive?: boolean` - Process directories recursively (default: false)
342
+ - `index?: boolean` - Generate index file (default: false)
343
+ - `prefix?: string` - Add prefix to component names
344
+ - `suffix?: string` - Add suffix to component names
345
+ - `splitColors?: boolean` - Enable color splitting feature
346
+ - `fixedStrokeWidth?: boolean` - Enable stroke fixing feature
330
347
 
331
348
  ## Examples
332
349
 
@@ -342,106 +359,99 @@ Optimize SVG content using SVGO. **Note: This is a synchronous function.**
342
359
  ### Generated React Component
343
360
 
344
361
  ```tsx
345
- import { SVGProps } from 'react';
346
- import { memo } from 'react';
347
- import { forwardRef } from 'react';
348
-
349
- const StarIcon = memo(
350
- forwardRef<SVGSVGElement, SVGProps<SVGSVGElement> & { className?: string }>(
351
- props => {
352
- return (
353
- <svg viewBox="0 0 24 24" {...props}>
354
- <path
355
- d="m12 2 3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01z"
356
- fill="currentColor"
357
- className="star-fill"
358
- />
359
- </svg>
360
- );
361
- }
362
- )
363
- );
364
-
365
- StarIcon.displayName = 'StarIcon';
366
-
367
- export default StarIcon;
362
+ import type { SVGProps } from 'react';
363
+
364
+ interface StarIconProps extends SVGProps<SVGSVGElement> {}
365
+
366
+ const StarIcon = (props: StarIconProps) => {
367
+ return (
368
+ <svg viewBox="0 0 24 24" {...props}>
369
+ <path
370
+ d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"
371
+ fill="currentColor"
372
+ className="star-fill"
373
+ />
374
+ </svg>
375
+ );
376
+ };
377
+
368
378
  export { StarIcon };
369
379
  ```
370
380
 
371
- ### Generated React Component with Split Colors
381
+ ### Generated React Component with Color Splitting
372
382
 
373
383
  ```tsx
374
- import { SVGProps } from 'react';
375
- import { memo } from 'react';
376
- import { forwardRef } from 'react';
377
-
378
- interface MultiColorIconProps extends SVGProps<SVGSVGElement> {
379
- className?: string;
380
- fillColor1?: string;
381
- fillColor1Class?: string;
382
- strokeColor1?: string;
383
- strokeColor1Class?: string;
384
- gradientColor1?: string;
385
- gradientColor1Class?: string;
386
- isFixedStrokeWidth?: boolean;
384
+ import type { SVGProps } from 'react';
385
+
386
+ interface StarIconProps extends SVGProps<SVGSVGElement> {
387
+ fillColor?: string;
387
388
  }
388
389
 
389
- const MultiColorIcon = memo(
390
- forwardRef<SVGSVGElement, MultiColorIconProps>((props, ref) => {
391
- const {
392
- fillColor1 = '#FF0000',
393
- fillColor1Class = '',
394
- strokeColor1 = '#00FF00',
395
- strokeColor1Class = '',
396
- gradientColor1 = '#FFFF00',
397
- gradientColor1Class = '',
398
- isFixedStrokeWidth = false,
399
- ...rest
400
- } = props;
401
-
402
- return (
403
- <svg
404
- ref={ref}
405
- viewBox="0 0 24 24"
406
- vectorEffect={isFixedStrokeWidth ? 'non-scaling-stroke' : undefined}
407
- {...rest}
408
- >
409
- <path
410
- fill={fillColor1}
411
- className={fillColor1Class}
412
- stroke={strokeColor1}
413
- className={strokeColor1Class}
414
- />
415
- <linearGradient>
416
- <stop stopColor={gradientColor1} className={gradientColor1Class} />
417
- </linearGradient>
418
- </svg>
419
- );
420
- })
421
- );
422
-
423
- MultiColorIcon.displayName = 'MultiColorIcon';
424
-
425
- export default MultiColorIcon;
426
- export { MultiColorIcon };
390
+ const StarIcon = ({ fillColor = 'currentColor', ...props }: StarIconProps) => {
391
+ return (
392
+ <svg viewBox="0 0 24 24" {...props}>
393
+ <path
394
+ d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"
395
+ fill={fillColor}
396
+ className="star-fill"
397
+ />
398
+ </svg>
399
+ );
400
+ };
401
+
402
+ export { StarIcon };
427
403
  ```
428
404
 
429
405
  ### Generated Vue Component
430
406
 
431
407
  ```vue
432
408
  <script setup lang="ts">
433
- interface Props {
434
- class?: string;
435
- style?: string | Record<string, any>;
409
+ import type { SVGAttributes } from 'vue';
410
+
411
+ interface StarIconProps extends SVGAttributes {}
412
+
413
+ defineOptions({ inheritAttrs: false });
414
+ </script>
415
+
416
+ <template>
417
+ <svg v-bind="$attrs" viewBox="0 0 24 24">
418
+ <path
419
+ d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"
420
+ fill="currentColor"
421
+ class="star-fill"
422
+ />
423
+ </svg>
424
+ </template>
425
+ ```
426
+
427
+ ### Generated Vue Component with Color Splitting
428
+
429
+ ```vue
430
+ <script setup lang="ts">
431
+ import type { SVGAttributes } from 'vue';
432
+
433
+ interface StarIconProps extends SVGAttributes {
434
+ fillColor?: string;
436
435
  }
437
436
 
438
- const props = withDefaults(defineProps<Props>(), {
439
- class: '',
440
- style: undefined,
437
+ const props = withDefaults(defineProps<StarIconProps>(), {
438
+ fillColor: 'currentColor',
441
439
  });
442
440
 
443
- // Component name for debugging
444
- const __name = 'StarIcon';
441
+ defineOptions({ inheritAttrs: false });
442
+ </script>
443
+
444
+ <template>
445
+ <svg v-bind="$attrs" viewBox="0 0 24 24">
446
+ <path
447
+ d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"
448
+ :fill="fillColor"
449
+ class="star-fill"
450
+ />
451
+ </svg>
452
+ </template>
453
+ ```
454
+
445
455
  </script>
446
456
 
447
457
  <template>
@@ -457,7 +467,8 @@ const __name = 'StarIcon';
457
467
  <style scoped>
458
468
  /* Add component-specific styles here */
459
469
  </style>
460
- ```
470
+
471
+ ````
461
472
 
462
473
  ## Advanced Configuration
463
474
 
@@ -490,7 +501,7 @@ const result = await convertToReact(svgContent, {
490
501
  // - strokeColor1 (for stroke colors)
491
502
  // - gradientColor1, gradientColor2 (for gradient colors)
492
503
  // - fillColor1Class, strokeColor1Class, etc. (for CSS classes)
493
- ```
504
+ ````
494
505
 
495
506
  ### Fixed Stroke Width Support
496
507
 
package/dist/cli.d.ts CHANGED
@@ -1,2 +1 @@
1
-
2
- export { }
1
+ #!/usr/bin/env node