svger-cli 2.0.2 β 2.0.3
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/.svgerconfig.example.json +38 -0
- package/CHANGELOG.md +64 -0
- package/DEVELOPMENT.md +353 -0
- package/README.md +24 -5
- package/SECURITY.md +69 -0
- package/dist/builder.js +16 -16
- package/dist/clean.js +2 -2
- package/dist/cli.js +38 -38
- package/dist/config.js +11 -11
- package/dist/core/error-handler.js +12 -9
- package/dist/core/framework-templates.js +5 -3
- package/dist/core/performance-engine.js +9 -8
- package/dist/core/plugin-manager.js +7 -5
- package/dist/core/style-compiler.js +17 -15
- package/dist/core/template-manager.js +14 -14
- package/dist/index.d.ts +8 -6
- package/dist/index.js +5 -5
- package/dist/lock.js +7 -7
- package/dist/processors/svg-processor.d.ts +9 -3
- package/dist/processors/svg-processor.js +53 -17
- package/dist/services/config.js +11 -9
- package/dist/services/file-watcher.js +3 -3
- package/dist/services/svg-service.js +24 -12
- package/dist/templates/ComponentTemplate.js +25 -25
- package/dist/types/index.d.ts +7 -1
- package/dist/utils/native.d.ts +31 -1
- package/dist/utils/native.js +43 -8
- package/dist/watch.d.ts +1 -1
- package/dist/watch.js +14 -14
- package/docs/ADR-SVG-INTRGRATION-METHODS-001.adr.md +157 -0
- package/docs/ADR-SVG-INTRGRATION-METHODS-002.adr.md +550 -0
- package/docs/FRAMEWORK-GUIDE.md +768 -0
- package/docs/IMPLEMENTATION-SUMMARY.md +376 -0
- package/docs/TDR-SVG-INTRGRATION-METHODS-001.tdr.md +115 -0
- package/package.json +155 -14
|
@@ -0,0 +1,768 @@
|
|
|
1
|
+
# SVGER-CLI - Multi-Framework SVG to Component Converter π
|
|
2
|
+
|
|
3
|
+
> Zero-dependency, enterprise-grade SVG processing toolkit supporting **8 modern UI frameworks**
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/svger-cli)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](https://www.typescriptlang.org/)
|
|
8
|
+
[](https://nodejs.org/)
|
|
9
|
+
|
|
10
|
+
## β¨ Features
|
|
11
|
+
|
|
12
|
+
- **π― Multi-Framework Support**: React, Vue, Svelte, Angular, Solid, Preact, Lit, Vanilla JS
|
|
13
|
+
- **π¦ Zero Dependencies**: Native Node.js implementation, no external runtime dependencies
|
|
14
|
+
- **β‘ High Performance**: Batch processing with parallel execution and intelligent caching
|
|
15
|
+
- **π Type-Safe**: Full TypeScript support with comprehensive type definitions
|
|
16
|
+
- **π¨ Framework-Idiomatic**: Generates components following best practices for each framework
|
|
17
|
+
- **π Watch Mode**: Auto-rebuild components on SVG file changes
|
|
18
|
+
- **π File Locking**: Prevent accidental overwrites with lock/unlock system
|
|
19
|
+
- **βοΈ Configurable**: Flexible configuration via `.svgconfig.json` or CLI options
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## π¦ Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install -g svger-cli
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Or use with npx (no installation):
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npx svger-cli build my-svgs/ components/
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## π Quick Start
|
|
38
|
+
|
|
39
|
+
### Basic Usage
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Build React components (default)
|
|
43
|
+
svger-cli build ./svgs ./components
|
|
44
|
+
|
|
45
|
+
# Build Vue 3 components with Composition API
|
|
46
|
+
svger-cli build ./svgs ./components --framework vue --composition
|
|
47
|
+
|
|
48
|
+
# Build Angular standalone components
|
|
49
|
+
svger-cli build ./svgs ./components --framework angular --standalone
|
|
50
|
+
|
|
51
|
+
# Build Svelte components
|
|
52
|
+
svger-cli build ./svgs ./components --framework svelte
|
|
53
|
+
|
|
54
|
+
# Watch mode for development
|
|
55
|
+
svger-cli watch ./svgs ./components --framework vue
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Generate Single Component
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# Generate single React component
|
|
62
|
+
svger-cli generate ./icon.svg ./components --framework react
|
|
63
|
+
|
|
64
|
+
# Generate Angular component
|
|
65
|
+
svger-cli generate ./icon.svg ./components --framework angular --standalone
|
|
66
|
+
|
|
67
|
+
# Generate Lit web component
|
|
68
|
+
svger-cli generate ./icon.svg ./components --framework lit
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## π― Supported Frameworks
|
|
74
|
+
|
|
75
|
+
| Framework | Version | TypeScript | Options |
|
|
76
|
+
|-----------|---------|------------|---------|
|
|
77
|
+
| **React** | 18+ | β
| `forwardRef`, `memo` |
|
|
78
|
+
| **Vue** | 3+ | β
| `scriptSetup`, `composition` |
|
|
79
|
+
| **Svelte** | 4+ | β
| Native TypeScript |
|
|
80
|
+
| **Angular** | 16+ | β
| `standalone`, `signals` |
|
|
81
|
+
| **Solid** | 1.7+ | β
| Reactive primitives |
|
|
82
|
+
| **Preact** | 10+ | β
| Lightweight React alternative |
|
|
83
|
+
| **Lit** | 3+ | β
| Web Components |
|
|
84
|
+
| **Vanilla** | ES6+ | β
| Pure JavaScript |
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## π Framework-Specific Examples
|
|
89
|
+
|
|
90
|
+
### React
|
|
91
|
+
|
|
92
|
+
Generate modern React components with TypeScript, forwardRef, and proper prop types:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
svger-cli build ./svgs ./components --framework react
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Generated Output** (`components/Icon.tsx`):
|
|
99
|
+
|
|
100
|
+
```tsx
|
|
101
|
+
import React from "react";
|
|
102
|
+
import type { SVGProps } from "react";
|
|
103
|
+
|
|
104
|
+
export interface IconProps extends SVGProps<SVGSVGElement> {
|
|
105
|
+
size?: number | string;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const Icon = React.forwardRef<SVGSVGElement, IconProps>(
|
|
109
|
+
({ size, className, style, ...props }, ref) => {
|
|
110
|
+
const dimensions = size ? { width: size, height: size } : {
|
|
111
|
+
width: props.width || 24,
|
|
112
|
+
height: props.height || 24
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
return (
|
|
116
|
+
<svg
|
|
117
|
+
ref={ref}
|
|
118
|
+
viewBox="0 0 24 24"
|
|
119
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
120
|
+
width={dimensions.width}
|
|
121
|
+
height={dimensions.height}
|
|
122
|
+
fill={props.fill || "currentColor"}
|
|
123
|
+
className={className}
|
|
124
|
+
style={style}
|
|
125
|
+
{...props}
|
|
126
|
+
>
|
|
127
|
+
{/* SVG content */}
|
|
128
|
+
</svg>
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
Icon.displayName = "Icon";
|
|
134
|
+
export default Icon;
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Usage**:
|
|
138
|
+
|
|
139
|
+
```tsx
|
|
140
|
+
import Icon from "./components/Icon";
|
|
141
|
+
|
|
142
|
+
<Icon size={32} className="text-blue-500" />
|
|
143
|
+
<Icon width={48} height={48} fill="#ff0000" />
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
### Vue 3
|
|
149
|
+
|
|
150
|
+
Generate Vue 3 components with Composition API and TypeScript:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
# Composition API with <script setup>
|
|
154
|
+
svger-cli build ./svgs ./components --framework vue --composition
|
|
155
|
+
|
|
156
|
+
# Options API (legacy)
|
|
157
|
+
svger-cli build ./svgs ./components --framework vue --no-composition
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
**Generated Output** (`components/Icon.vue`):
|
|
161
|
+
|
|
162
|
+
```vue
|
|
163
|
+
<template>
|
|
164
|
+
<svg
|
|
165
|
+
:class="className"
|
|
166
|
+
:style="style"
|
|
167
|
+
:width="width || 24"
|
|
168
|
+
:height="height || 24"
|
|
169
|
+
:fill="fill || 'currentColor'"
|
|
170
|
+
:stroke="stroke"
|
|
171
|
+
viewBox="0 0 24 24"
|
|
172
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
173
|
+
v-bind="$attrs"
|
|
174
|
+
>
|
|
175
|
+
<!-- SVG content -->
|
|
176
|
+
</svg>
|
|
177
|
+
</template>
|
|
178
|
+
|
|
179
|
+
<script setup lang="ts">
|
|
180
|
+
interface Props {
|
|
181
|
+
className?: string;
|
|
182
|
+
style?: string | Record<string, any>;
|
|
183
|
+
width?: string | number;
|
|
184
|
+
height?: string | number;
|
|
185
|
+
fill?: string;
|
|
186
|
+
stroke?: string;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
withDefaults(defineProps<Props>(), {
|
|
190
|
+
className: '',
|
|
191
|
+
fill: 'currentColor',
|
|
192
|
+
width: 24,
|
|
193
|
+
height: 24
|
|
194
|
+
});
|
|
195
|
+
</script>
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**Usage**:
|
|
199
|
+
|
|
200
|
+
```vue
|
|
201
|
+
<script setup>
|
|
202
|
+
import Icon from "./components/Icon.vue";
|
|
203
|
+
</script>
|
|
204
|
+
|
|
205
|
+
<template>
|
|
206
|
+
<Icon :width="32" fill="#ff0000" class="icon" />
|
|
207
|
+
</template>
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
### Svelte
|
|
213
|
+
|
|
214
|
+
Generate Svelte components with TypeScript support:
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
svger-cli build ./svgs ./components --framework svelte
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
**Generated Output** (`components/Icon.svelte`):
|
|
221
|
+
|
|
222
|
+
```svelte
|
|
223
|
+
<script lang="ts">
|
|
224
|
+
export let className: string = '';
|
|
225
|
+
export let style: string = '';
|
|
226
|
+
export let width: string | number = 24;
|
|
227
|
+
export let height: string | number = 24;
|
|
228
|
+
export let fill: string = 'currentColor';
|
|
229
|
+
export let stroke: string = '';
|
|
230
|
+
</script>
|
|
231
|
+
|
|
232
|
+
<svg
|
|
233
|
+
class={className}
|
|
234
|
+
{style}
|
|
235
|
+
{width}
|
|
236
|
+
{height}
|
|
237
|
+
{fill}
|
|
238
|
+
{stroke}
|
|
239
|
+
viewBox="0 0 24 24"
|
|
240
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
241
|
+
{...$$restProps}
|
|
242
|
+
>
|
|
243
|
+
<!-- SVG content -->
|
|
244
|
+
</svg>
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
**Usage**:
|
|
248
|
+
|
|
249
|
+
```svelte
|
|
250
|
+
<script>
|
|
251
|
+
import Icon from "./components/Icon.svelte";
|
|
252
|
+
</script>
|
|
253
|
+
|
|
254
|
+
<Icon width={32} fill="#ff0000" class="icon" />
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
### Angular
|
|
260
|
+
|
|
261
|
+
Generate Angular standalone components with modern best practices:
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
# Standalone components (Angular 16+)
|
|
265
|
+
svger-cli build ./svgs ./components --framework angular --standalone
|
|
266
|
+
|
|
267
|
+
# Module-based components (legacy)
|
|
268
|
+
svger-cli build ./svgs ./components --framework angular --no-standalone
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
**Generated Output** (`components/Icon.component.ts`):
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
import { Component, Input, ChangeDetectionStrategy } from '@angular/core';
|
|
275
|
+
|
|
276
|
+
@Component({
|
|
277
|
+
selector: 'app-icon',
|
|
278
|
+
standalone: true,
|
|
279
|
+
template: `
|
|
280
|
+
<svg
|
|
281
|
+
[attr.class]="className"
|
|
282
|
+
[attr.width]="width"
|
|
283
|
+
[attr.height]="height"
|
|
284
|
+
[attr.fill]="fill"
|
|
285
|
+
[attr.stroke]="stroke"
|
|
286
|
+
viewBox="0 0 24 24"
|
|
287
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
288
|
+
>
|
|
289
|
+
<!-- SVG content -->
|
|
290
|
+
</svg>
|
|
291
|
+
`,
|
|
292
|
+
changeDetection: ChangeDetectionStrategy.OnPush
|
|
293
|
+
})
|
|
294
|
+
export class IconComponent {
|
|
295
|
+
@Input() className: string = '';
|
|
296
|
+
@Input() width: string | number = 24;
|
|
297
|
+
@Input() height: string | number = 24;
|
|
298
|
+
@Input() fill: string = 'currentColor';
|
|
299
|
+
@Input() stroke: string = '';
|
|
300
|
+
}
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
**Usage**:
|
|
304
|
+
|
|
305
|
+
```typescript
|
|
306
|
+
import { IconComponent } from "./components/Icon.component";
|
|
307
|
+
|
|
308
|
+
@Component({
|
|
309
|
+
selector: 'app-root',
|
|
310
|
+
standalone: true,
|
|
311
|
+
imports: [IconComponent],
|
|
312
|
+
template: `<app-icon [width]="32" fill="#ff0000"></app-icon>`
|
|
313
|
+
})
|
|
314
|
+
export class AppComponent {}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
### Solid
|
|
320
|
+
|
|
321
|
+
Generate SolidJS components with reactive primitives:
|
|
322
|
+
|
|
323
|
+
```bash
|
|
324
|
+
svger-cli build ./svgs ./components --framework solid
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
**Generated Output** (`components/Icon.tsx`):
|
|
328
|
+
|
|
329
|
+
```tsx
|
|
330
|
+
import { Component, JSX } from 'solid-js';
|
|
331
|
+
|
|
332
|
+
export interface IconProps extends JSX.SvgSVGAttributes<SVGSVGElement> {
|
|
333
|
+
className?: string;
|
|
334
|
+
width?: string | number;
|
|
335
|
+
height?: string | number;
|
|
336
|
+
fill?: string;
|
|
337
|
+
stroke?: string;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
const Icon: Component<IconProps> = (props) => (
|
|
341
|
+
<svg
|
|
342
|
+
class={props.className}
|
|
343
|
+
style={props.style}
|
|
344
|
+
width={props.width || 24}
|
|
345
|
+
height={props.height || 24}
|
|
346
|
+
fill={props.fill || 'currentColor'}
|
|
347
|
+
stroke={props.stroke}
|
|
348
|
+
viewBox="0 0 24 24"
|
|
349
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
350
|
+
{...props}
|
|
351
|
+
>
|
|
352
|
+
{/* SVG content */}
|
|
353
|
+
</svg>
|
|
354
|
+
);
|
|
355
|
+
|
|
356
|
+
export default Icon;
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
**Usage**:
|
|
360
|
+
|
|
361
|
+
```tsx
|
|
362
|
+
import Icon from "./components/Icon";
|
|
363
|
+
|
|
364
|
+
<Icon width={32} fill="#ff0000" class="icon" />
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
### Preact
|
|
370
|
+
|
|
371
|
+
Generate Preact components (lightweight React alternative):
|
|
372
|
+
|
|
373
|
+
```bash
|
|
374
|
+
svger-cli build ./svgs ./components --framework preact
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
**Generated Output** (`components/Icon.tsx`):
|
|
378
|
+
|
|
379
|
+
```tsx
|
|
380
|
+
import { h, FunctionComponent } from 'preact';
|
|
381
|
+
import { JSX } from 'preact/jsx-runtime';
|
|
382
|
+
|
|
383
|
+
export interface IconProps extends JSX.SVGAttributes<SVGSVGElement> {
|
|
384
|
+
className?: string;
|
|
385
|
+
width?: string | number;
|
|
386
|
+
height?: string | number;
|
|
387
|
+
fill?: string;
|
|
388
|
+
stroke?: string;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
const Icon: FunctionComponent<IconProps> = ({
|
|
392
|
+
className,
|
|
393
|
+
style,
|
|
394
|
+
width,
|
|
395
|
+
height,
|
|
396
|
+
fill,
|
|
397
|
+
stroke,
|
|
398
|
+
...props
|
|
399
|
+
}) => {
|
|
400
|
+
return (
|
|
401
|
+
<svg
|
|
402
|
+
class={className}
|
|
403
|
+
style={style}
|
|
404
|
+
width={width || 24}
|
|
405
|
+
height={height || 24}
|
|
406
|
+
fill={fill || 'currentColor'}
|
|
407
|
+
stroke={stroke}
|
|
408
|
+
viewBox="0 0 24 24"
|
|
409
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
410
|
+
{...props}
|
|
411
|
+
>
|
|
412
|
+
{/* SVG content */}
|
|
413
|
+
</svg>
|
|
414
|
+
);
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
export default Icon;
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
---
|
|
421
|
+
|
|
422
|
+
### Lit (Web Components)
|
|
423
|
+
|
|
424
|
+
Generate standards-based Web Components with Lit:
|
|
425
|
+
|
|
426
|
+
```bash
|
|
427
|
+
svger-cli build ./svgs ./components --framework lit
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
**Generated Output** (`components/Icon.ts`):
|
|
431
|
+
|
|
432
|
+
```typescript
|
|
433
|
+
import { LitElement, html, css, svg } from 'lit';
|
|
434
|
+
import { customElement, property } from 'lit/decorators.js';
|
|
435
|
+
|
|
436
|
+
@customElement('app-icon')
|
|
437
|
+
export class Icon extends LitElement {
|
|
438
|
+
@property({ type: String }) className = '';
|
|
439
|
+
@property({ type: String, reflect: true }) width = '24';
|
|
440
|
+
@property({ type: String, reflect: true }) height = '24';
|
|
441
|
+
@property({ type: String, reflect: true }) fill = 'currentColor';
|
|
442
|
+
@property({ type: String, reflect: true }) stroke = '';
|
|
443
|
+
|
|
444
|
+
static styles = css`:host { display: inline-block; }`;
|
|
445
|
+
|
|
446
|
+
render() {
|
|
447
|
+
return svg`
|
|
448
|
+
<svg
|
|
449
|
+
class="${this.className}"
|
|
450
|
+
width="${this.width}"
|
|
451
|
+
height="${this.height}"
|
|
452
|
+
fill="${this.fill}"
|
|
453
|
+
stroke="${this.stroke}"
|
|
454
|
+
viewBox="0 0 24 24"
|
|
455
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
456
|
+
>
|
|
457
|
+
<!-- SVG content -->
|
|
458
|
+
</svg>
|
|
459
|
+
`;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
**Usage**:
|
|
465
|
+
|
|
466
|
+
```html
|
|
467
|
+
<app-icon width="32" fill="#ff0000"></app-icon>
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
---
|
|
471
|
+
|
|
472
|
+
### Vanilla JavaScript
|
|
473
|
+
|
|
474
|
+
Generate framework-free functions for maximum compatibility:
|
|
475
|
+
|
|
476
|
+
```bash
|
|
477
|
+
svger-cli build ./svgs ./components --framework vanilla
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
**Generated Output** (`components/Icon.ts`):
|
|
481
|
+
|
|
482
|
+
```typescript
|
|
483
|
+
export interface IconOptions {
|
|
484
|
+
className?: string;
|
|
485
|
+
width?: string | number;
|
|
486
|
+
height?: string | number;
|
|
487
|
+
fill?: string;
|
|
488
|
+
stroke?: string;
|
|
489
|
+
[key: string]: any;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
export function Icon(options: IconOptions = {}): SVGSVGElement {
|
|
493
|
+
const {
|
|
494
|
+
className = '',
|
|
495
|
+
width = 24,
|
|
496
|
+
height = 24,
|
|
497
|
+
fill = 'currentColor',
|
|
498
|
+
stroke = '',
|
|
499
|
+
...attrs
|
|
500
|
+
} = options;
|
|
501
|
+
|
|
502
|
+
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
503
|
+
svg.setAttribute('viewBox', '0 0 24 24');
|
|
504
|
+
svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
|
|
505
|
+
|
|
506
|
+
if (className) svg.setAttribute('class', className);
|
|
507
|
+
svg.setAttribute('width', String(width));
|
|
508
|
+
svg.setAttribute('height', String(height));
|
|
509
|
+
svg.setAttribute('fill', fill);
|
|
510
|
+
if (stroke) svg.setAttribute('stroke', stroke);
|
|
511
|
+
|
|
512
|
+
Object.entries(attrs).forEach(([key, value]) => {
|
|
513
|
+
svg.setAttribute(key, String(value));
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
svg.innerHTML = `<!-- SVG content -->`;
|
|
517
|
+
|
|
518
|
+
return svg;
|
|
519
|
+
}
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
**Usage**:
|
|
523
|
+
|
|
524
|
+
```typescript
|
|
525
|
+
import { Icon } from "./components/Icon";
|
|
526
|
+
|
|
527
|
+
const iconElement = Icon({ width: 32, fill: '#ff0000' });
|
|
528
|
+
document.body.appendChild(iconElement);
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
---
|
|
532
|
+
|
|
533
|
+
## βοΈ Configuration
|
|
534
|
+
|
|
535
|
+
### Config File (`.svgconfig.json`)
|
|
536
|
+
|
|
537
|
+
Create a configuration file in your project root:
|
|
538
|
+
|
|
539
|
+
```bash
|
|
540
|
+
svger-cli config --init
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
Example configuration:
|
|
544
|
+
|
|
545
|
+
```json
|
|
546
|
+
{
|
|
547
|
+
"src": "./my-svgs",
|
|
548
|
+
"out": "./components",
|
|
549
|
+
"framework": "react",
|
|
550
|
+
"typescript": true,
|
|
551
|
+
"frameworkOptions": {
|
|
552
|
+
"composition": true,
|
|
553
|
+
"standalone": true,
|
|
554
|
+
"memo": false,
|
|
555
|
+
"forwardRef": true
|
|
556
|
+
},
|
|
557
|
+
"indexFileStrategy": "combined",
|
|
558
|
+
"cleanBefore": false,
|
|
559
|
+
"watch": false
|
|
560
|
+
}
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
### Configuration Options
|
|
564
|
+
|
|
565
|
+
| Option | Type | Default | Description |
|
|
566
|
+
|--------|------|---------|-------------|
|
|
567
|
+
| `framework` | string | `"react"` | Target framework |
|
|
568
|
+
| `typescript` | boolean | `true` | Generate TypeScript |
|
|
569
|
+
| `frameworkOptions` | object | `{}` | Framework-specific options |
|
|
570
|
+
| `indexFileStrategy` | string | `"combined"` | Index generation strategy |
|
|
571
|
+
| `cleanBefore` | boolean | `false` | Clean output before build |
|
|
572
|
+
| `watch` | boolean | `false` | Enable watch mode |
|
|
573
|
+
|
|
574
|
+
### Framework Options
|
|
575
|
+
|
|
576
|
+
#### React
|
|
577
|
+
- `forwardRef`: Enable React.forwardRef (default: `true`)
|
|
578
|
+
- `memo`: Wrap component with React.memo (default: `false`)
|
|
579
|
+
|
|
580
|
+
#### Vue
|
|
581
|
+
- `scriptSetup`: Use Composition API with `<script setup>` (default: `true`)
|
|
582
|
+
- `composition`: Enable Composition API (Options API if false)
|
|
583
|
+
|
|
584
|
+
#### Angular
|
|
585
|
+
- `standalone`: Generate standalone components (default: `true`)
|
|
586
|
+
- `signals`: Use Angular signals for reactive state (default: `false`)
|
|
587
|
+
|
|
588
|
+
#### Solid
|
|
589
|
+
- `signals`: Use Solid's fine-grained reactivity (default: `true`)
|
|
590
|
+
|
|
591
|
+
---
|
|
592
|
+
|
|
593
|
+
## π CLI Reference
|
|
594
|
+
|
|
595
|
+
### Commands
|
|
596
|
+
|
|
597
|
+
```bash
|
|
598
|
+
# Build all SVGs from source to output
|
|
599
|
+
svger-cli build <src> <out> [options]
|
|
600
|
+
|
|
601
|
+
# Watch for changes and rebuild automatically
|
|
602
|
+
svger-cli watch <src> <out> [options]
|
|
603
|
+
|
|
604
|
+
# Generate single component from SVG file
|
|
605
|
+
svger-cli generate <svgFile> <out> [options]
|
|
606
|
+
|
|
607
|
+
# Lock files to prevent overwrites
|
|
608
|
+
svger-cli lock <files...>
|
|
609
|
+
|
|
610
|
+
# Unlock files
|
|
611
|
+
svger-cli unlock <files...>
|
|
612
|
+
|
|
613
|
+
# Manage configuration
|
|
614
|
+
svger-cli config [--init|--set key=value|--show]
|
|
615
|
+
|
|
616
|
+
# Clean output directory
|
|
617
|
+
svger-cli clean <out>
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
### Global Options
|
|
621
|
+
|
|
622
|
+
```bash
|
|
623
|
+
--framework <type> # react|vue|svelte|angular|solid|preact|lit|vanilla
|
|
624
|
+
--typescript # Generate TypeScript (default)
|
|
625
|
+
--no-typescript # Generate JavaScript
|
|
626
|
+
--composition # Vue Composition API
|
|
627
|
+
--standalone # Angular standalone components
|
|
628
|
+
--signals # Angular/Solid signals
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
### Examples
|
|
632
|
+
|
|
633
|
+
```bash
|
|
634
|
+
# Build React components with TypeScript
|
|
635
|
+
svger-cli build ./svgs ./components
|
|
636
|
+
|
|
637
|
+
# Build Vue components with Composition API
|
|
638
|
+
svger-cli build ./svgs ./components --framework vue --composition
|
|
639
|
+
|
|
640
|
+
# Build Angular standalone components
|
|
641
|
+
svger-cli build ./svgs ./components --framework angular --standalone
|
|
642
|
+
|
|
643
|
+
# Build JavaScript Svelte components
|
|
644
|
+
svger-cli build ./svgs ./components --framework svelte --no-typescript
|
|
645
|
+
|
|
646
|
+
# Generate single Lit web component
|
|
647
|
+
svger-cli generate ./icon.svg ./components --framework lit
|
|
648
|
+
|
|
649
|
+
# Watch mode for Vue development
|
|
650
|
+
svger-cli watch ./svgs ./components --framework vue --composition
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
---
|
|
654
|
+
|
|
655
|
+
## π§ͺ Testing
|
|
656
|
+
|
|
657
|
+
The project includes comprehensive testing for all 8 frameworks:
|
|
658
|
+
|
|
659
|
+
```bash
|
|
660
|
+
# Run framework tests
|
|
661
|
+
node test-frameworks.js
|
|
662
|
+
|
|
663
|
+
# Build project
|
|
664
|
+
npm run build
|
|
665
|
+
|
|
666
|
+
# Watch mode during development
|
|
667
|
+
npm run dev
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
Test output validates:
|
|
671
|
+
- β
Component generation for all frameworks
|
|
672
|
+
- β
TypeScript type correctness
|
|
673
|
+
- β
Framework-specific patterns
|
|
674
|
+
- β
Proper file extensions
|
|
675
|
+
- β
Code syntax validity
|
|
676
|
+
|
|
677
|
+
---
|
|
678
|
+
|
|
679
|
+
## ποΈ Architecture
|
|
680
|
+
|
|
681
|
+
SVGER-CLI follows a modular, zero-dependency architecture:
|
|
682
|
+
|
|
683
|
+
```
|
|
684
|
+
svger-cli/
|
|
685
|
+
βββ src/
|
|
686
|
+
β βββ core/ # Core processing engines
|
|
687
|
+
β β βββ framework-templates.ts # Multi-framework generator
|
|
688
|
+
β β βββ logger.ts # Professional logging
|
|
689
|
+
β β βββ error-handler.ts # Error management
|
|
690
|
+
β β βββ performance-engine.ts # Optimization
|
|
691
|
+
β βββ processors/ # SVG processing logic
|
|
692
|
+
β β βββ svg-processor.ts # SVG parsing and generation
|
|
693
|
+
β βββ services/ # Business logic services
|
|
694
|
+
β β βββ svg-service.ts # High-level SVG operations
|
|
695
|
+
β β βββ config.ts # Configuration management
|
|
696
|
+
β βββ utils/ # Native utilities
|
|
697
|
+
β β βββ native.ts # Zero-dependency helpers
|
|
698
|
+
β βββ types/ # TypeScript definitions
|
|
699
|
+
β βββ index.ts # Comprehensive type system
|
|
700
|
+
βββ test-output/ # Framework test results
|
|
701
|
+
βββ dist/ # Compiled JavaScript
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
---
|
|
705
|
+
|
|
706
|
+
## π€ Contributing
|
|
707
|
+
|
|
708
|
+
We welcome contributions! Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
|
|
709
|
+
|
|
710
|
+
### Development Setup
|
|
711
|
+
|
|
712
|
+
```bash
|
|
713
|
+
# Clone repository
|
|
714
|
+
git clone https://github.com/yourusername/svger-cli.git
|
|
715
|
+
cd svger-cli
|
|
716
|
+
|
|
717
|
+
# Install dependencies
|
|
718
|
+
npm install
|
|
719
|
+
|
|
720
|
+
# Build project
|
|
721
|
+
npm run build
|
|
722
|
+
|
|
723
|
+
# Run tests
|
|
724
|
+
node test-frameworks.js
|
|
725
|
+
|
|
726
|
+
# Watch mode
|
|
727
|
+
npm run dev
|
|
728
|
+
```
|
|
729
|
+
|
|
730
|
+
---
|
|
731
|
+
|
|
732
|
+
## π License
|
|
733
|
+
|
|
734
|
+
MIT License - see [LICENSE](./LICENSE) file for details.
|
|
735
|
+
|
|
736
|
+
---
|
|
737
|
+
|
|
738
|
+
## π Credits
|
|
739
|
+
|
|
740
|
+
Developed with β€οΈ by the SVGER-CLI team.
|
|
741
|
+
|
|
742
|
+
Special thanks to the open-source community and the maintainers of React, Vue, Svelte, Angular, Solid, Preact, Lit, and all the frameworks we support.
|
|
743
|
+
|
|
744
|
+
---
|
|
745
|
+
|
|
746
|
+
## π Support
|
|
747
|
+
|
|
748
|
+
- **Issues**: [GitHub Issues](https://github.com/yourusername/svger-cli/issues)
|
|
749
|
+
- **Discussions**: [GitHub Discussions](https://github.com/yourusername/svger-cli/discussions)
|
|
750
|
+
- **Documentation**: [Full Docs](https://svger-cli.dev)
|
|
751
|
+
|
|
752
|
+
---
|
|
753
|
+
|
|
754
|
+
## πΊοΈ Roadmap
|
|
755
|
+
|
|
756
|
+
- [ ] React Native support
|
|
757
|
+
- [ ] Next.js optimization
|
|
758
|
+
- [ ] Nuxt.js integration
|
|
759
|
+
- [ ] SvelteKit optimization
|
|
760
|
+
- [ ] Component caching system
|
|
761
|
+
- [ ] Custom template support
|
|
762
|
+
- [ ] SVG optimization presets
|
|
763
|
+
- [ ] Icon pack generation
|
|
764
|
+
- [ ] Storybook integration
|
|
765
|
+
|
|
766
|
+
---
|
|
767
|
+
|
|
768
|
+
**Made with TypeScript, Node.js, and Zero Dependencies** π
|