@shohojdhara/atomix 0.3.12 → 0.3.14

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 (155) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +2 -0
  3. package/dist/atomix.css +101 -88
  4. package/dist/atomix.css.map +1 -1
  5. package/dist/atomix.min.css +5 -15258
  6. package/dist/atomix.min.css.map +1 -1
  7. package/dist/charts.d.ts +1 -1
  8. package/dist/charts.js +17 -19
  9. package/dist/charts.js.map +1 -1
  10. package/dist/core.d.ts +41 -11
  11. package/dist/core.js +55 -41
  12. package/dist/core.js.map +1 -1
  13. package/dist/forms.d.ts +28 -11
  14. package/dist/forms.js +25 -24
  15. package/dist/forms.js.map +1 -1
  16. package/dist/heavy.d.ts +1 -1
  17. package/dist/heavy.js +32 -25
  18. package/dist/heavy.js.map +1 -1
  19. package/dist/index.d.ts +122 -46
  20. package/dist/index.esm.js +865 -200
  21. package/dist/index.esm.js.map +1 -1
  22. package/dist/index.js +870 -204
  23. package/dist/index.js.map +1 -1
  24. package/dist/index.min.js +1 -1
  25. package/dist/index.min.js.map +1 -1
  26. package/dist/theme.d.ts +27 -2
  27. package/dist/theme.js +721 -108
  28. package/dist/theme.js.map +1 -1
  29. package/package.json +1 -1
  30. package/scripts/atomix-cli.js +610 -1111
  31. package/scripts/cli/component-generator.js +610 -0
  32. package/scripts/cli/documentation-sync.js +542 -0
  33. package/scripts/cli/interactive-init.js +84 -288
  34. package/scripts/cli/mappings.js +211 -0
  35. package/scripts/cli/migration-tools.js +95 -288
  36. package/scripts/cli/template-manager.js +107 -0
  37. package/scripts/cli/templates/README.md +123 -0
  38. package/scripts/cli/templates/composable-templates.js +149 -0
  39. package/scripts/cli/templates/config-templates.js +126 -0
  40. package/scripts/cli/templates/index.js +95 -0
  41. package/scripts/cli/templates/project-templates.js +214 -0
  42. package/scripts/cli/templates/react-templates.js +261 -0
  43. package/scripts/cli/templates/scss-templates.js +156 -0
  44. package/scripts/cli/templates/storybook-templates.js +236 -0
  45. package/scripts/cli/templates/testing-templates.js +45 -0
  46. package/scripts/cli/templates/token-templates.js +447 -0
  47. package/scripts/cli/templates/types-templates.js +133 -0
  48. package/scripts/cli/templates-original-backup.js +1655 -0
  49. package/scripts/cli/templates.js +35 -0
  50. package/scripts/cli/templates_backup.js +684 -0
  51. package/scripts/cli/theme-bridge.js +20 -14
  52. package/scripts/cli/token-manager.js +150 -77
  53. package/scripts/cli/utils.js +37 -25
  54. package/src/components/Accordion/Accordion.stories.tsx +5 -5
  55. package/src/components/Accordion/Accordion.test.tsx +57 -0
  56. package/src/components/Accordion/Accordion.tsx +4 -0
  57. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +41 -44
  58. package/src/components/AtomixGlass/stories/AtomixGlass.stories.tsx +1 -1
  59. package/src/components/AtomixGlass/stories/Examples.stories.tsx +37 -37
  60. package/src/components/AtomixGlass/stories/Modes.stories.tsx +1 -2
  61. package/src/components/AtomixGlass/stories/Playground.stories.tsx +50 -51
  62. package/src/components/Avatar/Avatar.stories.tsx +26 -26
  63. package/src/components/Badge/Badge.stories.tsx +31 -31
  64. package/src/components/Badge/Badge.test.tsx +51 -0
  65. package/src/components/Badge/Badge.tsx +20 -1
  66. package/src/components/Block/Block.stories.tsx +5 -5
  67. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +1 -1
  68. package/src/components/Breadcrumb/Breadcrumb.tsx +2 -2
  69. package/src/components/Button/Button.stories.tsx +13 -13
  70. package/src/components/Button/Button.tsx +4 -4
  71. package/src/components/Button/ButtonGroup.stories.tsx +2 -2
  72. package/src/components/Button/README.md +5 -0
  73. package/src/components/Callout/Callout.stories.tsx +11 -11
  74. package/src/components/Callout/Callout.test.tsx +10 -10
  75. package/src/components/Callout/Callout.tsx +7 -7
  76. package/src/components/Callout/README.md +9 -8
  77. package/src/components/Card/Card.tsx +2 -2
  78. package/src/components/Chart/Chart.stories.tsx +6 -6
  79. package/src/components/Chart/Chart.tsx +1 -1
  80. package/src/components/ColorModeToggle/ColorModeToggle.stories.tsx +1 -1
  81. package/src/components/DataTable/DataTable.tsx +14 -12
  82. package/src/components/DatePicker/DatePicker.stories.tsx +6 -6
  83. package/src/components/Dropdown/Dropdown.stories.tsx +4 -4
  84. package/src/components/Form/Checkbox.stories.tsx +3 -3
  85. package/src/components/Form/Checkbox.tsx +4 -2
  86. package/src/components/Form/Form.stories.tsx +3 -3
  87. package/src/components/Form/FormGroup.stories.tsx +1 -1
  88. package/src/components/Form/Input.stories.tsx +28 -16
  89. package/src/components/Form/Input.test.tsx +59 -0
  90. package/src/components/Form/Input.tsx +97 -95
  91. package/src/components/Form/Radio.stories.tsx +94 -94
  92. package/src/components/Form/Radio.tsx +2 -2
  93. package/src/components/Form/Select.stories.tsx +4 -4
  94. package/src/components/Form/Select.tsx +2 -2
  95. package/src/components/Form/Textarea.stories.tsx +22 -7
  96. package/src/components/Form/Textarea.test.tsx +45 -0
  97. package/src/components/Form/Textarea.tsx +88 -86
  98. package/src/components/List/List.stories.tsx +2 -2
  99. package/src/components/Modal/Modal.stories.tsx +4 -4
  100. package/src/components/Navigation/Navbar/Navbar.stories.tsx +5 -5
  101. package/src/components/Navigation/Navbar/Navbar.tsx +1 -1
  102. package/src/components/Navigation/README.md +1 -1
  103. package/src/components/Pagination/Pagination.stories.tsx +5 -2
  104. package/src/components/Pagination/Pagination.tsx +1 -1
  105. package/src/components/PhotoViewer/PhotoViewer.stories.tsx +10 -10
  106. package/src/components/Popover/Popover.stories.tsx +1 -1
  107. package/src/components/ProductReview/ProductReview.tsx +1 -1
  108. package/src/components/Progress/Progress.tsx +46 -46
  109. package/src/components/Rating/Rating.stories.tsx +4 -4
  110. package/src/components/Rating/Rating.tsx +8 -8
  111. package/src/components/Slider/Slider.stories.tsx +63 -63
  112. package/src/components/Spinner/Spinner.stories.tsx +2 -2
  113. package/src/components/Spinner/Spinner.test.tsx +35 -0
  114. package/src/components/Spinner/Spinner.tsx +9 -2
  115. package/src/components/Testimonial/Testimonial.stories.tsx +1 -1
  116. package/src/components/Toggle/Toggle.stories.tsx +32 -9
  117. package/src/components/Toggle/Toggle.test.tsx +91 -0
  118. package/src/components/Toggle/Toggle.tsx +44 -27
  119. package/src/components/Tooltip/Tooltip.tsx +1 -1
  120. package/src/layouts/Grid/Grid.stories.tsx +49 -49
  121. package/src/layouts/MasonryGrid/MasonryGrid.stories.tsx +2 -2
  122. package/src/lib/composables/useAccordion.ts +12 -3
  123. package/src/lib/composables/useBreadcrumb.ts +2 -2
  124. package/src/lib/composables/useCallout.ts +7 -7
  125. package/src/lib/composables/useNavbar.ts +1 -1
  126. package/src/lib/constants/components.ts +1 -1
  127. package/src/lib/storybook/InteractiveDemo.tsx +113 -0
  128. package/src/lib/storybook/PreviewContainer.tsx +36 -0
  129. package/src/lib/storybook/VariantsGrid.tsx +21 -0
  130. package/src/lib/storybook/index.ts +3 -0
  131. package/src/lib/theme/core/createThemeObject.ts +9 -5
  132. package/src/lib/theme/devtools/CLI.ts +155 -0
  133. package/src/lib/theme/devtools/DesignTokensCustomizer.stories.tsx +213 -0
  134. package/src/lib/theme/devtools/DesignTokensCustomizer.tsx +566 -0
  135. package/src/lib/theme/devtools/LiveEditor.tsx +2 -1
  136. package/src/lib/theme/devtools/index.ts +3 -0
  137. package/src/lib/theme/errors/errors.ts +8 -0
  138. package/src/lib/theme/runtime/ThemeProvider.tsx +117 -57
  139. package/src/lib/theme/runtime/__tests__/ThemeProvider.integration.test.tsx +305 -0
  140. package/src/lib/theme/runtime/__tests__/ThemeProvider.test.tsx +588 -0
  141. package/src/lib/theme/utils/__tests__/themeValidation.test.ts +264 -0
  142. package/src/lib/theme/utils/index.ts +1 -0
  143. package/src/lib/theme/utils/themeValidation.ts +501 -0
  144. package/src/lib/theme-tools.ts +32 -3
  145. package/src/lib/types/components.ts +81 -26
  146. package/src/lib/utils/themeNaming.ts +1 -1
  147. package/src/styles/06-components/_components.atomix-glass.scss +14 -15
  148. package/src/styles/06-components/_components.callout.scss +29 -33
  149. package/src/styles/06-components/_index.scss +1 -1
  150. package/src/styles/99-utilities/_utilities.display.scss +14 -3
  151. package/src/styles/99-utilities/_utilities.flex.scss +10 -10
  152. package/src/styles/99-utilities/_utilities.text.scss +28 -8
  153. package/scripts/cli/__tests__/cli-commands.test.js +0 -204
  154. package/scripts/cli/__tests__/utils.test.js +0 -201
  155. package/scripts/cli/__tests__/vitest.config.js +0 -26
