@rakeyshgidwani/roger-ui-bank-theme-stan-design 0.1.4 → 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.
Files changed (164) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/dist/index.d.ts +131 -131
  3. package/dist/index.esm.js +148 -148
  4. package/dist/index.js +148 -148
  5. package/dist/styles.css +1 -1
  6. package/package.json +1 -1
  7. package/src/components/ui/accessibility-demo.tsx +271 -0
  8. package/src/components/ui/advanced-component-architecture-demo.tsx +916 -0
  9. package/src/components/ui/advanced-transition-system-demo.tsx +670 -0
  10. package/src/components/ui/advanced-transition-system.tsx +395 -0
  11. package/src/components/ui/animation/animated-container.tsx +166 -0
  12. package/src/components/ui/animation/index.ts +19 -0
  13. package/src/components/ui/animation/staggered-container.tsx +68 -0
  14. package/src/components/ui/animation-demo.tsx +250 -0
  15. package/src/components/ui/badge.tsx +33 -0
  16. package/src/components/ui/battery-conscious-animation-demo.tsx +568 -0
  17. package/src/components/ui/border-radius-shadow-demo.tsx +187 -0
  18. package/src/components/ui/button.tsx +36 -0
  19. package/src/components/ui/card.tsx +207 -0
  20. package/src/components/ui/checkbox.tsx +30 -0
  21. package/src/components/ui/color-preview.tsx +411 -0
  22. package/src/components/ui/data-display/chart.tsx +653 -0
  23. package/src/components/ui/data-display/data-grid-simple.tsx +76 -0
  24. package/src/components/ui/data-display/data-grid.tsx +680 -0
  25. package/src/components/ui/data-display/list.tsx +456 -0
  26. package/src/components/ui/data-display/table.tsx +482 -0
  27. package/src/components/ui/data-display/timeline.tsx +441 -0
  28. package/src/components/ui/data-display/tree.tsx +602 -0
  29. package/src/components/ui/data-display/types.ts +536 -0
  30. package/src/components/ui/enterprise-mobile-experience-demo.tsx +749 -0
  31. package/src/components/ui/enterprise-mobile-experience.tsx +464 -0
  32. package/src/components/ui/feedback/alert.tsx +157 -0
  33. package/src/components/ui/feedback/progress.tsx +292 -0
  34. package/src/components/ui/feedback/skeleton.tsx +185 -0
  35. package/src/components/ui/feedback/toast.tsx +280 -0
  36. package/src/components/ui/feedback/types.ts +125 -0
  37. package/src/components/ui/font-preview.tsx +288 -0
  38. package/src/components/ui/form-demo.tsx +553 -0
  39. package/src/components/ui/hardware-acceleration-demo.tsx +547 -0
  40. package/src/components/ui/input.tsx +35 -0
  41. package/src/components/ui/label.tsx +16 -0
  42. package/src/components/ui/layout-demo.tsx +367 -0
  43. package/src/components/ui/layouts/adaptive-layout.tsx +139 -0
  44. package/src/components/ui/layouts/desktop-layout.tsx +224 -0
  45. package/src/components/ui/layouts/index.ts +10 -0
  46. package/src/components/ui/layouts/mobile-layout.tsx +162 -0
  47. package/src/components/ui/layouts/tablet-layout.tsx +197 -0
  48. package/src/components/ui/mobile-form-validation.tsx +451 -0
  49. package/src/components/ui/mobile-input-demo.tsx +201 -0
  50. package/src/components/ui/mobile-input.tsx +281 -0
  51. package/src/components/ui/mobile-skeleton-loading-demo.tsx +638 -0
  52. package/src/components/ui/navigation/breadcrumb.tsx +158 -0
  53. package/src/components/ui/navigation/index.ts +36 -0
  54. package/src/components/ui/navigation/menu.tsx +374 -0
  55. package/src/components/ui/navigation/navigation-demo.tsx +324 -0
  56. package/src/components/ui/navigation/pagination.tsx +272 -0
  57. package/src/components/ui/navigation/sidebar.tsx +383 -0
  58. package/src/components/ui/navigation/stepper.tsx +303 -0
  59. package/src/components/ui/navigation/tabs.tsx +205 -0
  60. package/src/components/ui/navigation/types.ts +299 -0
  61. package/src/components/ui/overlay/backdrop.tsx +81 -0
  62. package/src/components/ui/overlay/focus-manager.tsx +143 -0
  63. package/src/components/ui/overlay/index.ts +36 -0
  64. package/src/components/ui/overlay/modal.tsx +270 -0
  65. package/src/components/ui/overlay/overlay-manager.tsx +110 -0
  66. package/src/components/ui/overlay/popover.tsx +462 -0
  67. package/src/components/ui/overlay/portal.tsx +79 -0
  68. package/src/components/ui/overlay/tooltip.tsx +303 -0
  69. package/src/components/ui/overlay/types.ts +196 -0
  70. package/src/components/ui/performance-demo.tsx +596 -0
  71. package/src/components/ui/semantic-input-system-demo.tsx +502 -0
  72. package/src/components/ui/semantic-input-system-demo.tsx.disabled +873 -0
  73. package/src/components/ui/tablet-layout.tsx +192 -0
  74. package/src/components/ui/theme-customizer.tsx +386 -0
  75. package/src/components/ui/theme-preview.tsx +310 -0
  76. package/src/components/ui/theme-switcher.tsx +264 -0
  77. package/src/components/ui/theme-toggle.tsx +38 -0
  78. package/src/components/ui/token-demo.tsx +195 -0
  79. package/src/components/ui/touch-demo.tsx +462 -0
  80. package/src/components/ui/touch-friendly-interface-demo.tsx +519 -0
  81. package/src/components/ui/touch-friendly-interface.tsx +296 -0
  82. package/src/hooks/index.ts +190 -0
  83. package/src/hooks/use-accessibility-support.ts +518 -0
  84. package/src/hooks/use-adaptive-layout.ts +289 -0
  85. package/src/hooks/use-advanced-patterns.ts +294 -0
  86. package/src/hooks/use-advanced-transition-system.ts +393 -0
  87. package/src/hooks/use-animation-profile.ts +288 -0
  88. package/src/hooks/use-battery-animations.ts +384 -0
  89. package/src/hooks/use-battery-conscious-loading.ts +475 -0
  90. package/src/hooks/use-battery-optimization.ts +330 -0
  91. package/src/hooks/use-battery-status.ts +299 -0
  92. package/src/hooks/use-component-performance.ts +344 -0
  93. package/src/hooks/use-device-loading-states.ts +459 -0
  94. package/src/hooks/use-device.tsx +110 -0
  95. package/src/hooks/use-enterprise-mobile-experience.ts +488 -0
  96. package/src/hooks/use-form-feedback.ts +403 -0
  97. package/src/hooks/use-form-performance.ts +513 -0
  98. package/src/hooks/use-frame-rate.ts +251 -0
  99. package/src/hooks/use-gestures.ts +338 -0
  100. package/src/hooks/use-hardware-acceleration.ts +341 -0
  101. package/src/hooks/use-input-accessibility.ts +455 -0
  102. package/src/hooks/use-input-performance.ts +506 -0
  103. package/src/hooks/use-layout-performance.ts +319 -0
  104. package/src/hooks/use-loading-accessibility.ts +535 -0
  105. package/src/hooks/use-loading-performance.ts +473 -0
  106. package/src/hooks/use-memory-usage.ts +287 -0
  107. package/src/hooks/use-mobile-form-layout.ts +464 -0
  108. package/src/hooks/use-mobile-form-validation.ts +518 -0
  109. package/src/hooks/use-mobile-keyboard-optimization.ts +472 -0
  110. package/src/hooks/use-mobile-layout.ts +302 -0
  111. package/src/hooks/use-mobile-optimization.ts +406 -0
  112. package/src/hooks/use-mobile-skeleton.ts +402 -0
  113. package/src/hooks/use-mobile-touch.ts +414 -0
  114. package/src/hooks/use-performance-throttling.ts +348 -0
  115. package/src/hooks/use-performance.ts +316 -0
  116. package/src/hooks/use-reusable-architecture.ts +414 -0
  117. package/src/hooks/use-semantic-input-types.ts +357 -0
  118. package/src/hooks/use-semantic-input.ts +565 -0
  119. package/src/hooks/use-tablet-layout.ts +384 -0
  120. package/src/hooks/use-touch-friendly-input.ts +524 -0
  121. package/src/hooks/use-touch-friendly-interface.ts +331 -0
  122. package/src/hooks/use-touch-optimization.ts +375 -0
  123. package/src/index.ts +279 -279
  124. package/src/lib/utils.ts +6 -0
  125. package/src/themes/README.md +272 -0
  126. package/src/themes/ThemeContext.tsx +31 -0
  127. package/src/themes/ThemeProvider.tsx +232 -0
  128. package/src/themes/accessibility/index.ts +27 -0
  129. package/src/themes/accessibility.ts +259 -0
  130. package/src/themes/aria-patterns.ts +420 -0
  131. package/src/themes/base-themes.ts +55 -0
  132. package/src/themes/colorManager.ts +380 -0
  133. package/src/themes/examples/dark-theme.ts +154 -0
  134. package/src/themes/examples/minimal-theme.ts +108 -0
  135. package/src/themes/focus-management.ts +701 -0
  136. package/src/themes/fontLoader.ts +201 -0
  137. package/src/themes/high-contrast.ts +621 -0
  138. package/src/themes/index.ts +19 -0
  139. package/src/themes/inheritance.ts +227 -0
  140. package/src/themes/keyboard-navigation.ts +550 -0
  141. package/src/themes/motion-reduction.ts +662 -0
  142. package/src/themes/navigation.ts +238 -0
  143. package/src/themes/screen-reader.ts +645 -0
  144. package/src/themes/systemThemeDetector.ts +182 -0
  145. package/src/themes/themeCSSUpdater.ts +262 -0
  146. package/src/themes/themePersistence.ts +238 -0
  147. package/src/themes/themes/default.ts +586 -0
  148. package/src/themes/themes/harvey.ts +554 -0
  149. package/src/themes/themes/stan-design.ts +683 -0
  150. package/src/themes/types.ts +460 -0
  151. package/src/themes/useSystemTheme.ts +48 -0
  152. package/src/themes/useTheme.ts +87 -0
  153. package/src/themes/validation.ts +462 -0
  154. package/src/tokens/index.ts +34 -0
  155. package/src/tokens/tokenExporter.ts +397 -0
  156. package/src/tokens/tokenGenerator.ts +276 -0
  157. package/src/tokens/tokenManager.ts +248 -0
  158. package/src/tokens/tokenValidator.ts +543 -0
  159. package/src/tokens/types.ts +78 -0
  160. package/src/utils/bundle-analyzer.ts +260 -0
  161. package/src/utils/bundle-splitting.ts +483 -0
  162. package/src/utils/lazy-loading.ts +441 -0
  163. package/src/utils/performance-monitor.ts +513 -0
  164. package/src/utils/tree-shaking.ts +274 -0
