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
|
@@ -128,45 +128,45 @@ export class TemplateManager {
|
|
|
128
128
|
*/
|
|
129
129
|
generateReactFunctional(options) {
|
|
130
130
|
const { componentName, svgContent, defaultWidth = 24, defaultHeight = 24, defaultFill = 'currentColor', } = options;
|
|
131
|
-
return `import React from "react";
|
|
132
|
-
import type { SVGProps } from "react";
|
|
133
|
-
|
|
134
|
-
export interface ${componentName}Props extends SVGProps<SVGSVGElement> {
|
|
135
|
-
size?: number | string;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* ${componentName} SVG Component
|
|
140
|
-
* Generated by svger-cli
|
|
141
|
-
*/
|
|
142
|
-
const ${componentName} = React.forwardRef<SVGSVGElement, ${componentName}Props>(
|
|
143
|
-
({ size, className, style, ...props }, ref) => {
|
|
144
|
-
const dimensions = size ? { width: size, height: size } : {
|
|
145
|
-
width: props.width || ${defaultWidth},
|
|
146
|
-
height: props.height || ${defaultHeight}
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
return (
|
|
150
|
-
<svg
|
|
151
|
-
ref={ref}
|
|
152
|
-
viewBox="0 0 ${defaultWidth} ${defaultHeight}"
|
|
153
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
154
|
-
width={dimensions.width}
|
|
155
|
-
height={dimensions.height}
|
|
156
|
-
fill={props.fill || "${defaultFill}"}
|
|
157
|
-
className={className}
|
|
158
|
-
style={style}
|
|
159
|
-
{...props}
|
|
160
|
-
>
|
|
161
|
-
${svgContent}
|
|
162
|
-
</svg>
|
|
163
|
-
);
|
|
164
|
-
}
|
|
165
|
-
);
|
|
166
|
-
|
|
167
|
-
${componentName}.displayName = "${componentName}";
|
|
168
|
-
|
|
169
|
-
export default ${componentName};
|
|
131
|
+
return `import React from "react";
|
|
132
|
+
import type { SVGProps } from "react";
|
|
133
|
+
|
|
134
|
+
export interface ${componentName}Props extends SVGProps<SVGSVGElement> {
|
|
135
|
+
size?: number | string;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* ${componentName} SVG Component
|
|
140
|
+
* Generated by svger-cli
|
|
141
|
+
*/
|
|
142
|
+
const ${componentName} = React.forwardRef<SVGSVGElement, ${componentName}Props>(
|
|
143
|
+
({ size, className, style, ...props }, ref) => {
|
|
144
|
+
const dimensions = size ? { width: size, height: size } : {
|
|
145
|
+
width: props.width || ${defaultWidth},
|
|
146
|
+
height: props.height || ${defaultHeight}
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
return (
|
|
150
|
+
<svg
|
|
151
|
+
ref={ref}
|
|
152
|
+
viewBox="0 0 ${defaultWidth} ${defaultHeight}"
|
|
153
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
154
|
+
width={dimensions.width}
|
|
155
|
+
height={dimensions.height}
|
|
156
|
+
fill={props.fill || "${defaultFill}"}
|
|
157
|
+
className={className}
|
|
158
|
+
style={style}
|
|
159
|
+
{...props}
|
|
160
|
+
>
|
|
161
|
+
${svgContent}
|
|
162
|
+
</svg>
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
${componentName}.displayName = "${componentName}";
|
|
168
|
+
|
|
169
|
+
export default ${componentName};
|
|
170
170
|
`;
|
|
171
171
|
}
|
|
172
172
|
/**
|
|
@@ -174,34 +174,34 @@ export default ${componentName};
|
|
|
174
174
|
*/
|
|
175
175
|
generateReactForwardRef(options) {
|
|
176
176
|
const { componentName, svgContent, defaultWidth = 24, defaultHeight = 24, defaultFill = 'currentColor', } = options;
|
|
177
|
-
return `import { forwardRef } from "react";
|
|
178
|
-
import type { SVGProps } from "react";
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* ${componentName} SVG Component with forwardRef
|
|
182
|
-
* Generated by svger-cli
|
|
183
|
-
*/
|
|
184
|
-
const ${componentName} = forwardRef<SVGSVGElement, SVGProps<SVGSVGElement>>(
|
|
185
|
-
(props, ref) => (
|
|
186
|
-
<svg
|
|
187
|
-
ref={ref}
|
|
188
|
-
viewBox="0 0 ${defaultWidth} ${defaultHeight}"
|
|
189
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
190
|
-
width={props.width || ${defaultWidth}}
|
|
191
|
-
height={props.height || ${defaultHeight}}
|
|
192
|
-
fill={props.fill || "${defaultFill}"}
|
|
193
|
-
className={props.className}
|
|
194
|
-
style={props.style}
|
|
195
|
-
{...props}
|
|
196
|
-
>
|
|
197
|
-
${svgContent}
|
|
198
|
-
</svg>
|
|
199
|
-
)
|
|
200
|
-
);
|
|
201
|
-
|
|
202
|
-
${componentName}.displayName = "${componentName}";
|
|
203
|
-
|
|
204
|
-
export default ${componentName};
|
|
177
|
+
return `import { forwardRef } from "react";
|
|
178
|
+
import type { SVGProps } from "react";
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* ${componentName} SVG Component with forwardRef
|
|
182
|
+
* Generated by svger-cli
|
|
183
|
+
*/
|
|
184
|
+
const ${componentName} = forwardRef<SVGSVGElement, SVGProps<SVGSVGElement>>(
|
|
185
|
+
(props, ref) => (
|
|
186
|
+
<svg
|
|
187
|
+
ref={ref}
|
|
188
|
+
viewBox="0 0 ${defaultWidth} ${defaultHeight}"
|
|
189
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
190
|
+
width={props.width || ${defaultWidth}}
|
|
191
|
+
height={props.height || ${defaultHeight}}
|
|
192
|
+
fill={props.fill || "${defaultFill}"}
|
|
193
|
+
className={props.className}
|
|
194
|
+
style={props.style}
|
|
195
|
+
{...props}
|
|
196
|
+
>
|
|
197
|
+
${svgContent}
|
|
198
|
+
</svg>
|
|
199
|
+
)
|
|
200
|
+
);
|
|
201
|
+
|
|
202
|
+
${componentName}.displayName = "${componentName}";
|
|
203
|
+
|
|
204
|
+
export default ${componentName};
|
|
205
205
|
`;
|
|
206
206
|
}
|
|
207
207
|
/**
|
|
@@ -209,33 +209,33 @@ export default ${componentName};
|
|
|
209
209
|
*/
|
|
210
210
|
generateReactClass(options) {
|
|
211
211
|
const { componentName, svgContent, defaultWidth = 24, defaultHeight = 24, defaultFill = 'currentColor', } = options;
|
|
212
|
-
return `import { Component } from "react";
|
|
213
|
-
import type { SVGProps } from "react";
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* ${componentName} SVG Component (Class-based)
|
|
217
|
-
* Generated by svger-cli
|
|
218
|
-
*/
|
|
219
|
-
class ${componentName} extends Component<SVGProps<SVGSVGElement>> {
|
|
220
|
-
render() {
|
|
221
|
-
const { width = ${defaultWidth}, height = ${defaultHeight}, fill = "${defaultFill}", ...props } = this.props;
|
|
222
|
-
|
|
223
|
-
return (
|
|
224
|
-
<svg
|
|
225
|
-
viewBox="0 0 ${defaultWidth} ${defaultHeight}"
|
|
226
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
227
|
-
width={width}
|
|
228
|
-
height={height}
|
|
229
|
-
fill={fill}
|
|
230
|
-
{...props}
|
|
231
|
-
>
|
|
232
|
-
${svgContent}
|
|
233
|
-
</svg>
|
|
234
|
-
);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
export default ${componentName};
|
|
212
|
+
return `import { Component } from "react";
|
|
213
|
+
import type { SVGProps } from "react";
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* ${componentName} SVG Component (Class-based)
|
|
217
|
+
* Generated by svger-cli
|
|
218
|
+
*/
|
|
219
|
+
class ${componentName} extends Component<SVGProps<SVGSVGElement>> {
|
|
220
|
+
render() {
|
|
221
|
+
const { width = ${defaultWidth}, height = ${defaultHeight}, fill = "${defaultFill}", ...props } = this.props;
|
|
222
|
+
|
|
223
|
+
return (
|
|
224
|
+
<svg
|
|
225
|
+
viewBox="0 0 ${defaultWidth} ${defaultHeight}"
|
|
226
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
227
|
+
width={width}
|
|
228
|
+
height={height}
|
|
229
|
+
fill={fill}
|
|
230
|
+
{...props}
|
|
231
|
+
>
|
|
232
|
+
${svgContent}
|
|
233
|
+
</svg>
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export default ${componentName};
|
|
239
239
|
`;
|
|
240
240
|
}
|
|
241
241
|
/**
|
|
@@ -243,32 +243,32 @@ export default ${componentName};
|
|
|
243
243
|
*/
|
|
244
244
|
generateStyledComponents(options) {
|
|
245
245
|
const { componentName, svgContent, defaultWidth = 24, defaultHeight = 24, defaultFill = 'currentColor', } = options;
|
|
246
|
-
return `import styled from "styled-components";
|
|
247
|
-
import type { SVGProps } from "react";
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* ${componentName} SVG Component with Styled Components
|
|
251
|
-
* Generated by svger-cli
|
|
252
|
-
*/
|
|
253
|
-
const StyledSVG = styled.svg<SVGProps<SVGSVGElement>>\`
|
|
254
|
-
width: \${props => props.width || '${defaultWidth}px'};
|
|
255
|
-
height: \${props => props.height || '${defaultHeight}px'};
|
|
256
|
-
fill: \${props => props.fill || '${defaultFill}'};
|
|
257
|
-
\`;
|
|
258
|
-
|
|
259
|
-
const ${componentName} = (props: SVGProps<SVGSVGElement>) => (
|
|
260
|
-
<StyledSVG
|
|
261
|
-
viewBox="0 0 ${defaultWidth} ${defaultHeight}"
|
|
262
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
263
|
-
{...props}
|
|
264
|
-
>
|
|
265
|
-
${svgContent}
|
|
266
|
-
</StyledSVG>
|
|
267
|
-
);
|
|
268
|
-
|
|
269
|
-
${componentName}.displayName = "${componentName}";
|
|
270
|
-
|
|
271
|
-
export default ${componentName};
|
|
246
|
+
return `import styled from "styled-components";
|
|
247
|
+
import type { SVGProps } from "react";
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* ${componentName} SVG Component with Styled Components
|
|
251
|
+
* Generated by svger-cli
|
|
252
|
+
*/
|
|
253
|
+
const StyledSVG = styled.svg<SVGProps<SVGSVGElement>>\`
|
|
254
|
+
width: \${props => props.width || '${defaultWidth}px'};
|
|
255
|
+
height: \${props => props.height || '${defaultHeight}px'};
|
|
256
|
+
fill: \${props => props.fill || '${defaultFill}'};
|
|
257
|
+
\`;
|
|
258
|
+
|
|
259
|
+
const ${componentName} = (props: SVGProps<SVGSVGElement>) => (
|
|
260
|
+
<StyledSVG
|
|
261
|
+
viewBox="0 0 ${defaultWidth} ${defaultHeight}"
|
|
262
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
263
|
+
{...props}
|
|
264
|
+
>
|
|
265
|
+
${svgContent}
|
|
266
|
+
</StyledSVG>
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
${componentName}.displayName = "${componentName}";
|
|
270
|
+
|
|
271
|
+
export default ${componentName};
|
|
272
272
|
`;
|
|
273
273
|
}
|
|
274
274
|
/**
|
|
@@ -276,48 +276,48 @@ export default ${componentName};
|
|
|
276
276
|
*/
|
|
277
277
|
generateTypeScriptNative(options) {
|
|
278
278
|
const { componentName, svgContent, defaultWidth = 24, defaultHeight = 24, defaultFill = 'currentColor', } = options;
|
|
279
|
-
return `/**
|
|
280
|
-
* ${componentName} SVG Icon (Native TypeScript)
|
|
281
|
-
* Generated by svger-cli
|
|
282
|
-
*/
|
|
283
|
-
|
|
284
|
-
export interface ${componentName}Options {
|
|
285
|
-
width?: number | string;
|
|
286
|
-
height?: number | string;
|
|
287
|
-
fill?: string;
|
|
288
|
-
className?: string;
|
|
289
|
-
style?: Record<string, any>;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
export function ${componentName}(options: ${componentName}Options = {}): string {
|
|
293
|
-
const {
|
|
294
|
-
width = ${defaultWidth},
|
|
295
|
-
height = ${defaultHeight},
|
|
296
|
-
fill = "${defaultFill}",
|
|
297
|
-
className = "",
|
|
298
|
-
style = {}
|
|
299
|
-
} = options;
|
|
300
|
-
|
|
301
|
-
const styleString = Object.entries(style)
|
|
302
|
-
.map(([key, value]) => \`\${key}: \${value}\`)
|
|
303
|
-
.join("; ");
|
|
304
|
-
|
|
305
|
-
return \`
|
|
306
|
-
<svg
|
|
307
|
-
viewBox="0 0 ${defaultWidth} ${defaultHeight}"
|
|
308
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
309
|
-
width="\${width}"
|
|
310
|
-
height="\${height}"
|
|
311
|
-
fill="\${fill}"
|
|
312
|
-
class="\${className}"
|
|
313
|
-
style="\${styleString}"
|
|
314
|
-
>
|
|
315
|
-
${svgContent}
|
|
316
|
-
</svg>
|
|
317
|
-
\`.trim();
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
export default ${componentName};
|
|
279
|
+
return `/**
|
|
280
|
+
* ${componentName} SVG Icon (Native TypeScript)
|
|
281
|
+
* Generated by svger-cli
|
|
282
|
+
*/
|
|
283
|
+
|
|
284
|
+
export interface ${componentName}Options {
|
|
285
|
+
width?: number | string;
|
|
286
|
+
height?: number | string;
|
|
287
|
+
fill?: string;
|
|
288
|
+
className?: string;
|
|
289
|
+
style?: Record<string, any>;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
export function ${componentName}(options: ${componentName}Options = {}): string {
|
|
293
|
+
const {
|
|
294
|
+
width = ${defaultWidth},
|
|
295
|
+
height = ${defaultHeight},
|
|
296
|
+
fill = "${defaultFill}",
|
|
297
|
+
className = "",
|
|
298
|
+
style = {}
|
|
299
|
+
} = options;
|
|
300
|
+
|
|
301
|
+
const styleString = Object.entries(style)
|
|
302
|
+
.map(([key, value]) => \`\${key}: \${value}\`)
|
|
303
|
+
.join("; ");
|
|
304
|
+
|
|
305
|
+
return \`
|
|
306
|
+
<svg
|
|
307
|
+
viewBox="0 0 ${defaultWidth} ${defaultHeight}"
|
|
308
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
309
|
+
width="\${width}"
|
|
310
|
+
height="\${height}"
|
|
311
|
+
fill="\${fill}"
|
|
312
|
+
class="\${className}"
|
|
313
|
+
style="\${styleString}"
|
|
314
|
+
>
|
|
315
|
+
${svgContent}
|
|
316
|
+
</svg>
|
|
317
|
+
\`.trim();
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
export default ${componentName};
|
|
321
321
|
`;
|
|
322
322
|
}
|
|
323
323
|
/**
|
|
@@ -343,192 +343,192 @@ export default ${componentName};
|
|
|
343
343
|
*/
|
|
344
344
|
generateEnhancedStyled(options) {
|
|
345
345
|
const { componentName, svgContent, defaultWidth = 24, defaultHeight = 24, defaultFill = 'currentColor', } = options;
|
|
346
|
-
return `import React from "react";
|
|
347
|
-
import type { SVGProps } from "react";
|
|
348
|
-
|
|
349
|
-
/**
|
|
350
|
-
* ${componentName} SVG Component with Enhanced Styling
|
|
351
|
-
* Generated by svger-cli with comprehensive styling support
|
|
352
|
-
*/
|
|
353
|
-
|
|
354
|
-
export interface ${componentName}Props extends SVGProps<SVGSVGElement> {
|
|
355
|
-
// Size variants
|
|
356
|
-
size?: number | string | 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
357
|
-
|
|
358
|
-
// Color variants
|
|
359
|
-
variant?: 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info';
|
|
360
|
-
|
|
361
|
-
// Animation options
|
|
362
|
-
animate?: boolean | 'spin' | 'pulse' | 'bounce' | 'fade';
|
|
363
|
-
|
|
364
|
-
// Theme support
|
|
365
|
-
theme?: 'light' | 'dark' | 'auto';
|
|
366
|
-
|
|
367
|
-
// Responsive behavior
|
|
368
|
-
responsive?: boolean;
|
|
369
|
-
|
|
370
|
-
// Interaction states
|
|
371
|
-
loading?: boolean;
|
|
372
|
-
disabled?: boolean;
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
const sizeMap = {
|
|
376
|
-
xs: 12,
|
|
377
|
-
sm: 16,
|
|
378
|
-
md: 24,
|
|
379
|
-
lg: 32,
|
|
380
|
-
xl: 48,
|
|
381
|
-
} as const;
|
|
382
|
-
|
|
383
|
-
const colorMap = {
|
|
384
|
-
primary: '#007bff',
|
|
385
|
-
secondary: '#6c757d',
|
|
386
|
-
success: '#28a745',
|
|
387
|
-
warning: '#ffc107',
|
|
388
|
-
danger: '#dc3545',
|
|
389
|
-
info: '#17a2b8',
|
|
390
|
-
} as const;
|
|
391
|
-
|
|
392
|
-
const ${componentName} = React.forwardRef<SVGSVGElement, ${componentName}Props>(
|
|
393
|
-
({
|
|
394
|
-
size = 'md',
|
|
395
|
-
variant,
|
|
396
|
-
animate = false,
|
|
397
|
-
theme = 'auto',
|
|
398
|
-
responsive = false,
|
|
399
|
-
loading = false,
|
|
400
|
-
disabled = false,
|
|
401
|
-
style,
|
|
402
|
-
className,
|
|
403
|
-
...props
|
|
404
|
-
}, ref) => {
|
|
405
|
-
|
|
406
|
-
// Calculate size
|
|
407
|
-
const dimensions = React.useMemo(() => {
|
|
408
|
-
if (typeof size === 'number') return { width: size, height: size };
|
|
409
|
-
if (typeof size === 'string' && !isNaN(Number(size))) return { width: Number(size), height: Number(size) };
|
|
410
|
-
const mappedSize = sizeMap[size as keyof typeof sizeMap] || sizeMap.md;
|
|
411
|
-
return { width: mappedSize, height: mappedSize };
|
|
412
|
-
}, [size]);
|
|
413
|
-
|
|
414
|
-
// Generate styles
|
|
415
|
-
const computedStyles = React.useMemo(() => {
|
|
416
|
-
const baseStyles: React.CSSProperties = {
|
|
417
|
-
display: 'inline-block',
|
|
418
|
-
verticalAlign: 'middle',
|
|
419
|
-
transition: 'all 0.2s ease-in-out',
|
|
420
|
-
};
|
|
421
|
-
|
|
422
|
-
// Apply color variant
|
|
423
|
-
if (variant) {
|
|
424
|
-
baseStyles.color = colorMap[variant];
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
// Apply theme
|
|
428
|
-
if (theme === 'dark') {
|
|
429
|
-
baseStyles.filter = 'invert(1)';
|
|
430
|
-
} else if (theme === 'auto') {
|
|
431
|
-
baseStyles.filter = 'var(--svger-theme-filter, none)';
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
// Apply animation
|
|
435
|
-
if (animate) {
|
|
436
|
-
if (animate === true || animate === 'spin') {
|
|
437
|
-
baseStyles.animation = 'svger-spin 2s linear infinite';
|
|
438
|
-
} else if (animate === 'pulse') {
|
|
439
|
-
baseStyles.animation = 'svger-pulse 2s ease-in-out infinite';
|
|
440
|
-
} else if (animate === 'bounce') {
|
|
441
|
-
baseStyles.animation = 'svger-bounce 1s infinite';
|
|
442
|
-
} else if (animate === 'fade') {
|
|
443
|
-
baseStyles.animation = 'svger-fade 2s ease-in-out infinite alternate';
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
// Apply loading state
|
|
448
|
-
if (loading) {
|
|
449
|
-
baseStyles.animation = 'svger-spin 1s linear infinite';
|
|
450
|
-
baseStyles.opacity = 0.7;
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
// Apply disabled state
|
|
454
|
-
if (disabled) {
|
|
455
|
-
baseStyles.opacity = 0.5;
|
|
456
|
-
baseStyles.pointerEvents = 'none';
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
// Apply responsive behavior
|
|
460
|
-
if (responsive) {
|
|
461
|
-
baseStyles.width = '100%';
|
|
462
|
-
baseStyles.height = 'auto';
|
|
463
|
-
baseStyles.maxWidth = \`\${dimensions.width}px\`;
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
return { ...baseStyles, ...style };
|
|
467
|
-
}, [variant, theme, animate, loading, disabled, responsive, dimensions, style]);
|
|
468
|
-
|
|
469
|
-
// Generate class names
|
|
470
|
-
const classNames = React.useMemo(() => {
|
|
471
|
-
const classes = ['svger-icon'];
|
|
472
|
-
|
|
473
|
-
if (typeof size === 'string' && sizeMap[size as keyof typeof sizeMap]) {
|
|
474
|
-
classes.push(\`svger-size-\${size}\`);
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
if (variant) {
|
|
478
|
-
classes.push(\`svger-variant-\${variant}\`);
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
if (theme) {
|
|
482
|
-
classes.push(\`svger-theme-\${theme}\`);
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
if (animate) {
|
|
486
|
-
const animationType = animate === true ? 'spin' : animate;
|
|
487
|
-
classes.push(\`svger-animate-\${animationType}\`);
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
if (responsive) {
|
|
491
|
-
classes.push('svger-responsive');
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
if (loading) {
|
|
495
|
-
classes.push('svger-loading');
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
if (disabled) {
|
|
499
|
-
classes.push('svger-disabled');
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
if (className) {
|
|
503
|
-
classes.push(className);
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
return classes.join(' ');
|
|
507
|
-
}, [size, variant, theme, animate, responsive, loading, disabled, className]);
|
|
508
|
-
|
|
509
|
-
return (
|
|
510
|
-
<svg
|
|
511
|
-
ref={ref}
|
|
512
|
-
viewBox="0 0 ${defaultWidth} ${defaultHeight}"
|
|
513
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
514
|
-
width={responsive ? '100%' : dimensions.width}
|
|
515
|
-
height={responsive ? 'auto' : dimensions.height}
|
|
516
|
-
fill={props.fill || "${defaultFill}"}
|
|
517
|
-
className={classNames}
|
|
518
|
-
style={computedStyles}
|
|
519
|
-
aria-hidden={props['aria-hidden'] || (disabled ? 'true' : undefined)}
|
|
520
|
-
aria-busy={loading ? 'true' : undefined}
|
|
521
|
-
{...props}
|
|
522
|
-
>
|
|
523
|
-
${svgContent}
|
|
524
|
-
</svg>
|
|
525
|
-
);
|
|
526
|
-
}
|
|
527
|
-
);
|
|
528
|
-
|
|
529
|
-
${componentName}.displayName = "${componentName}";
|
|
530
|
-
|
|
531
|
-
export default ${componentName};
|
|
346
|
+
return `import React from "react";
|
|
347
|
+
import type { SVGProps } from "react";
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* ${componentName} SVG Component with Enhanced Styling
|
|
351
|
+
* Generated by svger-cli with comprehensive styling support
|
|
352
|
+
*/
|
|
353
|
+
|
|
354
|
+
export interface ${componentName}Props extends SVGProps<SVGSVGElement> {
|
|
355
|
+
// Size variants
|
|
356
|
+
size?: number | string | 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
357
|
+
|
|
358
|
+
// Color variants
|
|
359
|
+
variant?: 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info';
|
|
360
|
+
|
|
361
|
+
// Animation options
|
|
362
|
+
animate?: boolean | 'spin' | 'pulse' | 'bounce' | 'fade';
|
|
363
|
+
|
|
364
|
+
// Theme support
|
|
365
|
+
theme?: 'light' | 'dark' | 'auto';
|
|
366
|
+
|
|
367
|
+
// Responsive behavior
|
|
368
|
+
responsive?: boolean;
|
|
369
|
+
|
|
370
|
+
// Interaction states
|
|
371
|
+
loading?: boolean;
|
|
372
|
+
disabled?: boolean;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
const sizeMap = {
|
|
376
|
+
xs: 12,
|
|
377
|
+
sm: 16,
|
|
378
|
+
md: 24,
|
|
379
|
+
lg: 32,
|
|
380
|
+
xl: 48,
|
|
381
|
+
} as const;
|
|
382
|
+
|
|
383
|
+
const colorMap = {
|
|
384
|
+
primary: '#007bff',
|
|
385
|
+
secondary: '#6c757d',
|
|
386
|
+
success: '#28a745',
|
|
387
|
+
warning: '#ffc107',
|
|
388
|
+
danger: '#dc3545',
|
|
389
|
+
info: '#17a2b8',
|
|
390
|
+
} as const;
|
|
391
|
+
|
|
392
|
+
const ${componentName} = React.forwardRef<SVGSVGElement, ${componentName}Props>(
|
|
393
|
+
({
|
|
394
|
+
size = 'md',
|
|
395
|
+
variant,
|
|
396
|
+
animate = false,
|
|
397
|
+
theme = 'auto',
|
|
398
|
+
responsive = false,
|
|
399
|
+
loading = false,
|
|
400
|
+
disabled = false,
|
|
401
|
+
style,
|
|
402
|
+
className,
|
|
403
|
+
...props
|
|
404
|
+
}, ref) => {
|
|
405
|
+
|
|
406
|
+
// Calculate size
|
|
407
|
+
const dimensions = React.useMemo(() => {
|
|
408
|
+
if (typeof size === 'number') return { width: size, height: size };
|
|
409
|
+
if (typeof size === 'string' && !isNaN(Number(size))) return { width: Number(size), height: Number(size) };
|
|
410
|
+
const mappedSize = sizeMap[size as keyof typeof sizeMap] || sizeMap.md;
|
|
411
|
+
return { width: mappedSize, height: mappedSize };
|
|
412
|
+
}, [size]);
|
|
413
|
+
|
|
414
|
+
// Generate styles
|
|
415
|
+
const computedStyles = React.useMemo(() => {
|
|
416
|
+
const baseStyles: React.CSSProperties = {
|
|
417
|
+
display: 'inline-block',
|
|
418
|
+
verticalAlign: 'middle',
|
|
419
|
+
transition: 'all 0.2s ease-in-out',
|
|
420
|
+
};
|
|
421
|
+
|
|
422
|
+
// Apply color variant
|
|
423
|
+
if (variant) {
|
|
424
|
+
baseStyles.color = colorMap[variant];
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
// Apply theme
|
|
428
|
+
if (theme === 'dark') {
|
|
429
|
+
baseStyles.filter = 'invert(1)';
|
|
430
|
+
} else if (theme === 'auto') {
|
|
431
|
+
baseStyles.filter = 'var(--svger-theme-filter, none)';
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// Apply animation
|
|
435
|
+
if (animate) {
|
|
436
|
+
if (animate === true || animate === 'spin') {
|
|
437
|
+
baseStyles.animation = 'svger-spin 2s linear infinite';
|
|
438
|
+
} else if (animate === 'pulse') {
|
|
439
|
+
baseStyles.animation = 'svger-pulse 2s ease-in-out infinite';
|
|
440
|
+
} else if (animate === 'bounce') {
|
|
441
|
+
baseStyles.animation = 'svger-bounce 1s infinite';
|
|
442
|
+
} else if (animate === 'fade') {
|
|
443
|
+
baseStyles.animation = 'svger-fade 2s ease-in-out infinite alternate';
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// Apply loading state
|
|
448
|
+
if (loading) {
|
|
449
|
+
baseStyles.animation = 'svger-spin 1s linear infinite';
|
|
450
|
+
baseStyles.opacity = 0.7;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// Apply disabled state
|
|
454
|
+
if (disabled) {
|
|
455
|
+
baseStyles.opacity = 0.5;
|
|
456
|
+
baseStyles.pointerEvents = 'none';
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// Apply responsive behavior
|
|
460
|
+
if (responsive) {
|
|
461
|
+
baseStyles.width = '100%';
|
|
462
|
+
baseStyles.height = 'auto';
|
|
463
|
+
baseStyles.maxWidth = \`\${dimensions.width}px\`;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
return { ...baseStyles, ...style };
|
|
467
|
+
}, [variant, theme, animate, loading, disabled, responsive, dimensions, style]);
|
|
468
|
+
|
|
469
|
+
// Generate class names
|
|
470
|
+
const classNames = React.useMemo(() => {
|
|
471
|
+
const classes = ['svger-icon'];
|
|
472
|
+
|
|
473
|
+
if (typeof size === 'string' && sizeMap[size as keyof typeof sizeMap]) {
|
|
474
|
+
classes.push(\`svger-size-\${size}\`);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
if (variant) {
|
|
478
|
+
classes.push(\`svger-variant-\${variant}\`);
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
if (theme) {
|
|
482
|
+
classes.push(\`svger-theme-\${theme}\`);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
if (animate) {
|
|
486
|
+
const animationType = animate === true ? 'spin' : animate;
|
|
487
|
+
classes.push(\`svger-animate-\${animationType}\`);
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
if (responsive) {
|
|
491
|
+
classes.push('svger-responsive');
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
if (loading) {
|
|
495
|
+
classes.push('svger-loading');
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
if (disabled) {
|
|
499
|
+
classes.push('svger-disabled');
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
if (className) {
|
|
503
|
+
classes.push(className);
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
return classes.join(' ');
|
|
507
|
+
}, [size, variant, theme, animate, responsive, loading, disabled, className]);
|
|
508
|
+
|
|
509
|
+
return (
|
|
510
|
+
<svg
|
|
511
|
+
ref={ref}
|
|
512
|
+
viewBox="0 0 ${defaultWidth} ${defaultHeight}"
|
|
513
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
514
|
+
width={responsive ? '100%' : dimensions.width}
|
|
515
|
+
height={responsive ? 'auto' : dimensions.height}
|
|
516
|
+
fill={props.fill || "${defaultFill}"}
|
|
517
|
+
className={classNames}
|
|
518
|
+
style={computedStyles}
|
|
519
|
+
aria-hidden={props['aria-hidden'] || (disabled ? 'true' : undefined)}
|
|
520
|
+
aria-busy={loading ? 'true' : undefined}
|
|
521
|
+
{...props}
|
|
522
|
+
>
|
|
523
|
+
${svgContent}
|
|
524
|
+
</svg>
|
|
525
|
+
);
|
|
526
|
+
}
|
|
527
|
+
);
|
|
528
|
+
|
|
529
|
+
${componentName}.displayName = "${componentName}";
|
|
530
|
+
|
|
531
|
+
export default ${componentName};
|
|
532
532
|
`;
|
|
533
533
|
}
|
|
534
534
|
}
|