svger-cli 2.0.6 → 2.0.7

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.
@@ -4,6 +4,8 @@ export class FrameworkTemplateEngine {
4
4
  switch (framework) {
5
5
  case 'react':
6
6
  return this.generateReactComponent(componentName, svgContent, typescript, frameworkOptions);
7
+ case 'react-native':
8
+ return this.generateReactNativeComponent(componentName, svgContent, typescript, frameworkOptions);
7
9
  case 'vue':
8
10
  return this.generateVueComponent(componentName, svgContent, typescript, frameworkOptions);
9
11
  case 'svelte':
@@ -26,6 +28,7 @@ export class FrameworkTemplateEngine {
26
28
  const tsExt = typescript ? 'ts' : 'js';
27
29
  switch (framework) {
28
30
  case 'react':
31
+ case 'react-native':
29
32
  case 'preact':
30
33
  case 'solid':
31
34
  return typescript ? 'tsx' : 'jsx';
@@ -59,328 +62,413 @@ export class FrameworkTemplateEngine {
59
62
  }
60
63
  generateReactComponent(componentName, svgContent, typescript, options) {
61
64
  const { attributes, innerContent } = this.parseSVG(svgContent);
62
- return `import React from "react";
63
- import type { SVGProps } from "react";
64
-
65
- export interface ${componentName}Props extends SVGProps<SVGSVGElement> {
66
- size?: number | string;
67
- }
68
-
69
- const ${componentName} = React.forwardRef<SVGSVGElement, ${componentName}Props>(
70
- ({ size, className, style, ...props }, ref) => {
71
- const dimensions = size ? { width: size, height: size } : {
72
- width: props.width || ${attributes.width || 24},
73
- height: props.height || ${attributes.height || 24}
74
- };
75
-
76
- return (
77
- <svg
78
- ref={ref}
79
- viewBox="${attributes.viewBox || '0 0 24 24'}"
80
- xmlns="http://www.w3.org/2000/svg"
81
- width={dimensions.width}
82
- height={dimensions.height}
83
- fill={props.fill || "${attributes.fill || 'currentColor'}"}
84
- className={className}
85
- style={style}
86
- {...props}
87
- >
88
- ${innerContent}
89
- </svg>
90
- );
91
- }
92
- );
93
-
94
- ${componentName}.displayName = "${componentName}";
95
-
96
- export default ${componentName};
65
+ return `import React from "react";
66
+ import type { SVGProps } from "react";
67
+
68
+ export interface ${componentName}Props extends SVGProps<SVGSVGElement> {
69
+ size?: number | string;
70
+ }
71
+
72
+ const ${componentName} = React.forwardRef<SVGSVGElement, ${componentName}Props>(
73
+ ({ size, className, style, ...props }, ref) => {
74
+ const dimensions = size ? { width: size, height: size } : {
75
+ width: props.width || ${attributes.width || 24},
76
+ height: props.height || ${attributes.height || 24}
77
+ };
78
+
79
+ return (
80
+ <svg
81
+ ref={ref}
82
+ viewBox="${attributes.viewBox || '0 0 24 24'}"
83
+ xmlns="http://www.w3.org/2000/svg"
84
+ width={dimensions.width}
85
+ height={dimensions.height}
86
+ fill={props.fill || "${attributes.fill || 'currentColor'}"}
87
+ className={className}
88
+ style={style}
89
+ {...props}
90
+ >
91
+ ${innerContent}
92
+ </svg>
93
+ );
94
+ }
95
+ );
96
+
97
+ ${componentName}.displayName = "${componentName}";
98
+
99
+ export default ${componentName};
100
+ `;
101
+ }
102
+ generateReactNativeComponent(componentName, svgContent, typescript, options) {
103
+ const { attributes, innerContent } = this.parseSVG(svgContent);
104
+ // Convert SVG elements to React Native SVG components
105
+ const convertedContent = innerContent
106
+ .replace(/<path/g, '<Path')
107
+ .replace(/<\/path>/g, '</Path>')
108
+ .replace(/<circle/g, '<Circle')
109
+ .replace(/<\/circle>/g, '</Circle>')
110
+ .replace(/<rect/g, '<Rect')
111
+ .replace(/<\/rect>/g, '</Rect>')
112
+ .replace(/<line/g, '<Line')
113
+ .replace(/<\/line>/g, '</Line>')
114
+ .replace(/<polygon/g, '<Polygon')
115
+ .replace(/<\/polygon>/g, '</Polygon>')
116
+ .replace(/<polyline/g, '<Polyline')
117
+ .replace(/<\/polyline>/g, '</Polyline>')
118
+ .replace(/<ellipse/g, '<Ellipse')
119
+ .replace(/<\/ellipse>/g, '</Ellipse>')
120
+ .replace(/<g>/g, '<G>')
121
+ .replace(/<\/g>/g, '</G>')
122
+ .replace(/<defs>/g, '<Defs>')
123
+ .replace(/<\/defs>/g, '</Defs>')
124
+ .replace(/<clipPath/g, '<ClipPath')
125
+ .replace(/<\/clipPath>/g, '</ClipPath>')
126
+ .replace(/<linearGradient/g, '<LinearGradient')
127
+ .replace(/<\/linearGradient>/g, '</LinearGradient>')
128
+ .replace(/<radialGradient/g, '<RadialGradient')
129
+ .replace(/<\/radialGradient>/g, '</RadialGradient>')
130
+ .replace(/<stop/g, '<Stop')
131
+ .replace(/<\/stop>/g, '</Stop>')
132
+ .replace(/stroke-width=/g, 'strokeWidth=')
133
+ .replace(/stroke-linecap=/g, 'strokeLinecap=')
134
+ .replace(/stroke-linejoin=/g, 'strokeLinejoin=')
135
+ .replace(/fill-rule=/g, 'fillRule=')
136
+ .replace(/clip-rule=/g, 'clipRule=');
137
+ return `import React from "react";
138
+ import Svg, {
139
+ Path,
140
+ Circle,
141
+ Rect,
142
+ Line,
143
+ Polygon,
144
+ Polyline,
145
+ Ellipse,
146
+ G,
147
+ Defs,
148
+ ClipPath,
149
+ LinearGradient,
150
+ RadialGradient,
151
+ Stop,
152
+ } from "react-native-svg";
153
+ import type { SvgProps } from "react-native-svg";
154
+
155
+ export interface ${componentName}Props extends SvgProps {
156
+ size?: number | string;
157
+ color?: string;
158
+ }
159
+
160
+ const ${componentName} = React.forwardRef<Svg, ${componentName}Props>(
161
+ ({ size, color, ...props }, ref) => {
162
+ const dimensions = size ? { width: size, height: size } : {
163
+ width: props.width || ${attributes.width || 24},
164
+ height: props.height || ${attributes.height || 24}
165
+ };
166
+
167
+ return (
168
+ <Svg
169
+ ref={ref}
170
+ viewBox="${attributes.viewBox || '0 0 24 24'}"
171
+ width={dimensions.width}
172
+ height={dimensions.height}
173
+ fill={color || props.fill || "${attributes.fill || 'currentColor'}"}
174
+ {...props}
175
+ >
176
+ ${convertedContent}
177
+ </Svg>
178
+ );
179
+ }
180
+ );
181
+
182
+ ${componentName}.displayName = "${componentName}";
183
+
184
+ export default ${componentName};
97
185
  `;
98
186
  }
99
187
  generateVueComponent(componentName, svgContent, typescript, options) {
100
188
  const { attributes, innerContent } = this.parseSVG(svgContent);
101
189
  const { scriptSetup = true } = options;
102
190
  if (scriptSetup && typescript) {
103
- return `<template>
104
- <svg
105
- :class="className"
106
- :style="style"
107
- :width="width || ${attributes.width || 24}"
108
- :height="height || ${attributes.height || 24}"
109
- :fill="fill || '${attributes.fill || 'currentColor'}'"
110
- :stroke="stroke"
111
- viewBox="${attributes.viewBox || '0 0 24 24'}"
112
- xmlns="http://www.w3.org/2000/svg"
113
- v-bind="$attrs"
114
- >
115
- ${innerContent}
116
- </svg>
117
- </template>
118
-
119
- <script setup lang="ts">
120
- interface Props {
121
- className?: string;
122
- style?: string | Record<string, any>;
123
- width?: string | number;
124
- height?: string | number;
125
- fill?: string;
126
- stroke?: string;
127
- }
128
-
129
- withDefaults(defineProps<Props>(), {
130
- className: '',
131
- fill: '${attributes.fill || 'currentColor'}',
132
- width: ${attributes.width || 24},
133
- height: ${attributes.height || 24}
134
- });
135
- </script>
191
+ return `<template>
192
+ <svg
193
+ :class="className"
194
+ :style="style"
195
+ :width="width || ${attributes.width || 24}"
196
+ :height="height || ${attributes.height || 24}"
197
+ :fill="fill || '${attributes.fill || 'currentColor'}'"
198
+ :stroke="stroke"
199
+ viewBox="${attributes.viewBox || '0 0 24 24'}"
200
+ xmlns="http://www.w3.org/2000/svg"
201
+ v-bind="$attrs"
202
+ >
203
+ ${innerContent}
204
+ </svg>
205
+ </template>
206
+
207
+ <script setup lang="ts">
208
+ interface Props {
209
+ className?: string;
210
+ style?: string | Record<string, any>;
211
+ width?: string | number;
212
+ height?: string | number;
213
+ fill?: string;
214
+ stroke?: string;
215
+ }
216
+
217
+ withDefaults(defineProps<Props>(), {
218
+ className: '',
219
+ fill: '${attributes.fill || 'currentColor'}',
220
+ width: ${attributes.width || 24},
221
+ height: ${attributes.height || 24}
222
+ });
223
+ </script>
136
224
  `;
137
225
  }
138
- return `<template>
139
- <svg
140
- :class="className"
141
- :style="style"
142
- :width="width"
143
- :height="height"
144
- :fill="fill"
145
- :stroke="stroke"
146
- viewBox="${attributes.viewBox || '0 0 24 24'}"
147
- xmlns="http://www.w3.org/2000/svg"
148
- v-bind="$attrs"
149
- >
150
- ${innerContent}
151
- </svg>
152
- </template>
153
-
154
- <script${typescript ? ' lang="ts"' : ''}>
155
- import { defineComponent } from 'vue';
156
-
157
- export default defineComponent({
158
- name: '${componentName}',
159
- props: {
160
- className: { type: String, default: '' },
161
- style: { type: [String, Object], default: '' },
162
- width: { type: [String, Number], default: ${attributes.width || 24} },
163
- height: { type: [String, Number], default: ${attributes.height || 24} },
164
- fill: { type: String, default: '${attributes.fill || 'currentColor'}' },
165
- stroke: { type: String, default: '' }
166
- }
167
- });
168
- </script>
226
+ return `<template>
227
+ <svg
228
+ :class="className"
229
+ :style="style"
230
+ :width="width"
231
+ :height="height"
232
+ :fill="fill"
233
+ :stroke="stroke"
234
+ viewBox="${attributes.viewBox || '0 0 24 24'}"
235
+ xmlns="http://www.w3.org/2000/svg"
236
+ v-bind="$attrs"
237
+ >
238
+ ${innerContent}
239
+ </svg>
240
+ </template>
241
+
242
+ <script${typescript ? ' lang="ts"' : ''}>
243
+ import { defineComponent } from 'vue';
244
+
245
+ export default defineComponent({
246
+ name: '${componentName}',
247
+ props: {
248
+ className: { type: String, default: '' },
249
+ style: { type: [String, Object], default: '' },
250
+ width: { type: [String, Number], default: ${attributes.width || 24} },
251
+ height: { type: [String, Number], default: ${attributes.height || 24} },
252
+ fill: { type: String, default: '${attributes.fill || 'currentColor'}' },
253
+ stroke: { type: String, default: '' }
254
+ }
255
+ });
256
+ </script>
169
257
  `;
170
258
  }
171
259
  generateSvelteComponent(componentName, svgContent, typescript) {
172
260
  const { attributes, innerContent } = this.parseSVG(svgContent);
173
- return `<script${typescript ? ' lang="ts"' : ''}>
174
- export let className${typescript ? ': string' : ''} = '';
175
- export let style${typescript ? ': string' : ''} = '';
176
- export let width${typescript ? ': string | number' : ''} = ${attributes.width || 24};
177
- export let height${typescript ? ': string | number' : ''} = ${attributes.height || 24};
178
- export let fill${typescript ? ': string' : ''} = '${attributes.fill || 'currentColor'}';
179
- export let stroke${typescript ? ': string' : ''} = '';
180
- </script>
181
-
182
- <svg
183
- class={className}
184
- {style}
185
- {width}
186
- {height}
187
- {fill}
188
- {stroke}
189
- viewBox="${attributes.viewBox || '0 0 24 24'}"
190
- xmlns="http://www.w3.org/2000/svg"
191
- {...$$restProps}
192
- >
193
- ${innerContent}
194
- </svg>
261
+ return `<script${typescript ? ' lang="ts"' : ''}>
262
+ export let className${typescript ? ': string' : ''} = '';
263
+ export let style${typescript ? ': string' : ''} = '';
264
+ export let width${typescript ? ': string | number' : ''} = ${attributes.width || 24};
265
+ export let height${typescript ? ': string | number' : ''} = ${attributes.height || 24};
266
+ export let fill${typescript ? ': string' : ''} = '${attributes.fill || 'currentColor'}';
267
+ export let stroke${typescript ? ': string' : ''} = '';
268
+ </script>
269
+
270
+ <svg
271
+ class={className}
272
+ {style}
273
+ {width}
274
+ {height}
275
+ {fill}
276
+ {stroke}
277
+ viewBox="${attributes.viewBox || '0 0 24 24'}"
278
+ xmlns="http://www.w3.org/2000/svg"
279
+ {...$$restProps}
280
+ >
281
+ ${innerContent}
282
+ </svg>
195
283
  `;
196
284
  }
197
285
  generateAngularComponent(componentName, svgContent, typescript, options) {
198
286
  const { attributes, innerContent } = this.parseSVG(svgContent);
199
287
  const { standalone = true } = options;
200
288
  const kebabName = this.toKebabCase(componentName);
201
- return `import { Component, Input${standalone ? ', ChangeDetectionStrategy' : ''} } from '@angular/core';
202
-
203
- @Component({
204
- selector: '${kebabName}',
205
- ${standalone ? 'standalone: true,' : ''}
206
- template: \`
207
- <svg
208
- [attr.class]="className"
209
- [attr.width]="width"
210
- [attr.height]="height"
211
- [attr.fill]="fill"
212
- [attr.stroke]="stroke"
213
- viewBox="${attributes.viewBox || '0 0 24 24'}"
214
- xmlns="http://www.w3.org/2000/svg"
215
- >
216
- ${innerContent}
217
- </svg>
289
+ return `import { Component, Input${standalone ? ', ChangeDetectionStrategy' : ''} } from '@angular/core';
290
+
291
+ @Component({
292
+ selector: '${kebabName}',
293
+ ${standalone ? 'standalone: true,' : ''}
294
+ template: \`
295
+ <svg
296
+ [attr.class]="className"
297
+ [attr.width]="width"
298
+ [attr.height]="height"
299
+ [attr.fill]="fill"
300
+ [attr.stroke]="stroke"
301
+ viewBox="${attributes.viewBox || '0 0 24 24'}"
302
+ xmlns="http://www.w3.org/2000/svg"
303
+ >
304
+ ${innerContent}
305
+ </svg>
218
306
  \`,${standalone
219
- ? `
307
+ ? `
220
308
  changeDetection: ChangeDetectionStrategy.OnPush`
221
- : ''}
222
- })
223
- export class ${componentName}Component {
224
- @Input() className: string = '';
225
- @Input() width: string | number = ${attributes.width || 24};
226
- @Input() height: string | number = ${attributes.height || 24};
227
- @Input() fill: string = '${attributes.fill || 'currentColor'}';
228
- @Input() stroke: string = '';
229
- }
309
+ : ''}
310
+ })
311
+ export class ${componentName}Component {
312
+ @Input() className: string = '';
313
+ @Input() width: string | number = ${attributes.width || 24};
314
+ @Input() height: string | number = ${attributes.height || 24};
315
+ @Input() fill: string = '${attributes.fill || 'currentColor'}';
316
+ @Input() stroke: string = '';
317
+ }
230
318
  `;
231
319
  }
232
320
  generateSolidComponent(componentName, svgContent, typescript) {
233
321
  const { attributes, innerContent } = this.parseSVG(svgContent);
234
- return `import { Component, JSX } from 'solid-js';
235
-
236
- export interface ${componentName}Props extends JSX.SvgSVGAttributes<SVGSVGElement> {
237
- className?: string;
238
- width?: string | number;
239
- height?: string | number;
240
- fill?: string;
241
- stroke?: string;
242
- }
243
-
244
- const ${componentName}: Component<${componentName}Props> = (props) => (
245
- <svg
246
- class={props.className}
247
- style={props.style}
248
- width={props.width || ${attributes.width || 24}}
249
- height={props.height || ${attributes.height || 24}}
250
- fill={props.fill || '${attributes.fill || 'currentColor'}'}
251
- stroke={props.stroke}
252
- viewBox="${attributes.viewBox || '0 0 24 24'}"
253
- xmlns="http://www.w3.org/2000/svg"
254
- {...props}
255
- >
256
- ${innerContent}
257
- </svg>
258
- );
259
-
260
- export default ${componentName};
322
+ return `import { Component, JSX } from 'solid-js';
323
+
324
+ export interface ${componentName}Props extends JSX.SvgSVGAttributes<SVGSVGElement> {
325
+ className?: string;
326
+ width?: string | number;
327
+ height?: string | number;
328
+ fill?: string;
329
+ stroke?: string;
330
+ }
331
+
332
+ const ${componentName}: Component<${componentName}Props> = (props) => (
333
+ <svg
334
+ class={props.className}
335
+ style={props.style}
336
+ width={props.width || ${attributes.width || 24}}
337
+ height={props.height || ${attributes.height || 24}}
338
+ fill={props.fill || '${attributes.fill || 'currentColor'}'}
339
+ stroke={props.stroke}
340
+ viewBox="${attributes.viewBox || '0 0 24 24'}"
341
+ xmlns="http://www.w3.org/2000/svg"
342
+ {...props}
343
+ >
344
+ ${innerContent}
345
+ </svg>
346
+ );
347
+
348
+ export default ${componentName};
261
349
  `;
