@rakeyshgidwani/roger-ui-bank-theme-stan-design 0.1.4 → 0.1.6

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,543 @@
1
+ import type { ThemeTokens, DesignToken, TokenType } from './types';
2
+
3
+ export interface ValidationResult {
4
+ isValid: boolean;
5
+ errors: ValidationError[];
6
+ warnings: ValidationWarning[];
7
+ }
8
+
9
+ export interface ValidationError {
10
+ path: string;
11
+ message: string;
12
+ severity: 'error' | 'critical';
13
+ }
14
+
15
+ export interface ValidationWarning {
16
+ path: string;
17
+ message: string;
18
+ suggestion?: string;
19
+ }
20
+
21
+ export class TokenValidator {
22
+ /**
23
+ * Validates a complete theme tokens object
24
+ */
25
+ static validateTokens(tokens: ThemeTokens): ValidationResult {
26
+ const errors: ValidationError[] = [];
27
+ const warnings: ValidationWarning[] = [];
28
+
29
+ // Validate basic structure
30
+ if (!tokens.theme) {
31
+ errors.push({
32
+ path: 'theme',
33
+ message: 'Theme name is required',
34
+ severity: 'critical'
35
+ });
36
+ }
37
+
38
+ if (!tokens.version) {
39
+ errors.push({
40
+ path: 'version',
41
+ message: 'Theme version is required',
42
+ severity: 'critical'
43
+ });
44
+ }
45
+
46
+ if (!tokens.tokens) {
47
+ errors.push({
48
+ path: 'tokens',
49
+ message: 'Tokens object is required',
50
+ severity: 'critical'
51
+ });
52
+ }
53
+
54
+ // Validate token categories
55
+ if (tokens.tokens) {
56
+ this.validateTokenCategory(tokens.tokens.color, 'color', errors, warnings);
57
+ this.validateTokenCategory(tokens.tokens.font, 'font', errors, warnings);
58
+ this.validateTokenCategory(tokens.tokens.spacing, 'spacing', errors, warnings);
59
+ this.validateTokenCategory(tokens.tokens.shadow, 'shadow', errors, warnings);
60
+ this.validateTokenCategory(tokens.tokens.transition, 'transition', errors, warnings);
61
+ this.validateTokenCategory(tokens.tokens.breakpoint, 'breakpoint', errors, warnings);
62
+ }
63
+
64
+ return {
65
+ isValid: errors.length === 0,
66
+ errors,
67
+ warnings
68
+ };
69
+ }
70
+
71
+ /**
72
+ * Validates a specific token category
73
+ */
74
+ private static validateTokenCategory(
75
+ category: any,
76
+ categoryName: string,
77
+ errors: ValidationError[],
78
+ warnings: ValidationWarning[]
79
+ ) {
80
+ if (!category) return;
81
+
82
+ if (typeof category !== 'object') {
83
+ errors.push({
84
+ path: `tokens.${categoryName}`,
85
+ message: `${categoryName} category must be an object`,
86
+ severity: 'error'
87
+ });
88
+ return;
89
+ }
90
+
91
+ this.validateTokenGroup(category, `tokens.${categoryName}`, errors, warnings);
92
+ }
93
+
94
+ /**
95
+ * Validates a token group recursively
96
+ */
97
+ private static validateTokenGroup(
98
+ group: any,
99
+ path: string,
100
+ errors: ValidationError[],
101
+ warnings: ValidationWarning[]
102
+ ) {
103
+ Object.entries(group).forEach(([key, value]) => {
104
+ const currentPath = `${path}.${key}`;
105
+
106
+ if (this.isToken(value)) {
107
+ this.validateToken(value as DesignToken, currentPath, errors, warnings);
108
+ } else if (typeof value === 'object' && value !== null) {
109
+ // Recursively validate nested groups
110
+ this.validateTokenGroup(value, currentPath, errors, warnings);
111
+ } else {
112
+ errors.push({
113
+ path: currentPath,
114
+ message: `Invalid token structure at ${currentPath}`,
115
+ severity: 'error'
116
+ });
117
+ }
118
+ });
119
+ }
120
+
121
+ /**
122
+ * Validates an individual token
123
+ */
124
+ private static validateToken(
125
+ token: DesignToken,
126
+ path: string,
127
+ errors: ValidationError[],
128
+ warnings: ValidationWarning[]
129
+ ) {
130
+ // Check required properties
131
+ if (token.value === undefined || token.value === null) {
132
+ errors.push({
133
+ path,
134
+ message: 'Token value is required',
135
+ severity: 'error'
136
+ });
137
+ }
138
+
139
+ if (!token.type) {
140
+ errors.push({
141
+ path,
142
+ message: 'Token type is required',
143
+ severity: 'error'
144
+ });
145
+ } else if (!this.isValidTokenType(token.type)) {
146
+ errors.push({
147
+ path,
148
+ message: `Invalid token type: ${token.type}`,
149
+ severity: 'error'
150
+ });
151
+ }
152
+
153
+ // Validate token type-specific values
154
+ this.validateTokenValue(token, path, errors, warnings);
155
+
156
+ // Check for missing descriptions (warning)
157
+ if (!token.description) {
158
+ warnings.push({
159
+ path,
160
+ message: 'Token description is missing',
161
+ suggestion: 'Add a description to improve token documentation'
162
+ });
163
+ }
164
+
165
+ // Check for missing tags (warning)
166
+ if (!token.tags || token.tags.length === 0) {
167
+ warnings.push({
168
+ path,
169
+ message: 'Token tags are missing',
170
+ suggestion: 'Add tags to improve token categorization and searchability'
171
+ });
172
+ }
173
+ }
174
+
175
+ /**
176
+ * Validates token value based on type
177
+ */
178
+ private static validateTokenValue(
179
+ token: DesignToken,
180
+ path: string,
181
+ errors: ValidationError[],
182
+ warnings: ValidationWarning[]
183
+ ) {
184
+ switch (token.type) {
185
+ case 'color':
186
+ this.validateColorToken(token, path, errors, warnings);
187
+ break;
188
+ case 'fontFamily':
189
+ this.validateFontFamilyToken(token, path, errors, warnings);
190
+ break;
191
+ case 'fontSize':
192
+ this.validateFontSizeToken(token, path, errors, warnings);
193
+ break;
194
+ case 'fontWeight':
195
+ this.validateFontWeightToken(token, path, errors, warnings);
196
+ break;
197
+ case 'lineHeight':
198
+ this.validateLineHeightToken(token, path, errors, warnings);
199
+ break;
200
+ case 'spacing':
201
+ this.validateSpacingToken(token, path, errors, warnings);
202
+ break;
203
+ case 'shadow':
204
+ this.validateShadowToken(token, path, errors, warnings);
205
+ break;
206
+ case 'transition':
207
+ this.validateTransitionToken(token, path, errors, warnings);
208
+ break;
209
+ case 'breakpoint':
210
+ this.validateBreakpointToken(token, path, errors, warnings);
211
+ break;
212
+ }
213
+ }
214
+
215
+ /**
216
+ * Validates color tokens
217
+ */
218
+ private static validateColorToken(
219
+ token: DesignToken,
220
+ path: string,
221
+ errors: ValidationError[],
222
+ warnings: ValidationWarning[]
223
+ ) {
224
+ const value = token.value as string;
225
+
226
+ if (typeof value !== 'string') {
227
+ errors.push({
228
+ path,
229
+ message: 'Color token value must be a string',
230
+ severity: 'error'
231
+ });
232
+ return;
233
+ }
234
+
235
+ // Check if it's a valid color format
236
+ if (!this.isValidColor(value)) {
237
+ errors.push({
238
+ path,
239
+ message: `Invalid color format: ${value}`,
240
+ severity: 'error'
241
+ });
242
+ }
243
+
244
+ // Check for semantic color consistency
245
+ if (token.category === 'color' && !(token as any).semantic) {
246
+ warnings.push({
247
+ path,
248
+ message: 'Semantic color missing semantic property',
249
+ suggestion: 'Add semantic property (primary, secondary, accent, success, warning, error, neutral)'
250
+ });
251
+ }
252
+ }
253
+
254
+ /**
255
+ * Validates font family tokens
256
+ */
257
+ private static validateFontFamilyToken(
258
+ token: DesignToken,
259
+ path: string,
260
+ errors: ValidationError[],
261
+ _warnings: ValidationWarning[]
262
+ ) {
263
+ const value = token.value as string;
264
+
265
+ if (typeof value !== 'string') {
266
+ errors.push({
267
+ path,
268
+ message: 'Font family token value must be a string',
269
+ severity: 'error'
270
+ });
271
+ }
272
+
273
+ if (value.trim().length === 0) {
274
+ errors.push({
275
+ path,
276
+ message: 'Font family token value cannot be empty',
277
+ severity: 'error'
278
+ });
279
+ }
280
+ }
281
+
282
+ /**
283
+ * Validates font size tokens
284
+ */
285
+ private static validateFontSizeToken(
286
+ token: DesignToken,
287
+ path: string,
288
+ errors: ValidationError[],
289
+ _warnings: ValidationWarning[]
290
+ ) {
291
+ const value = token.value as string | number;
292
+
293
+ if (typeof value === 'number') {
294
+ if (value <= 0) {
295
+ errors.push({
296
+ path,
297
+ message: 'Font size token value must be positive',
298
+ severity: 'error'
299
+ });
300
+ }
301
+ } else if (typeof value === 'string') {
302
+ if (!this.isValidCSSUnit(value)) {
303
+ errors.push({
304
+ path,
305
+ message: `Invalid font size unit: ${value}`,
306
+ severity: 'error'
307
+ });
308
+ }
309
+ } else {
310
+ errors.push({
311
+ path,
312
+ message: 'Font size token value must be a number or valid CSS unit string',
313
+ severity: 'error'
314
+ });
315
+ }
316
+ }
317
+
318
+ /**
319
+ * Validates font weight tokens
320
+ */
321
+ private static validateFontWeightToken(
322
+ token: DesignToken,
323
+ path: string,
324
+ errors: ValidationError[],
325
+ _warnings: ValidationWarning[]
326
+ ) {
327
+ const value = token.value as string | number;
328
+
329
+ if (typeof value === 'number') {
330
+ if (value < 100 || value > 900 || value % 100 !== 0) {
331
+ errors.push({
332
+ path,
333
+ message: 'Font weight token value must be a multiple of 100 between 100 and 900',
334
+ severity: 'error'
335
+ });
336
+ }
337
+ } else if (typeof value === 'string') {
338
+ const validWeights = ['normal', 'bold', 'lighter', 'bolder'];
339
+ if (!validWeights.includes(value)) {
340
+ errors.push({
341
+ path,
342
+ message: `Invalid font weight value: ${value}`,
343
+ severity: 'error'
344
+ });
345
+ }
346
+ } else {
347
+ errors.push({
348
+ path,
349
+ message: 'Font weight token value must be a number or valid string',
350
+ severity: 'error'
351
+ });
352
+ }
353
+ }
354
+
355
+ /**
356
+ * Validates line height tokens
357
+ */
358
+ private static validateLineHeightToken(
359
+ token: DesignToken,
360
+ path: string,
361
+ errors: ValidationError[],
362
+ _warnings: ValidationWarning[]
363
+ ) {
364
+ const value = token.value as string | number;
365
+
366
+ if (typeof value === 'number') {
367
+ if (value <= 0) {
368
+ errors.push({
369
+ path,
370
+ message: 'Line height token value must be positive',
371
+ severity: 'error'
372
+ });
373
+ }
374
+ } else if (typeof value === 'string') {
375
+ if (!this.isValidCSSUnit(value) && value !== 'normal') {
376
+ errors.push({
377
+ path,
378
+ message: `Invalid line height value: ${value}`,
379
+ severity: 'error'
380
+ });
381
+ }
382
+ } else {
383
+ errors.push({
384
+ path,
385
+ message: 'Line height token value must be a number or valid CSS unit string',
386
+ severity: 'error'
387
+ });
388
+ }
389
+ }
390
+
391
+ /**
392
+ * Validates spacing tokens
393
+ */
394
+ private static validateSpacingToken(
395
+ token: DesignToken,
396
+ path: string,
397
+ errors: ValidationError[],
398
+ _warnings: ValidationWarning[]
399
+ ) {
400
+ const value = token.value as number;
401
+
402
+ if (typeof value !== 'number') {
403
+ errors.push({
404
+ path,
405
+ message: 'Spacing token value must be a number',
406
+ severity: 'error'
407
+ });
408
+ return;
409
+ }
410
+
411
+ if (value < 0) {
412
+ errors.push({
413
+ path,
414
+ message: 'Spacing token value cannot be negative',
415
+ severity: 'error'
416
+ });
417
+ }
418
+ }
419
+
420
+ /**
421
+ * Validates shadow tokens
422
+ */
423
+ private static validateShadowToken(
424
+ token: DesignToken,
425
+ path: string,
426
+ errors: ValidationError[],
427
+ _warnings: ValidationWarning[]
428
+ ) {
429
+ const value = token.value as string;
430
+
431
+ if (typeof value !== 'string') {
432
+ errors.push({
433
+ path,
434
+ message: 'Shadow token value must be a string',
435
+ severity: 'error'
436
+ });
437
+ }
438
+
439
+ if (value.trim().length === 0) {
440
+ errors.push({
441
+ path,
442
+ message: 'Shadow token value cannot be empty',
443
+ severity: 'error'
444
+ });
445
+ }
446
+ }
447
+
448
+ /**
449
+ * Validates transition tokens
450
+ */
451
+ private static validateTransitionToken(
452
+ token: DesignToken,
453
+ path: string,
454
+ errors: ValidationError[],
455
+ _warnings: ValidationWarning[]
456
+ ) {
457
+ const value = token.value as string;
458
+
459
+ if (typeof value !== 'string') {
460
+ errors.push({
461
+ path,
462
+ message: 'Transition token value must be a string',
463
+ severity: 'error'
464
+ });
465
+ }
466
+
467
+ if (value.trim().length === 0) {
468
+ errors.push({
469
+ path,
470
+ message: 'Transition token value cannot be empty',
471
+ severity: 'error'
472
+ });
473
+ }
474
+ }
475
+
476
+ /**
477
+ * Validates breakpoint tokens
478
+ */
479
+ private static validateBreakpointToken(
480
+ token: DesignToken,
481
+ path: string,
482
+ errors: ValidationError[],
483
+ _warnings: ValidationWarning[]
484
+ ) {
485
+ const value = token.value as number;
486
+
487
+ if (typeof value !== 'number') {
488
+ errors.push({
489
+ path,
490
+ message: 'Breakpoint token value must be a number',
491
+ severity: 'error'
492
+ });
493
+ return;
494
+ }
495
+
496
+ if (value < 0) {
497
+ errors.push({
498
+ path,
499
+ message: 'Breakpoint token value cannot be negative',
500
+ severity: 'error'
501
+ });
502
+ }
503
+ }
504
+
505
+ /**
506
+ * Checks if a value is a valid token
507
+ */
508
+ private static isToken(value: any): value is DesignToken {
509
+ return value &&
510
+ typeof value === 'object' &&
511
+ 'value' in value &&
512
+ 'type' in value;
513
+ }
514
+
515
+ /**
516
+ * Checks if a token type is valid
517
+ */
518
+ private static isValidTokenType(type: any): type is TokenType {
519
+ const validTypes: TokenType[] = [
520
+ 'color', 'fontFamily', 'fontSize', 'fontWeight', 'lineHeight',
521
+ 'letterSpacing', 'spacing', 'borderRadius', 'shadow', 'transition',
522
+ 'zIndex', 'breakpoint'
523
+ ];
524
+ return validTypes.includes(type);
525
+ }
526
+
527
+ /**
528
+ * Checks if a color value is valid
529
+ */
530
+ private static isValidColor(color: string): boolean {
531
+ // Basic color validation - hex, rgb, rgba, named colors
532
+ const colorRegex = /^(#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})|rgb\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*\)|rgba\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*,\s*[\d.]+\s*\)|transparent|currentColor)$/;
533
+ return colorRegex.test(color);
534
+ }
535
+
536
+ /**
537
+ * Checks if a CSS unit is valid
538
+ */
539
+ private static isValidCSSUnit(value: string): boolean {
540
+ const unitRegex = /^[\d.]+(px|em|rem|vh|vw|%|ch|ex|in|cm|mm|pt|pc)$/;
541
+ return unitRegex.test(value);
542
+ }
543
+ }
@@ -0,0 +1,78 @@
1
+ export interface DesignToken {
2
+ value: string | number;
3
+ type: TokenType;
4
+ description?: string;
5
+ category?: string;
6
+ tags?: string[];
7
+ }
8
+
9
+ export type TokenType =
10
+ | 'color'
11
+ | 'fontFamily'
12
+ | 'fontSize'
13
+ | 'fontWeight'
14
+ | 'lineHeight'
15
+ | 'letterSpacing'
16
+ | 'spacing'
17
+ | 'borderRadius'
18
+ | 'shadow'
19
+ | 'transition'
20
+ | 'zIndex'
21
+ | 'breakpoint';
22
+
23
+ export interface ColorToken extends DesignToken {
24
+ type: 'color';
25
+ value: string;
26
+ contrast?: {
27
+ light: string;
28
+ dark: string;
29
+ };
30
+ semantic?: 'primary' | 'secondary' | 'accent' | 'success' | 'warning' | 'error' | 'neutral';
31
+ }
32
+
33
+ export interface FontToken extends DesignToken {
34
+ type: 'fontFamily' | 'fontSize' | 'fontWeight' | 'lineHeight' | 'letterSpacing';
35
+ value: string | number;
36
+ }
37
+
38
+ export interface SpacingToken extends DesignToken {
39
+ type: 'spacing';
40
+ value: number;
41
+ unit?: 'px' | 'rem' | 'em';
42
+ }
43
+
44
+ export interface ShadowToken extends DesignToken {
45
+ type: 'shadow';
46
+ value: string;
47
+ elevation?: 'low' | 'medium' | 'high';
48
+ }
49
+
50
+ export interface TransitionToken extends DesignToken {
51
+ type: 'transition';
52
+ value: string;
53
+ easing?: 'linear' | 'ease-in' | 'ease-out' | 'ease-in-out';
54
+ }
55
+
56
+ export interface TokenGroup {
57
+ [key: string]: DesignToken | TokenGroup;
58
+ }
59
+
60
+ export interface ThemeTokens {
61
+ theme: string;
62
+ version: string;
63
+ tokens: {
64
+ color?: TokenGroup;
65
+ font?: TokenGroup;
66
+ spacing?: TokenGroup;
67
+ shadow?: TokenGroup;
68
+ transition?: TokenGroup;
69
+ breakpoint?: TokenGroup;
70
+ };
71
+ }
72
+
73
+ export interface TokenExportOptions {
74
+ format: 'json' | 'css' | 'scss' | 'js' | 'ts';
75
+ platform?: 'web' | 'ios' | 'android' | 'figma';
76
+ includeMetadata?: boolean;
77
+ includeComments?: boolean;
78
+ }