@shohojdhara/atomix 0.4.7 → 0.4.9

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 (176) hide show
  1. package/atomix.config.ts +58 -1
  2. package/dist/atomix.css +172 -157
  3. package/dist/atomix.css.map +1 -1
  4. package/dist/atomix.min.css +4 -4
  5. package/dist/atomix.min.css.map +1 -1
  6. package/dist/charts.d.ts +33 -0
  7. package/dist/charts.js +1274 -164
  8. package/dist/charts.js.map +1 -1
  9. package/dist/core.d.ts +33 -10
  10. package/dist/core.js +1099 -83
  11. package/dist/core.js.map +1 -1
  12. package/dist/forms.d.ts +33 -0
  13. package/dist/forms.js +2106 -1050
  14. package/dist/forms.js.map +1 -1
  15. package/dist/heavy.d.ts +42 -1
  16. package/dist/heavy.js +1663 -638
  17. package/dist/heavy.js.map +1 -1
  18. package/dist/index.d.ts +442 -270
  19. package/dist/index.esm.js +1947 -680
  20. package/dist/index.esm.js.map +1 -1
  21. package/dist/index.js +1982 -712
  22. package/dist/index.js.map +1 -1
  23. package/dist/index.min.js +1 -1
  24. package/dist/index.min.js.map +1 -1
  25. package/package.json +6 -3
  26. package/scripts/atomix-cli.js +136 -1827
  27. package/scripts/cli/__tests__/basic.test.js +3 -2
  28. package/scripts/cli/__tests__/clean.test.js +278 -0
  29. package/scripts/cli/__tests__/component-validator.test.js +433 -0
  30. package/scripts/cli/__tests__/generator.test.js +613 -0
  31. package/scripts/cli/__tests__/glass-motion.test.js +256 -0
  32. package/scripts/cli/__tests__/integration.test.js +719 -108
  33. package/scripts/cli/__tests__/migrate.test.js +74 -0
  34. package/scripts/cli/__tests__/security.test.js +206 -0
  35. package/scripts/cli/__tests__/test-setup.js +3 -1
  36. package/scripts/cli/__tests__/theme-bridge.test.js +507 -0
  37. package/scripts/cli/__tests__/token-provider.test.js +361 -0
  38. package/scripts/cli/__tests__/utils.test.js +5 -5
  39. package/scripts/cli/commands/benchmark.js +105 -0
  40. package/scripts/cli/commands/build-theme.js +115 -0
  41. package/scripts/cli/commands/clean.js +109 -0
  42. package/scripts/cli/commands/doctor.js +88 -0
  43. package/scripts/cli/commands/generate.js +218 -0
  44. package/scripts/cli/commands/init.js +73 -0
  45. package/scripts/cli/commands/migrate.js +106 -0
  46. package/scripts/cli/commands/sync-tokens.js +206 -0
  47. package/scripts/cli/commands/theme-bridge.js +248 -0
  48. package/scripts/cli/commands/tokens.js +157 -0
  49. package/scripts/cli/commands/validate.js +194 -0
  50. package/scripts/cli/internal/ai-engine.js +156 -0
  51. package/scripts/cli/internal/compiler.js +114 -0
  52. package/scripts/cli/internal/component-validator.js +443 -0
  53. package/scripts/cli/internal/config-loader.js +162 -0
  54. package/scripts/cli/internal/filesystem.js +158 -0
  55. package/scripts/cli/internal/generator.js +430 -0
  56. package/scripts/cli/internal/glass-generator.js +398 -0
  57. package/scripts/cli/internal/hook-generator.js +369 -0
  58. package/scripts/cli/internal/hooks.js +61 -0
  59. package/scripts/cli/internal/itcss-generator.js +565 -0
  60. package/scripts/cli/internal/motion-generator.js +679 -0
  61. package/scripts/cli/internal/template-engine.js +301 -0
  62. package/scripts/cli/internal/theme-bridge.js +664 -0
  63. package/scripts/cli/internal/tokens/engine.js +122 -0
  64. package/scripts/cli/internal/tokens/provider.js +34 -0
  65. package/scripts/cli/internal/tokens/providers/figma.js +50 -0
  66. package/scripts/cli/internal/tokens/providers/style-dictionary.js +48 -0
  67. package/scripts/cli/internal/tokens/providers/w3c.js +48 -0
  68. package/scripts/cli/internal/tokens/token-provider.js +443 -0
  69. package/scripts/cli/internal/tokens/token-validator.js +513 -0
  70. package/scripts/cli/internal/validator.js +276 -0
  71. package/scripts/cli/internal/wizard.js +115 -0
  72. package/scripts/cli/mappings.js +23 -0
  73. package/scripts/cli/migration-tools.js +164 -94
  74. package/scripts/cli/plugins/style-dictionary.js +46 -0
  75. package/scripts/cli/templates/README.md +525 -95
  76. package/scripts/cli/templates/common-templates.js +40 -14
  77. package/scripts/cli/templates/components/react-component.ts +282 -0
  78. package/scripts/cli/templates/config/project-config.ts +112 -0
  79. package/scripts/cli/templates/hooks/use-component.ts +477 -0
  80. package/scripts/cli/templates/index.js +19 -4
  81. package/scripts/cli/templates/index.ts +171 -0
  82. package/scripts/cli/templates/next-templates.js +72 -0
  83. package/scripts/cli/templates/react-templates.js +70 -126
  84. package/scripts/cli/templates/scss-templates.js +35 -35
  85. package/scripts/cli/templates/stories/storybook-story.ts +241 -0
  86. package/scripts/cli/templates/styles/scss-component.ts +255 -0
  87. package/scripts/cli/templates/tests/vitest-test.ts +229 -0
  88. package/scripts/cli/templates/token-templates.js +337 -1
  89. package/scripts/cli/templates/tokens/token-generators.ts +1088 -0
  90. package/scripts/cli/templates/types/component-types.ts +145 -0
  91. package/scripts/cli/templates/utils/testing-utils.ts +144 -0
  92. package/scripts/cli/templates/vanilla-templates.js +39 -0
  93. package/scripts/cli/token-manager.js +8 -2
  94. package/scripts/cli/utils/cache-manager.js +240 -0
  95. package/scripts/cli/utils/detector.js +46 -0
  96. package/scripts/cli/utils/diagnostics.js +289 -0
  97. package/scripts/cli/utils/error.js +89 -0
  98. package/scripts/cli/utils/helpers.js +67 -0
  99. package/scripts/cli/utils/logger.js +75 -0
  100. package/scripts/cli/utils/security.js +302 -0
  101. package/scripts/cli/utils/telemetry.js +115 -0
  102. package/scripts/cli/utils/validation.js +37 -0
  103. package/scripts/cli/utils.js +28 -341
  104. package/src/components/Accordion/Accordion.stories.tsx +0 -18
  105. package/src/components/Accordion/Accordion.test.tsx +0 -17
  106. package/src/components/Accordion/Accordion.tsx +0 -4
  107. package/src/components/AtomixGlass/AtomixGlass.test.tsx +37 -3
  108. package/src/components/AtomixGlass/AtomixGlass.tsx +143 -31
  109. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +129 -31
  110. package/src/components/AtomixGlass/PerformanceDashboard.tsx +219 -0
  111. package/src/components/AtomixGlass/README.md +25 -10
  112. package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +216 -0
  113. package/src/components/AtomixGlass/animation-system.ts +578 -0
  114. package/src/components/AtomixGlass/shader-utils.ts +4 -1
  115. package/src/components/AtomixGlass/stories/Overview.stories.tsx +157 -6
  116. package/src/components/AtomixGlass/stories/Phase1-Animation.stories.tsx +653 -0
  117. package/src/components/AtomixGlass/stories/Phase1-Test.stories.tsx +95 -0
  118. package/src/components/AtomixGlass/stories/Playground.stories.tsx +51 -51
  119. package/src/components/AtomixGlass/stories/shared-components.tsx +6 -0
  120. package/src/components/Avatar/Avatar.tsx +1 -1
  121. package/src/components/Button/Button.stories.disabled-link.tsx +10 -0
  122. package/src/components/Button/Button.stories.tsx +10 -0
  123. package/src/components/Button/Button.test.tsx +16 -11
  124. package/src/components/Button/Button.tsx +4 -4
  125. package/src/components/Card/Card.tsx +1 -1
  126. package/src/components/Dropdown/Dropdown.tsx +12 -12
  127. package/src/components/Form/Select.tsx +62 -3
  128. package/src/components/Modal/Modal.tsx +14 -3
  129. package/src/components/Navigation/Navbar/Navbar.tsx +44 -0
  130. package/src/components/Slider/Slider.stories.tsx +3 -3
  131. package/src/components/Slider/Slider.tsx +38 -0
  132. package/src/components/Steps/Steps.tsx +3 -3
  133. package/src/components/Tabs/Tabs.tsx +77 -8
  134. package/src/components/Testimonial/Testimonial.tsx +1 -1
  135. package/src/components/TypedButton/TypedButton.stories.tsx +59 -0
  136. package/src/components/TypedButton/TypedButton.tsx +39 -0
  137. package/src/components/TypedButton/index.ts +2 -0
  138. package/src/components/VideoPlayer/VideoPlayer.tsx +11 -4
  139. package/src/lib/composables/index.ts +4 -7
  140. package/src/lib/composables/types.ts +45 -0
  141. package/src/lib/composables/useAccordion.ts +0 -7
  142. package/src/lib/composables/useAtomixGlass.ts +148 -6
  143. package/src/lib/composables/useAtomixGlassStyles.ts +9 -7
  144. package/src/lib/composables/useChartExport.ts +3 -13
  145. package/src/lib/composables/useDropdown.ts +66 -0
  146. package/src/lib/composables/useFocusTrap.ts +80 -0
  147. package/src/lib/composables/usePerformanceMonitor.ts +448 -0
  148. package/src/lib/composables/useResponsiveGlass.presets.ts +192 -0
  149. package/src/lib/composables/useResponsiveGlass.ts +441 -0
  150. package/src/lib/composables/useTooltip.ts +16 -0
  151. package/src/lib/composables/useTypedButton.ts +66 -0
  152. package/src/lib/config/index.ts +62 -5
  153. package/src/lib/constants/components.ts +62 -7
  154. package/src/lib/theme/devtools/__tests__/useHistory.test.tsx +150 -0
  155. package/src/lib/theme/tokens/centralized-tokens.ts +120 -0
  156. package/src/lib/theme/utils/__tests__/domUtils.test.ts +101 -0
  157. package/src/lib/types/components.ts +37 -11
  158. package/src/lib/types/glass.ts +35 -0
  159. package/src/lib/types/index.ts +1 -0
  160. package/src/lib/utils/displacement-generator.ts +1 -1
  161. package/src/styles/01-settings/_settings.testtypecheck.scss +53 -0
  162. package/src/styles/01-settings/_settings.typedbutton.scss +53 -0
  163. package/src/styles/06-components/_components.atomix-glass.scss +17 -21
  164. package/src/styles/06-components/_components.edge-panel.scss +1 -5
  165. package/src/styles/06-components/_components.modal.scss +1 -4
  166. package/src/styles/06-components/_components.navbar.scss +1 -1
  167. package/src/styles/06-components/_components.testbutton.scss +212 -0
  168. package/src/styles/06-components/_components.testtypecheck.scss +212 -0
  169. package/src/styles/06-components/_components.tooltip.scss +9 -5
  170. package/src/styles/06-components/_components.typedbutton.scss +212 -0
  171. package/src/styles/99-utilities/_index.scss +1 -0
  172. package/src/styles/99-utilities/_utilities.text.scss +1 -1
  173. package/src/styles/99-utilities/_utilities.touch-target.scss +36 -0
  174. package/scripts/cli/component-generator.js +0 -564
  175. package/scripts/cli/interactive-init.js +0 -357
  176. package/src/styles/06-components/old.chart.styles.scss +0 -2788