262
350
  }
263
351
  generatePreactComponent(componentName, svgContent, typescript) {
264
352
  const { attributes, innerContent } = this.parseSVG(svgContent);
265
- return `import { h, FunctionComponent } from 'preact';
266
- import { JSX } from 'preact/jsx-runtime';
267
-
268
- export interface ${componentName}Props extends JSX.SVGAttributes<SVGSVGElement> {
269
- className?: string;
270
- width?: string | number;
271
- height?: string | number;
272
- fill?: string;
273
- stroke?: string;
274
- }
275
-
276
- const ${componentName}: FunctionComponent<${componentName}Props> = ({
277
- className,
278
- style,
279
- width,
280
- height,
281
- fill,
282
- stroke,
283
- ...props
284
- }) => {
285
- return (
286
- <svg
287
- class={className}
288
- style={style}
289
- width={width || ${attributes.width || 24}}
290
- height={height || ${attributes.height || 24}}
291
- fill={fill || '${attributes.fill || 'currentColor'}'}
292
- stroke={stroke}
293
- viewBox="${attributes.viewBox || '0 0 24 24'}"
294
- xmlns="http://www.w3.org/2000/svg"
295
- {...props}
296
- >
297
- ${innerContent}
298
- </svg>
299
- );
300
- };
301
-
302
- export default ${componentName};
353
+ return `import { h, FunctionComponent } from 'preact';
354
+ import { JSX } from 'preact/jsx-runtime';
355
+
356
+ export interface ${componentName}Props extends JSX.SVGAttributes<SVGSVGElement> {
357
+ className?: string;
358
+ width?: string | number;
359
+ height?: string | number;
360
+ fill?: string;
361
+ stroke?: string;
362
+ }
363
+
364
+ const ${componentName}: FunctionComponent<${componentName}Props> = ({
365
+ className,
366
+ style,
367
+ width,
368
+ height,
369
+ fill,
370
+ stroke,
371
+ ...props
372
+ }) => {
373
+ return (
374
+ <svg
375
+ class={className}
376
+ style={style}
377
+ width={width || ${attributes.width || 24}}
378
+ height={height || ${attributes.height || 24}}
379
+ fill={fill || '${attributes.fill || 'currentColor'}'}
380
+ stroke={stroke}
381
+ viewBox="${attributes.viewBox || '0 0 24 24'}"
382
+ xmlns="http://www.w3.org/2000/svg"
383
+ {...props}
384
+ >
385
+ ${innerContent}
386
+ </svg>
387
+ );
388
+ };
389
+
390
+ export default ${componentName};
303
391
  `;
304
392
  }
305
393
  generateLitComponent(componentName, svgContent, typescript) {
306
394
  const { attributes, innerContent } = this.parseSVG(svgContent);
307
395
  const kebabName = this.toKebabCase(componentName);
308
- return `import { LitElement, html, css, svg } from 'lit';
309
- import { customElement, property } from 'lit/decorators.js';
310
-
311
- @customElement('${kebabName}')
312
- export class ${componentName} extends LitElement {
313
- @property({ type: String }) className = '';
314
- @property({ type: String, reflect: true }) width = '${attributes.width || 24}';
315
- @property({ type: String, reflect: true }) height = '${attributes.height || 24}';
316
- @property({ type: String, reflect: true }) fill = '${attributes.fill || 'currentColor'}';
317
- @property({ type: String, reflect: true }) stroke = '';
318
-
319
- static styles = css\`:host { display: inline-block; }\`;
320
-
321
- render() {
322
- return svg\`
323
- <svg
324
- class="\${this.className}"
325
- width="\${this.width}"
326
- height="\${this.height}"
327
- fill="\${this.fill}"
328
- stroke="\${this.stroke}"
329
- viewBox="${attributes.viewBox || '0 0 24 24'}"
330
- xmlns="http://www.w3.org/2000/svg"
331
- >
332
- ${innerContent}
333
- </svg>
334
- \`;
335
- }
336
- }
337
-
338
- declare global {
339
- interface HTMLElementTagNameMap {
340
- '${kebabName}': ${componentName};
341
- }
342
- }
396
+ return `import { LitElement, html, css, svg } from 'lit';
397
+ import { customElement, property } from 'lit/decorators.js';
398
+
399
+ @customElement('${kebabName}')
400
+ export class ${componentName} extends LitElement {
401
+ @property({ type: String }) className = '';
402
+ @property({ type: String, reflect: true }) width = '${attributes.width || 24}';
403
+ @property({ type: String, reflect: true }) height = '${attributes.height || 24}';
404
+ @property({ type: String, reflect: true }) fill = '${attributes.fill || 'currentColor'}';
405
+ @property({ type: String, reflect: true }) stroke = '';
406
+
407
+ static styles = css\`:host { display: inline-block; }\`;
408
+
409
+ render() {
410
+ return svg\`
411
+ <svg
412
+ class="\${this.className}"
413
+ width="\${this.width}"
414
+ height="\${this.height}"
415
+ fill="\${this.fill}"
416
+ stroke="\${this.stroke}"
417
+ viewBox="${attributes.viewBox || '0 0 24 24'}"
418
+ xmlns="http://www.w3.org/2000/svg"
419
+ >
420
+ ${innerContent}
421
+ </svg>
422
+ \`;
423
+ }
424
+ }
425
+
426
+ declare global {
427
+ interface HTMLElementTagNameMap {
428
+ '${kebabName}': ${componentName};
429
+ }
430
+ }
343
431
  `;
344
432
  }
345
433
  generateVanillaComponent(componentName, svgContent, typescript) {
346
434
  const { attributes, innerContent } = this.parseSVG(svgContent);
347
- return `export interface ${componentName}Options {
348
- className?: string;
349
- width?: string | number;
350
- height?: string | number;
351
- fill?: string;
352
- stroke?: string;
353
- [key: string]: any;
354
- }
355
-
356
- export function ${componentName}(options: ${componentName}Options = {}): SVGSVGElement {
357
- const {
358
- className = '',
359
- width = ${attributes.width || 24},
360
- height = ${attributes.height || 24},
361
- fill = '${attributes.fill || 'currentColor'}',
362
- stroke = '',
363
- ...attrs
364
- } = options;
365
-
366
- const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
367
- svg.setAttribute('viewBox', '${attributes.viewBox || '0 0 24 24'}');
368
- svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
369
-
370
- if (className) svg.setAttribute('class', className);
371
- svg.setAttribute('width', String(width));
372
- svg.setAttribute('height', String(height));
373
- svg.setAttribute('fill', fill);
374
- if (stroke) svg.setAttribute('stroke', stroke);
375
-
376
- Object.entries(attrs).forEach(([key, value]) => {
377
- svg.setAttribute(key, String(value));
378
- });
379
-
380
- svg.innerHTML = \`${innerContent}\`;
381
-
382
- return svg;
383
- }
435
+ return `export interface ${componentName}Options {
436
+ className?: string;
437
+ width?: string | number;
438
+ height?: string | number;
439
+ fill?: string;
440
+ stroke?: string;
441
+ [key: string]: any;
442
+ }
443
+
444
+ export function ${componentName}(options: ${componentName}Options = {}): SVGSVGElement {
445
+ const {
446
+ className = '',
447
+ width = ${attributes.width || 24},
448
+ height = ${attributes.height || 24},
449
+ fill = '${attributes.fill || 'currentColor'}',
450
+ stroke = '',
451
+ ...attrs
452
+ } = options;
453
+
454
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
455
+ svg.setAttribute('viewBox', '${attributes.viewBox || '0 0 24 24'}');
456
+ svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
457
+
458
+ if (className) svg.setAttribute('class', className);
459
+ svg.setAttribute('width', String(width));
460
+ svg.setAttribute('height', String(height));
461
+ svg.setAttribute('fill', fill);
462
+ if (stroke) svg.setAttribute('stroke', stroke);
463
+
464
+ Object.entries(attrs).forEach(([key, value]) => {
465
+ svg.setAttribute(key, String(value));
466
+ });
467
+
468
+ svg.innerHTML = \`${innerContent}\`;
469
+
470
+ return svg;
471
+ }
384
472
  `;
385
473
  }
386
474
  toKebabCase(str) {