@shohojdhara/atomix 0.4.8 → 0.5.0

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 (177) hide show
  1. package/atomix.config.ts +58 -1
  2. package/dist/atomix.css +148 -120
  3. package/dist/atomix.css.map +1 -1
  4. package/dist/atomix.min.css +1 -1
  5. package/dist/atomix.min.css.map +1 -1
  6. package/dist/charts.d.ts +33 -0
  7. package/dist/charts.js +1227 -122
  8. package/dist/charts.js.map +1 -1
  9. package/dist/core.d.ts +33 -10
  10. package/dist/core.js +1052 -41
  11. package/dist/core.js.map +1 -1
  12. package/dist/forms.d.ts +33 -0
  13. package/dist/forms.js +2086 -1035
  14. package/dist/forms.js.map +1 -1
  15. package/dist/heavy.d.ts +42 -1
  16. package/dist/heavy.js +1620 -600
  17. package/dist/heavy.js.map +1 -1
  18. package/dist/index.d.ts +441 -270
  19. package/dist/index.esm.js +1900 -638
  20. package/dist/index.esm.js.map +1 -1
  21. package/dist/index.js +1935 -670
  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 +148 -4
  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 +4 -1
  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 +135 -14
  44. package/scripts/cli/commands/init.js +45 -18
  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/component-validator.js +443 -0
  52. package/scripts/cli/internal/config-loader.js +162 -0
  53. package/scripts/cli/internal/filesystem.js +102 -2
  54. package/scripts/cli/internal/generator.js +359 -39
  55. package/scripts/cli/internal/glass-generator.js +398 -0
  56. package/scripts/cli/internal/hook-generator.js +369 -0
  57. package/scripts/cli/internal/hooks.js +61 -0
  58. package/scripts/cli/internal/itcss-generator.js +565 -0
  59. package/scripts/cli/internal/motion-generator.js +679 -0
  60. package/scripts/cli/internal/template-engine.js +301 -0
  61. package/scripts/cli/internal/theme-bridge.js +664 -0
  62. package/scripts/cli/internal/tokens/engine.js +122 -0
  63. package/scripts/cli/internal/tokens/provider.js +34 -0
  64. package/scripts/cli/internal/tokens/providers/figma.js +50 -0
  65. package/scripts/cli/internal/tokens/providers/style-dictionary.js +48 -0
  66. package/scripts/cli/internal/tokens/providers/w3c.js +48 -0
  67. package/scripts/cli/internal/tokens/token-provider.js +443 -0
  68. package/scripts/cli/internal/tokens/token-validator.js +513 -0
  69. package/scripts/cli/internal/validator.js +276 -0
  70. package/scripts/cli/internal/wizard.js +60 -6
  71. package/scripts/cli/mappings.js +23 -0
  72. package/scripts/cli/migration-tools.js +164 -94
  73. package/scripts/cli/plugins/style-dictionary.js +46 -0
  74. package/scripts/cli/templates/README.md +525 -95
  75. package/scripts/cli/templates/common-templates.js +40 -14
  76. package/scripts/cli/templates/components/react-component.ts +282 -0
  77. package/scripts/cli/templates/config/project-config.ts +112 -0
  78. package/scripts/cli/templates/hooks/use-component.ts +477 -0
  79. package/scripts/cli/templates/index.js +19 -4
  80. package/scripts/cli/templates/index.ts +171 -0
  81. package/scripts/cli/templates/next-templates.js +72 -0
  82. package/scripts/cli/templates/react-templates.js +70 -126
  83. package/scripts/cli/templates/scss-templates.js +35 -35
  84. package/scripts/cli/templates/stories/storybook-story.ts +241 -0
  85. package/scripts/cli/templates/styles/scss-component.ts +255 -0
  86. package/scripts/cli/templates/tests/vitest-test.ts +229 -0
  87. package/scripts/cli/templates/token-templates.js +337 -1
  88. package/scripts/cli/templates/tokens/token-generators.ts +1088 -0
  89. package/scripts/cli/templates/types/component-types.ts +145 -0
  90. package/scripts/cli/templates/utils/testing-utils.ts +144 -0
  91. package/scripts/cli/templates/vanilla-templates.js +39 -0
  92. package/scripts/cli/token-manager.js +8 -2
  93. package/scripts/cli/utils/cache-manager.js +240 -0
  94. package/scripts/cli/utils/detector.js +46 -0
  95. package/scripts/cli/utils/diagnostics.js +289 -0
  96. package/scripts/cli/utils/error.js +45 -3
  97. package/scripts/cli/utils/helpers.js +24 -0
  98. package/scripts/cli/utils/logger.js +1 -1
  99. package/scripts/cli/utils/security.js +302 -0
  100. package/scripts/cli/utils/telemetry.js +115 -0
  101. package/scripts/cli/utils/validation.js +4 -38
  102. package/scripts/cli/utils.js +46 -0
  103. package/src/components/Accordion/Accordion.stories.tsx +0 -18
  104. package/src/components/Accordion/Accordion.test.tsx +0 -17
  105. package/src/components/Accordion/Accordion.tsx +0 -4
  106. package/src/components/AtomixGlass/AtomixGlass.tsx +102 -2
  107. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +125 -12
  108. package/src/components/AtomixGlass/PerformanceDashboard.tsx +219 -0
  109. package/src/components/AtomixGlass/README.md +25 -10
  110. package/src/components/AtomixGlass/animation-system.ts +578 -0
  111. package/src/components/AtomixGlass/shader-utils.ts +3 -0
  112. package/src/components/AtomixGlass/stories/AnimationFeatures.stories.tsx +653 -0
  113. package/src/components/AtomixGlass/stories/AnimationTests.stories.tsx +95 -0
  114. package/src/components/AtomixGlass/stories/CardExamples.stories.tsx +212 -0
  115. package/src/components/AtomixGlass/stories/DashboardExamples.stories.tsx +348 -0
  116. package/src/components/AtomixGlass/stories/EcommerceExamples.stories.tsx +410 -0
  117. package/src/components/AtomixGlass/stories/FormExamples.stories.tsx +436 -0
  118. package/src/components/AtomixGlass/stories/HeroExamples.stories.tsx +264 -0
  119. package/src/components/AtomixGlass/stories/InteractivePlayground.stories.tsx +247 -0
  120. package/src/components/AtomixGlass/stories/MobileUIExamples.stories.tsx +418 -0
  121. package/src/components/AtomixGlass/stories/ModalExamples.stories.tsx +402 -0
  122. package/src/components/AtomixGlass/stories/Overview.stories.tsx +157 -6
  123. package/src/components/AtomixGlass/stories/Playground.stories.tsx +658 -93
  124. package/src/components/AtomixGlass/stories/PresetGallery.stories.tsx +335 -0
  125. package/src/components/AtomixGlass/stories/WidgetExamples.stories.tsx +441 -0
  126. package/src/components/AtomixGlass/stories/argTypes.ts +384 -0
  127. package/src/components/AtomixGlass/stories/shared-components.tsx +91 -1
  128. package/src/components/AtomixGlass/stories/types.ts +127 -0
  129. package/src/components/Avatar/Avatar.tsx +1 -1
  130. package/src/components/Button/Button.stories.disabled-link.tsx +10 -0
  131. package/src/components/Button/Button.stories.tsx +10 -0
  132. package/src/components/Button/Button.test.tsx +16 -11
  133. package/src/components/Button/Button.tsx +4 -4
  134. package/src/components/Card/Card.tsx +1 -1
  135. package/src/components/Dropdown/Dropdown.tsx +12 -12
  136. package/src/components/Form/Select.tsx +62 -3
  137. package/src/components/Modal/Modal.tsx +14 -3
  138. package/src/components/Navigation/Navbar/Navbar.tsx +44 -0
  139. package/src/components/Slider/Slider.stories.tsx +3 -3
  140. package/src/components/Slider/Slider.tsx +38 -0
  141. package/src/components/Steps/Steps.tsx +3 -3
  142. package/src/components/Tabs/Tabs.tsx +77 -8
  143. package/src/components/Testimonial/Testimonial.tsx +1 -1
  144. package/src/components/TypedButton/TypedButton.stories.tsx +59 -0
  145. package/src/components/TypedButton/TypedButton.tsx +39 -0
  146. package/src/components/TypedButton/index.ts +2 -0
  147. package/src/components/VideoPlayer/VideoPlayer.tsx +11 -4
  148. package/src/lib/composables/index.ts +4 -7
  149. package/src/lib/composables/types.ts +45 -0
  150. package/src/lib/composables/useAccordion.ts +0 -7
  151. package/src/lib/composables/useAtomixGlass.ts +144 -5
  152. package/src/lib/composables/useChartExport.ts +3 -13
  153. package/src/lib/composables/useDropdown.ts +66 -0
  154. package/src/lib/composables/useFocusTrap.ts +80 -0
  155. package/src/lib/composables/usePerformanceMonitor.ts +448 -0
  156. package/src/lib/composables/useResponsiveGlass.presets.ts +192 -0
  157. package/src/lib/composables/useResponsiveGlass.ts +441 -0
  158. package/src/lib/composables/useTooltip.ts +16 -0
  159. package/src/lib/composables/useTypedButton.ts +66 -0
  160. package/src/lib/config/index.ts +62 -5
  161. package/src/lib/constants/components.ts +55 -0
  162. package/src/lib/theme/devtools/__tests__/useHistory.test.tsx +150 -0
  163. package/src/lib/theme/tokens/centralized-tokens.ts +120 -0
  164. package/src/lib/theme/utils/__tests__/domUtils.test.ts +101 -0
  165. package/src/lib/types/components.ts +37 -11
  166. package/src/lib/types/glass.ts +35 -0
  167. package/src/lib/types/index.ts +1 -0
  168. package/src/lib/utils/displacement-generator.ts +1 -1
  169. package/src/styles/01-settings/_settings.testtypecheck.scss +53 -0
  170. package/src/styles/01-settings/_settings.typedbutton.scss +53 -0
  171. package/src/styles/06-components/_components.testbutton.scss +212 -0
  172. package/src/styles/06-components/_components.testtypecheck.scss +212 -0
  173. package/src/styles/06-components/_components.typedbutton.scss +212 -0
  174. package/src/styles/99-utilities/_index.scss +1 -0
  175. package/src/styles/99-utilities/_utilities.text.scss +1 -1
  176. package/src/styles/99-utilities/_utilities.touch-target.scss +36 -0
  177. package/src/styles/06-components/old.chart.styles.scss +0 -2788