@@ -0,0 +1,664 @@
1
+ /**
2
+ * Atomix CLI Theme Bridge Generator
3
+ * Automatically syncs design tokens with theme providers (Tailwind, CSS-in-JS, etc.)
4
+ */
5
+
6
+ import { writeFile, mkdir } from 'fs/promises';
7
+ import { dirname, join } from 'path';
8
+ import { filesystem } from './filesystem.js';
9
+ import { tokenProvider } from './tokens/token-provider.js';
10
+ import { AtomixCLIError } from '../utils/error.js';
11
+ import chalk from 'chalk';
12
+
13
+ /**
14
+ * Theme provider types supported by Atomix
15
+ */
16
+ export const THEME_PROVIDERS = {
17
+ TAILWIND: 'tailwind',
18
+ CSS_IN_JS: 'css-in-js',
19
+ EMOTION: 'emotion',
20
+ STYLED_COMPONENTS: 'styled-components',
21
+ VANILLA_EXTRACT: 'vanilla-extract',
22
+ CSS_VARIABLES: 'css-variables'
23
+ };
24
+
25
+ /**
26
+ * Generates Tailwind theme configuration from design tokens
27
+ * @param {Object} tokens - Design tokens object
28
+ * @returns {string} Tailwind theme configuration
29
+ */
30
+ export function generateTailwindTheme(tokens) {
31
+ const themeConfig = [];
32
+
33
+ // Colors
34
+ if (tokens.colors) {
35
+ themeConfig.push(' colors: {');
36
+ Object.entries(tokens.colors).forEach(([key, value]) => {
37
+ if (typeof value === 'object') {
38
+ // Handle nested color objects by expanding them
39
+ themeConfig.push(` ${key}: {`);
40
+ Object.entries(value).forEach(([variant, variantValue]) => {
41
+ themeConfig.push(` ${variant}: '${variantValue}',`);
42
+ });
43
+ themeConfig.push(' },');
44
+ } else {
45
+ themeConfig.push(` ${key}: '${value}',`);
46
+ }
47
+ });
48
+ themeConfig.push(' },');
49
+ }
50
+
51
+ // Spacing
52
+ if (tokens.spacing) {
53
+ themeConfig.push(' spacing: {');
54
+ Object.entries(tokens.spacing).forEach(([key, value]) => {
55
+ themeConfig.push(` ${key}: '${value}',`);
56
+ });
57
+ themeConfig.push(' },');
58
+ }
59
+
60
+ // Typography
61
+ if (tokens.typography) {
62
+ if (tokens.typography.fontSize) {
63
+ themeConfig.push(' fontSize: {');
64
+ Object.entries(tokens.typography.fontSize).forEach(([key, value]) => {
65
+ const size = typeof value === 'object' ? value.size : value;
66
+ themeConfig.push(` ${key}: '${size}',`);
67
+ });
68
+ themeConfig.push(' },');
69
+ }
70
+
71
+ if (tokens.typography.fontFamily) {
72
+ themeConfig.push(' fontFamily: {');
73
+ Object.entries(tokens.typography.fontFamily).forEach(([key, value]) => {
74
+ themeConfig.push(` ${key}: [${JSON.stringify(value)}],`);
75
+ });
76
+ themeConfig.push(' },');
77
+ }
78
+ }
79
+
80
+ // Breakpoints
81
+ if (tokens.breakpoints) {
82
+ themeConfig.push(' screens: {');
83
+ Object.entries(tokens.breakpoints).forEach(([key, value]) => {
84
+ themeConfig.push(` ${key}: '${value}',`);
85
+ });
86
+ themeConfig.push(' },');
87
+ }
88
+
89
+ // Shadows
90
+ if (tokens.shadows) {
91
+ themeConfig.push(' boxShadow: {');
92
+ Object.entries(tokens.shadows).forEach(([key, value]) => {
93
+ themeConfig.push(` ${key}: '${value}',`);
94
+ });
95
+ themeConfig.push(' },');
96
+ }
97
+
98
+ // Border Radius
99
+ if (tokens.radius) {
100
+ themeConfig.push(' borderRadius: {');
101
+ Object.entries(tokens.radius).forEach(([key, value]) => {
102
+ themeConfig.push(` ${key}: '${value}',`);
103
+ });
104
+ themeConfig.push(' },');
105
+ }
106
+
107
+ // Animation
108
+ if (tokens.animation) {
109
+ themeConfig.push(' animation: {');
110
+ Object.entries(tokens.animation).forEach(([key, value]) => {
111
+ if (typeof value === 'string') {
112
+ themeConfig.push(` ${key}: '${value}',`);
113
+ }
114
+ });
115
+ themeConfig.push(' },');
116
+
117
+ themeConfig.push(' keyframes: {');
118
+ Object.entries(tokens.animation).forEach(([key, value]) => {
119
+ if (typeof value === 'object' && value.keyframes) {
120
+ themeConfig.push(` ${key}: ${JSON.stringify(value.keyframes)},`);
121
+ }
122
+ });
123
+ themeConfig.push(' },');
124
+ }
125
+
126
+ themeConfig.push('}');
127
+
128
+ return `module.exports = {
129
+ theme: {
130
+ ${themeConfig.join('\n')}
131
+ };
132
+ `;
133
+ }
134
+
135
+ /**
136
+ * Generates CSS-in-JS theme object from design tokens
137
+ * @param {Object} tokens - Design tokens object
138
+ * @param {string} provider - CSS-in-JS provider (emotion, styled-components, vanilla-extract)
139
+ * @returns {string} Theme configuration
140
+ */
141
+ export function generateCssInJsTheme(tokens, provider = 'emotion') {
142
+ const lines = [];
143
+
144
+ if (provider === 'vanilla-extract') {
145
+ lines.push("import { createGlobalTheme } from '@vanilla-extract/css';\n");
146
+ lines.push('export const theme = createGlobalTheme(\':root\', {');
147
+ } else {
148
+ lines.push('export const theme = {');
149
+ }
150
+
151
+ // Colors
152
+ if (tokens.colors) {
153
+ lines.push(' colors: {');
154
+ Object.entries(tokens.colors).forEach(([key, value]) => {
155
+ if (typeof value === 'object') {
156
+ // Expand nested color objects
157
+ lines.push(` ${key}: {`);
158
+ Object.entries(value).forEach(([variant, variantValue]) => {
159
+ lines.push(` ${variant}: '${variantValue}',`);
160
+ });
161
+ lines.push(' },');
162
+ } else {
163
+ lines.push(` ${key}: '${value}',`);
164
+ }
165
+ });
166
+ lines.push(' },');
167
+ }
168
+
169
+ // Spacing
170
+ if (tokens.spacing) {
171
+ lines.push(' space: {');
172
+ Object.entries(tokens.spacing).forEach(([key, value]) => {
173
+ lines.push(` ${key}: '${value}',`);
174
+ });
175
+ lines.push(' },');
176
+ }
177
+
178
+ // Typography
179
+ if (tokens.typography) {
180
+ lines.push(' fonts: {');
181
+ if (tokens.typography.fontFamily) {
182
+ Object.entries(tokens.typography.fontFamily).forEach(([key, value]) => {
183
+ lines.push(` ${key}: '${value}',`);
184
+ });
185
+ }
186
+ lines.push(' },');
187
+
188
+ if (tokens.typography.fontSize) {
189
+ lines.push(' fontSizes: {');
190
+ Object.entries(tokens.typography.fontSize).forEach(([key, value]) => {
191
+ const size = typeof value === 'object' ? value.size : value;
192
+ lines.push(` ${key}: '${size}',`);
193
+ });
194
+ lines.push(' },');
195
+ }
196
+ }
197
+
198
+ // Breakpoints
199
+ if (tokens.breakpoints) {
200
+ lines.push(' breakpoints: {');
201
+ Object.entries(tokens.breakpoints).forEach(([key, value]) => {
202
+ lines.push(` ${key}: '${value}',`);
203
+ });
204
+ lines.push(' },');
205
+ }
206
+
207
+ // Shadows
208
+ if (tokens.shadows) {
209
+ lines.push(' shadows: {');
210
+ Object.entries(tokens.shadows).forEach(([key, value]) => {
211
+ lines.push(` ${key}: '${value}',`);
212
+ });
213
+ lines.push(' },');
214
+ }
215
+
216
+ // Border Radius
217
+ if (tokens.radius) {
218
+ lines.push(' radii: {');
219
+ Object.entries(tokens.radius).forEach(([key, value]) => {
220
+ lines.push(` ${key}: '${value}',`);
221
+ });
222
+ lines.push(' },');
223
+ }
224
+
225
+ // Z-index
226
+ if (tokens.zIndex) {
227
+ lines.push(' zIndices: {');
228
+ Object.entries(tokens.zIndex).forEach(([key, value]) => {
229
+ lines.push(` ${key}: ${value},`);
230
+ });
231
+ lines.push(' },');
232
+ }
233
+
234
+ lines.push('};');
235
+
236
+ if (provider === 'vanilla-extract') {
237
+ lines.push('\nexport type Theme = typeof theme;');
238
+ }
239
+
240
+ return lines.join('\n');
241
+ }
242
+
243
+ /**
244
+ * Generates CSS custom properties from design tokens
245
+ * @param {Object} tokens - Design tokens object
246
+ * @param {Object} options - Generation options
247
+ * @returns {string} CSS custom properties
248
+ */
249
+ export function generateCssVariables(tokens, options = {}) {
250
+ const { selector = ':root', prefix = 'atomix' } = options;
251
+ const lines = [`${selector} {`];
252
+
253
+ // Colors
254
+ if (tokens.colors) {
255
+ Object.entries(tokens.colors).forEach(([key, value]) => {
256
+ if (typeof value === 'object') {
257
+ // Handle color variants (light/dark mode)
258
+ if (value.base) {
259
+ lines.push(` --${prefix}-${key}: ${value.base};`);
260
+ }
261
+ if (value.light) {
262
+ lines.push(` --${prefix}-${key}-light: ${value.light};`);
263
+ }
264
+ if (value.dark) {
265
+ lines.push(` --${prefix}-${key}-dark: ${value.dark};`);
266
+ }
267
+ } else {
268
+ lines.push(` --${prefix}-${key}: ${value};`);
269
+ }
270
+ });
271
+ }
272
+
273
+ // Spacing
274
+ if (tokens.spacing) {
275
+ Object.entries(tokens.spacing).forEach(([key, value]) => {
276
+ lines.push(` --${prefix}-space-${key}: ${value};`);
277
+ });
278
+ }
279
+
280
+ // Typography
281
+ if (tokens.typography) {
282
+ if (tokens.typography.fontFamily) {
283
+ Object.entries(tokens.typography.fontFamily).forEach(([key, value]) => {
284
+ lines.push(` --${prefix}-font-${key}: ${value};`);
285
+ });
286
+ }
287
+
288
+ if (tokens.typography.fontSize) {
289
+ Object.entries(tokens.typography.fontSize).forEach(([key, value]) => {
290
+ const size = typeof value === 'object' ? value.size : value;
291
+ lines.push(` --${prefix}-text-${key}: ${size};`);
292
+ });
293
+ }
294
+ }
295
+
296
+ // Breakpoints
297
+ if (tokens.breakpoints) {
298
+ Object.entries(tokens.breakpoints).forEach(([key, value]) => {
299
+ lines.push(` --${prefix}-breakpoint-${key}: ${value};`);
300
+ });
301
+ }
302
+
303
+ // Shadows
304
+ if (tokens.shadows) {
305
+ Object.entries(tokens.shadows).forEach(([key, value]) => {
306
+ lines.push(` --${prefix}-shadow-${key}: ${value};`);
307
+ });
308
+ }
309
+
310
+ // Border Radius
311
+ if (tokens.radius) {
312
+ Object.entries(tokens.radius).forEach(([key, value]) => {
313
+ lines.push(` --${prefix}-radius-${key}: ${value};`);
314
+ });
315
+ }
316
+
317
+ // Z-index
318
+ if (tokens.zIndex) {
319
+ Object.entries(tokens.zIndex).forEach(([key, value]) => {
320
+ lines.push(` --${prefix}-z-${key}: ${value};`);
321
+ });
322
+ }
323
+
324
+ // Motion
325
+ if (tokens.motion) {
326
+ if (tokens.motion.duration) {
327
+ Object.entries(tokens.motion.duration).forEach(([key, value]) => {
328
+ lines.push(` --${prefix}-duration-${key}: ${value};`);
329
+ });
330
+ }
331
+
332
+ if (tokens.motion.easing) {
333
+ Object.entries(tokens.motion.easing).forEach(([key, value]) => {
334
+ lines.push(` --${prefix}-easing-${key}: ${value};`);
335
+ });
336
+ }
337
+ }
338
+
339
+ lines.push('}');
340
+
341
+ return lines.join('\n');
342
+ }
343
+
344
+ /**
345
+ * Syncs design tokens to Tailwind config
346
+ * @param {string} tokenPath - Path to design tokens file
347
+ * @param {string} outputPath - Path to output Tailwind config
348
+ * @param {Object} options - Sync options
349
+ * @returns {Promise<Object>} Result with created files
350
+ */
351
+ export async function syncToTailwind(tokenPath, outputPath, options = {}) {
352
+ try {
353
+ const tokens = await tokenProvider.loadTokens(tokenPath);
354
+ const tailwindConfig = generateTailwindTheme(tokens);
355
+
356
+ await filesystem.writeFile(outputPath, tailwindConfig, 'utf8');
357
+
358
+ return {
359
+ success: true,
360
+ created: [outputPath],
361
+ tokensSynced: Object.keys(tokens).length
362
+ };
363
+ } catch (error) {
364
+ throw new AtomixCLIError(
365
+ `Failed to sync to Tailwind: ${error.message}`,
366
+ 'TAILWIND_SYNC_FAILED',
367
+ [
368
+ 'Verify design tokens file exists and is valid',
369
+ 'Check output path is writable',
370
+ 'Ensure tokens follow expected structure'
371
+ ]
372
+ );
373
+ }
374
+ }
375
+
376
+ /**
377
+ * Syncs design tokens to CSS-in-JS theme
378
+ * @param {string} tokenPath - Path to design tokens file
379
+ * @param {string} outputPath - Path to output theme file
380
+ * @param {string} provider - CSS-in-JS provider
381
+ * @param {Object} options - Sync options
382
+ * @returns {Promise<Object>} Result with created files
383
+ */
384
+ export async function syncToCssInJs(tokenPath, outputPath, provider = 'emotion', options = {}) {
385
+ try {
386
+ const tokens = await tokenProvider.loadTokens(tokenPath);
387
+ const themeContent = generateCssInJsTheme(tokens, provider);
388
+
389
+ await filesystem.writeFile(outputPath, themeContent, 'utf8');
390
+
391
+ return {
392
+ success: true,
393
+ created: [outputPath],
394
+ tokensSynced: Object.keys(tokens).length,
395
+ provider
396
+ };
397
+ } catch (error) {
398
+ throw new AtomixCLIError(
399
+ `Failed to sync to CSS-in-JS: ${error.message}`,
400
+ 'CSS_IN_JS_SYNC_FAILED',
401
+ [
402
+ 'Verify design tokens file exists',
403
+ 'Check provider is supported (emotion, styled-components, vanilla-extract)',
404
+ 'Ensure output directory is writable'
405
+ ]
406
+ );
407
+ }
408
+ }
409
+
410
+ /**
411
+ * Syncs design tokens to CSS variables
412
+ * @param {string} tokenPath - Path to design tokens file
413
+ * @param {string} outputPath - Path to output CSS file
414
+ * @param {Object} options - Sync options
415
+ * @returns {Promise<Object>} Result with created files
416
+ */
417
+ export async function syncToCssVariables(tokenPath, outputPath, options = {}) {
418
+ try {
419
+ const tokens = await tokenProvider.loadTokens(tokenPath);
420
+ const cssContent = generateCssVariables(tokens, options);
421
+
422
+ await filesystem.writeFile(outputPath, cssContent, 'utf8');
423
+
424
+ return {
425
+ success: true,
426
+ created: [outputPath],
427
+ tokensSynced: Object.keys(tokens).length
428
+ };
429
+ } catch (error) {
430
+ throw new AtomixCLIError(
431
+ `Failed to sync to CSS variables: ${error.message}`,
432
+ 'CSS_VARIABLES_SYNC_FAILED',
433
+ [
434
+ 'Verify design tokens file exists',
435
+ 'Check output path is writable',
436
+ 'Ensure tokens have valid values'
437
+ ]
438
+ );
439
+ }
440
+ }
441
+
442
+ /**
443
+ * Creates a complete theme package with all formats
444
+ * @param {string} tokenPath - Path to design tokens file
445
+ * @param {string} outputDir - Output directory for theme files
446
+ * @param {Object} options - Generation options
447
+ * @returns {Promise<Object>} Result with all created files
448
+ */
449
+ export async function createThemePackage(tokenPath, outputDir, options = {}) {
450
+ const results = {
451
+ success: true,
452
+ created: [],
453
+ tokensSynced: 0,
454
+ formats: []
455
+ };
456
+
457
+ try {
458
+ const tokens = await tokenProvider.loadTokens(tokenPath);
459
+ results.tokensSynced = Object.keys(tokens).length;
460
+
461
+ // Ensure output directory exists
462
+ await filesystem.createDirectory(outputDir);
463
+
464
+ // Generate Tailwind config
465
+ if (options.formats?.includes('tailwind') || !options.formats) {
466
+ const tailwindPath = join(outputDir, 'tailwind.theme.js');
467
+ const tailwindResult = await syncToTailwind(tokenPath, tailwindPath);
468
+ results.created.push(...tailwindResult.created);
469
+ results.formats.push('tailwind');
470
+ }
471
+
472
+ // Generate CSS-in-JS theme
473
+ if (options.formats?.includes('css-in-js') || !options.formats) {
474
+ const themePath = join(outputDir, 'theme.ts');
475
+ const themeResult = await syncToCssInJs(tokenPath, themePath, 'emotion');
476
+ results.created.push(...themeResult.created);
477
+ results.formats.push('css-in-js');
478
+ }
479
+
480
+ // Generate CSS variables
481
+ if (options.formats?.includes('css-variables') || !options.formats) {
482
+ const cssPath = join(outputDir, 'variables.css');
483
+ const cssResult = await syncToCssVariables(tokenPath, cssPath, options);
484
+ results.created.push(...cssResult.created);
485
+ results.formats.push('css-variables');
486
+ }
487
+
488
+ // Generate TypeScript types
489
+ if (options.typescript !== false) {
490
+ const typesPath = join(outputDir, 'theme.types.ts');
491
+ const typesContent = generateTypeScriptTypes(tokens);
492
+ await filesystem.writeFile(typesPath, typesContent, 'utf8');
493
+ results.created.push(typesPath);
494
+ results.formats.push('typescript');
495
+ }
496
+
497
+ return results;
498
+ } catch (error) {
499
+ throw new AtomixCLIError(
500
+ `Failed to create theme package: ${error.message}`,
501
+ 'THEME_PACKAGE_CREATION_FAILED',
502
+ [
503
+ 'Verify design tokens file exists and is valid',
504
+ 'Check output directory is writable',
505
+ 'Ensure all required dependencies are installed'
506
+ ]
507
+ );
508
+ }
509
+ }
510
+
511
+ /**
512
+ * Generates TypeScript type definitions for theme
513
+ * @param {Object} tokens - Design tokens object
514
+ * @returns {string} TypeScript type definitions
515
+ */
516
+ export function generateTypeScriptTypes(tokens) {
517
+ const lines = [
518
+ '/**',
519
+ ' * Atomix Theme Type Definitions',
520
+ ' * Auto-generated from design tokens',
521
+ ' */\n',
522
+ 'export interface AtomixTheme {',
523
+ ];
524
+
525
+ if (tokens.colors) {
526
+ lines.push(' colors: {');
527
+ Object.keys(tokens.colors).forEach(key => {
528
+ lines.push(` ${key}: string;`);
529
+ });
530
+ lines.push(' };');
531
+ }
532
+
533
+ if (tokens.spacing) {
534
+ lines.push(' space: {');
535
+ Object.keys(tokens.spacing).forEach(key => {
536
+ lines.push(` ${key}: string;`);
537
+ });
538
+ lines.push(' };');
539
+ }
540
+
541
+ if (tokens.typography) {
542
+ lines.push(' fonts: {');
543
+ if (tokens.typography.fontFamily) {
544
+ Object.keys(tokens.typography.fontFamily).forEach(key => {
545
+ lines.push(` ${key}: string;`);
546
+ });
547
+ }
548
+ lines.push(' };');
549
+
550
+ lines.push(' fontSizes: {');
551
+ if (tokens.typography.fontSize) {
552
+ Object.keys(tokens.typography.fontSize).forEach(key => {
553
+ lines.push(` ${key}: string;`);
554
+ });
555
+ }
556
+ lines.push(' };');
557
+ }
558
+
559
+ if (tokens.breakpoints) {
560
+ lines.push(' breakpoints: {');
561
+ Object.keys(tokens.breakpoints).forEach(key => {
562
+ lines.push(` ${key}: string;`);
563
+ });
564
+ lines.push(' };');
565
+ }
566
+
567
+ if (tokens.shadows) {
568
+ lines.push(' shadows: {');
569
+ Object.keys(tokens.shadows).forEach(key => {
570
+ lines.push(` ${key}: string;`);
571
+ });
572
+ lines.push(' };');
573
+ }
574
+
575
+ if (tokens.radius) {
576
+ lines.push(' radii: {');
577
+ Object.keys(tokens.radius).forEach(key => {
578
+ lines.push(` ${key}: string;`);
579
+ });
580
+ lines.push(' };');
581
+ }
582
+
583
+ if (tokens.zIndex) {
584
+ lines.push(' zIndices: {');
585
+ Object.keys(tokens.zIndex).forEach(key => {
586
+ lines.push(` ${key}: number;`);
587
+ });
588
+ lines.push(' };');
589
+ }
590
+
591
+ lines.push('}\n');
592
+ lines.push('export type ThemeColor = keyof AtomixTheme[\'colors\'];');
593
+ lines.push('export type ThemeSpacing = keyof AtomixTheme[\'space\'];');
594
+ lines.push('export type ThemeFontSize = keyof AtomixTheme[\'fontSizes\'];');
595
+
596
+ return lines.join('\n');
597
+ }
598
+
599
+ /**
600
+ * Validates theme synchronization
601
+ * @param {string} tokenPath - Path to design tokens
602
+ * @param {string} themePath - Path to generated theme
603
+ * @param {string} provider - Theme provider type
604
+ * @returns {Promise<Object>} Validation result
605
+ */
606
+ export async function validateThemeSync(tokenPath, themePath, provider) {
607
+ try {
608
+ const tokens = await tokenProvider.loadTokens(tokenPath);
609
+ const themeContent = await filesystem.readFile(themePath, 'utf8');
610
+
611
+ const issues = [];
612
+ let valid = true;
613
+
614
+ // Check if all token keys are present in theme
615
+ for (const category of Object.keys(tokens)) {
616
+ const tokenKeys = Object.keys(tokens[category]);
617
+ const missingKeys = tokenKeys.filter(key => !themeContent.includes(key));
618
+
619
+ if (missingKeys.length > 0) {
620
+ valid = false;
621
+ issues.push({
622
+ severity: 'warning',
623
+ message: `Missing tokens in theme: ${missingKeys.join(', ')}`,
624
+ category
625
+ });
626
+ }
627
+ }
628
+
629
+ // Provider-specific validation
630
+ if (provider === 'tailwind') {
631
+ if (!themeContent.includes('module.exports')) {
632
+ valid = false;
633
+ issues.push({
634
+ severity: 'error',
635
+ message: 'Tailwind config must use CommonJS exports'
636
+ });
637
+ }
638
+ }
639
+
640
+ if (provider === 'css-variables') {
641
+ if (!themeContent.includes(':root')) {
642
+ valid = false;
643
+ issues.push({
644
+ severity: 'error',
645
+ message: 'CSS variables must be defined in :root selector'
646
+ });
647
+ }
648
+ }
649
+
650
+ return {
651
+ valid,
652
+ issues,
653
+ tokensChecked: Object.keys(tokens).length
654
+ };
655
+ } catch (error) {
656
+ return {
657
+ valid: false,
658
+ issues: [{
659
+ severity: 'error',
660
+ message: `Validation failed: ${error.message}`
661
+ }]
662
+ };
663
+ }
664
+ }