@@ -0,0 +1,462 @@
1
+ // Theme Validation System
2
+ // This file provides comprehensive validation for theme configurations
3
+
4
+ import {
5
+ MultiThemeConfig,
6
+ ThemeValidationResult,
7
+ ThemeValidationError,
8
+ ThemeValidationWarning
9
+ } from './types';
10
+ import { ColorManager } from './colorManager';
11
+
12
+ export class ThemeValidator {
13
+ private static readonly REQUIRED_FIELDS = [
14
+ 'fonts.primary.family',
15
+ 'fonts.primary.sizes.md',
16
+ 'colors.primary.500',
17
+ 'colors.semantic.success',
18
+ 'colors.semantic.error',
19
+ 'colors.semantic.warning',
20
+ 'colors.semantic.info',
21
+ 'colors.surface.background',
22
+ 'colors.text.primary',
23
+ 'spacing.scale.md',
24
+ 'shadows.md',
25
+ 'transitions.duration.normal',
26
+ 'transitions.easing.ease',
27
+ 'meta.name',
28
+ 'meta.description',
29
+ 'meta.version'
30
+ ];
31
+
32
+ private static readonly COLOR_FORMATS = {
33
+ hex: /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/,
34
+ rgb: /^rgb\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*\)$/,
35
+ rgba: /^rgba\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*,\s*[\d.]+\s*\)$/,
36
+ hsl: /^hsl\(\s*\d+\s*,\s*\d+%\s*,\s*\d+%\s*\)$/,
37
+ hsla: /^hsla\(\s*\d+\s*,\s*\d+%\s*,\s*\d+%\s*,\s*[\d.]+\s*\)$/
38
+ };
39
+
40
+ private static readonly FONT_WEIGHTS = [100, 200, 300, 400, 500, 600, 700, 800, 900];
41
+
42
+ /**
43
+ * Validate a complete theme configuration
44
+ */
45
+ static validateTheme(theme: MultiThemeConfig): ThemeValidationResult {
46
+ const errors: ThemeValidationError[] = [];
47
+ const warnings: ThemeValidationWarning[] = [];
48
+
49
+ // Validate required fields
50
+ this.validateRequiredFields(theme, errors);
51
+
52
+ // Validate color formats
53
+ this.validateColorFormats(theme, errors, warnings);
54
+
55
+ // Validate color contrast
56
+ this.validateColorContrast(theme, warnings);
57
+
58
+ // Validate font configurations
59
+ this.validateFontConfigurations(theme, warnings);
60
+
61
+ // Validate spacing scales
62
+ this.validateSpacingScales(theme, warnings);
63
+
64
+ // Validate navigation configurations
65
+ this.validateNavigationConfigurations(theme, errors, warnings);
66
+
67
+ // Validate metadata
68
+ this.validateMetadata(theme, errors, warnings);
69
+
70
+ // Validate semantic consistency
71
+ this.validateSemanticConsistency(theme, warnings);
72
+
73
+ return {
74
+ isValid: errors.length === 0,
75
+ errors,
76
+ warnings
77
+ };
78
+ }
79
+
80
+ /**
81
+ * Validate that all required fields are present
82
+ */
83
+ private static validateRequiredFields(theme: MultiThemeConfig, errors: ThemeValidationError[]): void {
84
+ for (const fieldPath of this.REQUIRED_FIELDS) {
85
+ const value = this.getNestedValue(theme, fieldPath);
86
+ if (value === undefined || value === null || value === '') {
87
+ errors.push({
88
+ path: fieldPath,
89
+ message: `Required field '${fieldPath}' is missing or empty`,
90
+ severity: 'error'
91
+ });
92
+ }
93
+ }
94
+ }
95
+
96
+ /**
97
+ * Validate color format consistency
98
+ */
99
+ private static validateColorFormats(theme: MultiThemeConfig, errors: ThemeValidationError[], warnings: ThemeValidationWarning[]): void {
100
+ const colorFields = this.getAllColorFields(theme);
101
+ const formats = new Set<string>();
102
+
103
+ for (const { path, value } of colorFields) {
104
+ if (typeof value === 'string') {
105
+ // Use colorManager for validation
106
+ if (!ColorManager.isValidColor(value)) {
107
+ errors.push({
108
+ path,
109
+ message: `Invalid color format: '${value}'. Expected hex, rgb, hsl, or named color format`,
110
+ severity: 'error'
111
+ });
112
+ } else {
113
+ const format = this.detectColorFormat(value);
114
+ if (format) {
115
+ formats.add(format);
116
+ }
117
+ }
118
+ }
119
+ }
120
+
121
+ // Warn if multiple color formats are used
122
+ if (formats.size > 1) {
123
+ warnings.push({
124
+ path: 'colors',
125
+ message: `Multiple color formats detected: ${Array.from(formats).join(', ')}. Consider using a consistent format for better maintainability`,
126
+ severity: 'warning'
127
+ });
128
+ }
129
+ }
130
+
131
+ /**
132
+ * Validate color contrast ratios
133
+ */
134
+ private static validateColorContrast(theme: MultiThemeConfig, warnings: ThemeValidationWarning[]): void {
135
+ const textColors = [
136
+ theme.colors?.text?.primary,
137
+ theme.colors?.text?.secondary,
138
+ theme.colors?.text?.muted
139
+ ].filter(Boolean);
140
+
141
+ const backgroundColors = [
142
+ theme.colors?.surface?.background,
143
+ theme.colors?.surface?.surface
144
+ ].filter(Boolean);
145
+
146
+ for (const textColor of textColors) {
147
+ for (const bgColor of backgroundColors) {
148
+ if (textColor && bgColor) {
149
+ // Use colorManager for contrast checking
150
+ const accessibility = ColorManager.checkColorContrast(textColor, bgColor);
151
+
152
+ if (!accessibility.aa) {
153
+ warnings.push({
154
+ path: 'colors',
155
+ message: `Color contrast ratio ${accessibility.contrastRatio.toFixed(2)}:1 between '${textColor}' and '${bgColor}' is below WCAG AA standard (4.5:1)`,
156
+ severity: 'warning'
157
+ });
158
+ } else if (!accessibility.aaa) {
159
+ warnings.push({
160
+ path: 'colors',
161
+ message: `Color contrast ratio ${accessibility.contrastRatio.toFixed(2)}:1 between '${textColor}' and '${bgColor}' is below WCAG AAA standard (7:1)`,
162
+ severity: 'info'
163
+ });
164
+ }
165
+
166
+ // Add accessibility recommendations
167
+ if (accessibility.recommended.length > 0) {
168
+ warnings.push({
169
+ path: 'colors',
170
+ message: `Accessibility recommendations: ${accessibility.recommended.join('; ')}`,
171
+ severity: 'info'
172
+ });
173
+ }
174
+ }
175
+ }
176
+ }
177
+ }
178
+
179
+ /**
180
+ * Validate font configurations
181
+ */
182
+ private static validateFontConfigurations(theme: MultiThemeConfig, warnings: ThemeValidationWarning[]): void {
183
+ // Validate font weights
184
+ if (theme.fonts?.primary?.weights) {
185
+ for (const weight of theme.fonts.primary.weights) {
186
+ if (!this.FONT_WEIGHTS.includes(weight)) {
187
+ warnings.push({
188
+ path: 'fonts.primary.weights',
189
+ message: `Font weight ${weight} is not a standard CSS font weight. Consider using: ${this.FONT_WEIGHTS.join(', ')}`,
190
+ severity: 'warning'
191
+ });
192
+ }
193
+ }
194
+ }
195
+
196
+ // Validate font size scale
197
+ if (theme.fonts?.primary?.sizes) {
198
+ const sizes = Object.values(theme.fonts.primary.sizes);
199
+ const numericSizes = sizes.map(size => parseFloat(size)).filter(size => !isNaN(size));
200
+
201
+ if (numericSizes.length > 1) {
202
+ for (let i = 1; i < numericSizes.length; i++) {
203
+ if (numericSizes[i] <= numericSizes[i - 1]) {
204
+ warnings.push({
205
+ path: 'fonts.primary.sizes',
206
+ message: `Font sizes should be in ascending order. Found: ${numericSizes[i - 1]} followed by ${numericSizes[i]}`,
207
+ severity: 'warning'
208
+ });
209
+ }
210
+ }
211
+ }
212
+ }
213
+
214
+ // Validate font family fallbacks
215
+ if (theme.fonts?.primary?.family) {
216
+ const family = theme.fonts.primary.family;
217
+ if (!family.includes(',') && !family.includes('"') && !family.includes("'")) {
218
+ warnings.push({
219
+ path: 'fonts.primary.family',
220
+ message: `Font family '${family}' should include fallback fonts for better cross-platform compatibility`,
221
+ severity: 'warning'
222
+ });
223
+ }
224
+ }
225
+ }
226
+
227
+ /**
228
+ * Validate spacing scales
229
+ */
230
+ private static validateSpacingScales(theme: MultiThemeConfig, warnings: ThemeValidationWarning[]): void {
231
+ if (theme.spacing?.scale) {
232
+ const scales = Object.values(theme.spacing.scale);
233
+ const numericScales = scales.map(scale => parseFloat(scale)).filter(scale => !isNaN(scale));
234
+
235
+ if (numericScales.length > 1) {
236
+ // Check if spacing follows a consistent pattern
237
+ const ratios = [];
238
+ for (let i = 1; i < numericScales.length; i++) {
239
+ ratios.push(numericScales[i] / numericScales[i - 1]);
240
+ }
241
+
242
+ const avgRatio = ratios.reduce((sum, ratio) => sum + ratio, 0) / ratios.length;
243
+ const variance = ratios.reduce((sum, ratio) => sum + Math.pow(ratio - avgRatio, 2), 0) / ratios.length;
244
+
245
+ if (variance > 0.1) { // High variance indicates inconsistent spacing
246
+ warnings.push({
247
+ path: 'spacing.scale',
248
+ message: `Spacing scale appears inconsistent. Consider using a mathematical scale (e.g., 1.5x or 2x multiplier) for better visual harmony`,
249
+ severity: 'warning'
250
+ });
251
+ }
252
+ }
253
+ }
254
+ }
255
+
256
+ /**
257
+ * Validate navigation configurations
258
+ */
259
+ private static validateNavigationConfigurations(theme: MultiThemeConfig, _errors: ThemeValidationError[], warnings: ThemeValidationWarning[]): void {
260
+ if (theme.navigation) {
261
+ // Validate layout and behavior combinations
262
+ const { layout, behavior } = theme.navigation;
263
+
264
+ if (layout === 'sidebar' && behavior === 'floating') {
265
+ warnings.push({
266
+ path: 'navigation',
267
+ message: 'Sidebar layout with floating behavior may cause usability issues. Consider using static or sticky behavior',
268
+ severity: 'warning'
269
+ });
270
+ }
271
+
272
+ if (layout === 'tabs' && behavior === 'overlay') {
273
+ warnings.push({
274
+ path: 'navigation',
275
+ message: 'Tab layout with overlay behavior is unusual. Consider using static or sticky behavior',
276
+ severity: 'warning'
277
+ });
278
+ }
279
+
280
+ // Validate responsive behavior
281
+ if (theme.navigation.responsive === 'desktop-first' && layout === 'horizontal') {
282
+ warnings.push({
283
+ path: 'navigation',
284
+ message: 'Desktop-first responsive approach with horizontal layout may cause mobile usability issues',
285
+ severity: 'warning'
286
+ });
287
+ }
288
+ }
289
+ }
290
+
291
+ /**
292
+ * Validate metadata
293
+ */
294
+ private static validateMetadata(theme: MultiThemeConfig, errors: ThemeValidationError[], warnings: ThemeValidationWarning[]): void {
295
+ if (theme.meta) {
296
+ // Validate version format
297
+ if (theme.meta.version && !/^\d+\.\d+\.\d+/.test(theme.meta.version)) {
298
+ warnings.push({
299
+ path: 'meta.version',
300
+ message: `Version '${theme.meta.version}' should follow semantic versioning (e.g., 1.0.0)`,
301
+ severity: 'warning'
302
+ });
303
+ }
304
+
305
+ // Validate category
306
+ if (theme.meta.category && !['brand', 'enterprise', 'custom', 'accessibility'].includes(theme.meta.category)) {
307
+ errors.push({
308
+ path: 'meta.category',
309
+ message: `Invalid category '${theme.meta.category}'. Must be one of: brand, enterprise, custom, accessibility`,
310
+ severity: 'error'
311
+ });
312
+ }
313
+
314
+ // Validate tags
315
+ if (theme.meta.tags && theme.meta.tags.length > 10) {
316
+ warnings.push({
317
+ path: 'meta.tags',
318
+ message: `Theme has ${theme.meta.tags.length} tags. Consider limiting to 10 tags for better organization`,
319
+ severity: 'warning'
320
+ });
321
+ }
322
+ }
323
+ }
324
+
325
+ /**
326
+ * Validate semantic consistency
327
+ */
328
+ private static validateSemanticConsistency(theme: MultiThemeConfig, warnings: ThemeValidationWarning[]): void {
329
+ // Check if semantic colors are distinct from primary colors
330
+ if (theme.colors?.semantic && theme.colors?.primary) {
331
+ const semanticColors = Object.values(theme.colors.semantic);
332
+ const primaryColors = Object.values(theme.colors.primary);
333
+
334
+ for (const semanticColor of semanticColors) {
335
+ for (const primaryColor of primaryColors) {
336
+ if (this.colorsAreSimilar(semanticColor, primaryColor)) {
337
+ warnings.push({
338
+ path: 'colors.semantic',
339
+ message: `Semantic color '${semanticColor}' is too similar to primary color '${primaryColor}'. Consider using more distinct colors for better semantic clarity`,
340
+ severity: 'warning'
341
+ });
342
+ }
343
+ }
344
+ }
345
+ }
346
+ }
347
+
348
+ /**
349
+ * Helper: Get nested value from object using dot notation
350
+ */
351
+ private static getNestedValue(obj: any, path: string): any {
352
+ return path.split('.').reduce((current, key) => current?.[key], obj);
353
+ }
354
+
355
+ /**
356
+ * Helper: Get all color fields from theme
357
+ */
358
+ private static getAllColorFields(theme: MultiThemeConfig): Array<{ path: string; value: any }> {
359
+ const fields: Array<{ path: string; value: any }> = [];
360
+
361
+ const traverseColors = (obj: any, path: string) => {
362
+ if (obj && typeof obj === 'object') {
363
+ for (const [key, value] of Object.entries(obj)) {
364
+ const currentPath = path ? `${path}.${key}` : key;
365
+ if (typeof value === 'string' && this.isColorValue(value)) {
366
+ fields.push({ path: currentPath, value });
367
+ } else if (typeof value === 'object') {
368
+ traverseColors(value, currentPath);
369
+ }
370
+ }
371
+ }
372
+ };
373
+
374
+ traverseColors(theme.colors, 'colors');
375
+ return fields;
376
+ }
377
+
378
+ /**
379
+ * Helper: Detect color format
380
+ */
381
+ private static detectColorFormat(color: string): string | null {
382
+ for (const [format, regex] of Object.entries(this.COLOR_FORMATS)) {
383
+ if (regex.test(color)) {
384
+ return format;
385
+ }
386
+ }
387
+ return null;
388
+ }
389
+
390
+ /**
391
+ * Helper: Check if value looks like a color
392
+ */
393
+ private static isColorValue(value: string): boolean {
394
+ // Accept any string that might be a color, let detectColorFormat validate it
395
+ return value.startsWith('#') ||
396
+ value.startsWith('rgb') ||
397
+ value.startsWith('hsl') ||
398
+ value.startsWith('var(--') ||
399
+ value === 'transparent' ||
400
+ value === 'currentColor' ||
401
+ value === 'inherit' ||
402
+ // Also accept any string that might be a color (for validation)
403
+ value.includes('color') ||
404
+ value.includes('invalid');
405
+ }
406
+
407
+ /**
408
+ * Helper: Calculate color contrast ratio
409
+ */
410
+ private static calculateColorContrast(color1: string, color2: string): number {
411
+ try {
412
+ const luminance1 = this.getLuminance(color1);
413
+ const luminance2 = this.getLuminance(color2);
414
+
415
+ const lighter = Math.max(luminance1, luminance2);
416
+ const darker = Math.min(luminance1, luminance2);
417
+
418
+ return (lighter + 0.05) / (darker + 0.05);
419
+ } catch {
420
+ return 1; // Default fallback
421
+ }
422
+ }
423
+
424
+ /**
425
+ * Helper: Get luminance of a color
426
+ */
427
+ private static getLuminance(color: string): number {
428
+ // Handle CSS variables and other formats
429
+ if (color.startsWith('var(--') || color === 'transparent' || color === 'currentColor' || color === 'inherit') {
430
+ return 0.5; // Default fallback
431
+ }
432
+
433
+ // Convert hex to RGB and calculate luminance
434
+ try {
435
+ const hex = color.replace('#', '');
436
+ const r = parseInt(hex.substr(0, 2), 16) / 255;
437
+ const g = parseInt(hex.substr(2, 2), 16) / 255;
438
+ const b = parseInt(hex.substr(4, 2), 16) / 255;
439
+
440
+ const [rs, gs, bs] = [r, g, b].map(c => {
441
+ if (c <= 0.03928) return c / 12.92;
442
+ return Math.pow((c + 0.055) / 1.055, 2.4);
443
+ });
444
+
445
+ return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;
446
+ } catch {
447
+ return 0.5; // Default fallback
448
+ }
449
+ }
450
+
451
+ /**
452
+ * Helper: Check if two colors are similar
453
+ */
454
+ private static colorsAreSimilar(color1: string, color2: string): boolean {
455
+ try {
456
+ const contrast = this.calculateColorContrast(color1, color2);
457
+ return contrast < 2.0; // Very low contrast indicates similar colors
458
+ } catch {
459
+ return false;
460
+ }
461
+ }
462
+ }
@@ -0,0 +1,34 @@
1
+ // Core token types and interfaces
2
+ export type {
3
+ DesignToken,
4
+ TokenType,
5
+ ColorToken,
6
+ FontToken,
7
+ SpacingToken,
8
+ ShadowToken,
9
+ TransitionToken,
10
+ TokenGroup,
11
+ ThemeTokens,
12
+ TokenExportOptions
13
+ } from './types';
14
+
15
+ // Token generation
16
+ export { TokenGenerator } from './tokenGenerator';
17
+
18
+ // Token export functionality
19
+ export { TokenExporter } from './tokenExporter';
20
+
21
+ // Token validation
22
+ export type { ValidationResult, ValidationError, ValidationWarning } from './tokenValidator';
23
+ export { TokenValidator } from './tokenValidator';
24
+
25
+ // Main token manager
26
+ export type { TokenManagerOptions } from './tokenManager';
27
+ export { TokenManager } from './tokenManager';
28
+
29
+ // Convenience functions
30
+ import { TokenManager, type TokenManagerOptions } from './tokenManager';
31
+ export const createTokenManager = (options?: TokenManagerOptions) => new TokenManager(options);
32
+
33
+ // Default token manager instance
34
+ export const defaultTokenManager = new TokenManager();