svger-cli 2.0.1 → 2.0.2
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/dist/cli.js +0 -0
- package/dist/core/error-handler.d.ts +63 -0
- package/dist/core/error-handler.js +224 -0
- package/dist/core/framework-templates.d.ts +17 -0
- package/{src/core/framework-templates.ts → dist/core/framework-templates.js} +100 -137
- package/dist/core/logger.d.ts +22 -0
- package/dist/core/logger.js +85 -0
- package/dist/core/performance-engine.d.ts +67 -0
- package/dist/core/performance-engine.js +251 -0
- package/dist/core/plugin-manager.d.ts +56 -0
- package/dist/core/plugin-manager.js +189 -0
- package/dist/core/style-compiler.d.ts +88 -0
- package/dist/core/style-compiler.js +466 -0
- package/dist/core/template-manager.d.ts +64 -0
- package/{src/core/template-manager.ts → dist/core/template-manager.js} +172 -255
- package/dist/index.d.ts +151 -0
- package/{src/index.ts → dist/index.js} +30 -108
- package/dist/processors/svg-processor.d.ts +67 -0
- package/dist/processors/svg-processor.js +225 -0
- package/dist/services/config.d.ts +55 -0
- package/dist/services/config.js +209 -0
- package/dist/services/file-watcher.d.ts +54 -0
- package/dist/services/file-watcher.js +180 -0
- package/dist/services/svg-service.d.ts +81 -0
- package/dist/services/svg-service.js +383 -0
- package/dist/types/index.d.ts +140 -0
- package/dist/types/index.js +4 -0
- package/dist/utils/native.d.ts +74 -0
- package/dist/utils/native.js +305 -0
- package/package.json +9 -10
- package/.svgconfig.json +0 -3
- package/CODE_OF_CONDUCT.md +0 -79
- package/CONTRIBUTING.md +0 -146
- package/TESTING.md +0 -143
- package/cli-framework.test.js +0 -16
- package/cli-test-angular/Arrowbenddownleft.component.ts +0 -27
- package/cli-test-angular/Vite.component.ts +0 -27
- package/cli-test-angular/index.ts +0 -25
- package/cli-test-output/Arrowbenddownleft.vue +0 -33
- package/cli-test-output/Vite.vue +0 -33
- package/cli-test-output/index.ts +0 -25
- package/cli-test-react/Arrowbenddownleft.tsx +0 -39
- package/cli-test-react/Vite.tsx +0 -39
- package/cli-test-react/index.ts +0 -25
- package/cli-test-svelte/Arrowbenddownleft.svelte +0 -22
- package/cli-test-svelte/Vite.svelte +0 -22
- package/cli-test-svelte/index.ts +0 -25
- package/docs/ADR-SVG-INTRGRATION-METHODS-001.adr.md +0 -157
- package/docs/ADR-SVG-INTRGRATION-METHODS-002.adr.md +0 -550
- package/docs/FRAMEWORK-GUIDE.md +0 -768
- package/docs/IMPLEMENTATION-SUMMARY.md +0 -376
- package/docs/TDR-SVG-INTRGRATION-METHODS-001.tdr.md +0 -115
- package/frameworks.test.js +0 -170
- package/my-svgs/ArrowBendDownLeft.svg +0 -6
- package/my-svgs/vite.svg +0 -1
- package/src/builder.ts +0 -104
- package/src/clean.ts +0 -21
- package/src/cli.ts +0 -221
- package/src/config.ts +0 -81
- package/src/core/error-handler.ts +0 -303
- package/src/core/logger.ts +0 -104
- package/src/core/performance-engine.ts +0 -327
- package/src/core/plugin-manager.ts +0 -228
- package/src/core/style-compiler.ts +0 -605
- package/src/lock.ts +0 -74
- package/src/processors/svg-processor.ts +0 -288
- package/src/services/config.ts +0 -241
- package/src/services/file-watcher.ts +0 -218
- package/src/services/svg-service.ts +0 -468
- package/src/templates/ComponentTemplate.ts +0 -57
- package/src/types/index.ts +0 -169
- package/src/utils/native.ts +0 -352
- package/src/watch.ts +0 -88
- package/test-output-mulit/TestIcon-angular-module.component.ts +0 -26
- package/test-output-mulit/TestIcon-angular-standalone.component.ts +0 -27
- package/test-output-mulit/TestIcon-lit.ts +0 -35
- package/test-output-mulit/TestIcon-preact.tsx +0 -38
- package/test-output-mulit/TestIcon-react.tsx +0 -35
- package/test-output-mulit/TestIcon-solid.tsx +0 -27
- package/test-output-mulit/TestIcon-svelte.svelte +0 -22
- package/test-output-mulit/TestIcon-vanilla.ts +0 -37
- package/test-output-mulit/TestIcon-vue-composition.vue +0 -33
- package/test-output-mulit/TestIcon-vue-options.vue +0 -31
- package/tsconfig.json +0 -18
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Comprehensive styling system for SVG components
|
|
3
|
+
* Supports all CSS properties, responsive design, theming, and dynamic styling
|
|
4
|
+
*/
|
|
5
|
+
export interface StyleTheme {
|
|
6
|
+
name: string;
|
|
7
|
+
colors: Record<string, string>;
|
|
8
|
+
sizes: Record<string, number | string>;
|
|
9
|
+
spacing: Record<string, number | string>;
|
|
10
|
+
breakpoints?: Record<string, string>;
|
|
11
|
+
animations?: Record<string, string>;
|
|
12
|
+
}
|
|
13
|
+
export interface ResponsiveValue<T> {
|
|
14
|
+
base: T;
|
|
15
|
+
sm?: T;
|
|
16
|
+
md?: T;
|
|
17
|
+
lg?: T;
|
|
18
|
+
xl?: T;
|
|
19
|
+
[key: string]: T | undefined;
|
|
20
|
+
}
|
|
21
|
+
export interface SVGStyleOptions {
|
|
22
|
+
fill?: string | ResponsiveValue<string>;
|
|
23
|
+
stroke?: string | ResponsiveValue<string>;
|
|
24
|
+
strokeWidth?: number | string | ResponsiveValue<number | string>;
|
|
25
|
+
width?: number | string | ResponsiveValue<number | string>;
|
|
26
|
+
height?: number | string | ResponsiveValue<number | string>;
|
|
27
|
+
size?: number | string | ResponsiveValue<number | string>;
|
|
28
|
+
transform?: string;
|
|
29
|
+
rotate?: number | string;
|
|
30
|
+
scale?: number | string;
|
|
31
|
+
translateX?: number | string;
|
|
32
|
+
translateY?: number | string;
|
|
33
|
+
opacity?: number | ResponsiveValue<number>;
|
|
34
|
+
filter?: string;
|
|
35
|
+
clipPath?: string;
|
|
36
|
+
mask?: string;
|
|
37
|
+
animation?: string;
|
|
38
|
+
transition?: string;
|
|
39
|
+
hover?: Partial<SVGStyleOptions>;
|
|
40
|
+
focus?: Partial<SVGStyleOptions>;
|
|
41
|
+
active?: Partial<SVGStyleOptions>;
|
|
42
|
+
disabled?: Partial<SVGStyleOptions>;
|
|
43
|
+
theme?: string | StyleTheme;
|
|
44
|
+
responsive?: boolean;
|
|
45
|
+
css?: Record<string, string | number>;
|
|
46
|
+
className?: string;
|
|
47
|
+
'aria-label'?: string;
|
|
48
|
+
'aria-hidden'?: boolean;
|
|
49
|
+
title?: string;
|
|
50
|
+
role?: string;
|
|
51
|
+
}
|
|
52
|
+
export interface CompiledStyles {
|
|
53
|
+
inline: Record<string, string | number>;
|
|
54
|
+
classes: string[];
|
|
55
|
+
cssRules: string[];
|
|
56
|
+
mediaQueries: string[];
|
|
57
|
+
}
|
|
58
|
+
export declare class SVGStyleCompiler {
|
|
59
|
+
private static instance;
|
|
60
|
+
private themes;
|
|
61
|
+
private globalCSS;
|
|
62
|
+
private constructor();
|
|
63
|
+
static getInstance(): SVGStyleCompiler;
|
|
64
|
+
/**
|
|
65
|
+
* Compile SVG styling options into CSS
|
|
66
|
+
*/
|
|
67
|
+
compileStyles(options: SVGStyleOptions, componentName: string): CompiledStyles;
|
|
68
|
+
/**
|
|
69
|
+
* Register a custom theme
|
|
70
|
+
*/
|
|
71
|
+
registerTheme(theme: StyleTheme): void;
|
|
72
|
+
/**
|
|
73
|
+
* Generate CSS for a component with all styling options
|
|
74
|
+
*/
|
|
75
|
+
generateComponentCSS(componentName: string, options: SVGStyleOptions): string;
|
|
76
|
+
/**
|
|
77
|
+
* Generate enhanced React component template with full styling support
|
|
78
|
+
*/
|
|
79
|
+
generateStyledComponent(componentName: string, svgContent: string, options?: SVGStyleOptions): string;
|
|
80
|
+
private loadDefaultThemes;
|
|
81
|
+
private resolveTheme;
|
|
82
|
+
private compileBaseStyles;
|
|
83
|
+
private compileResponsiveStyles;
|
|
84
|
+
private compileInteractionStates;
|
|
85
|
+
private isResponsiveValue;
|
|
86
|
+
private camelToKebab;
|
|
87
|
+
}
|
|
88
|
+
export declare const styleCompiler: SVGStyleCompiler;
|
|
@@ -0,0 +1,466 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Comprehensive styling system for SVG components
|
|
3
|
+
* Supports all CSS properties, responsive design, theming, and dynamic styling
|
|
4
|
+
*/
|
|
5
|
+
export class SVGStyleCompiler {
|
|
6
|
+
static instance;
|
|
7
|
+
themes = new Map();
|
|
8
|
+
globalCSS = [];
|
|
9
|
+
constructor() {
|
|
10
|
+
this.loadDefaultThemes();
|
|
11
|
+
}
|
|
12
|
+
static getInstance() {
|
|
13
|
+
if (!SVGStyleCompiler.instance) {
|
|
14
|
+
SVGStyleCompiler.instance = new SVGStyleCompiler();
|
|
15
|
+
}
|
|
16
|
+
return SVGStyleCompiler.instance;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Compile SVG styling options into CSS
|
|
20
|
+
*/
|
|
21
|
+
compileStyles(options, componentName) {
|
|
22
|
+
const compiled = {
|
|
23
|
+
inline: {},
|
|
24
|
+
classes: [],
|
|
25
|
+
cssRules: [],
|
|
26
|
+
mediaQueries: []
|
|
27
|
+
};
|
|
28
|
+
// Get theme if specified
|
|
29
|
+
const theme = this.resolveTheme(options.theme);
|
|
30
|
+
// Compile base styles
|
|
31
|
+
this.compileBaseStyles(options, compiled, theme);
|
|
32
|
+
// Compile responsive styles
|
|
33
|
+
if (options.responsive) {
|
|
34
|
+
this.compileResponsiveStyles(options, compiled, theme, componentName);
|
|
35
|
+
}
|
|
36
|
+
// Compile interaction states
|
|
37
|
+
this.compileInteractionStates(options, compiled, componentName);
|
|
38
|
+
// Add custom CSS
|
|
39
|
+
if (options.css) {
|
|
40
|
+
Object.assign(compiled.inline, options.css);
|
|
41
|
+
}
|
|
42
|
+
// Add class names
|
|
43
|
+
if (options.className) {
|
|
44
|
+
compiled.classes.push(options.className);
|
|
45
|
+
}
|
|
46
|
+
return compiled;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Register a custom theme
|
|
50
|
+
*/
|
|
51
|
+
registerTheme(theme) {
|
|
52
|
+
this.themes.set(theme.name, theme);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Generate CSS for a component with all styling options
|
|
56
|
+
*/
|
|
57
|
+
generateComponentCSS(componentName, options) {
|
|
58
|
+
const compiled = this.compileStyles(options, componentName);
|
|
59
|
+
let css = '';
|
|
60
|
+
// Add CSS rules
|
|
61
|
+
if (compiled.cssRules.length > 0) {
|
|
62
|
+
css += compiled.cssRules.join('\n') + '\n';
|
|
63
|
+
}
|
|
64
|
+
// Add media queries
|
|
65
|
+
if (compiled.mediaQueries.length > 0) {
|
|
66
|
+
css += compiled.mediaQueries.join('\n') + '\n';
|
|
67
|
+
}
|
|
68
|
+
return css;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Generate enhanced React component template with full styling support
|
|
72
|
+
*/
|
|
73
|
+
generateStyledComponent(componentName, svgContent, options = {}) {
|
|
74
|
+
const compiled = this.compileStyles(options, componentName);
|
|
75
|
+
const hasCustomStyles = compiled.cssRules.length > 0 || compiled.mediaQueries.length > 0;
|
|
76
|
+
const imports = hasCustomStyles
|
|
77
|
+
? `import React from 'react';\nimport type { SVGProps } from "react";`
|
|
78
|
+
: `import type { SVGProps } from "react";`;
|
|
79
|
+
const styledCSS = hasCustomStyles ? `
|
|
80
|
+
const ${componentName}Styles = \`
|
|
81
|
+
${compiled.cssRules.join('\n')}
|
|
82
|
+
${compiled.mediaQueries.join('\n')}
|
|
83
|
+
\`;
|
|
84
|
+
|
|
85
|
+
// Inject styles
|
|
86
|
+
if (typeof document !== 'undefined') {
|
|
87
|
+
const styleId = '${componentName.toLowerCase()}-styles';
|
|
88
|
+
if (!document.getElementById(styleId)) {
|
|
89
|
+
const style = document.createElement('style');
|
|
90
|
+
style.id = styleId;
|
|
91
|
+
style.textContent = ${componentName}Styles;
|
|
92
|
+
document.head.appendChild(style);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
` : '';
|
|
96
|
+
const inlineStyleObject = Object.keys(compiled.inline).length > 0
|
|
97
|
+
? `const defaultStyles = ${JSON.stringify(compiled.inline, null, 2)};`
|
|
98
|
+
: '';
|
|
99
|
+
const classNames = compiled.classes.length > 0
|
|
100
|
+
? `'${compiled.classes.join(' ')} ' + (props.className || '')`
|
|
101
|
+
: 'props.className';
|
|
102
|
+
return `${imports}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* ${componentName} SVG Component with Enhanced Styling
|
|
106
|
+
* Generated by svger-cli with comprehensive styling support
|
|
107
|
+
*/
|
|
108
|
+
|
|
109
|
+
${styledCSS}${inlineStyleObject}
|
|
110
|
+
|
|
111
|
+
export interface ${componentName}Props extends SVGProps<SVGSVGElement> {
|
|
112
|
+
// Enhanced styling props
|
|
113
|
+
size?: number | string;
|
|
114
|
+
variant?: 'primary' | 'secondary' | 'accent' | 'muted';
|
|
115
|
+
responsive?: boolean;
|
|
116
|
+
|
|
117
|
+
// Animation props
|
|
118
|
+
animate?: boolean;
|
|
119
|
+
animationType?: 'spin' | 'pulse' | 'bounce' | 'fade';
|
|
120
|
+
|
|
121
|
+
// Theme props
|
|
122
|
+
theme?: 'light' | 'dark' | 'auto';
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const ${componentName} = React.forwardRef<SVGSVGElement, ${componentName}Props>(
|
|
126
|
+
({
|
|
127
|
+
size,
|
|
128
|
+
variant = 'primary',
|
|
129
|
+
responsive = false,
|
|
130
|
+
animate = false,
|
|
131
|
+
animationType = 'spin',
|
|
132
|
+
theme = 'auto',
|
|
133
|
+
style,
|
|
134
|
+
className,
|
|
135
|
+
...props
|
|
136
|
+
}, ref) => {
|
|
137
|
+
|
|
138
|
+
// Calculate dimensions
|
|
139
|
+
const dimensions = React.useMemo(() => {
|
|
140
|
+
if (size) {
|
|
141
|
+
return { width: size, height: size };
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
width: props.width || ${options.width || 24},
|
|
145
|
+
height: props.height || ${options.height || 24}
|
|
146
|
+
};
|
|
147
|
+
}, [size, props.width, props.height]);
|
|
148
|
+
|
|
149
|
+
// Combine styles
|
|
150
|
+
const combinedStyles = React.useMemo(() => {
|
|
151
|
+
const baseStyles = ${inlineStyleObject ? 'defaultStyles' : '{}'};
|
|
152
|
+
const variantStyles = getVariantStyles(variant);
|
|
153
|
+
const animationStyles = animate ? getAnimationStyles(animationType) : {};
|
|
154
|
+
const themeStyles = getThemeStyles(theme);
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
...baseStyles,
|
|
158
|
+
...variantStyles,
|
|
159
|
+
...animationStyles,
|
|
160
|
+
...themeStyles,
|
|
161
|
+
...style
|
|
162
|
+
};
|
|
163
|
+
}, [variant, animate, animationType, theme, style]);
|
|
164
|
+
|
|
165
|
+
// Combine class names
|
|
166
|
+
const combinedClassName = React.useMemo(() => {
|
|
167
|
+
const classes = [];
|
|
168
|
+
${compiled.classes.length > 0 ? `classes.push('${compiled.classes.join(' ')}');` : ''}
|
|
169
|
+
if (responsive) classes.push(\`\${componentName.toLowerCase()}-responsive\`);
|
|
170
|
+
if (animate) classes.push(\`\${componentName.toLowerCase()}-animate-\${animationType}\`);
|
|
171
|
+
classes.push(\`\${componentName.toLowerCase()}-variant-\${variant}\`);
|
|
172
|
+
classes.push(\`\${componentName.toLowerCase()}-theme-\${theme}\`);
|
|
173
|
+
if (className) classes.push(className);
|
|
174
|
+
return classes.join(' ');
|
|
175
|
+
}, [responsive, animate, animationType, variant, theme, className]);
|
|
176
|
+
|
|
177
|
+
return (
|
|
178
|
+
<svg
|
|
179
|
+
ref={ref}
|
|
180
|
+
viewBox="0 0 24 24"
|
|
181
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
182
|
+
width={dimensions.width}
|
|
183
|
+
height={dimensions.height}
|
|
184
|
+
fill={props.fill || "${options.fill || 'currentColor'}"}
|
|
185
|
+
className={combinedClassName}
|
|
186
|
+
style={combinedStyles}
|
|
187
|
+
aria-hidden={props['aria-hidden']}
|
|
188
|
+
aria-label={props['aria-label']}
|
|
189
|
+
role={props.role || 'img'}
|
|
190
|
+
{...props}
|
|
191
|
+
>
|
|
192
|
+
${options.title ? `<title>${options.title}</title>` : ''}
|
|
193
|
+
${svgContent}
|
|
194
|
+
</svg>
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
// Utility functions for styling
|
|
200
|
+
function getVariantStyles(variant: string): React.CSSProperties {
|
|
201
|
+
const variants = {
|
|
202
|
+
primary: { color: 'var(--color-primary, #007bff)' },
|
|
203
|
+
secondary: { color: 'var(--color-secondary, #6c757d)' },
|
|
204
|
+
accent: { color: 'var(--color-accent, #28a745)' },
|
|
205
|
+
muted: { color: 'var(--color-muted, #6c757d)', opacity: 0.7 }
|
|
206
|
+
};
|
|
207
|
+
return variants[variant as keyof typeof variants] || variants.primary;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function getAnimationStyles(animationType: string): React.CSSProperties {
|
|
211
|
+
const animations = {
|
|
212
|
+
spin: { animation: 'svger-spin 1s linear infinite' },
|
|
213
|
+
pulse: { animation: 'svger-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite' },
|
|
214
|
+
bounce: { animation: 'svger-bounce 1s infinite' },
|
|
215
|
+
fade: { animation: 'svger-fade 2s ease-in-out infinite alternate' }
|
|
216
|
+
};
|
|
217
|
+
return animations[animationType as keyof typeof animations] || {};
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function getThemeStyles(theme: string): React.CSSProperties {
|
|
221
|
+
if (theme === 'dark') {
|
|
222
|
+
return { filter: 'invert(1) hue-rotate(180deg)' };
|
|
223
|
+
}
|
|
224
|
+
if (theme === 'auto') {
|
|
225
|
+
return { filter: 'var(--svger-theme-filter, none)' };
|
|
226
|
+
}
|
|
227
|
+
return {};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
${componentName}.displayName = "${componentName}";
|
|
231
|
+
|
|
232
|
+
export default ${componentName};
|
|
233
|
+
|
|
234
|
+
// CSS Animations (injected globally)
|
|
235
|
+
if (typeof document !== 'undefined') {
|
|
236
|
+
const animationCSS = \`
|
|
237
|
+
@keyframes svger-spin {
|
|
238
|
+
from { transform: rotate(0deg); }
|
|
239
|
+
to { transform: rotate(360deg); }
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
@keyframes svger-pulse {
|
|
243
|
+
0%, 100% { opacity: 1; }
|
|
244
|
+
50% { opacity: 0.5; }
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
@keyframes svger-bounce {
|
|
248
|
+
0%, 20%, 53%, 80%, 100% { transform: translate3d(0,0,0); }
|
|
249
|
+
40%, 43% { transform: translate3d(0,-30px,0); }
|
|
250
|
+
70% { transform: translate3d(0,-15px,0); }
|
|
251
|
+
90% { transform: translate3d(0,-4px,0); }
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
@keyframes svger-fade {
|
|
255
|
+
from { opacity: 0.4; }
|
|
256
|
+
to { opacity: 1; }
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/* CSS Custom Properties for theming */
|
|
260
|
+
:root {
|
|
261
|
+
--color-primary: #007bff;
|
|
262
|
+
--color-secondary: #6c757d;
|
|
263
|
+
--color-accent: #28a745;
|
|
264
|
+
--color-muted: #6c757d;
|
|
265
|
+
--svger-theme-filter: none;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
@media (prefers-color-scheme: dark) {
|
|
269
|
+
:root {
|
|
270
|
+
--svger-theme-filter: invert(1) hue-rotate(180deg);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
\`;
|
|
274
|
+
|
|
275
|
+
const globalStyleId = 'svger-global-animations';
|
|
276
|
+
if (!document.getElementById(globalStyleId)) {
|
|
277
|
+
const style = document.createElement('style');
|
|
278
|
+
style.id = globalStyleId;
|
|
279
|
+
style.textContent = animationCSS;
|
|
280
|
+
document.head.appendChild(style);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
`;
|
|
284
|
+
}
|
|
285
|
+
// Private helper methods
|
|
286
|
+
loadDefaultThemes() {
|
|
287
|
+
// Light theme
|
|
288
|
+
this.registerTheme({
|
|
289
|
+
name: 'light',
|
|
290
|
+
colors: {
|
|
291
|
+
primary: '#007bff',
|
|
292
|
+
secondary: '#6c757d',
|
|
293
|
+
success: '#28a745',
|
|
294
|
+
warning: '#ffc107',
|
|
295
|
+
danger: '#dc3545',
|
|
296
|
+
info: '#17a2b8',
|
|
297
|
+
light: '#f8f9fa',
|
|
298
|
+
dark: '#343a40'
|
|
299
|
+
},
|
|
300
|
+
sizes: {
|
|
301
|
+
xs: 12,
|
|
302
|
+
sm: 16,
|
|
303
|
+
md: 24,
|
|
304
|
+
lg: 32,
|
|
305
|
+
xl: 48
|
|
306
|
+
},
|
|
307
|
+
spacing: {
|
|
308
|
+
1: '0.25rem',
|
|
309
|
+
2: '0.5rem',
|
|
310
|
+
3: '0.75rem',
|
|
311
|
+
4: '1rem',
|
|
312
|
+
5: '1.5rem'
|
|
313
|
+
},
|
|
314
|
+
breakpoints: {
|
|
315
|
+
sm: '576px',
|
|
316
|
+
md: '768px',
|
|
317
|
+
lg: '992px',
|
|
318
|
+
xl: '1200px'
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
// Dark theme
|
|
322
|
+
this.registerTheme({
|
|
323
|
+
name: 'dark',
|
|
324
|
+
colors: {
|
|
325
|
+
primary: '#0d6efd',
|
|
326
|
+
secondary: '#6c757d',
|
|
327
|
+
success: '#198754',
|
|
328
|
+
warning: '#ffc107',
|
|
329
|
+
danger: '#dc3545',
|
|
330
|
+
info: '#0dcaf0',
|
|
331
|
+
light: '#212529',
|
|
332
|
+
dark: '#f8f9fa'
|
|
333
|
+
},
|
|
334
|
+
sizes: {
|
|
335
|
+
xs: 12,
|
|
336
|
+
sm: 16,
|
|
337
|
+
md: 24,
|
|
338
|
+
lg: 32,
|
|
339
|
+
xl: 48
|
|
340
|
+
},
|
|
341
|
+
spacing: {
|
|
342
|
+
1: '0.25rem',
|
|
343
|
+
2: '0.5rem',
|
|
344
|
+
3: '0.75rem',
|
|
345
|
+
4: '1rem',
|
|
346
|
+
5: '1.5rem'
|
|
347
|
+
},
|
|
348
|
+
breakpoints: {
|
|
349
|
+
sm: '576px',
|
|
350
|
+
md: '768px',
|
|
351
|
+
lg: '992px',
|
|
352
|
+
xl: '1200px'
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
resolveTheme(theme) {
|
|
357
|
+
if (!theme)
|
|
358
|
+
return null;
|
|
359
|
+
if (typeof theme === 'string') {
|
|
360
|
+
return this.themes.get(theme) || null;
|
|
361
|
+
}
|
|
362
|
+
return theme;
|
|
363
|
+
}
|
|
364
|
+
compileBaseStyles(options, compiled, theme) {
|
|
365
|
+
// Handle basic properties
|
|
366
|
+
const styleMap = {
|
|
367
|
+
fill: 'fill',
|
|
368
|
+
stroke: 'stroke',
|
|
369
|
+
strokeWidth: 'strokeWidth',
|
|
370
|
+
opacity: 'opacity',
|
|
371
|
+
transform: 'transform',
|
|
372
|
+
filter: 'filter',
|
|
373
|
+
clipPath: 'clipPath',
|
|
374
|
+
mask: 'mask',
|
|
375
|
+
animation: 'animation',
|
|
376
|
+
transition: 'transition'
|
|
377
|
+
};
|
|
378
|
+
for (const [cssProp, optionKey] of Object.entries(styleMap)) {
|
|
379
|
+
const value = options[optionKey];
|
|
380
|
+
if (value !== undefined) {
|
|
381
|
+
if (this.isResponsiveValue(value)) {
|
|
382
|
+
compiled.inline[cssProp] = value.base;
|
|
383
|
+
}
|
|
384
|
+
else {
|
|
385
|
+
compiled.inline[cssProp] = value;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
// Handle size shorthand
|
|
390
|
+
if (options.size !== undefined) {
|
|
391
|
+
const sizeValue = this.isResponsiveValue(options.size)
|
|
392
|
+
? options.size.base
|
|
393
|
+
: options.size;
|
|
394
|
+
compiled.inline.width = sizeValue;
|
|
395
|
+
compiled.inline.height = sizeValue;
|
|
396
|
+
}
|
|
397
|
+
// Handle transform shortcuts
|
|
398
|
+
const transforms = [];
|
|
399
|
+
if (options.rotate)
|
|
400
|
+
transforms.push(`rotate(${options.rotate}deg)`);
|
|
401
|
+
if (options.scale)
|
|
402
|
+
transforms.push(`scale(${options.scale})`);
|
|
403
|
+
if (options.translateX)
|
|
404
|
+
transforms.push(`translateX(${options.translateX})`);
|
|
405
|
+
if (options.translateY)
|
|
406
|
+
transforms.push(`translateY(${options.translateY})`);
|
|
407
|
+
if (transforms.length > 0) {
|
|
408
|
+
const existingTransform = compiled.inline.transform;
|
|
409
|
+
compiled.inline.transform = existingTransform
|
|
410
|
+
? `${existingTransform} ${transforms.join(' ')}`
|
|
411
|
+
: transforms.join(' ');
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
compileResponsiveStyles(options, compiled, theme, componentName) {
|
|
415
|
+
const breakpoints = theme?.breakpoints || {
|
|
416
|
+
sm: '576px',
|
|
417
|
+
md: '768px',
|
|
418
|
+
lg: '992px',
|
|
419
|
+
xl: '1200px'
|
|
420
|
+
};
|
|
421
|
+
for (const [prop, value] of Object.entries(options)) {
|
|
422
|
+
if (this.isResponsiveValue(value)) {
|
|
423
|
+
const responsiveValue = value;
|
|
424
|
+
for (const [breakpoint, breakpointValue] of Object.entries(responsiveValue)) {
|
|
425
|
+
if (breakpoint === 'base')
|
|
426
|
+
continue;
|
|
427
|
+
const mediaQuery = breakpoints[breakpoint];
|
|
428
|
+
if (mediaQuery && breakpointValue !== undefined) {
|
|
429
|
+
const rule = `@media (min-width: ${mediaQuery}) {
|
|
430
|
+
.${componentName.toLowerCase()}-responsive {
|
|
431
|
+
${this.camelToKebab(prop)}: ${breakpointValue};
|
|
432
|
+
}
|
|
433
|
+
}`;
|
|
434
|
+
compiled.mediaQueries.push(rule);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
compileInteractionStates(options, compiled, componentName) {
|
|
441
|
+
const states = ['hover', 'focus', 'active', 'disabled'];
|
|
442
|
+
for (const state of states) {
|
|
443
|
+
const stateStyles = options[state];
|
|
444
|
+
if (stateStyles) {
|
|
445
|
+
const selector = state === 'disabled'
|
|
446
|
+
? `.${componentName.toLowerCase()}[disabled], .${componentName.toLowerCase()}[aria-disabled="true"]`
|
|
447
|
+
: `.${componentName.toLowerCase()}:${state}`;
|
|
448
|
+
const rules = [];
|
|
449
|
+
for (const [prop, value] of Object.entries(stateStyles)) {
|
|
450
|
+
rules.push(` ${this.camelToKebab(prop)}: ${value};`);
|
|
451
|
+
}
|
|
452
|
+
if (rules.length > 0) {
|
|
453
|
+
compiled.cssRules.push(`${selector} {\n${rules.join('\n')}\n}`);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
isResponsiveValue(value) {
|
|
459
|
+
return value && typeof value === 'object' && 'base' in value;
|
|
460
|
+
}
|
|
461
|
+
camelToKebab(str) {
|
|
462
|
+
return str.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, '$1-$2').toLowerCase();
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
// Export singleton instance
|
|
466
|
+
export const styleCompiler = SVGStyleCompiler.getInstance();
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Template, ComponentGenerationOptions } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Template management system for customizable component generation
|
|
4
|
+
*/
|
|
5
|
+
export declare class TemplateManager {
|
|
6
|
+
private static instance;
|
|
7
|
+
private templates;
|
|
8
|
+
private defaultTemplate;
|
|
9
|
+
private constructor();
|
|
10
|
+
static getInstance(): TemplateManager;
|
|
11
|
+
/**
|
|
12
|
+
* Load built-in templates
|
|
13
|
+
*/
|
|
14
|
+
private loadBuiltinTemplates;
|
|
15
|
+
/**
|
|
16
|
+
* Register a new template
|
|
17
|
+
*/
|
|
18
|
+
registerTemplate(template: Template): void;
|
|
19
|
+
/**
|
|
20
|
+
* Generate component using specified template
|
|
21
|
+
*/
|
|
22
|
+
generateComponent(templateName: string, options: ComponentGenerationOptions): string;
|
|
23
|
+
/**
|
|
24
|
+
* Load custom template from file
|
|
25
|
+
*/
|
|
26
|
+
loadCustomTemplate(templatePath: string): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Get list of available templates
|
|
29
|
+
*/
|
|
30
|
+
getAvailableTemplates(): string[];
|
|
31
|
+
/**
|
|
32
|
+
* Set default template
|
|
33
|
+
*/
|
|
34
|
+
setDefaultTemplate(templateName: string): void;
|
|
35
|
+
/**
|
|
36
|
+
* Standard React Functional Component
|
|
37
|
+
*/
|
|
38
|
+
private generateReactFunctional;
|
|
39
|
+
/**
|
|
40
|
+
* React Functional Component with forwardRef
|
|
41
|
+
*/
|
|
42
|
+
private generateReactForwardRef;
|
|
43
|
+
/**
|
|
44
|
+
* React Class Component (legacy)
|
|
45
|
+
*/
|
|
46
|
+
private generateReactClass;
|
|
47
|
+
/**
|
|
48
|
+
* Styled Components Template
|
|
49
|
+
*/
|
|
50
|
+
private generateStyledComponents;
|
|
51
|
+
/**
|
|
52
|
+
* TypeScript Native (no React dependencies)
|
|
53
|
+
*/
|
|
54
|
+
private generateTypeScriptNative;
|
|
55
|
+
/**
|
|
56
|
+
* Process string template with variable substitution
|
|
57
|
+
*/
|
|
58
|
+
private processStringTemplate;
|
|
59
|
+
/**
|
|
60
|
+
* Enhanced Styled Template with comprehensive styling support
|
|
61
|
+
*/
|
|
62
|
+
private generateEnhancedStyled;
|
|
63
|
+
}
|
|
64
|
+
export declare const templateManager: TemplateManager;
|