@@ -0,0 +1,264 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import {
3
+ validateDesignTokens,
4
+ validateColorFormats,
5
+ validateRequiredTokens,
6
+ validateAccessibility,
7
+ validateColorFormat,
8
+ getContrastRatioBetweenColors,
9
+ validateContrastRatio,
10
+ validateAndMergeTokens
11
+ } from '../themeValidation';
12
+ import { defaultTokens } from '../../tokens/tokens';
13
+
14
+ describe('Theme Validation', () => {
15
+ describe('validateColorFormat', () => {
16
+ it('should validate valid hex colors', () => {
17
+ expect(validateColorFormat('#ff0000')).toBe(true);
18
+ expect(validateColorFormat('#abc')).toBe(true);
19
+ expect(validateColorFormat('#123456')).toBe(true);
20
+ expect(validateColorFormat('#abcdef12')).toBe(true); // with alpha
21
+ });
22
+
23
+ it('should validate valid RGB/RGBA colors', () => {
24
+ expect(validateColorFormat('rgb(255, 0, 0)')).toBe(true);
25
+ expect(validateColorFormat('rgba(255, 0, 0, 0.5)')).toBe(true);
26
+ expect(validateColorFormat('rgb(0, 128, 255)')).toBe(true);
27
+ });
28
+
29
+ it('should validate valid HSL/HSLA colors', () => {
30
+ expect(validateColorFormat('hsl(0, 100%, 50%)')).toBe(true);
31
+ expect(validateColorFormat('hsla(120, 75%, 25%, 0.8)')).toBe(true);
32
+ expect(validateColorFormat('hsl(229, 75%, 66%)')).toBe(true);
33
+ });
34
+
35
+ it('should reject invalid color formats', () => {
36
+ expect(validateColorFormat('not-a-color')).toBe(false);
37
+ expect(validateColorFormat('#gggggg')).toBe(false);
38
+ expect(validateColorFormat('rgb(300, 0, 0)')).toBe(false);
39
+ expect(validateColorFormat('hsl(400, 50%, 50%)')).toBe(false);
40
+ expect(validateColorFormat('')).toBe(false);
41
+ });
42
+ });
43
+
44
+ describe('getContrastRatioBetweenColors', () => {
45
+ it('should calculate contrast ratio correctly', () => {
46
+ const ratio = getContrastRatioBetweenColors('#ffffff', '#000000');
47
+ expect(ratio).toBeCloseTo(21, 0); // White on black should be very high contrast
48
+
49
+ const lowRatio = getContrastRatioBetweenColors('#808080', '#808080');
50
+ expect(lowRatio).toBe(1); // Same color should be 1:1
51
+ });
52
+
53
+ it('should return null for invalid colors', () => {
54
+ const result = getContrastRatioBetweenColors('#ffffff', 'invalid-color');
55
+ expect(result).toBeNull();
56
+ });
57
+ });
58
+
59
+ describe('validateContrastRatio', () => {
60
+ it('should validate contrast ratios', () => {
61
+ const result = validateContrastRatio('#ffffff', '#000000');
62
+ expect(result.valid).toBe(true);
63
+ expect(result.ratio).toBeGreaterThan(20);
64
+
65
+ const lowContrast = validateContrastRatio('#cccccc', '#dddddd');
66
+ expect(lowContrast.valid).toBe(false);
67
+ expect(lowContrast.ratio).toBeLessThan(4.5);
68
+ });
69
+
70
+ it('should handle large text requirements', () => {
71
+ const result = validateContrastRatio('#cccccc', '#dddddd', true);
72
+ expect(result.valid).toBe(false);
73
+ expect(result.requiredRatio).toBe(3);
74
+ });
75
+ });
76
+
77
+ describe('validateColorFormats', () => {
78
+ it('should validate valid color tokens', () => {
79
+ const validTokens = {
80
+ primary: '#667eea',
81
+ secondary: '#764ba2',
82
+ success: '#10b981',
83
+ };
84
+
85
+ const result = validateColorFormats(validTokens);
86
+ expect(result.valid).toBe(true);
87
+ expect(result.errors).toHaveLength(0);
88
+ });
89
+
90
+ it('should detect invalid color formats', () => {
91
+ const invalidTokens = {
92
+ primary: 'not-a-color',
93
+ secondary: '#gggggg',
94
+ success: '#10b981',
95
+ };
96
+
97
+ const result = validateColorFormats(invalidTokens);
98
+ expect(result.valid).toBe(false);
99
+ expect(result.errors.length).toBe(2);
100
+ expect(result.errors.some(error => error.includes('primary'))).toBe(true);
101
+ expect(result.errors.some(error => error.includes('secondary'))).toBe(true);
102
+ });
103
+
104
+ it('should handle non-string values', () => {
105
+ const mixedTokens = {
106
+ primary: '#667eea',
107
+ secondary: 123, // invalid type
108
+ };
109
+
110
+ const result = validateColorFormats(mixedTokens);
111
+ expect(result.valid).toBe(false);
112
+ expect(result.errors.length).toBe(1);
113
+ expect(result.errors[0]).toContain('secondary');
114
+ });
115
+ });
116
+
117
+ describe('validateRequiredTokens', () => {
118
+ it('should validate complete tokens with all required tokens', () => {
119
+ const result = validateRequiredTokens(defaultTokens);
120
+ expect(result.valid).toBe(true);
121
+ expect(result.errors).toHaveLength(0);
122
+ });
123
+
124
+ it('should detect missing required tokens', () => {
125
+ const incompleteTokens = {
126
+ secondary: '#764ba2',
127
+ success: '#10b981',
128
+ // missing primary and other required tokens
129
+ };
130
+
131
+ const result = validateRequiredTokens(incompleteTokens);
132
+ expect(result.valid).toBe(false);
133
+ expect(result.errors.length).toBeGreaterThan(0);
134
+ expect(result.errors.some(error => error.includes('primary'))).toBe(true);
135
+ });
136
+
137
+ it('should provide warnings for missing RGB versions', () => {
138
+ const tokensWithoutRgb = {
139
+ primary: '#667eea',
140
+ secondary: '#764ba2',
141
+ success: '#10b981',
142
+ info: '#3b82f6',
143
+ warning: '#f59e0b',
144
+ error: '#ef4444',
145
+ light: '#f8f9fa',
146
+ dark: '#212529',
147
+ 'primary-text-emphasis': '#495057',
148
+ 'secondary-text-emphasis': '#6c757d',
149
+ 'tertiary-text-emphasis': '#868e96',
150
+ 'disabled-text-emphasis': '#adb5bd',
151
+ };
152
+
153
+ const result = validateRequiredTokens(tokensWithoutRgb);
154
+ expect(result.warnings.length).toBeGreaterThan(0);
155
+ expect(result.warnings.some(warning => warning.includes('RGB version'))).toBe(true);
156
+ });
157
+ });
158
+
159
+ describe('validateAccessibility', () => {
160
+ it('should validate contrast ratios for accessibility-critical combinations', () => {
161
+ const validTokens = {
162
+ ...defaultTokens,
163
+ 'primary-text-emphasis': '#000000',
164
+ 'primary-bg-subtle': '#ffffff',
165
+ 'secondary-text-emphasis': '#333333',
166
+ 'secondary-bg-subtle': '#f8f9fa',
167
+ 'error-text-emphasis': '#721c24',
168
+ 'error-bg-subtle': '#f8d7da',
169
+ 'success-text-emphasis': '#155724',
170
+ 'success-bg-subtle': '#d4edda',
171
+ };
172
+
173
+ const result = validateAccessibility(validTokens);
174
+ expect(result.valid).toBe(true);
175
+ });
176
+
177
+ it('should detect poor contrast ratios', () => {
178
+ const poorContrastTokens = {
179
+ 'primary-text-emphasis': '#cccccc', // low contrast
180
+ 'primary-bg-subtle': '#dddddd',
181
+ };
182
+
183
+ const result = validateAccessibility(poorContrastTokens);
184
+ expect(result.valid).toBe(false);
185
+ expect(result.errors.length).toBeGreaterThan(0);
186
+ expect(result.errors[0]).toMatch(/contrast ratio.*below required/);
187
+ });
188
+
189
+ it('should provide warnings for missing accessibility check tokens', () => {
190
+ const incompleteTokens = {
191
+ 'primary-text-emphasis': '#000000',
192
+ // missing primary-bg-subtle
193
+ };
194
+
195
+ const result = validateAccessibility(incompleteTokens);
196
+ expect(result.warnings.length).toBeGreaterThan(0);
197
+ });
198
+ });
199
+
200
+ describe('validateDesignTokens', () => {
201
+ it('should validate complete and valid design tokens', () => {
202
+ // Skip accessibility validation as defaultTokens have known contrast issues
203
+ const result = validateDesignTokens(defaultTokens, { skipAccessibility: true });
204
+ expect(result.valid).toBe(true);
205
+ expect(result.errors).toHaveLength(0);
206
+ });
207
+
208
+ it('should detect validation errors', () => {
209
+ const invalidTokens = {
210
+ primary: 'invalid-color',
211
+ secondary: '#764ba2',
212
+ success: '#10b981',
213
+ };
214
+
215
+ const result = validateDesignTokens(invalidTokens);
216
+ expect(result.valid).toBe(false);
217
+ expect(result.errors.length).toBeGreaterThan(0);
218
+ });
219
+
220
+ it('should allow skipping certain validations', () => {
221
+ const invalidTokens = {
222
+ primary: 'invalid-color',
223
+ secondary: '#764ba2',
224
+ };
225
+
226
+ const result = validateDesignTokens(invalidTokens, {
227
+ skipColorValidation: true,
228
+ skipRequiredTokens: true,
229
+ skipAccessibility: true
230
+ });
231
+
232
+ expect(result.valid).toBe(true);
233
+ expect(result.errors).toHaveLength(0);
234
+ });
235
+ });
236
+
237
+ describe('validateAndMergeTokens', () => {
238
+ it('should merge partial tokens with defaults and validate', () => {
239
+ const partialTokens = {
240
+ primary: '#8b5cf6',
241
+ 'primary-hover': '#7c3aed',
242
+ };
243
+
244
+ const result = validateAndMergeTokens(partialTokens);
245
+ // Note: validation may fail due to accessibility issues in defaultTokens
246
+ // but tokens should still be merged correctly
247
+ expect(result.tokens.primary).toBe('#8b5cf6');
248
+ expect(result.tokens.secondary).toBe(defaultTokens.secondary); // from defaults
249
+ // Check that our custom tokens were added
250
+ expect(result.tokens['primary-hover']).toBe('#7c3aed');
251
+ });
252
+
253
+ it('should handle invalid partial tokens', () => {
254
+ const invalidPartialTokens = {
255
+ primary: 'invalid-color',
256
+ secondary: '#764ba2',
257
+ };
258
+
259
+ const result = validateAndMergeTokens(invalidPartialTokens);
260
+ expect(result.validation.valid).toBe(false);
261
+ expect(result.tokens.primary).toBe('invalid-color'); // still includes invalid token
262
+ });
263
+ });
264
+ });
@@ -6,6 +6,7 @@
6
6
 
7
7
  export * from './themeHelpers';
8
8
  export * from './themeUtils';
9
+ export * from './themeValidation';
9
10
  export * from './domUtils';
10
11
  export * from './injectCSS';
11
12