svgfusion 1.6.0 → 1.7.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 +166 -0
- package/dist/cli.js +368 -56
- package/dist/index.d.mts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +51 -36
- package/dist/index.mjs +51 -36
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -30,6 +30,14 @@ A powerful Node.js CLI tool and library that converts SVG files into optimized R
|
|
|
30
30
|
- **Zero Configuration**: Works out of the box with sensible defaults
|
|
31
31
|
- **Simple CLI**: Direct, intuitive command structure without subcommands
|
|
32
32
|
|
|
33
|
+
### 🚀 Advanced Features
|
|
34
|
+
|
|
35
|
+
- **Split Colors Mode**: Extract individual color props for maximum Tailwind CSS compatibility
|
|
36
|
+
- **Fixed Stroke Width**: Add `vector-effect="non-scaling-stroke"` support for consistent strokes
|
|
37
|
+
- **Duplicate Detection**: Automatic validation prevents component name conflicts
|
|
38
|
+
- **Gradient Support**: Full support for linearGradient and radialGradient color extraction
|
|
39
|
+
- **Smart Naming**: Intelligent component naming with conflict resolution suggestions
|
|
40
|
+
|
|
33
41
|
## Quick Start
|
|
34
42
|
|
|
35
43
|
### Simple as One Command
|
|
@@ -40,6 +48,9 @@ npx svgfusion ./icons --output ./components
|
|
|
40
48
|
|
|
41
49
|
# Add prefixes, suffixes, and generate index file
|
|
42
50
|
npx svgfusion ./icons --prefix Icon --suffix Component --index
|
|
51
|
+
|
|
52
|
+
# Advanced: Split colors for Tailwind CSS with fixed stroke width
|
|
53
|
+
npx svgfusion ./icons --split-colors --fixed-stroke-width --prefix Icon
|
|
43
54
|
```
|
|
44
55
|
|
|
45
56
|
### Installation
|
|
@@ -129,6 +140,8 @@ Options:
|
|
|
129
140
|
--no-optimize Skip SVG optimization
|
|
130
141
|
--prefix <prefix> Add prefix to component name (sanitized)
|
|
131
142
|
--suffix <suffix> Add suffix to component name (sanitized)
|
|
143
|
+
--split-colors Extract individual color props for each SVG color
|
|
144
|
+
--fixed-stroke-width Add support for non-scaling stroke width
|
|
132
145
|
-h, --help Show help
|
|
133
146
|
```
|
|
134
147
|
|
|
@@ -151,6 +164,12 @@ npx svgfusion ./assets/icons --output ./src/components --recursive --index
|
|
|
151
164
|
|
|
152
165
|
# Convert with custom naming
|
|
153
166
|
npx svgfusion ./assets/icons --output ./src/components --prefix Icon --suffix Component --index
|
|
167
|
+
|
|
168
|
+
# Advanced: Split colors for Tailwind CSS compatibility
|
|
169
|
+
npx svgfusion ./assets/icons --output ./src/components --split-colors --prefix Icon
|
|
170
|
+
|
|
171
|
+
# Advanced: Fixed stroke width with split colors
|
|
172
|
+
npx svgfusion ./assets/icons --output ./src/components --split-colors --fixed-stroke-width
|
|
154
173
|
```
|
|
155
174
|
|
|
156
175
|
### Programmatic Usage
|
|
@@ -178,6 +197,14 @@ const vueResult = convertToVue(svgContent, {
|
|
|
178
197
|
scriptSetup: true,
|
|
179
198
|
});
|
|
180
199
|
|
|
200
|
+
// Advanced: Split colors for Tailwind CSS
|
|
201
|
+
const reactWithColors = await convertToReact(svgContent, {
|
|
202
|
+
name: 'StarIcon',
|
|
203
|
+
splitColors: true,
|
|
204
|
+
isFixedStrokeWidth: true,
|
|
205
|
+
typescript: true,
|
|
206
|
+
});
|
|
207
|
+
|
|
181
208
|
console.log(reactResult.code); // Generated React component
|
|
182
209
|
console.log(vueResult.code); // Generated Vue component
|
|
183
210
|
```
|
|
@@ -201,6 +228,8 @@ const result = await batchConverter.convertBatch({
|
|
|
201
228
|
suffix: 'Component',
|
|
202
229
|
indexFormat: 'ts',
|
|
203
230
|
exportType: 'named',
|
|
231
|
+
splitColors: true,
|
|
232
|
+
isFixedStrokeWidth: true,
|
|
204
233
|
});
|
|
205
234
|
|
|
206
235
|
// Check results
|
|
@@ -232,6 +261,8 @@ Convert SVG to React component.
|
|
|
232
261
|
- `memo?: boolean` - Wrap with React.memo (default: `true`)
|
|
233
262
|
- `ref?: boolean` - Add forwardRef support (default: `true`)
|
|
234
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`)
|
|
235
266
|
|
|
236
267
|
### `convertToVue(svgContent, options)`
|
|
237
268
|
|
|
@@ -246,6 +277,8 @@ Convert SVG to Vue 3 component. **Note: This is a synchronous function.**
|
|
|
246
277
|
- `scriptSetup?: boolean` - Use script setup syntax (default: `true`)
|
|
247
278
|
- `compositionApi?: boolean` - Use Composition API (default: `true`)
|
|
248
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`)
|
|
249
282
|
|
|
250
283
|
### `BatchConverter`
|
|
251
284
|
|
|
@@ -268,8 +301,12 @@ Convert multiple SVG files to framework components.
|
|
|
268
301
|
- `prefix?: string` - Add prefix to component names
|
|
269
302
|
- `suffix?: string` - Add suffix to component names
|
|
270
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)
|
|
271
306
|
- All other conversion options from `convertToReact`/`convertToVue`
|
|
272
307
|
|
|
308
|
+
**Note:** The batch converter automatically validates for duplicate component names and throws an error if conflicts are detected.
|
|
309
|
+
|
|
273
310
|
**Returns:** `Promise<BatchConversionResult>`
|
|
274
311
|
|
|
275
312
|
#### `getComponentNames(results: BatchConversionResult)`
|
|
@@ -331,6 +368,64 @@ export default StarIcon;
|
|
|
331
368
|
export { StarIcon };
|
|
332
369
|
```
|
|
333
370
|
|
|
371
|
+
### Generated React Component with Split Colors
|
|
372
|
+
|
|
373
|
+
```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;
|
|
387
|
+
}
|
|
388
|
+
|
|
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 };
|
|
427
|
+
```
|
|
428
|
+
|
|
334
429
|
### Generated Vue Component
|
|
335
430
|
|
|
336
431
|
```vue
|
|
@@ -366,6 +461,77 @@ const __name = 'StarIcon';
|
|
|
366
461
|
|
|
367
462
|
## Advanced Configuration
|
|
368
463
|
|
|
464
|
+
### Split Colors for Tailwind CSS
|
|
465
|
+
|
|
466
|
+
The `splitColors` option extracts individual color properties from SVG elements, making them perfect for Tailwind CSS integration:
|
|
467
|
+
|
|
468
|
+
```typescript
|
|
469
|
+
// Input SVG with colors
|
|
470
|
+
const svgContent = `
|
|
471
|
+
<svg viewBox="0 0 24 24">
|
|
472
|
+
<path fill="#FF0000" stroke="#00FF00" />
|
|
473
|
+
<circle fill="#0000FF" />
|
|
474
|
+
<linearGradient>
|
|
475
|
+
<stop stop-color="#FFFF00" />
|
|
476
|
+
<stop stop-color="#FF00FF" />
|
|
477
|
+
</linearGradient>
|
|
478
|
+
</svg>
|
|
479
|
+
`;
|
|
480
|
+
|
|
481
|
+
// Convert with split colors
|
|
482
|
+
const result = await convertToReact(svgContent, {
|
|
483
|
+
name: 'MultiColorIcon',
|
|
484
|
+
splitColors: true,
|
|
485
|
+
typescript: true,
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
// Generated component props:
|
|
489
|
+
// - fillColor1, fillColor2 (for fill colors)
|
|
490
|
+
// - strokeColor1 (for stroke colors)
|
|
491
|
+
// - gradientColor1, gradientColor2 (for gradient colors)
|
|
492
|
+
// - fillColor1Class, strokeColor1Class, etc. (for CSS classes)
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
### Fixed Stroke Width Support
|
|
496
|
+
|
|
497
|
+
The `isFixedStrokeWidth` option adds support for non-scaling stroke width:
|
|
498
|
+
|
|
499
|
+
```typescript
|
|
500
|
+
const result = await convertToReact(svgContent, {
|
|
501
|
+
name: 'StrokeIcon',
|
|
502
|
+
isFixedStrokeWidth: true,
|
|
503
|
+
});
|
|
504
|
+
|
|
505
|
+
// Generated component includes:
|
|
506
|
+
// - isFixedStrokeWidth prop
|
|
507
|
+
// - vector-effect="non-scaling-stroke" when prop is true
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
### Duplicate Name Detection
|
|
511
|
+
|
|
512
|
+
The batch converter automatically detects and prevents duplicate component names:
|
|
513
|
+
|
|
514
|
+
```typescript
|
|
515
|
+
// These files would generate the same component name "Icon"
|
|
516
|
+
const files = ['./icons/icon.svg', './assets/icon.svg', './ui/icon.svg'];
|
|
517
|
+
|
|
518
|
+
// Batch processing will throw an error with conflict details
|
|
519
|
+
try {
|
|
520
|
+
await batchConverter.convertBatch({
|
|
521
|
+
inputDir: './icons',
|
|
522
|
+
outputDir: './components',
|
|
523
|
+
// ... other options
|
|
524
|
+
});
|
|
525
|
+
} catch (error) {
|
|
526
|
+
console.error(error.message);
|
|
527
|
+
// Error: Duplicate component names detected:
|
|
528
|
+
// Component name "Icon" conflicts:
|
|
529
|
+
// - ./icons/icon.svg
|
|
530
|
+
// - ./assets/icon.svg
|
|
531
|
+
// - ./ui/icon.svg
|
|
532
|
+
}
|
|
533
|
+
```
|
|
534
|
+
|
|
369
535
|
### Custom SVGO Configuration
|
|
370
536
|
|
|
371
537
|
```typescript
|