@shohojdhara/atomix 0.4.8 → 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 (165) 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 +4 -1
  112. package/src/components/AtomixGlass/stories/Overview.stories.tsx +157 -6
  113. package/src/components/AtomixGlass/stories/Phase1-Animation.stories.tsx +653 -0
  114. package/src/components/AtomixGlass/stories/Phase1-Test.stories.tsx +95 -0
  115. package/src/components/AtomixGlass/stories/Playground.stories.tsx +51 -51
  116. package/src/components/AtomixGlass/stories/shared-components.tsx +6 -0
  117. package/src/components/Avatar/Avatar.tsx +1 -1
  118. package/src/components/Button/Button.stories.disabled-link.tsx +10 -0
  119. package/src/components/Button/Button.stories.tsx +10 -0
  120. package/src/components/Button/Button.test.tsx +16 -11
  121. package/src/components/Button/Button.tsx +4 -4
  122. package/src/components/Card/Card.tsx +1 -1
  123. package/src/components/Dropdown/Dropdown.tsx +12 -12
  124. package/src/components/Form/Select.tsx +62 -3
  125. package/src/components/Modal/Modal.tsx +14 -3
  126. package/src/components/Navigation/Navbar/Navbar.tsx +44 -0
  127. package/src/components/Slider/Slider.stories.tsx +3 -3
  128. package/src/components/Slider/Slider.tsx +38 -0
  129. package/src/components/Steps/Steps.tsx +3 -3
  130. package/src/components/Tabs/Tabs.tsx +77 -8
  131. package/src/components/Testimonial/Testimonial.tsx +1 -1
  132. package/src/components/TypedButton/TypedButton.stories.tsx +59 -0
  133. package/src/components/TypedButton/TypedButton.tsx +39 -0
  134. package/src/components/TypedButton/index.ts +2 -0
  135. package/src/components/VideoPlayer/VideoPlayer.tsx +11 -4
  136. package/src/lib/composables/index.ts +4 -7
  137. package/src/lib/composables/types.ts +45 -0
  138. package/src/lib/composables/useAccordion.ts +0 -7
  139. package/src/lib/composables/useAtomixGlass.ts +144 -5
  140. package/src/lib/composables/useChartExport.ts +3 -13
  141. package/src/lib/composables/useDropdown.ts +66 -0
  142. package/src/lib/composables/useFocusTrap.ts +80 -0
  143. package/src/lib/composables/usePerformanceMonitor.ts +448 -0
  144. package/src/lib/composables/useResponsiveGlass.presets.ts +192 -0
  145. package/src/lib/composables/useResponsiveGlass.ts +441 -0
  146. package/src/lib/composables/useTooltip.ts +16 -0
  147. package/src/lib/composables/useTypedButton.ts +66 -0
  148. package/src/lib/config/index.ts +62 -5
  149. package/src/lib/constants/components.ts +55 -0
  150. package/src/lib/theme/devtools/__tests__/useHistory.test.tsx +150 -0
  151. package/src/lib/theme/tokens/centralized-tokens.ts +120 -0
  152. package/src/lib/theme/utils/__tests__/domUtils.test.ts +101 -0
  153. package/src/lib/types/components.ts +37 -11
  154. package/src/lib/types/glass.ts +35 -0
  155. package/src/lib/types/index.ts +1 -0
  156. package/src/lib/utils/displacement-generator.ts +1 -1
  157. package/src/styles/01-settings/_settings.testtypecheck.scss +53 -0
  158. package/src/styles/01-settings/_settings.typedbutton.scss +53 -0
  159. package/src/styles/06-components/_components.testbutton.scss +212 -0
  160. package/src/styles/06-components/_components.testtypecheck.scss +212 -0
  161. package/src/styles/06-components/_components.typedbutton.scss +212 -0
  162. package/src/styles/99-utilities/_index.scss +1 -0
  163. package/src/styles/99-utilities/_utilities.text.scss +1 -1
  164. package/src/styles/99-utilities/_utilities.touch-target.scss +36 -0
  165. package/src/styles/06-components/old.chart.styles.scss +0 -2788
