@rakeyshgidwani/roger-ui-bank-theme-stan-design 0.1.3 → 0.1.5
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/CHANGELOG.md +1 -1
- package/dist/index.d.ts +131 -131
- package/dist/index.esm.js +148 -148
- package/dist/index.js +148 -148
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/src/components/ui/accessibility-demo.tsx +271 -0
- package/src/components/ui/advanced-component-architecture-demo.tsx +916 -0
- package/src/components/ui/advanced-transition-system-demo.tsx +670 -0
- package/src/components/ui/advanced-transition-system.tsx +395 -0
- package/src/components/ui/animation/animated-container.tsx +166 -0
- package/src/components/ui/animation/index.ts +19 -0
- package/src/components/ui/animation/staggered-container.tsx +68 -0
- package/src/components/ui/animation-demo.tsx +250 -0
- package/src/components/ui/badge.tsx +33 -0
- package/src/components/ui/battery-conscious-animation-demo.tsx +568 -0
- package/src/components/ui/border-radius-shadow-demo.tsx +187 -0
- package/src/components/ui/button.tsx +36 -0
- package/src/components/ui/card.tsx +207 -0
- package/src/components/ui/checkbox.tsx +30 -0
- package/src/components/ui/color-preview.tsx +411 -0
- package/src/components/ui/data-display/chart.tsx +653 -0
- package/src/components/ui/data-display/data-grid-simple.tsx +76 -0
- package/src/components/ui/data-display/data-grid.tsx +680 -0
- package/src/components/ui/data-display/list.tsx +456 -0
- package/src/components/ui/data-display/table.tsx +482 -0
- package/src/components/ui/data-display/timeline.tsx +441 -0
- package/src/components/ui/data-display/tree.tsx +602 -0
- package/src/components/ui/data-display/types.ts +536 -0
- package/src/components/ui/enterprise-mobile-experience-demo.tsx +749 -0
- package/src/components/ui/enterprise-mobile-experience.tsx +464 -0
- package/src/components/ui/feedback/alert.tsx +157 -0
- package/src/components/ui/feedback/progress.tsx +292 -0
- package/src/components/ui/feedback/skeleton.tsx +185 -0
- package/src/components/ui/feedback/toast.tsx +280 -0
- package/src/components/ui/feedback/types.ts +125 -0
- package/src/components/ui/font-preview.tsx +288 -0
- package/src/components/ui/form-demo.tsx +553 -0
- package/src/components/ui/hardware-acceleration-demo.tsx +547 -0
- package/src/components/ui/input.tsx +35 -0
- package/src/components/ui/label.tsx +16 -0
- package/src/components/ui/layout-demo.tsx +367 -0
- package/src/components/ui/layouts/adaptive-layout.tsx +139 -0
- package/src/components/ui/layouts/desktop-layout.tsx +224 -0
- package/src/components/ui/layouts/index.ts +10 -0
- package/src/components/ui/layouts/mobile-layout.tsx +162 -0
- package/src/components/ui/layouts/tablet-layout.tsx +197 -0
- package/src/components/ui/mobile-form-validation.tsx +451 -0
- package/src/components/ui/mobile-input-demo.tsx +201 -0
- package/src/components/ui/mobile-input.tsx +281 -0
- package/src/components/ui/mobile-skeleton-loading-demo.tsx +638 -0
- package/src/components/ui/navigation/breadcrumb.tsx +158 -0
- package/src/components/ui/navigation/index.ts +36 -0
- package/src/components/ui/navigation/menu.tsx +374 -0
- package/src/components/ui/navigation/navigation-demo.tsx +324 -0
- package/src/components/ui/navigation/pagination.tsx +272 -0
- package/src/components/ui/navigation/sidebar.tsx +383 -0
- package/src/components/ui/navigation/stepper.tsx +303 -0
- package/src/components/ui/navigation/tabs.tsx +205 -0
- package/src/components/ui/navigation/types.ts +299 -0
- package/src/components/ui/overlay/backdrop.tsx +81 -0
- package/src/components/ui/overlay/focus-manager.tsx +143 -0
- package/src/components/ui/overlay/index.ts +36 -0
- package/src/components/ui/overlay/modal.tsx +270 -0
- package/src/components/ui/overlay/overlay-manager.tsx +110 -0
- package/src/components/ui/overlay/popover.tsx +462 -0
- package/src/components/ui/overlay/portal.tsx +79 -0
- package/src/components/ui/overlay/tooltip.tsx +303 -0
- package/src/components/ui/overlay/types.ts +196 -0
- package/src/components/ui/performance-demo.tsx +596 -0
- package/src/components/ui/semantic-input-system-demo.tsx +502 -0
- package/src/components/ui/semantic-input-system-demo.tsx.disabled +873 -0
- package/src/components/ui/tablet-layout.tsx +192 -0
- package/src/components/ui/theme-customizer.tsx +386 -0
- package/src/components/ui/theme-preview.tsx +310 -0
- package/src/components/ui/theme-switcher.tsx +264 -0
- package/src/components/ui/theme-toggle.tsx +38 -0
- package/src/components/ui/token-demo.tsx +195 -0
- package/src/components/ui/touch-demo.tsx +462 -0
- package/src/components/ui/touch-friendly-interface-demo.tsx +519 -0
- package/src/components/ui/touch-friendly-interface.tsx +296 -0
- package/src/hooks/index.ts +190 -0
- package/src/hooks/use-accessibility-support.ts +518 -0
- package/src/hooks/use-adaptive-layout.ts +289 -0
- package/src/hooks/use-advanced-patterns.ts +294 -0
- package/src/hooks/use-advanced-transition-system.ts +393 -0
- package/src/hooks/use-animation-profile.ts +288 -0
- package/src/hooks/use-battery-animations.ts +384 -0
- package/src/hooks/use-battery-conscious-loading.ts +475 -0
- package/src/hooks/use-battery-optimization.ts +330 -0
- package/src/hooks/use-battery-status.ts +299 -0
- package/src/hooks/use-component-performance.ts +344 -0
- package/src/hooks/use-device-loading-states.ts +459 -0
- package/src/hooks/use-device.tsx +110 -0
- package/src/hooks/use-enterprise-mobile-experience.ts +488 -0
- package/src/hooks/use-form-feedback.ts +403 -0
- package/src/hooks/use-form-performance.ts +513 -0
- package/src/hooks/use-frame-rate.ts +251 -0
- package/src/hooks/use-gestures.ts +338 -0
- package/src/hooks/use-hardware-acceleration.ts +341 -0
- package/src/hooks/use-input-accessibility.ts +455 -0
- package/src/hooks/use-input-performance.ts +506 -0
- package/src/hooks/use-layout-performance.ts +319 -0
- package/src/hooks/use-loading-accessibility.ts +535 -0
- package/src/hooks/use-loading-performance.ts +473 -0
- package/src/hooks/use-memory-usage.ts +287 -0
- package/src/hooks/use-mobile-form-layout.ts +464 -0
- package/src/hooks/use-mobile-form-validation.ts +518 -0
- package/src/hooks/use-mobile-keyboard-optimization.ts +472 -0
- package/src/hooks/use-mobile-layout.ts +302 -0
- package/src/hooks/use-mobile-optimization.ts +406 -0
- package/src/hooks/use-mobile-skeleton.ts +402 -0
- package/src/hooks/use-mobile-touch.ts +414 -0
- package/src/hooks/use-performance-throttling.ts +348 -0
- package/src/hooks/use-performance.ts +316 -0
- package/src/hooks/use-reusable-architecture.ts +414 -0
- package/src/hooks/use-semantic-input-types.ts +357 -0
- package/src/hooks/use-semantic-input.ts +565 -0
- package/src/hooks/use-tablet-layout.ts +384 -0
- package/src/hooks/use-touch-friendly-input.ts +524 -0
- package/src/hooks/use-touch-friendly-interface.ts +331 -0
- package/src/hooks/use-touch-optimization.ts +375 -0
- package/src/index.ts +279 -279
- package/src/lib/utils.ts +6 -0
- package/src/themes/README.md +272 -0
- package/src/themes/ThemeContext.tsx +31 -0
- package/src/themes/ThemeProvider.tsx +232 -0
- package/src/themes/accessibility/index.ts +27 -0
- package/src/themes/accessibility.ts +259 -0
- package/src/themes/aria-patterns.ts +420 -0
- package/src/themes/base-themes.ts +55 -0
- package/src/themes/colorManager.ts +380 -0
- package/src/themes/examples/dark-theme.ts +154 -0
- package/src/themes/examples/minimal-theme.ts +108 -0
- package/src/themes/focus-management.ts +701 -0
- package/src/themes/fontLoader.ts +201 -0
- package/src/themes/high-contrast.ts +621 -0
- package/src/themes/index.ts +19 -0
- package/src/themes/inheritance.ts +227 -0
- package/src/themes/keyboard-navigation.ts +550 -0
- package/src/themes/motion-reduction.ts +662 -0
- package/src/themes/navigation.ts +238 -0
- package/src/themes/screen-reader.ts +645 -0
- package/src/themes/systemThemeDetector.ts +182 -0
- package/src/themes/themeCSSUpdater.ts +262 -0
- package/src/themes/themePersistence.ts +238 -0
- package/src/themes/themes/default.ts +586 -0
- package/src/themes/themes/harvey.ts +554 -0
- package/src/themes/themes/stan-design.ts +683 -0
- package/src/themes/types.ts +460 -0
- package/src/themes/useSystemTheme.ts +48 -0
- package/src/themes/useTheme.ts +87 -0
- package/src/themes/validation.ts +462 -0
- package/src/tokens/index.ts +34 -0
- package/src/tokens/tokenExporter.ts +397 -0
- package/src/tokens/tokenGenerator.ts +276 -0
- package/src/tokens/tokenManager.ts +248 -0
- package/src/tokens/tokenValidator.ts +543 -0
- package/src/tokens/types.ts +78 -0
- package/src/utils/bundle-analyzer.ts +260 -0
- package/src/utils/bundle-splitting.ts +483 -0
- package/src/utils/lazy-loading.ts +441 -0
- package/src/utils/performance-monitor.ts +513 -0
- package/src/utils/tree-shaking.ts +274 -0
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
import type { ThemeTokens, TokenExportOptions } from './types';
|
|
2
|
+
|
|
3
|
+
export class TokenExporter {
|
|
4
|
+
/**
|
|
5
|
+
* Exports tokens in the specified format
|
|
6
|
+
*/
|
|
7
|
+
static exportTokens(tokens: ThemeTokens, options: TokenExportOptions): string {
|
|
8
|
+
switch (options.format) {
|
|
9
|
+
case 'json':
|
|
10
|
+
return this.exportAsJSON(tokens, options);
|
|
11
|
+
case 'css':
|
|
12
|
+
return this.exportAsCSS(tokens, options);
|
|
13
|
+
case 'scss':
|
|
14
|
+
return this.exportAsSCSS(tokens, options);
|
|
15
|
+
case 'js':
|
|
16
|
+
return this.exportAsJS(tokens, options);
|
|
17
|
+
case 'ts':
|
|
18
|
+
return this.exportAsTS(tokens, options);
|
|
19
|
+
default:
|
|
20
|
+
throw new Error(`Unsupported export format: ${options.format}`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Exports tokens as JSON
|
|
26
|
+
*/
|
|
27
|
+
private static exportAsJSON(tokens: ThemeTokens, options: TokenExportOptions): string {
|
|
28
|
+
const exportData = options.includeMetadata ? tokens : tokens.tokens;
|
|
29
|
+
return JSON.stringify(exportData, null, 2);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Exports tokens as CSS custom properties
|
|
34
|
+
*/
|
|
35
|
+
private static exportAsCSS(tokens: ThemeTokens, options: TokenExportOptions): string {
|
|
36
|
+
let css = '';
|
|
37
|
+
|
|
38
|
+
if (options.includeComments) {
|
|
39
|
+
css += `/* ${tokens.theme} Design Tokens - v${tokens.version} */\n`;
|
|
40
|
+
css += `/* Generated on: ${new Date().toISOString()} */\n\n`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
css += `:root {\n`;
|
|
44
|
+
|
|
45
|
+
// Export color tokens
|
|
46
|
+
if (tokens.tokens.color) {
|
|
47
|
+
css += this.exportColorTokensAsCSS(tokens.tokens.color, 2);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Export font tokens
|
|
51
|
+
if (tokens.tokens.font) {
|
|
52
|
+
css += this.exportFontTokensAsCSS(tokens.tokens.font, 2);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Export spacing tokens
|
|
56
|
+
if (tokens.tokens.spacing) {
|
|
57
|
+
css += this.exportSpacingTokensAsCSS(tokens.tokens.spacing, 2);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Export shadow tokens
|
|
61
|
+
if (tokens.tokens.shadow) {
|
|
62
|
+
css += this.exportShadowTokensAsCSS(tokens.tokens.shadow, 2);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Export transition tokens
|
|
66
|
+
if (tokens.tokens.transition) {
|
|
67
|
+
css += this.exportTransitionTokensAsCSS(tokens.tokens.transition, 2);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Export breakpoint tokens
|
|
71
|
+
if (tokens.tokens.breakpoint) {
|
|
72
|
+
css += this.exportBreakpointTokensAsCSS(tokens.tokens.breakpoint, 2);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
css += `}\n`;
|
|
76
|
+
return css;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Exports color tokens as CSS custom properties
|
|
81
|
+
*/
|
|
82
|
+
private static exportColorTokensAsCSS(colorTokens: any, indent: number): string {
|
|
83
|
+
let css = '';
|
|
84
|
+
const spaces = ' '.repeat(indent);
|
|
85
|
+
|
|
86
|
+
Object.entries(colorTokens).forEach(([category, categoryTokens]: [string, any]) => {
|
|
87
|
+
if (typeof categoryTokens === 'object' && categoryTokens.value) {
|
|
88
|
+
// Single token
|
|
89
|
+
css += `${spaces}--color-${category}: ${categoryTokens.value};\n`;
|
|
90
|
+
} else if (typeof categoryTokens === 'object') {
|
|
91
|
+
// Token group
|
|
92
|
+
Object.entries(categoryTokens).forEach(([shade, token]: [string, any]) => {
|
|
93
|
+
if (token && typeof token === 'object' && token.value) {
|
|
94
|
+
css += `${spaces}--color-${category}-${shade}: ${token.value};\n`;
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
return css;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Exports font tokens as CSS custom properties
|
|
105
|
+
*/
|
|
106
|
+
private static exportFontTokensAsCSS(fontTokens: any, indent: number): string {
|
|
107
|
+
let css = '';
|
|
108
|
+
const spaces = ' '.repeat(indent);
|
|
109
|
+
|
|
110
|
+
Object.entries(fontTokens).forEach(([name, token]: [string, any]) => {
|
|
111
|
+
if (token && typeof token === 'object' && token.value) {
|
|
112
|
+
const cssVarName = this.getFontCSSVarName(name, token.type);
|
|
113
|
+
css += `${spaces}--font-${cssVarName}: ${token.value};\n`;
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
return css;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Gets the CSS variable name for font tokens
|
|
122
|
+
*/
|
|
123
|
+
private static getFontCSSVarName(name: string, type: string): string {
|
|
124
|
+
if (type === 'fontFamily') {
|
|
125
|
+
return name;
|
|
126
|
+
}
|
|
127
|
+
if (type === 'fontSize') {
|
|
128
|
+
return name.replace('size-', 'size-');
|
|
129
|
+
}
|
|
130
|
+
if (type === 'fontWeight') {
|
|
131
|
+
return name.replace('weight-', 'weight-');
|
|
132
|
+
}
|
|
133
|
+
if (type === 'lineHeight') {
|
|
134
|
+
return name.replace('line-height-', 'line-height-');
|
|
135
|
+
}
|
|
136
|
+
return name;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Exports spacing tokens as CSS custom properties
|
|
141
|
+
*/
|
|
142
|
+
private static exportSpacingTokensAsCSS(spacingTokens: any, indent: number): string {
|
|
143
|
+
let css = '';
|
|
144
|
+
const spaces = ' '.repeat(indent);
|
|
145
|
+
|
|
146
|
+
Object.entries(spacingTokens).forEach(([scale, token]: [string, any]) => {
|
|
147
|
+
if (token && typeof token === 'object' && token.value) {
|
|
148
|
+
css += `${spaces}--spacing-${scale}: ${token.value}px;\n`;
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
return css;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Exports shadow tokens as CSS custom properties
|
|
157
|
+
*/
|
|
158
|
+
private static exportShadowTokensAsCSS(shadowTokens: any, indent: number): string {
|
|
159
|
+
let css = '';
|
|
160
|
+
const spaces = ' '.repeat(indent);
|
|
161
|
+
|
|
162
|
+
Object.entries(shadowTokens).forEach(([elevation, token]: [string, any]) => {
|
|
163
|
+
if (token && typeof token === 'object' && token.value) {
|
|
164
|
+
css += `${spaces}--shadow-${elevation}: ${token.value};\n`;
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
return css;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Exports transition tokens as CSS custom properties
|
|
173
|
+
*/
|
|
174
|
+
private static exportTransitionTokensAsCSS(transitionTokens: any, indent: number): string {
|
|
175
|
+
let css = '';
|
|
176
|
+
const spaces = ' '.repeat(indent);
|
|
177
|
+
|
|
178
|
+
Object.entries(transitionTokens).forEach(([name, token]: [string, any]) => {
|
|
179
|
+
if (token && typeof token === 'object' && token.value) {
|
|
180
|
+
css += `${spaces}--transition-${name}: ${token.value};\n`;
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
return css;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Exports breakpoint tokens as CSS custom properties
|
|
189
|
+
*/
|
|
190
|
+
private static exportBreakpointTokensAsCSS(breakpointTokens: any, indent: number): string {
|
|
191
|
+
let css = '';
|
|
192
|
+
const spaces = ' '.repeat(indent);
|
|
193
|
+
|
|
194
|
+
Object.entries(breakpointTokens).forEach(([name, token]: [string, any]) => {
|
|
195
|
+
if (token && typeof token === 'object' && token.value) {
|
|
196
|
+
css += `${spaces}--breakpoint-${name}: ${token.value}px;\n`;
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
return css;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Exports tokens as SCSS variables
|
|
205
|
+
*/
|
|
206
|
+
private static exportAsSCSS(tokens: ThemeTokens, options: TokenExportOptions): string {
|
|
207
|
+
let scss = '';
|
|
208
|
+
|
|
209
|
+
if (options.includeComments) {
|
|
210
|
+
scss += `// ${tokens.theme} Design Tokens - v${tokens.version}\n`;
|
|
211
|
+
scss += `// Generated on: ${new Date().toISOString()}\n\n`;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Export color tokens
|
|
215
|
+
if (tokens.tokens.color) {
|
|
216
|
+
scss += this.exportColorTokensAsSCSS(tokens.tokens.color);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Export font tokens
|
|
220
|
+
if (tokens.tokens.font) {
|
|
221
|
+
scss += this.exportFontTokensAsSCSS(tokens.tokens.font);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Export spacing tokens
|
|
225
|
+
if (tokens.tokens.spacing) {
|
|
226
|
+
scss += this.exportSpacingTokensAsSCSS(tokens.tokens.spacing);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Export shadow tokens
|
|
230
|
+
if (tokens.tokens.shadow) {
|
|
231
|
+
scss += this.exportShadowTokensAsSCSS(tokens.tokens.shadow);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Export transition tokens
|
|
235
|
+
if (tokens.tokens.transition) {
|
|
236
|
+
scss += this.exportTransitionTokensAsSCSS(tokens.tokens.transition);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Export breakpoint tokens
|
|
240
|
+
if (tokens.tokens.breakpoint) {
|
|
241
|
+
scss += this.exportBreakpointTokensAsSCSS(tokens.tokens.breakpoint);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
return scss;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Exports color tokens as SCSS variables
|
|
249
|
+
*/
|
|
250
|
+
private static exportColorTokensAsSCSS(colorTokens: any): string {
|
|
251
|
+
let scss = '\n// Color Tokens\n';
|
|
252
|
+
|
|
253
|
+
Object.entries(colorTokens).forEach(([category, categoryTokens]: [string, any]) => {
|
|
254
|
+
if (typeof categoryTokens === 'object' && categoryTokens.value) {
|
|
255
|
+
// Single token
|
|
256
|
+
scss += `$color-${category}: ${categoryTokens.value};\n`;
|
|
257
|
+
} else if (typeof categoryTokens === 'object') {
|
|
258
|
+
// Token group
|
|
259
|
+
Object.entries(categoryTokens).forEach(([shade, token]: [string, any]) => {
|
|
260
|
+
if (token && typeof token === 'object' && token.value) {
|
|
261
|
+
scss += `$color-${category}-${shade}: ${token.value};\n`;
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
return scss;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Exports font tokens as SCSS variables
|
|
272
|
+
*/
|
|
273
|
+
private static exportFontTokensAsSCSS(fontTokens: any): string {
|
|
274
|
+
let scss = '\n// Font Tokens\n';
|
|
275
|
+
|
|
276
|
+
Object.entries(fontTokens).forEach(([name, token]: [string, any]) => {
|
|
277
|
+
if (token && typeof token === 'object' && token.value) {
|
|
278
|
+
const scssVarName = this.getFontSCSSVarName(name, token.type);
|
|
279
|
+
scss += `$font-${scssVarName}: ${token.value};\n`;
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
return scss;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Gets the SCSS variable name for font tokens
|
|
288
|
+
*/
|
|
289
|
+
private static getFontSCSSVarName(name: string, type: string): string {
|
|
290
|
+
if (type === 'fontFamily') {
|
|
291
|
+
return name;
|
|
292
|
+
}
|
|
293
|
+
if (type === 'fontSize') {
|
|
294
|
+
return name.replace('size-', 'size-');
|
|
295
|
+
}
|
|
296
|
+
if (type === 'fontWeight') {
|
|
297
|
+
return name.replace('weight-', 'weight-');
|
|
298
|
+
}
|
|
299
|
+
if (type === 'lineHeight') {
|
|
300
|
+
return name.replace('line-height-', 'line-height-');
|
|
301
|
+
}
|
|
302
|
+
return name;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Exports spacing tokens as SCSS variables
|
|
307
|
+
*/
|
|
308
|
+
private static exportSpacingTokensAsSCSS(spacingTokens: any): string {
|
|
309
|
+
let scss = '\n// Spacing Tokens\n';
|
|
310
|
+
|
|
311
|
+
Object.entries(spacingTokens).forEach(([scale, token]: [string, any]) => {
|
|
312
|
+
if (token && typeof token === 'object' && token.value) {
|
|
313
|
+
scss += `$spacing-${scale}: ${token.value}px;\n`;
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
return scss;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Exports shadow tokens as SCSS variables
|
|
322
|
+
*/
|
|
323
|
+
private static exportShadowTokensAsSCSS(shadowTokens: any): string {
|
|
324
|
+
let scss = '\n// Shadow Tokens\n';
|
|
325
|
+
|
|
326
|
+
Object.entries(shadowTokens).forEach(([elevation, token]: [string, any]) => {
|
|
327
|
+
if (token && typeof token === 'object' && token.value) {
|
|
328
|
+
scss += `$shadow-${elevation}: ${token.value};\n`;
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
return scss;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Exports transition tokens as SCSS variables
|
|
337
|
+
*/
|
|
338
|
+
private static exportTransitionTokensAsSCSS(transitionTokens: any): string {
|
|
339
|
+
let scss = '\n// Transition Tokens\n';
|
|
340
|
+
|
|
341
|
+
Object.entries(transitionTokens).forEach(([name, token]: [string, any]) => {
|
|
342
|
+
if (token && typeof token === 'object' && token.value) {
|
|
343
|
+
scss += `$transition-${name}: ${token.value};\n`;
|
|
344
|
+
}
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
return scss;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Exports breakpoint tokens as SCSS variables
|
|
352
|
+
*/
|
|
353
|
+
private static exportBreakpointTokensAsSCSS(breakpointTokens: any): string {
|
|
354
|
+
let scss = '\n// Breakpoint Tokens\n';
|
|
355
|
+
|
|
356
|
+
Object.entries(breakpointTokens).forEach(([name, token]: [string, any]) => {
|
|
357
|
+
if (token && typeof token === 'object' && token.value) {
|
|
358
|
+
scss += `$breakpoint-${name}: ${token.value}px;\n`;
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
return scss;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Exports tokens as JavaScript object
|
|
367
|
+
*/
|
|
368
|
+
private static exportAsJS(tokens: ThemeTokens, options: TokenExportOptions): string {
|
|
369
|
+
const exportData = options.includeMetadata ? tokens : tokens.tokens;
|
|
370
|
+
let js = '';
|
|
371
|
+
|
|
372
|
+
if (options.includeComments) {
|
|
373
|
+
js += `// ${tokens.theme} Design Tokens - v${tokens.version}\n`;
|
|
374
|
+
js += `// Generated on: ${new Date().toISOString()}\n\n`;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
js += `module.exports = ${JSON.stringify(exportData, null, 2)};\n`;
|
|
378
|
+
return js;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Exports tokens as TypeScript object
|
|
383
|
+
*/
|
|
384
|
+
private static exportAsTS(tokens: ThemeTokens, options: TokenExportOptions): string {
|
|
385
|
+
const exportData = options.includeMetadata ? tokens : tokens.tokens;
|
|
386
|
+
let ts = '';
|
|
387
|
+
|
|
388
|
+
if (options.includeComments) {
|
|
389
|
+
ts += `// ${tokens.theme} Design Tokens - v${tokens.version}\n`;
|
|
390
|
+
ts += `// Generated on: ${new Date().toISOString()}\n\n`;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
ts += `export const tokens = ${JSON.stringify(exportData, null, 2)} as const;\n`;
|
|
394
|
+
ts += `export type Tokens = typeof tokens;\n`;
|
|
395
|
+
return ts;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import type { CompleteThemeConfig } from '../themes/types';
|
|
2
|
+
import type { ThemeTokens, TokenGroup, ColorToken, FontToken, SpacingToken, ShadowToken, TransitionToken } from './types';
|
|
3
|
+
|
|
4
|
+
export class TokenGenerator {
|
|
5
|
+
/**
|
|
6
|
+
* Generates design tokens from a complete theme configuration
|
|
7
|
+
*/
|
|
8
|
+
static generateTokens(themeConfig: CompleteThemeConfig): ThemeTokens {
|
|
9
|
+
return {
|
|
10
|
+
theme: themeConfig.meta.name,
|
|
11
|
+
version: themeConfig.meta.version || '1.0.0',
|
|
12
|
+
tokens: {
|
|
13
|
+
color: this.generateColorTokens(themeConfig.colors),
|
|
14
|
+
font: this.generateFontTokens(themeConfig.fonts),
|
|
15
|
+
spacing: this.generateSpacingTokens(themeConfig.spacing),
|
|
16
|
+
shadow: this.generateShadowTokens(themeConfig.shadows),
|
|
17
|
+
transition: this.generateTransitionTokens(themeConfig.transitions)
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Generates color tokens from theme colors
|
|
24
|
+
*/
|
|
25
|
+
private static generateColorTokens(colors: CompleteThemeConfig['colors']): TokenGroup {
|
|
26
|
+
const colorTokens: TokenGroup = {};
|
|
27
|
+
|
|
28
|
+
// Primary colors
|
|
29
|
+
if (colors.primary) {
|
|
30
|
+
colorTokens.primary = this.createColorGroup(colors.primary, 'primary');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Secondary colors
|
|
34
|
+
if (colors.secondary) {
|
|
35
|
+
colorTokens.secondary = this.createColorGroup(colors.secondary, 'secondary');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Neutral colors
|
|
39
|
+
if (colors.neutral) {
|
|
40
|
+
colorTokens.neutral = this.createColorGroup(colors.neutral, 'neutral');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Surface colors
|
|
44
|
+
if (colors.surface) {
|
|
45
|
+
colorTokens.surface = this.createColorGroup(colors.surface, 'neutral');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Text colors
|
|
49
|
+
if (colors.text) {
|
|
50
|
+
colorTokens.text = this.createColorGroup(colors.text, 'neutral');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Interactive colors
|
|
54
|
+
if (colors.interactive) {
|
|
55
|
+
colorTokens.interactive = this.createColorGroup(colors.interactive, 'neutral');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Semantic colors
|
|
59
|
+
if (colors.semantic) {
|
|
60
|
+
colorTokens.semantic = this.createColorGroup(colors.semantic, 'neutral');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return colorTokens;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Creates a color group from a color scale
|
|
68
|
+
*/
|
|
69
|
+
private static createColorGroup(colorScale: any, semantic: ColorToken['semantic']): TokenGroup {
|
|
70
|
+
const group: TokenGroup = {};
|
|
71
|
+
|
|
72
|
+
Object.entries(colorScale).forEach(([shade, value]) => {
|
|
73
|
+
if (typeof value === 'string') {
|
|
74
|
+
group[shade] = {
|
|
75
|
+
value,
|
|
76
|
+
type: 'color',
|
|
77
|
+
semantic,
|
|
78
|
+
description: `${semantic} color - ${shade} shade`,
|
|
79
|
+
category: 'color',
|
|
80
|
+
tags: [semantic, shade]
|
|
81
|
+
} as ColorToken;
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
return group;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Generates font tokens from theme fonts
|
|
90
|
+
*/
|
|
91
|
+
private static generateFontTokens(fonts: CompleteThemeConfig['fonts']): TokenGroup {
|
|
92
|
+
const fontTokens: TokenGroup = {};
|
|
93
|
+
|
|
94
|
+
// Font families
|
|
95
|
+
if (fonts.primary) {
|
|
96
|
+
fontTokens.primary = {
|
|
97
|
+
value: fonts.primary.family,
|
|
98
|
+
type: 'fontFamily',
|
|
99
|
+
description: 'Primary font family',
|
|
100
|
+
category: 'typography',
|
|
101
|
+
tags: ['primary', 'font']
|
|
102
|
+
} as FontToken;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (fonts.secondary) {
|
|
106
|
+
fontTokens.secondary = {
|
|
107
|
+
value: fonts.secondary.family,
|
|
108
|
+
type: 'fontFamily',
|
|
109
|
+
description: 'Secondary font family',
|
|
110
|
+
category: 'typography',
|
|
111
|
+
tags: ['secondary', 'font']
|
|
112
|
+
} as FontToken;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (fonts.display) {
|
|
116
|
+
fontTokens.display = {
|
|
117
|
+
value: fonts.display.family,
|
|
118
|
+
type: 'fontFamily',
|
|
119
|
+
description: 'Display font family',
|
|
120
|
+
category: 'typography',
|
|
121
|
+
tags: ['display', 'font']
|
|
122
|
+
} as FontToken;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (fonts.body) {
|
|
126
|
+
fontTokens.body = {
|
|
127
|
+
value: fonts.body.family,
|
|
128
|
+
type: 'fontFamily',
|
|
129
|
+
description: 'Body font family',
|
|
130
|
+
category: 'typography',
|
|
131
|
+
tags: ['body', 'font']
|
|
132
|
+
} as FontToken;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (fonts.mono) {
|
|
136
|
+
fontTokens.mono = {
|
|
137
|
+
value: fonts.mono.family,
|
|
138
|
+
type: 'fontFamily',
|
|
139
|
+
description: 'Monospace font family',
|
|
140
|
+
category: 'typography',
|
|
141
|
+
tags: ['mono', 'font']
|
|
142
|
+
} as FontToken;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Font sizes (from primary font)
|
|
146
|
+
if (fonts.primary?.sizes) {
|
|
147
|
+
Object.entries(fonts.primary.sizes).forEach(([size, value]) => {
|
|
148
|
+
fontTokens[`size-${size}`] = {
|
|
149
|
+
value,
|
|
150
|
+
type: 'fontSize',
|
|
151
|
+
description: `Font size - ${size}`,
|
|
152
|
+
category: 'typography',
|
|
153
|
+
tags: ['font', 'size', size]
|
|
154
|
+
} as FontToken;
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Font weights (from primary font)
|
|
159
|
+
if (fonts.primary?.weights) {
|
|
160
|
+
fonts.primary.weights.forEach((weight, index) => {
|
|
161
|
+
fontTokens[`weight-${index}`] = {
|
|
162
|
+
value: weight,
|
|
163
|
+
type: 'fontWeight',
|
|
164
|
+
description: `Font weight - ${weight}`,
|
|
165
|
+
category: 'typography',
|
|
166
|
+
tags: ['font', 'weight', weight.toString()]
|
|
167
|
+
} as FontToken;
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Line heights (from primary font)
|
|
172
|
+
if (fonts.primary?.lineHeights) {
|
|
173
|
+
Object.entries(fonts.primary.lineHeights).forEach(([height, value]) => {
|
|
174
|
+
fontTokens[`line-height-${height}`] = {
|
|
175
|
+
value,
|
|
176
|
+
type: 'lineHeight',
|
|
177
|
+
description: `Line height - ${height}`,
|
|
178
|
+
category: 'typography',
|
|
179
|
+
tags: ['font', 'line-height', height]
|
|
180
|
+
} as FontToken;
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Letter spacing (from primary font)
|
|
185
|
+
if (fonts.primary?.letterSpacing) {
|
|
186
|
+
Object.entries(fonts.primary.letterSpacing).forEach(([spacing, value]) => {
|
|
187
|
+
fontTokens[`letter-spacing-${spacing}`] = {
|
|
188
|
+
value,
|
|
189
|
+
type: 'letterSpacing',
|
|
190
|
+
description: `Letter spacing - ${spacing}`,
|
|
191
|
+
category: 'typography',
|
|
192
|
+
tags: ['font', 'letter-spacing', spacing]
|
|
193
|
+
} as FontToken;
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return fontTokens;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Generates spacing tokens from theme spacing
|
|
202
|
+
*/
|
|
203
|
+
private static generateSpacingTokens(spacing: CompleteThemeConfig['spacing']): TokenGroup {
|
|
204
|
+
const spacingTokens: TokenGroup = {};
|
|
205
|
+
|
|
206
|
+
if (spacing) {
|
|
207
|
+
Object.entries(spacing).forEach(([scale, value]) => {
|
|
208
|
+
spacingTokens[scale] = {
|
|
209
|
+
value,
|
|
210
|
+
type: 'spacing',
|
|
211
|
+
unit: 'px',
|
|
212
|
+
description: `Spacing scale - ${scale}`,
|
|
213
|
+
category: 'layout',
|
|
214
|
+
tags: ['spacing', 'layout', scale]
|
|
215
|
+
} as SpacingToken;
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return spacingTokens;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Generates shadow tokens from theme shadows
|
|
224
|
+
*/
|
|
225
|
+
private static generateShadowTokens(shadows: CompleteThemeConfig['shadows']): TokenGroup {
|
|
226
|
+
const shadowTokens: TokenGroup = {};
|
|
227
|
+
|
|
228
|
+
if (shadows) {
|
|
229
|
+
Object.entries(shadows).forEach(([elevation, value]) => {
|
|
230
|
+
shadowTokens[elevation] = {
|
|
231
|
+
value,
|
|
232
|
+
type: 'shadow',
|
|
233
|
+
elevation: elevation as 'low' | 'medium' | 'high',
|
|
234
|
+
description: `Shadow - ${elevation} elevation`,
|
|
235
|
+
category: 'effects',
|
|
236
|
+
tags: ['shadow', 'elevation', elevation]
|
|
237
|
+
} as ShadowToken;
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return shadowTokens;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Generates transition tokens from theme transitions
|
|
246
|
+
*/
|
|
247
|
+
private static generateTransitionTokens(transitions: CompleteThemeConfig['transitions']): TokenGroup {
|
|
248
|
+
const transitionTokens: TokenGroup = {};
|
|
249
|
+
|
|
250
|
+
if (transitions) {
|
|
251
|
+
Object.entries(transitions).forEach(([name, value]) => {
|
|
252
|
+
transitionTokens[name] = {
|
|
253
|
+
value,
|
|
254
|
+
type: 'transition',
|
|
255
|
+
easing: this.detectEasing(value),
|
|
256
|
+
description: `Transition - ${name}`,
|
|
257
|
+
category: 'animation',
|
|
258
|
+
tags: ['transition', 'animation', name]
|
|
259
|
+
} as TransitionToken;
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return transitionTokens;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Detects easing function from transition value
|
|
268
|
+
*/
|
|
269
|
+
private static detectEasing(transition: string): TransitionToken['easing'] {
|
|
270
|
+
if (transition.includes('ease-in-out')) return 'ease-in-out';
|
|
271
|
+
if (transition.includes('ease-in')) return 'ease-in';
|
|
272
|
+
if (transition.includes('ease-out')) return 'ease-out';
|
|
273
|
+
if (transition.includes('linear')) return 'linear';
|
|
274
|
+
return undefined;
|
|
275
|
+
}
|
|
276
|
+
}
|