svger-cli 2.0.6 → 2.0.8
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 +119 -119
- package/CHANGELOG.md +235 -156
- package/DEVELOPMENT.md +352 -352
- package/LICENSE +20 -20
- package/README.md +2377 -2654
- package/SECURITY.md +68 -68
- package/bin/svg-tool.js +2 -2
- package/dist/core/framework-templates.d.ts +1 -0
- package/dist/core/framework-templates.js +373 -285
- package/dist/core/style-compiler.js +201 -201
- package/dist/core/template-manager.js +348 -348
- package/dist/services/svg-service.js +12 -12
- package/dist/templates/ComponentTemplate.js +17 -17
- package/dist/types/index.d.ts +1 -1
- package/docs/ADR-SVG-INTRGRATION-METHODS-001.adr.md +157 -157
- package/docs/ADR-SVG-INTRGRATION-METHODS-002.adr.md +549 -549
- package/docs/FRAMEWORK-GUIDE.md +768 -768
- package/docs/IMPLEMENTATION-SUMMARY.md +376 -376
- package/package.json +178 -177
|
@@ -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) {
|