@@ -0,0 +1,276 @@
1
+ /**
2
+ * Atomix CLI Validator Logic
3
+ * Core validation logic for A11y, Tokens, and Performance
4
+ */
5
+
6
+ import { readFile, readdir } from 'fs/promises';
7
+ import { glob } from 'glob';
8
+ import { join } from 'path';
9
+ import { existsSync, statSync } from 'fs';
10
+
11
+ /**
12
+ * Validate Accessibility (A11y)
13
+ * Simple static analysis for common pitfalls
14
+ */
15
+ export async function validateA11y(projectRoot = process.cwd()) {
16
+ const issues = [];
17
+ const files = await glob('src/**/*.{tsx,jsx,html}', { cwd: projectRoot });
18
+
19
+ for (const file of files) {
20
+ const content = await readFile(join(projectRoot, file), 'utf8');
21
+
22
+ // Check for missing alt on images
23
+ // Skip if alt uses JSX expression syntax like alt={variable} or alt={string}
24
+ const hasAltAttribute = /<img[^>]*\salt=\{[^}]+\}/i.test(content); // JSX expression
25
+ const hasValidAltString = /<img[^>]+alt=["'][^"']+["'][^>]*>/i.test(content); // Valid string alt
26
+ const hasEmptyAltString = /<img[^>]+alt=["']\s*["'][^>]*>/i.test(content); // Empty string alt
27
+ const hasNoAltAttribute = /<img[^>]+(?!alt=)[^>]*>/i.test(content) && !hasAltAttribute;
28
+
29
+ if ((hasNoAltAttribute || hasEmptyAltString) && !(hasAltAttribute || hasValidAltString)) {
30
+ issues.push({
31
+ file,
32
+ type: 'A11y',
33
+ message: 'Missing or empty alt attribute on <img> tag',
34
+ severity: 'error'
35
+ });
36
+ }
37
+
38
+ // Check for button without labels (aria-label or text)
39
+ if (/<button[^>]*>\s*<\/button>/i.test(content) && !/aria-label=/i.test(content)) {
40
+ issues.push({
41
+ file,
42
+ type: 'A11y',
43
+ message: 'Button without text content or aria-label',
44
+ severity: 'warn'
45
+ });
46
+ }
47
+ }
48
+
49
+ return issues;
50
+ }
51
+
52
+ /**
53
+ * Validate Token Usage
54
+ */
55
+ export async function validateTokens(projectRoot = process.cwd()) {
56
+ const issues = [];
57
+ const themeDir = join(projectRoot, 'src/styles/01-settings');
58
+
59
+ if (!existsSync(themeDir)) {
60
+ issues.push({
61
+ file: 'src/styles/01-settings',
62
+ type: 'Tokens',
63
+ message: 'Design token settings directory missing',
64
+ severity: 'error'
65
+ });
66
+ return issues;
67
+ }
68
+
69
+ // Check for hardcoded colors in SCSS files
70
+ const scssFiles = await glob('src/**/*.scss', { cwd: projectRoot });
71
+ for (const file of scssFiles) {
72
+ const content = await readFile(join(projectRoot, file), 'utf8');
73
+
74
+ // Skip variable definitions (lines with $variable:)
75
+ const lines = content.split('\n');
76
+ const hardcodedColors = [];
77
+
78
+ for (const line of lines) {
79
+ // Skip comments
80
+ if (line.trim().startsWith('//') || line.trim().startsWith('/*')) continue;
81
+
82
+ // Skip variable definitions (these SHOULD have hex values)
83
+ if (/^\s*\$[\w-]+:\s*#[\da-fA-F]{3,6}/.test(line)) continue;
84
+
85
+ // Skip CSS var() fallbacks (these are good practices)
86
+ if (/var\([^)]+#[\da-fA-F]{3,6}/.test(line)) continue;
87
+
88
+ // Skip url(), data URIs, and other non-color contexts
89
+ if (/url\(/.test(line)) continue;
90
+
91
+ // Check for actual hardcoded colors in property values
92
+ const hexMatch = line.match(/(?<!\$[\w-]*:\s*)(?<!var\([^)]*)#([A-Fa-f0-9]{3}|[A-Fa-f0-9]{6})\b(?!;)/g);
93
+ if (hexMatch) {
94
+ hardcodedColors.push(...hexMatch);
95
+ }
96
+ }
97
+
98
+ if (hardcodedColors.length > 0) {
99
+ issues.push({
100
+ file,
101
+ type: 'Tokens',
102
+ message: `Hardcoded hex color(s) found: ${hardcodedColors.join(', ')}. Use variables or tokens.`,
103
+ severity: 'warn'
104
+ });
105
+ }
106
+ }
107
+
108
+ return issues;
109
+ }
110
+
111
+ /**
112
+ * Validate a single component: structure, A11y, and token usage
113
+ * @param {string} componentName - PascalCase component name (e.g. Button)
114
+ * @param {string} projectRoot - Project root directory
115
+ * @returns {Promise<{ valid: boolean, issues: Array<{type, severity, file, message}>, component: string }>}
116
+ */
117
+ export async function validateComponent(componentName, projectRoot = process.cwd()) {
118
+ const issues = [];
119
+ const componentsBase = join(projectRoot, 'src/components');
120
+ let componentDir = null;
121
+
122
+ if (!existsSync(componentsBase)) {
123
+ return {
124
+ valid: false,
125
+ issues: [{
126
+ type: 'Structure',
127
+ severity: 'error',
128
+ file: 'src/components',
129
+ message: 'Components directory not found. Expected src/components/<ComponentName>/'
130
+ }],
131
+ component: componentName
132
+ };
133
+ }
134
+
135
+ const entries = await readdir(componentsBase, { withFileTypes: true });
136
+ const match = entries.find(
137
+ (e) => e.isDirectory() && e.name.toLowerCase() === componentName.toLowerCase()
138
+ );
139
+ if (!match) {
140
+ return {
141
+ valid: false,
142
+ issues: [{
143
+ type: 'Structure',
144
+ severity: 'error',
145
+ file: `src/components/${componentName}`,
146
+ message: `Component directory not found. Looked in src/components/ for "${componentName}".`
147
+ }],
148
+ component: componentName
149
+ };
150
+ }
151
+ componentDir = join(componentsBase, match.name);
152
+ const componentFiles = await glob(`${match.name}/**/*.{tsx,jsx,html}`, {
153
+ cwd: componentsBase,
154
+ absolute: false
155
+ });
156
+ const fullPaths = componentFiles.map((f) => join(projectRoot, 'src/components', f));
157
+
158
+ // A11y on component files only
159
+ for (let i = 0; i < fullPaths.length; i++) {
160
+ const file = fullPaths[i];
161
+ const content = await readFile(file, 'utf8');
162
+ const relativeFile = join('src/components', componentFiles[i]);
163
+ // Check for missing alt on images (improved JSX handling)
164
+ const hasAltAttribute = /<img[^>]*\salt=\{[^}]+\}/i.test(content); // JSX expression
165
+ const hasValidAltString = /<img[^>]+alt=["'][^"']+["'][^>]*>/i.test(content); // Valid string alt
166
+ const hasEmptyAltString = /<img[^>]+alt=["']\s*["'][^>]*>/i.test(content); // Empty string alt
167
+ const hasNoAltAttribute = /<img[^>]+(?!alt=)[^>]*>/i.test(content) && !hasAltAttribute;
168
+
169
+ if ((hasNoAltAttribute || hasEmptyAltString) && !(hasAltAttribute || hasValidAltString)) {
170
+ issues.push({
171
+ file: relativeFile,
172
+ type: 'A11y',
173
+ message: 'Missing or empty alt attribute on <img> tag',
174
+ severity: 'error'
175
+ });
176
+ }
177
+ if (/<button[^>]*>\s*<\/button>/i.test(content) && !/aria-label=/i.test(content)) {
178
+ issues.push({
179
+ file: relativeFile,
180
+ type: 'A11y',
181
+ message: 'Button without text content or aria-label',
182
+ severity: 'warn'
183
+ });
184
+ }
185
+
186
+ // Check for hardcoded colors in TSX/JSX component files
187
+ const hexColorRegex = /(?<!['"`])#([A-Fa-f0-9]{3}|[A-Fa-f0-9]{6})\b(?!['"`])/g;
188
+ const hexMatches = content.match(hexColorRegex);
189
+ if (hexMatches) {
190
+ issues.push({
191
+ file: relativeFile,
192
+ type: 'Tokens',
193
+ message: `Hardcoded hex color(s) found in TSX: ${hexMatches.join(', ')}. Use design tokens or CSS variables.`,
194
+ severity: 'error'
195
+ });
196
+ }
197
+ }
198
+
199
+ // Token usage: component settings and component SCSS
200
+ const settingsPath = join(projectRoot, 'src/styles/01-settings');
201
+ const compStylesPath = join(projectRoot, 'src/styles/06-components');
202
+ const settingsFile = join(settingsPath, `_settings.${match.name.toLowerCase()}.scss`);
203
+ const compFile = join(compStylesPath, `_components.${match.name.toLowerCase()}.scss`);
204
+ for (const scssPath of [settingsFile, compFile]) {
205
+ if (!existsSync(scssPath)) continue;
206
+ const content = await readFile(scssPath, 'utf8');
207
+ const hexMatch = content.match(/(?<![$/*])#([A-Fa-f0-9]{3}|[A-Fa-f0-9]{6})\b/g);
208
+ if (hexMatch) {
209
+ issues.push({
210
+ file: scssPath.replace(projectRoot, '').replace(/^\//, '') || scssPath,
211
+ type: 'Tokens',
212
+ message: `Hardcoded hex color(s): ${hexMatch.join(', ')}. Use --atomix-* or project tokens.`,
213
+ severity: 'warn'
214
+ });
215
+ }
216
+ }
217
+
218
+ // Main component file exists
219
+ const mainExts = ['.tsx', '.jsx'];
220
+ let mainExists = false;
221
+ for (const ext of mainExts) {
222
+ if (existsSync(join(componentDir, `${match.name}${ext}`))) {
223
+ mainExists = true;
224
+ break;
225
+ }
226
+ }
227
+ if (!mainExists) {
228
+ issues.push({
229
+ type: 'Structure',
230
+ severity: 'error',
231
+ file: join('src/components', match.name),
232
+ message: `Main component file not found (e.g. ${match.name}.tsx)`
233
+ });
234
+ }
235
+
236
+ return {
237
+ valid: issues.filter((i) => i.severity === 'error').length === 0,
238
+ issues,
239
+ component: match.name
240
+ };
241
+ }
242
+
243
+ /**
244
+ * Validate Performance
245
+ * Calculate bundle size of CSS/JS if dist exists
246
+ */
247
+ export async function validatePerformance(projectRoot = process.cwd()) {
248
+ const issues = [];
249
+ const distDir = join(projectRoot, 'dist');
250
+
251
+ if (!existsSync(distDir)) {
252
+ return [{
253
+ file: 'dist',
254
+ type: 'Performance',
255
+ message: 'No build artifact found in dist/. Run build first for performance analysis.',
256
+ severity: 'warn'
257
+ }];
258
+ }
259
+
260
+ const files = await glob('dist/**/*.{js,css}', { cwd: projectRoot });
261
+ for (const file of files) {
262
+ const stats = statSync(join(projectRoot, file));
263
+ const sizeKB = stats.size / 1024;
264
+
265
+ if (sizeKB > 500) { // Arbitrary 500KB threshold
266
+ issues.push({
267
+ file,
268
+ type: 'Performance',
269
+ message: `Bundle size is large: ${sizeKB.toFixed(2)} KB`,
270
+ severity: 'warn'
271
+ });
272
+ }
273
+ }
274
+
275
+ return issues;
276
+ }
@@ -38,13 +38,15 @@ export const wizard = {
38
38
  // 4. Generate README
39
39
  const readme = type === 'react'
40
40
  ? commonTemplates.readme.react(basename(process.cwd()))
41
- : commonTemplates.readme.nextjs(basename(process.cwd()));
41
+ : type === 'nextjs'
42
+ ? commonTemplates.readme.nextjs(basename(process.cwd()))
43
+ : commonTemplates.readme.vanilla(basename(process.cwd()));
42
44
  await writeFile('README.md', readme, 'utf8');
43
45
 
44
46
  return true;
45
47
  },
46
48
 
47
- async _updatePackageJson() {
49
+ async _updatePackageJson(type, template, options = {}) {
48
50
  const packageJsonPath = join(process.cwd(), 'package.json');
49
51
  let pkg = { scripts: {}, dependencies: {}, devDependencies: {} };
50
52
 
@@ -52,10 +54,62 @@ export const wizard = {
52
54
  pkg = JSON.parse(await readFile(packageJsonPath, 'utf8'));
53
55
  }
54
56
 
55
- // Merge logic... (Simplified for refactor brevity)
56
- // Add scripts
57
- pkg.scripts['build:theme'] = `atomix build-theme themes/custom`;
58
-
57
+ // Merge logic: ensure Atomix CLI scripts exist for scaffolded projects
58
+ pkg.scripts = pkg.scripts || {};
59
+ pkg.scripts['build:theme'] = pkg.scripts['build:theme'] || 'atomix build-theme themes/custom';
60
+ pkg.scripts['generate:component'] = pkg.scripts['generate:component'] || 'atomix generate component';
61
+ pkg.scripts['validate'] = pkg.scripts['validate'] || 'atomix validate';
62
+
63
+ // Add required peer dependencies according to project guidelines
64
+ pkg.dependencies = pkg.dependencies || {};
65
+ pkg.devDependencies = pkg.devDependencies || {};
66
+
67
+ // Required runtime dependencies (from CLI_PEER_DEPENDENCIES.md)
68
+ if (!pkg.dependencies.react) {
69
+ pkg.dependencies.react = '^18.0.0';
70
+ }
71
+ if (!pkg.dependencies['react-dom']) {
72
+ pkg.dependencies['react-dom'] = '^18.0.0';
73
+ }
74
+ if (!pkg.dependencies['@phosphor-icons/react']) {
75
+ pkg.dependencies['@phosphor-icons/react'] = '2.1.10';
76
+ }
77
+
78
+ // Add @shohojdhara/atomix as dependency
79
+ if (!pkg.dependencies['@shohojdhara/atomix']) {
80
+ pkg.dependencies['@shohojdhara/atomix'] = 'latest';
81
+ }
82
+
83
+ // Required devDependencies based on template
84
+ if (template.devDependencies && Array.isArray(template.devDependencies)) {
85
+ // Template defines an array of package names (without versions)
86
+ for (const dep of template.devDependencies) {
87
+ if (!pkg.devDependencies[dep]) {
88
+ // Use default versions for common packages
89
+ const defaultVersions = {
90
+ 'vite': '^4.0.0',
91
+ '@vitejs/plugin-react': '^4.0.0',
92
+ 'typescript': '^5.0.0',
93
+ '@types/react': '^18.0.0',
94
+ '@types/react-dom': '^18.0.0',
95
+ 'sass': '^1.69.0',
96
+ '@types/node': '^20.0.0',
97
+ 'eslint': '^8.0.0',
98
+ 'eslint-config-next': '^14.0.0'
99
+ };
100
+ pkg.devDependencies[dep] = defaultVersions[dep] || '^1.0.0';
101
+ }
102
+ }
103
+ }
104
+
105
+ // Add engines field for Node.js version requirement
106
+ if (!pkg.engines) {
107
+ pkg.engines = {
108
+ node: '>=18.0.0',
109
+ npm: '>=8.0.0'
110
+ };
111
+ }
112
+
59
113
  await writeFile(packageJsonPath, JSON.stringify(pkg, null, 2), 'utf8');
60
114
  }
61
115
  };
@@ -65,6 +65,29 @@ export const tailwindToAtomix = {
65
65
  'rounded-md': 'u-radius-md',
66
66
  'rounded-lg': 'u-radius-lg',
67
67
  'rounded-full': 'u-radius-full',
68
+ // Shadow
69
+ 'shadow-sm': 'u-shadow-sm',
70
+ 'shadow': 'u-shadow-md',
71
+ 'shadow-md': 'u-shadow-md',
72
+ 'shadow-lg': 'u-shadow-lg',
73
+ 'shadow-xl': 'u-shadow-xl',
74
+ 'shadow-2xl': 'u-shadow-2xl',
75
+ 'shadow-inner': 'u-shadow-inner',
76
+ 'shadow-none': 'u-shadow-none',
77
+ // Opacity
78
+ 'opacity-0': 'u-opacity-0',
79
+ 'opacity-25': 'u-opacity-25',
80
+ 'opacity-50': 'u-opacity-50',
81
+ 'opacity-75': 'u-opacity-75',
82
+ 'opacity-100': 'u-opacity-100',
83
+ // Z-index
84
+ 'z-0': 'u-z-0',
85
+ 'z-10': 'u-z-10',
86
+ 'z-20': 'u-z-20',
87
+ 'z-30': 'u-z-30',
88
+ 'z-40': 'u-z-40',
89
+ 'z-50': 'u-z-50',
90
+ 'z-auto': 'u-z-auto',
68
91
  };
69
92
 
70
93
  /**