@@ -0,0 +1,1088 @@
1
+ /**
2
+ * Token Generation Templates (TypeScript)
3
+ * Design system token generators following W3C DTCG format
4
+ *
5
+ * @module templates/tokens
6
+ */
7
+
8
+ import type { CSSProperties } from 'react';
9
+
10
+ /**
11
+ * Token category types
12
+ */
13
+ export type TokenCategory =
14
+ | 'color'
15
+ | 'spacing'
16
+ | 'typography'
17
+ | 'shadow'
18
+ | 'radius'
19
+ | 'animation'
20
+ | 'breakpoint'
21
+ | 'zIndex';
22
+
23
+ /**
24
+ * Token format options
25
+ */
26
+ export type TokenFormat = 'scss' | 'css' | 'json' | 'ts';
27
+
28
+ /**
29
+ * Color token configuration
30
+ */
31
+ export interface ColorTokenConfig {
32
+ brand?: {
33
+ primary?: string[];
34
+ secondary?: string[];
35
+ accent?: string[];
36
+ };
37
+ semantic?: {
38
+ success?: string;
39
+ warning?: string;
40
+ error?: string;
41
+ info?: string;
42
+ };
43
+ neutral?: string[];
44
+ background?: {
45
+ light?: string;
46
+ dark?: string;
47
+ };
48
+ text?: {
49
+ light?: string;
50
+ dark?: string;
51
+ };
52
+ border?: {
53
+ light?: string;
54
+ dark?: string;
55
+ };
56
+ focus?: {
57
+ light?: string;
58
+ dark?: string;
59
+ };
60
+ }
61
+
62
+ /**
63
+ * Spacing token configuration
64
+ */
65
+ export interface SpacingTokenConfig {
66
+ baseUnit?: string; // e.g., '0.25rem' (4px)
67
+ scale?: number[]; // e.g., [0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 32, 40, 48, 56, 64]
68
+ componentSpecific?: {
69
+ buttonPaddingX?: string;
70
+ buttonPaddingY?: string;
71
+ cardPadding?: string;
72
+ modalPadding?: string;
73
+ };
74
+ layout?: {
75
+ containerPadding?: string;
76
+ gridGap?: string;
77
+ sectionSpacing?: string;
78
+ };
79
+ }
80
+
81
+ /**
82
+ * Typography token configuration
83
+ */
84
+ export interface TypographyTokenConfig {
85
+ fontFamilies?: {
86
+ sans?: string;
87
+ serif?: string;
88
+ mono?: string;
89
+ };
90
+ fontSizes?: Record<string, string>; // e.g., { xs: '0.75rem', sm: '0.875rem', ... }
91
+ lineHeights?: Record<string, number | string>;
92
+ fontWeights?: Record<string, number>;
93
+ letterSpacing?: Record<string, string>;
94
+ headings?: {
95
+ h1?: { fontSize?: string; lineHeight?: number };
96
+ h2?: { fontSize?: string; lineHeight?: number };
97
+ h3?: { fontSize?: string; lineHeight?: number };
98
+ h4?: { fontSize?: string; lineHeight?: number };
99
+ h5?: { fontSize?: string; lineHeight?: number };
100
+ h6?: { fontSize?: string; lineHeight?: number };
101
+ };
102
+ }
103
+
104
+ /**
105
+ * Shadow token configuration
106
+ */
107
+ export interface ShadowTokenConfig {
108
+ colors?: {
109
+ light?: string;
110
+ dark?: string;
111
+ };
112
+ shadows?: Record<string, string>;
113
+ componentSpecific?: {
114
+ button?: string;
115
+ buttonHover?: string;
116
+ card?: string;
117
+ dropdown?: string;
118
+ modal?: string;
119
+ popover?: string;
120
+ tooltip?: string;
121
+ };
122
+ }
123
+
124
+ /**
125
+ * Radius token configuration
126
+ */
127
+ export interface RadiusTokenConfig {
128
+ baseUnit?: string;
129
+ scale?: Record<string, string>;
130
+ componentSpecific?: {
131
+ button?: string;
132
+ card?: string;
133
+ input?: string;
134
+ badge?: string;
135
+ };
136
+ }
137
+
138
+ /**
139
+ * Animation token configuration
140
+ */
141
+ export interface AnimationTokenConfig {
142
+ durations?: Record<string, string>;
143
+ easings?: Record<string, string>;
144
+ presets?: {
145
+ fadeIn?: string;
146
+ slideInUp?: string;
147
+ scaleIn?: string;
148
+ pulse?: string;
149
+ shimmer?: string;
150
+ };
151
+ }
152
+
153
+ /**
154
+ * Breakpoint token configuration
155
+ */
156
+ export interface BreakpointTokenConfig {
157
+ breakpoints?: Record<string, string>;
158
+ containerMaxWidths?: Record<string, string>;
159
+ }
160
+
161
+ /**
162
+ * Z-Index token configuration
163
+ */
164
+ export interface ZIndexTokenConfig {
165
+ scale?: Record<string, number>;
166
+ }
167
+
168
+ /**
169
+ * Generate color tokens in SCSS format
170
+ *
171
+ * @param config - Color token configuration
172
+ * @returns SCSS color tokens string
173
+ */
174
+ export const generateColorTokens = (config: ColorTokenConfig = {}): string => {
175
+ const {
176
+ brand = {},
177
+ semantic = {},
178
+ neutral = [],
179
+ background = {},
180
+ text = {},
181
+ border = {},
182
+ focus = {},
183
+ } = config;
184
+
185
+ return `// Custom Color Tokens
186
+ // Generated by Atomix CLI
187
+ // =============================================================================
188
+
189
+ // Brand Colors
190
+ // Customize these to match your brand identity
191
+ ${generateBrandColors(brand)}
192
+
193
+ // Semantic Colors
194
+ ${generateSemanticColors(semantic)}
195
+
196
+ // Neutral Colors
197
+ ${generateNeutralColors(neutral)}
198
+
199
+ // Background Colors
200
+ ${generateBackgroundColors(background)}
201
+
202
+ // Text Colors
203
+ ${generateTextColors(text)}
204
+
205
+ // Border Colors
206
+ ${generateBorderColors(border)}
207
+
208
+ // Focus Colors
209
+ ${generateFocusColors(focus)}
210
+
211
+ // Export custom colors to override defaults
212
+ $primary: $custom-primary-6 !default;
213
+ $success: $custom-success !default;
214
+ $warning: $custom-warning !default;
215
+ $error: $custom-error !default;
216
+ $info: $custom-info !default;
217
+
218
+ // Dark mode overrides
219
+ $body-bg-dark: $custom-body-bg-dark !default;
220
+ $body-color-dark: $custom-body-color-dark !default;
221
+ $border-color-dark: $custom-border-color-dark !default;
222
+ `;
223
+ };
224
+
225
+ /**
226
+ * Generate spacing tokens in SCSS format
227
+ *
228
+ * @param config - Spacing token configuration
229
+ * @returns SCSS spacing tokens string
230
+ */
231
+ export const generateSpacingTokens = (config: SpacingTokenConfig = {}): string => {
232
+ const {
233
+ baseUnit = '0.25rem',
234
+ scale = [0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 32, 40, 48, 56, 64],
235
+ componentSpecific = {},
236
+ layout = {},
237
+ } = config;
238
+
239
+ return `// Custom Spacing Tokens
240
+ // Generated by Atomix CLI
241
+ // =============================================================================
242
+
243
+ // Base spacing unit (change this to scale all spacing)
244
+ $custom-spacing-base: ${baseUnit} !default; // 4px
245
+
246
+ // Spacing scale
247
+ ${generateSpacingScale(scale)}
248
+
249
+ // Component-specific spacing
250
+ ${generateComponentSpacing(componentSpecific)}
251
+
252
+ // Layout spacing
253
+ ${generateLayoutSpacing(layout)}
254
+
255
+ // Export to override defaults
256
+ $spacing-sizes: (
257
+ 0: $custom-spacing-0,
258
+ 1: $custom-spacing-1,
259
+ 2: $custom-spacing-2,
260
+ 3: $custom-spacing-3,
261
+ 4: $custom-spacing-4,
262
+ 5: $custom-spacing-5,
263
+ 6: $custom-spacing-6,
264
+ 8: $custom-spacing-8,
265
+ 10: $custom-spacing-10,
266
+ 12: $custom-spacing-12,
267
+ 16: $custom-spacing-16,
268
+ 20: $custom-spacing-20,
269
+ 24: $custom-spacing-24,
270
+ 32: $custom-spacing-32,
271
+ 40: $custom-spacing-40,
272
+ 48: $custom-spacing-48,
273
+ 56: $custom-spacing-56,
274
+ 64: $custom-spacing-64,
275
+ ) !default;
276
+ `;
277
+ };
278
+
279
+ /**
280
+ * Generate typography tokens in SCSS format
281
+ *
282
+ * @param config - Typography token configuration
283
+ * @returns SCSS typography tokens string
284
+ */
285
+ export const generateTypographyTokens = (config: TypographyTokenConfig = {}): string => {
286
+ const {
287
+ fontFamilies = {},
288
+ fontSizes = {},
289
+ lineHeights = {},
290
+ fontWeights = {},
291
+ letterSpacing = {},
292
+ headings = {},
293
+ } = config;
294
+
295
+ return `// Custom Typography Tokens
296
+ // Generated by Atomix CLI
297
+ // =============================================================================
298
+
299
+ // Font Families
300
+ ${generateFontFamilies(fontFamilies)}
301
+
302
+ // Font Size Scale
303
+ ${generateFontSizes(fontSizes)}
304
+
305
+ // Line Heights
306
+ ${generateLineHeights(lineHeights)}
307
+
308
+ // Font Weights
309
+ ${generateFontWeights(fontWeights)}
310
+
311
+ // Letter Spacing
312
+ ${generateLetterSpacing(letterSpacing)}
313
+
314
+ // Heading Sizes
315
+ ${generateHeadingSizes(headings)}
316
+
317
+ // Export to override defaults
318
+ $font-family-base: $custom-font-family-sans !default;
319
+ $font-family-monospace: $custom-font-family-mono !default;
320
+ $font-size-base: $custom-font-size-base !default;
321
+ $line-height-base: $custom-line-height-base !default;
322
+ $font-weight-base: $custom-font-weight-normal !default;
323
+
324
+ // Heading overrides
325
+ $h1-font-size: $custom-h1-font-size !default;
326
+ $h2-font-size: $custom-h2-font-size !default;
327
+ $h3-font-size: $custom-h3-font-size !default;
328
+ $h4-font-size: $custom-h4-font-size !default;
329
+ $h5-font-size: $custom-h5-font-size !default;
330
+ $h6-font-size: $custom-h6-font-size !default;
331
+ `;
332
+ };
333
+
334
+ /**
335
+ * Generate shadow tokens in SCSS format
336
+ *
337
+ * @param config - Shadow token configuration
338
+ * @returns SCSS shadow tokens string
339
+ */
340
+ export const generateShadowTokens = (config: ShadowTokenConfig = {}): string => {
341
+ const {
342
+ colors = {},
343
+ shadows = {},
344
+ componentSpecific = {},
345
+ } = config;
346
+
347
+ return `// Custom Box Shadow Tokens
348
+ // Generated by Atomix CLI
349
+ // =============================================================================
350
+
351
+ // Shadow Colors
352
+ ${generateShadowColors(colors)}
353
+
354
+ // Shadow Scale
355
+ ${generateShadowScale(shadows)}
356
+
357
+ // Component-specific Shadows
358
+ ${generateComponentShadows(componentSpecific)}
359
+
360
+ // Dark mode shadows
361
+ ${generateDarkModeShadows()}
362
+
363
+ // Export to override defaults
364
+ $box-shadow: $custom-shadow-base !default;
365
+ $box-shadow-xs: $custom-shadow-xs !default;
366
+ $box-shadow-sm: $custom-shadow-sm !default;
367
+ $box-shadow-lg: $custom-shadow-lg !default;
368
+ $box-shadow-xl: $custom-shadow-xl !default;
369
+ $box-shadow-inset: $custom-shadow-inner !default;
370
+
371
+ // Dark mode exports
372
+ $box-shadow-dark: $custom-shadow-base-dark !default;
373
+ $box-shadow-xs-dark: $custom-shadow-xs-dark !default;
374
+ $box-shadow-sm-dark: $custom-shadow-sm-dark !default;
375
+ $box-shadow-lg-dark: $custom-shadow-lg-dark !default;
376
+ $box-shadow-xl-dark: $custom-shadow-xl-dark !default;
377
+ `;
378
+ };
379
+
380
+ /**
381
+ * Generate border radius tokens in SCSS format
382
+ *
383
+ * @param config - Radius token configuration
384
+ * @returns SCSS radius tokens string
385
+ */
386
+ export const generateRadiusTokens = (config: RadiusTokenConfig = {}): string => {
387
+ const {
388
+ baseUnit = '0.25rem',
389
+ scale = {},
390
+ componentSpecific = {},
391
+ } = config;
392
+
393
+ return `// Custom Border Radius Tokens
394
+ // Generated by Atomix CLI
395
+ // =============================================================================
396
+
397
+ // Base radius unit
398
+ $custom-radius-base: ${baseUnit} !default;
399
+
400
+ // Radius Scale
401
+ ${generateRadiusScale(scale)}
402
+
403
+ // Component-specific Radius
404
+ ${generateComponentRadius(componentSpecific)}
405
+
406
+ // Export to override defaults
407
+ $border-radius-base: $custom-radius-md !default;
408
+ $border-radius-sm: $custom-radius-sm !default;
409
+ $border-radius-lg: $custom-radius-lg !default;
410
+ $border-radius-xl: $custom-radius-xl !default;
411
+ $border-radius-full: $custom-radius-full !default;
412
+ `;
413
+ };
414
+
415
+ /**
416
+ * Generate animation tokens in SCSS format
417
+ *
418
+ * @param config - Animation token configuration
419
+ * @returns SCSS animation tokens string
420
+ */
421
+ export const generateAnimationTokens = (config: AnimationTokenConfig = {}): string => {
422
+ const {
423
+ durations = {},
424
+ easings = {},
425
+ presets = {},
426
+ } = config;
427
+
428
+ return `// Custom Animation Tokens
429
+ // Generated by Atomix CLI
430
+ // =============================================================================
431
+
432
+ // Animation Durations
433
+ ${generateAnimationDurations(durations)}
434
+
435
+ // Easing Functions
436
+ ${generateEasings(easings)}
437
+
438
+ // Animation Presets
439
+ ${generateAnimationPresets(presets)}
440
+
441
+ // Keyframe Definitions
442
+ ${generateKeyframes()}
443
+ `;
444
+ };
445
+
446
+ /**
447
+ * Generate breakpoint tokens in SCSS format
448
+ *
449
+ * @param config - Breakpoint token configuration
450
+ * @returns SCSS breakpoint tokens string
451
+ */
452
+ export const generateBreakpointTokens = (config: BreakpointTokenConfig = {}): string => {
453
+ const {
454
+ breakpoints = {},
455
+ containerMaxWidths = {},
456
+ } = config;
457
+
458
+ return `// Custom Breakpoint Tokens
459
+ // Generated by Atomix CLI
460
+ // =============================================================================
461
+
462
+ // Responsive Breakpoints
463
+ ${generateBreakpoints(breakpoints)}
464
+
465
+ // Container Max Widths
466
+ ${generateContainerMaxWidths(containerMaxWidths)}
467
+
468
+ // Media Query Mixins
469
+ ${generateMediaQueryMixins(breakpoints)}
470
+ `;
471
+ };
472
+
473
+ /**
474
+ * Generate z-index tokens in SCSS format
475
+ *
476
+ * @param config - Z-Index token configuration
477
+ * @returns SCSS z-index tokens string
478
+ */
479
+ export const generateZIndexTokens = (config: ZIndexTokenConfig = {}): string => {
480
+ const {
481
+ scale = {},
482
+ } = config;
483
+
484
+ return `// Custom Z-Index Tokens
485
+ // Generated by Atomix CLI
486
+ // =============================================================================
487
+
488
+ // Z-Index Scale
489
+ ${generateZIndexScale(scale)}
490
+
491
+ // Component Z-Indexes
492
+ $z-index-dropdown: 1000 !default;
493
+ $z-index-sticky: 1020 !default;
494
+ $z-index-fixed: 1030 !default;
495
+ $z-index-modal-backdrop: 1040 !default;
496
+ $z-index-modal: 1050 !default;
497
+ $z-index-popover: 1060 !default;
498
+ $z-index-tooltip: 1070 !default;
499
+ `;
500
+ };
501
+
502
+ /**
503
+ * Generate complete design token set in JSON format (W3C DTCG)
504
+ *
505
+ * @param categories - Categories to include
506
+ * @returns JSON design tokens object
507
+ */
508
+ export const generateJSONTokens = (categories: TokenCategory[] = []): Record<string, unknown> => {
509
+ const tokens: Record<string, unknown> = {
510
+ $schema: 'https://design-tokens.org/schema.json',
511
+ version: '1.0.0',
512
+ source: 'Atomix CLI',
513
+ };
514
+
515
+ if (categories.includes('color') || categories.length === 0) {
516
+ tokens.color = {
517
+ primary: {
518
+ 1: { value: '#fff9e6', type: 'color' },
519
+ 6: { value: '#ffb800', type: 'color' },
520
+ 10: { value: '#997000', type: 'color' },
521
+ },
522
+ semantic: {
523
+ success: { value: '#22c55e', type: 'color' },
524
+ warning: { value: '#eab308', type: 'color' },
525
+ error: { value: '#ef4444', type: 'color' },
526
+ info: { value: '#3b82f6', type: 'color' },
527
+ },
528
+ };
529
+ }
530
+
531
+ if (categories.includes('spacing') || categories.length === 0) {
532
+ tokens.spacing = {
533
+ 0: { value: '0', type: 'dimension' },
534
+ 1: { value: '0.25rem', type: 'dimension' },
535
+ 2: { value: '0.5rem', type: 'dimension' },
536
+ 4: { value: '1rem', type: 'dimension' },
537
+ 8: { value: '2rem', type: 'dimension' },
538
+ };
539
+ }
540
+
541
+ return tokens;
542
+ };
543
+
544
+ /**
545
+ * Generate CSS custom properties from tokens
546
+ *
547
+ * @param tokens - Token values
548
+ * @returns CSS custom properties string
549
+ */
550
+ export const generateCSSTokens = (tokens: Record<string, string>): string => {
551
+ const cssVars = Object.entries(tokens)
552
+ .map(([key, value]) => ` --atomix-${key}: ${value};`)
553
+ .join('\n');
554
+
555
+ return `/* CSS Custom Properties */
556
+ /* Generated by Atomix CLI */
557
+
558
+ :root {
559
+ ${cssVars}
560
+ }
561
+ `;
562
+ };
563
+
564
+ // ============================================================================
565
+ // Helper Functions
566
+ // ============================================================================
567
+
568
+ const generateBrandColors = (brand: ColorTokenConfig['brand']): string => {
569
+ const { primary = [], secondary = [], accent = [] } = brand;
570
+
571
+ let output = '';
572
+
573
+ if (primary.length > 0) {
574
+ output += '$custom-primary-1: ' + (primary[0] || '#fff9e6') + ' !default;\n';
575
+ output += '$custom-primary-6: ' + (primary[5] || '#ffb800') + ' !default; // Main brand color\n';
576
+ output += '$custom-primary-10: ' + (primary[9] || '#997000') + ' !default;\n';
577
+ } else {
578
+ output += `$custom-primary-1: #fff9e6 !default;
579
+ $custom-primary-2: #fff4cc !default;
580
+ $custom-primary-3: #ffe699 !default;
581
+ $custom-primary-4: #ffd966 !default;
582
+ $custom-primary-5: #ffcc33 !default;
583
+ $custom-primary-6: #ffb800 !default; // Main brand color
584
+ $custom-primary-7: #e6a600 !default;
585
+ $custom-primary-8: #cc9400 !default;
586
+ $custom-primary-9: #b38200 !default;
587
+ $custom-primary-10: #997000 !default;
588
+ `;
589
+ }
590
+
591
+ return output;
592
+ };
593
+
594
+ const generateSemanticColors = (semantic: ColorTokenConfig['semantic']): string => {
595
+ const {
596
+ success = '#22c55e',
597
+ warning = '#eab308',
598
+ error = '#ef4444',
599
+ info = '#3b82f6',
600
+ } = semantic;
601
+
602
+ return `$custom-success: ${success} !default;
603
+ $custom-warning: ${warning} !default;
604
+ $custom-error: ${error} !default;
605
+ $custom-info: ${info} !default;
606
+ `;
607
+ };
608
+
609
+ const generateNeutralColors = (neutral: string[]): string => {
610
+ if (neutral.length === 0) {
611
+ return `$custom-gray-1: #f9fafb !default;
612
+ $custom-gray-2: #f3f4f6 !default;
613
+ $custom-gray-3: #e5e7eb !default;
614
+ $custom-gray-4: #d1d5db !default;
615
+ $custom-gray-5: #9ca3af !default;
616
+ $custom-gray-6: #6b7280 !default;
617
+ $custom-gray-7: #4b5563 !default;
618
+ $custom-gray-8: #374151 !default;
619
+ $custom-gray-9: #1f2937 !default;
620
+ $custom-gray-10: #111827 !default;
621
+ `;
622
+ }
623
+
624
+ return neutral.map((color, i) => `$custom-gray-${i + 1}: ${color} !default;`).join('\n') + '\n';
625
+ };
626
+
627
+ const generateBackgroundColors = (background: ColorTokenConfig['background']): string => {
628
+ const { light = '#ffffff', dark = '#1f2937' } = background;
629
+ return `$custom-body-bg: ${light} !default;
630
+ $custom-body-bg-dark: ${dark} !default;
631
+ `;
632
+ };
633
+
634
+ const generateTextColors = (text: ColorTokenConfig['text']): string => {
635
+ const { light = '#111827', dark = '#ffffff' } = text;
636
+ return `$custom-body-color: ${light} !default;
637
+ $custom-body-color-dark: ${dark} !default;
638
+ `;
639
+ };
640
+
641
+ const generateBorderColors = (border: ColorTokenConfig['border']): string => {
642
+ const { light = '#e5e7eb', dark = '#4b5563' } = border;
643
+ return `$custom-border-color: ${light} !default;
644
+ $custom-border-color-dark: ${dark} !default;
645
+ `;
646
+ };
647
+
648
+ const generateFocusColors = (focus: ColorTokenConfig['focus']): string => {
649
+ const { light = '#ffcc33', dark = '#ffd966' } = focus;
650
+ return `$custom-focus-color: ${light} !default;
651
+ $custom-focus-color-dark: ${dark} !default;
652
+ `;
653
+ };
654
+
655
+ const generateSpacingScale = (scale: number[]): string => {
656
+ return scale
657
+ .map((value) => `$custom-spacing-${value}: calc($custom-spacing-base * ${value}) !default; // ${value * 4}px`)
658
+ .join('\n') + '\n';
659
+ };
660
+
661
+ const generateComponentSpacing = (componentSpecific: SpacingTokenConfig['componentSpecific']): string => {
662
+ const {
663
+ buttonPaddingX = '$custom-spacing-4',
664
+ buttonPaddingY = '$custom-spacing-2',
665
+ cardPadding = '$custom-spacing-6',
666
+ modalPadding = '$custom-spacing-8',
667
+ } = componentSpecific;
668
+
669
+ return `$custom-button-padding-x: ${buttonPaddingX} !default;
670
+ $custom-button-padding-y: ${buttonPaddingY} !default;
671
+ $custom-card-padding: ${cardPadding} !default;
672
+ $custom-modal-padding: ${modalPadding} !default;
673
+ `;
674
+ };
675
+
676
+ const generateLayoutSpacing = (layout: SpacingTokenConfig['layout']): string => {
677
+ const {
678
+ containerPadding = '$custom-spacing-4',
679
+ gridGap = '$custom-spacing-6',
680
+ sectionSpacing = '$custom-spacing-16',
681
+ } = layout;
682
+
683
+ return `$custom-container-padding: ${containerPadding} !default;
684
+ $custom-grid-gap: ${gridGap} !default;
685
+ $custom-section-spacing: ${sectionSpacing} !default;
686
+ `;
687
+ };
688
+
689
+ const generateFontFamilies = (fontFamilies: TypographyTokenConfig['fontFamilies']): string => {
690
+ const {
691
+ sans = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
692
+ serif = 'Georgia, "Times New Roman", Times, serif',
693
+ mono = 'SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
694
+ } = fontFamilies;
695
+
696
+ return `$custom-font-family-sans: ${sans} !default;
697
+ $custom-font-family-serif: ${serif} !default;
698
+ $custom-font-family-mono: ${mono} !default;
699
+ `;
700
+ };
701
+
702
+ const generateFontSizes = (fontSizes: TypographyTokenConfig['fontSizes']): string => {
703
+ const defaultSizes: Record<string, string> = {
704
+ xs: '0.75rem',
705
+ sm: '0.875rem',
706
+ base: '1rem',
707
+ lg: '1.125rem',
708
+ xl: '1.25rem',
709
+ '2xl': '1.5rem',
710
+ '3xl': '1.875rem',
711
+ '4xl': '2.25rem',
712
+ '5xl': '3rem',
713
+ };
714
+
715
+ const sizes = { ...defaultSizes, ...fontSizes };
716
+
717
+ return Object.entries(sizes)
718
+ .map(([key, value]) => `$custom-font-size-${key}: ${value} !default;`)
719
+ .join('\n') + '\n';
720
+ };
721
+
722
+ const generateLineHeights = (lineHeights: TypographyTokenConfig['lineHeights']): string => {
723
+ const {
724
+ tight = 1.2,
725
+ base = 1.5,
726
+ relaxed = 1.75,
727
+ loose = 2,
728
+ } = lineHeights;
729
+
730
+ return `$custom-line-height-tight: ${tight} !default;
731
+ $custom-line-height-base: ${base} !default;
732
+ $custom-line-height-relaxed: ${relaxed} !default;
733
+ $custom-line-height-loose: ${loose} !default;
734
+ `;
735
+ };
736
+
737
+ const generateFontWeights = (fontWeights: TypographyTokenConfig['fontWeights']): string => {
738
+ const defaultWeights: Record<string, number> = {
739
+ light: 300,
740
+ normal: 400,
741
+ medium: 500,
742
+ semibold: 600,
743
+ bold: 700,
744
+ heavy: 800,
745
+ black: 900,
746
+ };
747
+
748
+ const weights = { ...defaultWeights, ...fontWeights };
749
+
750
+ return Object.entries(weights)
751
+ .map(([key, value]) => `$custom-font-weight-${key}: ${value} !default;`)
752
+ .join('\n') + '\n';
753
+ };
754
+
755
+ const generateLetterSpacing = (letterSpacing: TypographyTokenConfig['letterSpacing']): string => {
756
+ const {
757
+ tight = '-0.05em',
758
+ normal = '0',
759
+ wide = '0.025em',
760
+ wider = '0.05em',
761
+ widest = '0.1em',
762
+ } = letterSpacing;
763
+
764
+ return `$custom-letter-spacing-tight: ${tight} !default;
765
+ $custom-letter-spacing-normal: ${normal} !default;
766
+ $custom-letter-spacing-wide: ${wide} !default;
767
+ $custom-letter-spacing-wider: ${wider} !default;
768
+ $custom-letter-spacing-widest: ${widest} !default;
769
+ `;
770
+ };
771
+
772
+ const generateHeadingSizes = (headings: TypographyTokenConfig['headings']): string => {
773
+ const defaultHeadings = {
774
+ h1: { fontSize: '$custom-font-size-5xl' },
775
+ h2: { fontSize: '$custom-font-size-4xl' },
776
+ h3: { fontSize: '$custom-font-size-3xl' },
777
+ h4: { fontSize: '$custom-font-size-2xl' },
778
+ h5: { fontSize: '$custom-font-size-xl' },
779
+ h6: { fontSize: '$custom-font-size-lg' },
780
+ };
781
+
782
+ const mergedHeadings = { ...defaultHeadings, ...headings };
783
+
784
+ return Object.entries(mergedHeadings)
785
+ .map(([key, config]) => `$custom-${key}-font-size: ${(config as { fontSize?: string }).fontSize || '$custom-font-size-' + key} !default;`)
786
+ .join('\n') + '\n';
787
+ };
788
+
789
+ const generateShadowColors = (colors: ShadowTokenConfig['colors']): string => {
790
+ const {
791
+ light = 'rgba(0, 0, 0, 0.1)',
792
+ dark = 'rgba(0, 0, 0, 0.2)',
793
+ } = colors;
794
+
795
+ return `$custom-shadow-color: ${light} !default;
796
+ $custom-shadow-color-dark: ${dark} !default;
797
+ `;
798
+ };
799
+
800
+ const generateShadowScale = (shadows: ShadowTokenConfig['shadows']): string => {
801
+ const defaultShadows: Record<string, string> = {
802
+ xs: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
803
+ sm: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)',
804
+ base: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
805
+ md: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
806
+ lg: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',
807
+ xl: '0 25px 50px -12px rgba(0, 0, 0, 0.25)',
808
+ '2xl': '0 35px 60px -15px rgba(0, 0, 0, 0.3)',
809
+ inner: 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)',
810
+ none: 'none',
811
+ };
812
+
813
+ const mergedShadows = { ...defaultShadows, ...shadows };
814
+
815
+ return Object.entries(mergedShadows)
816
+ .map(([key, value]) => `$custom-shadow-${key}: ${value} !default;`)
817
+ .join('\n') + '\n';
818
+ };
819
+
820
+ const generateComponentShadows = (componentSpecific: ShadowTokenConfig['componentSpecific']): string => {
821
+ const {
822
+ button = '$custom-shadow-sm',
823
+ buttonHover = '$custom-shadow-md',
824
+ card = '$custom-shadow-base',
825
+ dropdown = '$custom-shadow-lg',
826
+ modal = '$custom-shadow-xl',
827
+ popover = '$custom-shadow-lg',
828
+ tooltip = '$custom-shadow-md',
829
+ } = componentSpecific;
830
+
831
+ return `$custom-button-shadow: ${button} !default;
832
+ $custom-button-shadow-hover: ${buttonHover} !default;
833
+ $custom-card-shadow: ${card} !default;
834
+ $custom-dropdown-shadow: ${dropdown} !default;
835
+ $custom-modal-shadow: ${modal} !default;
836
+ $custom-popover-shadow: ${popover} !default;
837
+ $custom-tooltip-shadow: ${tooltip} !default;
838
+ `;
839
+ };
840
+
841
+ const generateDarkModeShadows = (): string => {
842
+ return `$custom-shadow-xs-dark: 0 1px 2px 0 rgba(0, 0, 0, 0.3) !default;
843
+ $custom-shadow-sm-dark: 0 1px 3px 0 rgba(0, 0, 0, 0.4), 0 1px 2px 0 rgba(0, 0, 0, 0.3) !default;
844
+ $custom-shadow-base-dark: 0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -1px rgba(0, 0, 0, 0.3) !default;
845
+ $custom-shadow-lg-dark: 0 20px 25px -5px rgba(0, 0, 0, 0.5), 0 10px 10px -5px rgba(0, 0, 0, 0.4) !default;
846
+ $custom-shadow-xl-dark: 0 25px 50px -12px rgba(0, 0, 0, 0.6) !default;
847
+ `;
848
+ };
849
+
850
+ const generateRadiusScale = (scale: RadiusTokenConfig['scale']): string => {
851
+ const defaultScale: Record<string, string> = {
852
+ none: '0',
853
+ sm: '0.125rem',
854
+ md: '0.25rem',
855
+ lg: '0.5rem',
856
+ xl: '0.75rem',
857
+ '2xl': '1rem',
858
+ full: '9999px',
859
+ pill: '9999px',
860
+ };
861
+
862
+ const mergedScale = { ...defaultScale, ...scale };
863
+
864
+ return Object.entries(mergedScale)
865
+ .map(([key, value]) => `$custom-radius-${key}: ${value} !default;`)
866
+ .join('\n') + '\n';
867
+ };
868
+
869
+ const generateComponentRadius = (componentSpecific: RadiusTokenConfig['componentSpecific']): string => {
870
+ const {
871
+ button = '$custom-radius-md',
872
+ card = '$custom-radius-lg',
873
+ input = '$custom-radius-md',
874
+ badge = '$custom-radius-full',
875
+ } = componentSpecific;
876
+
877
+ return `$custom-button-radius: ${button} !default;
878
+ $custom-card-radius: ${card} !default;
879
+ $custom-input-radius: ${input} !default;
880
+ $custom-badge-radius: ${badge} !default;
881
+ `;
882
+ };
883
+
884
+ const generateAnimationDurations = (durations: AnimationTokenConfig['durations']): string => {
885
+ const defaultDurations: Record<string, string> = {
886
+ instant: '0ms',
887
+ fast: '150ms',
888
+ base: '300ms',
889
+ slow: '500ms',
890
+ slower: '750ms',
891
+ durationless: '0ms',
892
+ };
893
+
894
+ const mergedDurations = { ...defaultDurations, ...durations };
895
+
896
+ return Object.entries(mergedDurations)
897
+ .map(([key, value]) => `$custom-duration-${key}: ${value} !default;`)
898
+ .join('\n') + '\n';
899
+ };
900
+
901
+ const generateEasings = (easings: AnimationTokenConfig['easings']): string => {
902
+ const defaultEasings: Record<string, string> = {
903
+ linear: 'linear',
904
+ ease: 'ease',
905
+ 'ease-in': 'cubic-bezier(0.4, 0, 1, 1)',
906
+ 'ease-out': 'cubic-bezier(0, 0, 0.2, 1)',
907
+ 'ease-in-out': 'cubic-bezier(0.4, 0, 0.2, 1)',
908
+ smooth: 'cubic-bezier(0.23, 1, 0.32, 1)', // Atomix Ease
909
+ bounce: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)',
910
+ };
911
+
912
+ return Object.entries({ ...defaultEasings, ...easings })
913
+ .map(([key, value]) => `$custom-easing-${key}: ${value} !default;`)
914
+ .join('\n') + '\n';
915
+ };
916
+
917
+ const generateAnimationPresets = (presets: AnimationTokenConfig['presets']): string => {
918
+ const defaultPresets = {
919
+ fadeIn: 'atomix-fade-in var(--atomix-duration-base) var(--atomix-easing-smooth)',
920
+ slideInUp: 'atomix-slide-in-up var(--atomix-duration-slow) var(--atomix-easing-smooth)',
921
+ scaleIn: 'atomix-scale-in var(--atomix-duration-base) var(--atomix-easing-smooth)',
922
+ pulse: 'atomix-pulse 2s var(--atomix-easing-smooth) infinite',
923
+ shimmer: 'atomix-shimmer 2s linear infinite',
924
+ };
925
+
926
+ const mergedPresets = { ...defaultPresets, ...presets };
927
+
928
+ return Object.entries(mergedPresets)
929
+ .map(([key, value]) => `$custom-animation-${key}: ${value} !default;`)
930
+ .join('\n') + '\n';
931
+ };
932
+
933
+ const generateKeyframes = (): string => {
934
+ return `@keyframes atomix-fade-in {
935
+ from { opacity: 0; }
936
+ to { opacity: 1; }
937
+ }
938
+
939
+ @keyframes atomix-slide-in-up {
940
+ from {
941
+ opacity: 0;
942
+ transform: translateY(20px);
943
+ }
944
+ to {
945
+ opacity: 1;
946
+ transform: translateY(0);
947
+ }
948
+ }
949
+
950
+ @keyframes atomix-scale-in {
951
+ from {
952
+ opacity: 0;
953
+ transform: scale(0.9);
954
+ }
955
+ to {
956
+ opacity: 1;
957
+ transform: scale(1);
958
+ }
959
+ }
960
+
961
+ @keyframes atomix-pulse {
962
+ 0%, 100% { opacity: 1; }
963
+ 50% { opacity: 0.5; }
964
+ }
965
+
966
+ @keyframes atomix-shimmer {
967
+ 0% { background-position: -200% 0; }
968
+ 100% { background-position: 200% 0; }
969
+ }
970
+ `;
971
+ };
972
+
973
+ const generateBreakpoints = (breakpoints: BreakpointTokenConfig['breakpoints']): string => {
974
+ const defaultBreakpoints: Record<string, string> = {
975
+ sm: '640px',
976
+ md: '768px',
977
+ lg: '1024px',
978
+ xl: '1280px',
979
+ '2xl': '1536px',
980
+ };
981
+
982
+ const mergedBreakpoints = { ...defaultBreakpoints, ...breakpoints };
983
+
984
+ return Object.entries(mergedBreakpoints)
985
+ .map(([key, value]) => `$breakpoint-${key}: ${value} !default;`)
986
+ .join('\n') + '\n';
987
+ };
988
+
989
+ const generateContainerMaxWidths = (containerMaxWidths: BreakpointTokenConfig['containerMaxWidths']): string => {
990
+ const defaultMaxWidths: Record<string, string> = {
991
+ sm: '640px',
992
+ md: '768px',
993
+ lg: '1024px',
994
+ xl: '1280px',
995
+ '2xl': '1536px',
996
+ };
997
+
998
+ const mergedMaxWidths = { ...defaultMaxWidths, ...containerMaxWidths };
999
+
1000
+ return `$container-max-widths: (\n sm: ${mergedMaxWidths.sm || '640px'},\n md: ${mergedMaxWidths.md || '768px'},\n lg: ${mergedMaxWidths.lg || '1024px'},\n xl: ${mergedMaxWidths.xl || '1280px'},\n '2xl': ${mergedMaxWidths['2xl'] || '1536px'},\n) !default;\n`;
1001
+ };
1002
+
1003
+ const generateMediaQueryMixins = (breakpoints: BreakpointTokenConfig['breakpoints']): string => {
1004
+ const mergedBreakpoints = {
1005
+ sm: '640px',
1006
+ md: '768px',
1007
+ lg: '1024px',
1008
+ xl: '1280px',
1009
+ '2xl': '1536px',
1010
+ ...breakpoints,
1011
+ };
1012
+
1013
+ return `// Media Query Mixins
1014
+ @mixin atomix-media-breakpoint-up($breakpoint) {
1015
+ @if map-has-key($breakpoint-map, $breakpoint) {
1016
+ $min-width: map-get($breakpoint-map, $breakpoint);
1017
+ @media (min-width: $min-width) {
1018
+ @content;
1019
+ }
1020
+ } @else {
1021
+ @warn "Unknown breakpoint: #{$breakpoint}";
1022
+ @content;
1023
+ }
1024
+ }
1025
+
1026
+ @mixin atomix-media-breakpoint-down($breakpoint) {
1027
+ @if map-has-key($breakpoint-map, $breakpoint) {
1028
+ $max-width: map-get($breakpoint-map, $breakpoint);
1029
+ @media (max-width: $max-width) {
1030
+ @content;
1031
+ }
1032
+ } @else {
1033
+ @warn "Unknown breakpoint: #{$breakpoint}";
1034
+ @content;
1035
+ }
1036
+ }
1037
+
1038
+ // Breakpoint map for mixins
1039
+ $breakpoint-map: (
1040
+ sm: ${mergedBreakpoints.sm},
1041
+ md: ${mergedBreakpoints.md},
1042
+ lg: ${mergedBreakpoints.lg},
1043
+ xl: ${mergedBreakpoints.xl},
1044
+ '2xl': ${mergedBreakpoints['2xl']},
1045
+ ) !default;
1046
+ `;
1047
+ };
1048
+
1049
+ const generateZIndexScale = (scale: ZIndexTokenConfig['scale']): string => {
1050
+ const defaultScale: Record<string, number> = {
1051
+ hide: -1,
1052
+ base: 0,
1053
+ dropdown: 1000,
1054
+ sticky: 1020,
1055
+ fixed: 1030,
1056
+ modalBackdrop: 1040,
1057
+ modal: 1050,
1058
+ popover: 1060,
1059
+ tooltip: 1070,
1060
+ };
1061
+
1062
+ const mergedScale = { ...defaultScale, ...scale };
1063
+
1064
+ return Object.entries(mergedScale)
1065
+ .map(([key, value]) => `$z-index-${key.replace(/([A-Z])/g, '-$1').toLowerCase()}: ${value} !default;`)
1066
+ .join('\n') + '\n';
1067
+ };
1068
+
1069
+ /**
1070
+ * All token generation functions
1071
+ */
1072
+ export const tokenGenerators = {
1073
+ color: generateColorTokens,
1074
+ spacing: generateSpacingTokens,
1075
+ typography: generateTypographyTokens,
1076
+ shadow: generateShadowTokens,
1077
+ radius: generateRadiusTokens,
1078
+ animation: generateAnimationTokens,
1079
+ breakpoint: generateBreakpointTokens,
1080
+ zIndex: generateZIndexTokens,
1081
+ json: generateJSONTokens,
1082
+ css: generateCSSTokens,
1083
+ };
1084
+
1085
+ /**
1086
+ * Type for token generators object
1087
+ */
1088
+ export type TokenGenerators = typeof tokenGenerators;