@shohojdhara/atomix 0.3.1 → 0.3.3

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 (449) hide show
  1. package/CHANGELOG.md +0 -1
  2. package/README.md +41 -24
  3. package/dist/atomix.css +540 -666
  4. package/dist/atomix.min.css +3 -3
  5. package/dist/index.d.ts +7559 -5717
  6. package/dist/index.esm.js +5013 -2301
  7. package/dist/index.esm.js.map +1 -1
  8. package/dist/index.js +5084 -2356
  9. package/dist/index.js.map +1 -1
  10. package/dist/index.min.js +1 -1
  11. package/dist/index.min.js.map +1 -1
  12. package/dist/themes/applemix.css +1683 -722
  13. package/dist/themes/applemix.css.map +1 -0
  14. package/dist/themes/applemix.min.css +13 -10
  15. package/dist/themes/boomdevs.css +1358 -544
  16. package/dist/themes/boomdevs.css.map +1 -0
  17. package/dist/themes/boomdevs.min.css +13 -10
  18. package/dist/themes/esrar.css +1743 -718
  19. package/dist/themes/esrar.css.map +1 -0
  20. package/dist/themes/esrar.min.css +41 -7
  21. package/dist/themes/flashtrade.css +1735 -752
  22. package/dist/themes/flashtrade.css.map +1 -0
  23. package/dist/themes/flashtrade.min.css +19 -13
  24. package/dist/themes/mashroom.css +1765 -787
  25. package/dist/themes/mashroom.css.map +1 -0
  26. package/dist/themes/mashroom.min.css +87 -38
  27. package/dist/themes/shaj-default.css +1685 -713
  28. package/dist/themes/shaj-default.css.map +1 -0
  29. package/dist/themes/shaj-default.min.css +11 -7
  30. package/package.json +95 -26
  31. package/scripts/atomix-cli.js +1428 -0
  32. package/scripts/build-themes.js +208 -0
  33. package/scripts/cli/interactive-init.js +528 -0
  34. package/scripts/cli/migration-tools.js +603 -0
  35. package/scripts/cli/token-manager.js +519 -0
  36. package/scripts/sync-theme-config.js +309 -0
  37. package/src/components/List/ListGroup.tsx +1 -2
  38. package/src/components/Popover/Popover.tsx +2 -2
  39. package/src/components/Tooltip/Tooltip.stories.tsx +49 -12
  40. package/src/components/Tooltip/Tooltip.tsx +32 -58
  41. package/src/lib/composables/useAtomixGlass.ts +46 -46
  42. package/src/lib/composables/useTooltip.ts +285 -0
  43. package/src/lib/constants/cssVariables.ts +390 -0
  44. package/src/lib/hooks/__tests__/useComponentCustomization.test.ts +151 -0
  45. package/src/lib/hooks/index.ts +19 -0
  46. package/src/lib/hooks/useComponentCustomization.ts +175 -0
  47. package/src/lib/index.ts +10 -1
  48. package/src/lib/patterns/__tests__/slots.test.ts +108 -0
  49. package/src/lib/patterns/index.ts +35 -0
  50. package/src/lib/patterns/slots.tsx +421 -0
  51. package/src/lib/theme/__tests__/ThemeBuilder.test.ts +223 -0
  52. package/src/lib/theme/builders/ThemeBuilder.ts +372 -0
  53. package/src/lib/theme/config/index.ts +21 -0
  54. package/src/lib/theme/config/loader.ts +276 -0
  55. package/src/lib/theme/config/types.ts +98 -0
  56. package/src/lib/theme/config/validator.ts +326 -0
  57. package/src/lib/theme/constants.ts +183 -0
  58. package/src/lib/theme/core/ThemeCache.ts +283 -0
  59. package/src/lib/theme/core/ThemeEngine.test.ts +146 -0
  60. package/src/lib/theme/core/ThemeEngine.ts +657 -0
  61. package/src/lib/theme/core/ThemeRegistry.ts +284 -0
  62. package/src/lib/theme/core/ThemeValidator.ts +530 -0
  63. package/src/lib/theme/core/index.ts +24 -0
  64. package/src/lib/theme/createTheme.ts +83 -204
  65. package/src/lib/theme/cssVariableMapper.ts +261 -0
  66. package/src/lib/theme/devtools/CLI.ts +279 -0
  67. package/src/lib/theme/devtools/Inspector.tsx +594 -0
  68. package/src/lib/theme/devtools/Preview.tsx +392 -0
  69. package/src/lib/theme/devtools/index.ts +21 -0
  70. package/src/lib/theme/errors.test.ts +207 -0
  71. package/src/lib/theme/errors.ts +233 -0
  72. package/src/lib/theme/generateCSSVariables.ts +93 -9
  73. package/src/lib/theme/generators/CSSGenerator.ts +311 -0
  74. package/src/lib/theme/generators/ConfigGenerator.ts +287 -0
  75. package/src/lib/theme/generators/TypeGenerator.ts +228 -0
  76. package/src/lib/theme/generators/index.ts +21 -0
  77. package/src/lib/theme/i18n/index.ts +9 -0
  78. package/src/lib/theme/i18n/rtl.ts +325 -0
  79. package/src/lib/theme/index.ts +36 -109
  80. package/src/lib/theme/monitoring/ThemeAnalytics.ts +409 -0
  81. package/src/lib/theme/monitoring/index.ts +17 -0
  82. package/src/lib/theme/overrides/ComponentOverrides.ts +243 -0
  83. package/src/lib/theme/overrides/index.ts +15 -0
  84. package/src/lib/theme/runtime/ThemeApplicator.ts +252 -0
  85. package/src/lib/theme/runtime/ThemeErrorBoundary.tsx +233 -0
  86. package/src/lib/theme/runtime/ThemeManager.test.ts +176 -0
  87. package/src/lib/theme/runtime/ThemeManager.ts +442 -0
  88. package/src/lib/theme/runtime/ThemeProvider.tsx +318 -0
  89. package/src/lib/theme/runtime/index.ts +17 -0
  90. package/src/lib/theme/runtime/useTheme.ts +52 -0
  91. package/src/lib/theme/themeUtils.ts +27 -5
  92. package/src/lib/theme/types.ts +62 -1
  93. package/src/lib/theme/utils.ts +23 -22
  94. package/src/lib/theme/whitelabel/WhiteLabelManager.ts +364 -0
  95. package/src/lib/theme/whitelabel/index.ts +13 -0
  96. package/src/lib/theme-tools.ts +185 -0
  97. package/src/lib/types/components.ts +194 -0
  98. package/src/lib/types/partProps.ts +426 -0
  99. package/src/lib/utils/__tests__/componentUtils.test.ts +144 -0
  100. package/src/lib/utils/componentUtils.ts +163 -0
  101. package/src/lib/utils/index.ts +17 -57
  102. package/src/styles/01-settings/_settings.badge.scss +1 -1
  103. package/src/styles/01-settings/_settings.callout.scss +1 -1
  104. package/src/styles/01-settings/_settings.card.scss +1 -1
  105. package/src/styles/01-settings/_settings.colors.scss +10 -10
  106. package/src/styles/01-settings/_settings.input.scss +1 -1
  107. package/src/styles/01-settings/_settings.navbar.scss +1 -1
  108. package/src/styles/01-settings/_settings.tooltip.scss +1 -1
  109. package/src/styles/01-settings/_settings.upload.scss +1 -1
  110. package/src/styles/06-components/_components.chart.scss +2 -2
  111. package/src/styles/06-components/_components.tooltip.scss +31 -81
  112. package/src/styles/99-utilities/_utilities.border.scss +27 -58
  113. package/src/styles/99-utilities/_utilities.gradient.scss +12 -0
  114. package/src/styles/99-utilities/_utilities.position.scss +8 -15
  115. package/src/styles/99-utilities/_utilities.scss +2 -0
  116. package/src/styles/99-utilities/_utilities.spacing.scss +76 -121
  117. package/src/styles/99-utilities/_utilities.text.scss +30 -49
  118. package/src/themes/README.md +443 -0
  119. package/src/themes/THEME_CHECKLIST.md +74 -0
  120. package/src/themes/applemix/01-settings/_index.scss +24 -0
  121. package/src/themes/applemix/01-settings/_settings.animations.scss +0 -0
  122. package/src/themes/applemix/01-settings/_settings.background.scss +6 -0
  123. package/src/themes/applemix/01-settings/_settings.colors.scss +75 -0
  124. package/src/themes/applemix/01-settings/_settings.config.scss +15 -0
  125. package/src/themes/applemix/01-settings/_settings.typography.scss +30 -0
  126. package/src/themes/applemix/02-tools/_index.scss +4 -0
  127. package/src/themes/applemix/03-generic/_index.scss +7 -0
  128. package/src/themes/applemix/04-elements/_index.scss +7 -0
  129. package/src/themes/applemix/05-objects/_index.scss +7 -0
  130. package/src/themes/applemix/06-components/_index.scss +15 -0
  131. package/src/themes/applemix/99-utilities/_index.scss +7 -0
  132. package/src/themes/applemix/README.md +378 -0
  133. package/src/themes/applemix/index.scss +33 -0
  134. package/src/themes/boomdevs/01-settings/_index.scss +38 -0
  135. package/src/themes/boomdevs/01-settings/_settings.accordion.scss +12 -0
  136. package/src/themes/boomdevs/01-settings/_settings.animations.scss +11 -0
  137. package/src/themes/boomdevs/01-settings/_settings.avatar.scss +9 -0
  138. package/src/themes/boomdevs/01-settings/_settings.badge.scss +11 -0
  139. package/src/themes/boomdevs/01-settings/_settings.border-radius.scss +16 -0
  140. package/src/themes/boomdevs/01-settings/_settings.border.scss +10 -0
  141. package/src/themes/boomdevs/01-settings/_settings.box-shadow.scss +14 -0
  142. package/src/themes/boomdevs/01-settings/_settings.breadcrumb.scss +13 -0
  143. package/src/themes/boomdevs/01-settings/_settings.breakpoints.scss +15 -0
  144. package/src/themes/boomdevs/01-settings/_settings.button.scss +9 -0
  145. package/src/themes/boomdevs/01-settings/_settings.callout.scss +9 -0
  146. package/src/themes/boomdevs/01-settings/_settings.card.scss +11 -0
  147. package/src/themes/boomdevs/01-settings/_settings.checkbox.scss +9 -0
  148. package/src/themes/boomdevs/01-settings/_settings.colors.scss +145 -0
  149. package/src/themes/boomdevs/01-settings/_settings.dropdown.scss +11 -0
  150. package/src/themes/boomdevs/01-settings/_settings.grid.scss +16 -0
  151. package/src/themes/boomdevs/01-settings/_settings.input.scss +14 -0
  152. package/src/themes/boomdevs/01-settings/_settings.link.scss +11 -0
  153. package/src/themes/boomdevs/01-settings/_settings.list.scss +10 -0
  154. package/src/themes/boomdevs/01-settings/_settings.modal.scss +16 -0
  155. package/src/themes/boomdevs/01-settings/_settings.navbar.scss +16 -0
  156. package/src/themes/boomdevs/01-settings/_settings.pagination.scss +13 -0
  157. package/src/themes/boomdevs/01-settings/_settings.progress.scss +11 -0
  158. package/src/themes/boomdevs/01-settings/_settings.rating.scss +10 -0
  159. package/src/themes/boomdevs/01-settings/_settings.spacing.scss +33 -0
  160. package/src/themes/boomdevs/01-settings/_settings.spinner.scss +11 -0
  161. package/src/themes/boomdevs/01-settings/_settings.steps.scss +12 -0
  162. package/src/themes/boomdevs/01-settings/_settings.tabs.scss +12 -0
  163. package/src/themes/boomdevs/01-settings/_settings.todo.scss +15 -0
  164. package/src/themes/boomdevs/01-settings/_settings.toggle.scss +14 -0
  165. package/src/themes/boomdevs/01-settings/_settings.tooltip.scss +13 -0
  166. package/src/themes/boomdevs/01-settings/_settings.typography.scss +58 -0
  167. package/src/themes/boomdevs/01-settings/_settings.video-player.scss +12 -0
  168. package/src/themes/boomdevs/02-tools/_index.scss +7 -0
  169. package/src/themes/boomdevs/03-generic/_index.scss +7 -0
  170. package/src/themes/boomdevs/04-elements/_index.scss +7 -0
  171. package/src/themes/boomdevs/05-objects/_index.scss +7 -0
  172. package/src/themes/boomdevs/06-components/_components.button.scss +11 -0
  173. package/src/themes/boomdevs/06-components/_index.scss +11 -0
  174. package/src/themes/boomdevs/99-utilities/_index.scss +7 -0
  175. package/src/themes/boomdevs/index.scss +26 -0
  176. package/src/themes/esrar/01-settings/_index.scss +15 -0
  177. package/src/themes/esrar/01-settings/_settings.colors.scss +91 -0
  178. package/src/themes/esrar/02-tools/_index.scss +8 -0
  179. package/src/themes/esrar/02-tools/_tools.animations.scss +342 -0
  180. package/src/themes/esrar/06-components/_components.accordion.scss +49 -0
  181. package/src/themes/esrar/06-components/_components.avatar-group.scss +14 -0
  182. package/src/themes/esrar/06-components/_components.avatar.scss +61 -0
  183. package/src/themes/esrar/06-components/_components.badge.scss +117 -0
  184. package/src/themes/esrar/06-components/_components.breadcrumb.scss +65 -0
  185. package/src/themes/esrar/06-components/_components.btn-group.scss +19 -0
  186. package/src/themes/esrar/06-components/_components.button.scss +224 -0
  187. package/src/themes/esrar/06-components/_components.callout.scss +51 -0
  188. package/src/themes/esrar/06-components/_components.card.scss +134 -0
  189. package/src/themes/esrar/06-components/_components.chart.scss +24 -0
  190. package/src/themes/esrar/06-components/_components.checkbox-group.scss +26 -0
  191. package/src/themes/esrar/06-components/_components.checkbox.scss +71 -0
  192. package/src/themes/esrar/06-components/_components.color-mode-toggle.scss +29 -0
  193. package/src/themes/esrar/06-components/_components.countdown.scss +67 -0
  194. package/src/themes/esrar/06-components/_components.data-table.scss +22 -0
  195. package/src/themes/esrar/06-components/_components.datepicker.scss +20 -0
  196. package/src/themes/esrar/06-components/_components.dropdown.scss +272 -0
  197. package/src/themes/esrar/06-components/_components.edge-panel.scss +10 -0
  198. package/src/themes/esrar/06-components/_components.form-group.scss +15 -0
  199. package/src/themes/esrar/06-components/_components.form.scss +66 -0
  200. package/src/themes/esrar/06-components/_components.hero.scss +251 -0
  201. package/src/themes/esrar/06-components/_components.icon.scss +33 -0
  202. package/src/themes/esrar/06-components/_components.image-gallery.scss +29 -0
  203. package/src/themes/esrar/06-components/_components.input.scss +91 -0
  204. package/src/themes/esrar/06-components/_components.list-group.scss +26 -0
  205. package/src/themes/esrar/06-components/_components.modal.scss +148 -0
  206. package/src/themes/esrar/06-components/_components.notification.scss +80 -0
  207. package/src/themes/esrar/06-components/_components.pagination.scss +84 -0
  208. package/src/themes/esrar/06-components/_components.popover.scss +10 -0
  209. package/src/themes/esrar/06-components/_components.progress.scss +64 -0
  210. package/src/themes/esrar/06-components/_components.rating.scss +26 -0
  211. package/src/themes/esrar/06-components/_components.skeleton.scss +15 -0
  212. package/src/themes/esrar/06-components/_components.slider.scss +90 -0
  213. package/src/themes/esrar/06-components/_components.spinner.scss +71 -0
  214. package/src/themes/esrar/06-components/_components.steps.scss +76 -0
  215. package/src/themes/esrar/06-components/_components.tab.scss +58 -0
  216. package/src/themes/esrar/06-components/_components.tag.scss +21 -0
  217. package/src/themes/esrar/06-components/_components.timeline.scss +19 -0
  218. package/src/themes/esrar/06-components/_components.toast.scss +91 -0
  219. package/src/themes/esrar/06-components/_components.toggle.scss +74 -0
  220. package/src/themes/esrar/06-components/_components.tooltip.scss +45 -0
  221. package/src/themes/esrar/06-components/_components.upload.scss +102 -0
  222. package/src/themes/esrar/06-components/_index.scss +42 -0
  223. package/src/themes/esrar/index.scss +30 -0
  224. package/src/themes/flashtrade/01-settings/_index.scss +19 -0
  225. package/src/themes/flashtrade/01-settings/_settings.animations.scss +11 -0
  226. package/src/themes/flashtrade/01-settings/_settings.background.scss +9 -0
  227. package/src/themes/flashtrade/01-settings/_settings.colors.scss +79 -0
  228. package/src/themes/flashtrade/01-settings/_settings.config.scss +16 -0
  229. package/src/themes/flashtrade/01-settings/_settings.typography.scss +35 -0
  230. package/src/themes/flashtrade/02-tools/_index.scss +8 -0
  231. package/src/themes/flashtrade/03-generic/_index.scss +8 -0
  232. package/src/themes/flashtrade/04-elements/_index.scss +12 -0
  233. package/src/themes/flashtrade/05-objects/_index.scss +8 -0
  234. package/src/themes/flashtrade/06-components/_components.badge.scss +156 -0
  235. package/src/themes/flashtrade/06-components/_components.button.scss +135 -0
  236. package/src/themes/flashtrade/06-components/_components.card.scss +214 -0
  237. package/src/themes/flashtrade/06-components/_components.navbar.scss +227 -0
  238. package/src/themes/flashtrade/06-components/_index.scss +13 -0
  239. package/src/themes/flashtrade/99-utilities/_index.scss +9 -0
  240. package/src/themes/flashtrade/99-utilities/_utilities.trading.scss +187 -0
  241. package/src/themes/flashtrade/README.md +386 -0
  242. package/src/themes/flashtrade/demo.html +272 -0
  243. package/src/themes/flashtrade/index.scss +36 -0
  244. package/src/themes/mashroom/01-settings/_index.scss +69 -0
  245. package/src/themes/mashroom/01-settings/_settings.accordion.scss +32 -0
  246. package/src/themes/mashroom/01-settings/_settings.animations.scss +26 -0
  247. package/src/themes/mashroom/01-settings/_settings.avatar-group.scss +22 -0
  248. package/src/themes/mashroom/01-settings/_settings.avatar.scss +57 -0
  249. package/src/themes/mashroom/01-settings/_settings.badge.scss +19 -0
  250. package/src/themes/mashroom/01-settings/_settings.border-radius.scss +24 -0
  251. package/src/themes/mashroom/01-settings/_settings.border.scss +14 -0
  252. package/src/themes/mashroom/01-settings/_settings.box-shadow.scss +40 -0
  253. package/src/themes/mashroom/01-settings/_settings.breadcrumb.scss +0 -0
  254. package/src/themes/mashroom/01-settings/_settings.breakpoints.scss +17 -0
  255. package/src/themes/mashroom/01-settings/_settings.btn-group.scss +5 -0
  256. package/src/themes/mashroom/01-settings/_settings.button.scss +50 -0
  257. package/src/themes/mashroom/01-settings/_settings.callout.scss +81 -0
  258. package/src/themes/mashroom/01-settings/_settings.card.scss +52 -0
  259. package/src/themes/mashroom/01-settings/_settings.checkbox-group.scss +5 -0
  260. package/src/themes/mashroom/01-settings/_settings.checkbox.scss +23 -0
  261. package/src/themes/mashroom/01-settings/_settings.color-mode.scss +7 -0
  262. package/src/themes/mashroom/01-settings/_settings.colors.scss +180 -0
  263. package/src/themes/mashroom/01-settings/_settings.config.scss +4 -0
  264. package/src/themes/mashroom/01-settings/_settings.countdown.scss +20 -0
  265. package/src/themes/mashroom/01-settings/_settings.data-table.scss +56 -0
  266. package/src/themes/mashroom/01-settings/_settings.datepicker.scss +45 -0
  267. package/src/themes/mashroom/01-settings/_settings.design-tokens.scss +3 -0
  268. package/src/themes/mashroom/01-settings/_settings.dropdown.scss +45 -0
  269. package/src/themes/mashroom/01-settings/_settings.edge-panel.scss +24 -0
  270. package/src/themes/mashroom/01-settings/_settings.fonts.scss +8 -0
  271. package/src/themes/mashroom/01-settings/_settings.form-group.scss +14 -0
  272. package/src/themes/mashroom/01-settings/_settings.form.scss +6 -0
  273. package/src/themes/mashroom/01-settings/_settings.grid.scss +23 -0
  274. package/src/themes/mashroom/01-settings/_settings.hero.scss +41 -0
  275. package/src/themes/mashroom/01-settings/_settings.input.scss +51 -0
  276. package/src/themes/mashroom/01-settings/_settings.link.scss +13 -0
  277. package/src/themes/mashroom/01-settings/_settings.list-group.scss +16 -0
  278. package/src/themes/mashroom/01-settings/_settings.list.scss +13 -0
  279. package/src/themes/mashroom/01-settings/_settings.masonry-grid.scss +23 -0
  280. package/src/themes/mashroom/01-settings/_settings.menu.scss +50 -0
  281. package/src/themes/mashroom/01-settings/_settings.messages.scss +98 -0
  282. package/src/themes/mashroom/01-settings/_settings.modal.scss +41 -0
  283. package/src/themes/mashroom/01-settings/_settings.nav.scss +20 -0
  284. package/src/themes/mashroom/01-settings/_settings.navbar.scss +54 -0
  285. package/src/themes/mashroom/01-settings/_settings.pagination.scss +30 -0
  286. package/src/themes/mashroom/01-settings/_settings.photoviewer.scss +45 -0
  287. package/src/themes/mashroom/01-settings/_settings.popover.scss +20 -0
  288. package/src/themes/mashroom/01-settings/_settings.position.scss +9 -0
  289. package/src/themes/mashroom/01-settings/_settings.progress.scss +17 -0
  290. package/src/themes/mashroom/01-settings/_settings.rating.scss +11 -0
  291. package/src/themes/mashroom/01-settings/_settings.river.scss +50 -0
  292. package/src/themes/mashroom/01-settings/_settings.sectionintro.scss +31 -0
  293. package/src/themes/mashroom/01-settings/_settings.select.scss +47 -0
  294. package/src/themes/mashroom/01-settings/_settings.side-menu.scss +79 -0
  295. package/src/themes/mashroom/01-settings/_settings.skeleton.scss +24 -0
  296. package/src/themes/mashroom/01-settings/_settings.spacing.scss +66 -0
  297. package/src/themes/mashroom/01-settings/_settings.spinner.scss +34 -0
  298. package/src/themes/mashroom/01-settings/_settings.steps.scss +33 -0
  299. package/src/themes/mashroom/01-settings/_settings.tabs.scss +33 -0
  300. package/src/themes/mashroom/01-settings/_settings.testimonials.scss +24 -0
  301. package/src/themes/mashroom/01-settings/_settings.todo.scss +52 -0
  302. package/src/themes/mashroom/01-settings/_settings.toggle.scss +49 -0
  303. package/src/themes/mashroom/01-settings/_settings.tooltip.scss +20 -0
  304. package/src/themes/mashroom/01-settings/_settings.typography.scss +95 -0
  305. package/src/themes/mashroom/01-settings/_settings.upload.scss +96 -0
  306. package/src/themes/mashroom/01-settings/_settings.z-layers.scss +19 -0
  307. package/src/themes/mashroom/02-tools/_index.scss +8 -0
  308. package/src/themes/mashroom/02-tools/_tools.psychedelic-gradients.scss +78 -0
  309. package/src/themes/mashroom/02-tools/_tools.trippy-effects.scss +114 -0
  310. package/src/themes/mashroom/03-generic/_index.scss +6 -0
  311. package/src/themes/mashroom/04-elements/_index.scss +6 -0
  312. package/src/themes/mashroom/05-objects/_index.scss +6 -0
  313. package/src/themes/mashroom/06-components/_components.accordion.scss +187 -0
  314. package/src/themes/mashroom/06-components/_components.avatar-group.scss +276 -0
  315. package/src/themes/mashroom/06-components/_components.avatar.scss +114 -0
  316. package/src/themes/mashroom/06-components/_components.badge.scss +152 -0
  317. package/src/themes/mashroom/06-components/_components.breadcrumb.scss +162 -0
  318. package/src/themes/mashroom/06-components/_components.btn-group.scss +404 -0
  319. package/src/themes/mashroom/06-components/_components.button.scss +160 -0
  320. package/src/themes/mashroom/06-components/_components.callout.scss +140 -0
  321. package/src/themes/mashroom/06-components/_components.card.scss +225 -0
  322. package/src/themes/mashroom/06-components/_components.checkbox.scss +186 -0
  323. package/src/themes/mashroom/06-components/_components.color-mode-toggle.scss +308 -0
  324. package/src/themes/mashroom/06-components/_components.countdown.scss +402 -0
  325. package/src/themes/mashroom/06-components/_components.data-table.scss +354 -0
  326. package/src/themes/mashroom/06-components/_components.datepicker.scss +349 -0
  327. package/src/themes/mashroom/06-components/_components.dropdown.scss +334 -0
  328. package/src/themes/mashroom/06-components/_components.edge-panel.scss +413 -0
  329. package/src/themes/mashroom/06-components/_components.form-group.scss +433 -0
  330. package/src/themes/mashroom/06-components/_components.form.scss +358 -0
  331. package/src/themes/mashroom/06-components/_components.hero.scss +151 -0
  332. package/src/themes/mashroom/06-components/_components.input.scss +147 -0
  333. package/src/themes/mashroom/06-components/_components.list-group.scss +456 -0
  334. package/src/themes/mashroom/06-components/_components.list.scss +145 -0
  335. package/src/themes/mashroom/06-components/_components.menu.scss +497 -0
  336. package/src/themes/mashroom/06-components/_components.messages.scss +277 -0
  337. package/src/themes/mashroom/06-components/_components.modal.scss +264 -0
  338. package/src/themes/mashroom/06-components/_components.nav.scss +181 -0
  339. package/src/themes/mashroom/06-components/_components.navbar.scss +538 -0
  340. package/src/themes/mashroom/06-components/_components.pagination.scss +400 -0
  341. package/src/themes/mashroom/06-components/_components.photoviewer.scss +498 -0
  342. package/src/themes/mashroom/06-components/_components.popover.scss +383 -0
  343. package/src/themes/mashroom/06-components/_components.product-review.scss +408 -0
  344. package/src/themes/mashroom/06-components/_components.progress.scss +249 -0
  345. package/src/themes/mashroom/06-components/_components.rating.scss +300 -0
  346. package/src/themes/mashroom/06-components/_components.river.scss +570 -0
  347. package/src/themes/mashroom/06-components/_components.sectionintro.scss +546 -0
  348. package/src/themes/mashroom/06-components/_components.select.scss +455 -0
  349. package/src/themes/mashroom/06-components/_components.side-menu.scss +635 -0
  350. package/src/themes/mashroom/06-components/_components.skeleton.scss +447 -0
  351. package/src/themes/mashroom/06-components/_components.slider.scss +414 -0
  352. package/src/themes/mashroom/06-components/_components.spinner.scss +198 -0
  353. package/src/themes/mashroom/06-components/_components.steps.scss +350 -0
  354. package/src/themes/mashroom/06-components/_components.tabs.scss +269 -0
  355. package/src/themes/mashroom/06-components/_components.testimonials.scss +561 -0
  356. package/src/themes/mashroom/06-components/_components.toggle.scss +231 -0
  357. package/src/themes/mashroom/06-components/_components.tooltip.scss +167 -0
  358. package/src/themes/mashroom/06-components/_components.upload.scss +537 -0
  359. package/src/themes/mashroom/06-components/_components.video-player.scss +560 -0
  360. package/src/themes/mashroom/06-components/_index.scss +55 -0
  361. package/src/themes/mashroom/99-utilities/_index.scss +6 -0
  362. package/src/themes/mashroom/index.scss +26 -0
  363. package/src/themes/shaj-default/01-settings/_index.scss +69 -0
  364. package/src/themes/shaj-default/01-settings/_settings.accordion.scss +38 -0
  365. package/src/themes/shaj-default/01-settings/_settings.animations.scss +32 -0
  366. package/src/themes/shaj-default/01-settings/_settings.avatar-group.scss +28 -0
  367. package/src/themes/shaj-default/01-settings/_settings.avatar.scss +63 -0
  368. package/src/themes/shaj-default/01-settings/_settings.badge.scss +25 -0
  369. package/src/themes/shaj-default/01-settings/_settings.border-radius.scss +24 -0
  370. package/src/themes/shaj-default/01-settings/_settings.border.scss +20 -0
  371. package/src/themes/shaj-default/01-settings/_settings.box-shadow.scss +46 -0
  372. package/src/themes/shaj-default/01-settings/_settings.breadcrumb.scss +0 -0
  373. package/src/themes/shaj-default/01-settings/_settings.breakpoints.scss +23 -0
  374. package/src/themes/shaj-default/01-settings/_settings.btn-group.scss +11 -0
  375. package/src/themes/shaj-default/01-settings/_settings.button.scss +56 -0
  376. package/src/themes/shaj-default/01-settings/_settings.callout.scss +87 -0
  377. package/src/themes/shaj-default/01-settings/_settings.card.scss +52 -0
  378. package/src/themes/shaj-default/01-settings/_settings.checkbox-group.scss +11 -0
  379. package/src/themes/shaj-default/01-settings/_settings.checkbox.scss +29 -0
  380. package/src/themes/shaj-default/01-settings/_settings.color-mode.scss +13 -0
  381. package/src/themes/shaj-default/01-settings/_settings.colors.scss +91 -0
  382. package/src/themes/shaj-default/01-settings/_settings.config.scss +4 -0
  383. package/src/themes/shaj-default/01-settings/_settings.countdown.scss +26 -0
  384. package/src/themes/shaj-default/01-settings/_settings.data-table.scss +62 -0
  385. package/src/themes/shaj-default/01-settings/_settings.datepicker.scss +51 -0
  386. package/src/themes/shaj-default/01-settings/_settings.design-tokens.scss +9 -0
  387. package/src/themes/shaj-default/01-settings/_settings.dropdown.scss +51 -0
  388. package/src/themes/shaj-default/01-settings/_settings.edge-panel.scss +30 -0
  389. package/src/themes/shaj-default/01-settings/_settings.fonts.scss +13 -0
  390. package/src/themes/shaj-default/01-settings/_settings.form-group.scss +20 -0
  391. package/src/themes/shaj-default/01-settings/_settings.form.scss +12 -0
  392. package/src/themes/shaj-default/01-settings/_settings.grid.scss +29 -0
  393. package/src/themes/shaj-default/01-settings/_settings.hero.scss +47 -0
  394. package/src/themes/shaj-default/01-settings/_settings.input.scss +57 -0
  395. package/src/themes/shaj-default/01-settings/_settings.link.scss +19 -0
  396. package/src/themes/shaj-default/01-settings/_settings.list-group.scss +22 -0
  397. package/src/themes/shaj-default/01-settings/_settings.list.scss +19 -0
  398. package/src/themes/shaj-default/01-settings/_settings.masonry-grid.scss +29 -0
  399. package/src/themes/shaj-default/01-settings/_settings.menu.scss +56 -0
  400. package/src/themes/shaj-default/01-settings/_settings.messages.scss +104 -0
  401. package/src/themes/shaj-default/01-settings/_settings.modal.scss +47 -0
  402. package/src/themes/shaj-default/01-settings/_settings.nav.scss +26 -0
  403. package/src/themes/shaj-default/01-settings/_settings.navbar.scss +60 -0
  404. package/src/themes/shaj-default/01-settings/_settings.pagination.scss +36 -0
  405. package/src/themes/shaj-default/01-settings/_settings.photoviewer.scss +51 -0
  406. package/src/themes/shaj-default/01-settings/_settings.popover.scss +26 -0
  407. package/src/themes/shaj-default/01-settings/_settings.position.scss +15 -0
  408. package/src/themes/shaj-default/01-settings/_settings.progress.scss +23 -0
  409. package/src/themes/shaj-default/01-settings/_settings.rating.scss +17 -0
  410. package/src/themes/shaj-default/01-settings/_settings.river.scss +56 -0
  411. package/src/themes/shaj-default/01-settings/_settings.sectionintro.scss +37 -0
  412. package/src/themes/shaj-default/01-settings/_settings.select.scss +53 -0
  413. package/src/themes/shaj-default/01-settings/_settings.side-menu.scss +85 -0
  414. package/src/themes/shaj-default/01-settings/_settings.skeleton.scss +30 -0
  415. package/src/themes/shaj-default/01-settings/_settings.spacing.scss +72 -0
  416. package/src/themes/shaj-default/01-settings/_settings.spinner.scss +24 -0
  417. package/src/themes/shaj-default/01-settings/_settings.steps.scss +39 -0
  418. package/src/themes/shaj-default/01-settings/_settings.tabs.scss +39 -0
  419. package/src/themes/shaj-default/01-settings/_settings.testimonials.scss +30 -0
  420. package/src/themes/shaj-default/01-settings/_settings.todo.scss +58 -0
  421. package/src/themes/shaj-default/01-settings/_settings.toggle.scss +55 -0
  422. package/src/themes/shaj-default/01-settings/_settings.tooltip.scss +26 -0
  423. package/src/themes/shaj-default/01-settings/_settings.typography.scss +101 -0
  424. package/src/themes/shaj-default/01-settings/_settings.upload.scss +102 -0
  425. package/src/themes/shaj-default/01-settings/_settings.z-layers.scss +25 -0
  426. package/src/themes/shaj-default/02-tools/_index.scss +0 -0
  427. package/src/themes/shaj-default/03-generic/_generic.root.scss +0 -0
  428. package/src/themes/shaj-default/03-generic/_index.scss +2 -0
  429. package/src/themes/shaj-default/04-elements/_index.scss +0 -0
  430. package/src/themes/shaj-default/05-objects/_index.scss +0 -0
  431. package/src/themes/shaj-default/06-components/_components.button.scss +55 -0
  432. package/src/themes/shaj-default/06-components/_components.card.scss +57 -0
  433. package/src/themes/shaj-default/06-components/_components.input.scss +58 -0
  434. package/src/themes/shaj-default/06-components/_components.navbar.scss +99 -0
  435. package/src/themes/shaj-default/06-components/_components.tooltip.scss +0 -0
  436. package/src/themes/shaj-default/06-components/_index.scss +13 -0
  437. package/src/themes/shaj-default/99-utilities/_index.scss +0 -0
  438. package/src/themes/shaj-default/index.scss +25 -0
  439. package/src/themes/themes.config.js +219 -0
  440. package/theme.config.ts +360 -0
  441. package/src/lib/theme/ThemeManager.integration.test.ts +0 -124
  442. package/src/lib/theme/ThemeManager.stories.tsx +0 -472
  443. package/src/lib/theme/ThemeManager.test.ts +0 -190
  444. package/src/lib/theme/ThemeManager.ts +0 -645
  445. package/src/lib/theme/ThemeProvider.tsx +0 -377
  446. package/src/lib/theme/createTheme.test.ts +0 -475
  447. package/src/lib/theme/useTheme.test.tsx +0 -67
  448. package/src/lib/theme/useTheme.ts +0 -64
  449. package/src/lib/theme/utils.test.ts +0 -140
@@ -0,0 +1,1428 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Atomix CLI - Enhanced Version
5
+ * Design System Development Tools
6
+ */
7
+
8
+ import { program } from 'commander';
9
+ import { readFile, writeFile, mkdir, access, stat, rm } from 'fs/promises';
10
+ import { join, dirname, basename, relative, resolve } from 'path';
11
+ import { fileURLToPath } from 'url';
12
+ import { existsSync } from 'fs';
13
+ import * as sass from 'sass';
14
+ import postcss from 'postcss';
15
+ import autoprefixer from 'autoprefixer';
16
+ import cssnano from 'cssnano';
17
+ import chalk from 'chalk';
18
+ import ora from 'ora';
19
+ import chokidar from 'chokidar';
20
+ import inquirer from 'inquirer';
21
+ import boxen from 'boxen';
22
+ import { runInitWizard } from './cli/interactive-init.js';
23
+ import {
24
+ migrateTailwind,
25
+ migrateBootstrap,
26
+ migrateSCSSVariables,
27
+ displayMigrationReport
28
+ } from './cli/migration-tools.js';
29
+ import {
30
+ listTokens,
31
+ validateTokens,
32
+ exportTokens,
33
+ importTokens
34
+ } from './cli/token-manager.js';
35
+
36
+ const __filename = fileURLToPath(import.meta.url);
37
+ const __dirname = dirname(__filename);
38
+
39
+ // Package info
40
+ const packageJson = JSON.parse(
41
+ await readFile(join(__dirname, '../package.json'), 'utf8')
42
+ );
43
+
44
+ // CLI Configuration
45
+ const DEBUG = process.env.ATOMIX_DEBUG === 'true' || process.argv.includes('--debug');
46
+
47
+ /**
48
+ * Enhanced Error Class
49
+ */
50
+ class AtomixCLIError extends Error {
51
+ constructor(message, code, suggestions = []) {
52
+ super(message);
53
+ this.name = 'AtomixCLIError';
54
+ this.code = code;
55
+ this.suggestions = suggestions;
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Debug logger
61
+ */
62
+ function debug(message, data = null) {
63
+ if (DEBUG) {
64
+ console.log(chalk.gray(`[DEBUG] ${message}`));
65
+ if (data) {
66
+ console.log(chalk.gray(JSON.stringify(data, null, 2)));
67
+ }
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Error handler with suggestions
73
+ */
74
+ function handleError(error, spinner = null) {
75
+ if (spinner) spinner.fail(chalk.red('Operation failed'));
76
+
77
+ console.error(chalk.bold.red(`\n❌ ${error.message}`));
78
+
79
+ if (error instanceof AtomixCLIError && error.suggestions.length > 0) {
80
+ console.log(chalk.yellow('\n💡 Suggestions:'));
81
+ error.suggestions.forEach((suggestion, index) => {
82
+ console.log(chalk.gray(` ${index + 1}. ${suggestion}`));
83
+ });
84
+ }
85
+
86
+ if (DEBUG && error.stack) {
87
+ console.error(chalk.gray('\nStack trace:'));
88
+ console.error(chalk.gray(error.stack));
89
+ }
90
+
91
+ process.exit(1);
92
+ }
93
+
94
+ /**
95
+ * Component templates for design system
96
+ */
97
+ const componentTemplates = {
98
+ react: {
99
+ component: (name, options = {}) => `import React, { forwardRef, memo } from 'react';
100
+ ${options.scssModule ? `import styles from './${name}.module.scss';` : ''}
101
+ ${options.types ? `import type { ${name}Props } from '../../lib/types/components';` : ''}
102
+
103
+ ${options.types ? '' : `export interface ${name}Props {
104
+ /**
105
+ * Content to be rendered
106
+ */
107
+ children?: React.ReactNode;
108
+
109
+ /**
110
+ * Additional CSS classes
111
+ */
112
+ className?: string;
113
+
114
+ /**
115
+ * Size variant
116
+ */
117
+ size?: 'sm' | 'md' | 'lg';
118
+
119
+ /**
120
+ * Color variant
121
+ */
122
+ variant?: 'primary' | 'secondary' | 'success' | 'error';
123
+
124
+ /**
125
+ * Disabled state
126
+ */
127
+ disabled?: boolean;
128
+ }`}
129
+
130
+ /**
131
+ * ${name} component
132
+ *
133
+ * @component
134
+ * @example
135
+ * <${name} variant="primary" size="md">
136
+ * Content
137
+ * </${name}>
138
+ */
139
+ export const ${name} = memo(
140
+ forwardRef<HTMLDivElement, ${name}Props>(
141
+ ({ children, className = '', size = 'md', variant = 'primary', disabled = false, ...props }, ref) => {
142
+ ${options.scssModule ? `const componentClasses = [
143
+ styles.${name.toLowerCase()},
144
+ styles[\`${name.toLowerCase()}--\${size}\`],
145
+ styles[\`${name.toLowerCase()}--\${variant}\`],
146
+ disabled && styles['${name.toLowerCase()}--disabled'],
147
+ className
148
+ ].filter(Boolean).join(' ');` : `const componentClasses = \`c-${name.toLowerCase()} c-${name.toLowerCase()}--\${size} c-${name.toLowerCase()}--\${variant} \${disabled ? 'c-${name.toLowerCase()}--disabled' : ''} \${className}\`.trim();`}
149
+
150
+ return (
151
+ <div
152
+ ref={ref}
153
+ className={componentClasses}
154
+ aria-disabled={disabled}
155
+ {...props}
156
+ >
157
+ {children}
158
+ </div>
159
+ );
160
+ }
161
+ )
162
+ );
163
+
164
+ ${name}.displayName = '${name}';
165
+
166
+ export default ${name};`,
167
+
168
+ index: (name) => `export { default as ${name} } from './${name}';
169
+ export type { ${name}Props } from './${name}';`,
170
+
171
+ story: (name) => `import type { Meta, StoryObj } from '@storybook/react';
172
+ import { ${name} } from './${name}';
173
+
174
+ const meta: Meta<typeof ${name}> = {
175
+ title: 'Components/${name}',
176
+ component: ${name},
177
+ parameters: {
178
+ layout: 'centered',
179
+ },
180
+ tags: ['autodocs'],
181
+ argTypes: {
182
+ size: {
183
+ control: 'select',
184
+ options: ['sm', 'md', 'lg'],
185
+ },
186
+ variant: {
187
+ control: 'select',
188
+ options: ['primary', 'secondary', 'success', 'error'],
189
+ },
190
+ disabled: {
191
+ control: 'boolean',
192
+ },
193
+ },
194
+ };
195
+
196
+ export default meta;
197
+ type Story = StoryObj<typeof meta>;
198
+
199
+ export const Default: Story = {
200
+ args: {
201
+ children: '${name} Component',
202
+ size: 'md',
203
+ variant: 'primary',
204
+ },
205
+ };
206
+
207
+ export const Small: Story = {
208
+ args: {
209
+ ...Default.args,
210
+ size: 'sm',
211
+ },
212
+ };
213
+
214
+ export const Large: Story = {
215
+ args: {
216
+ ...Default.args,
217
+ size: 'lg',
218
+ },
219
+ };
220
+
221
+ export const Secondary: Story = {
222
+ args: {
223
+ ...Default.args,
224
+ variant: 'secondary',
225
+ },
226
+ };
227
+
228
+ export const Success: Story = {
229
+ args: {
230
+ ...Default.args,
231
+ variant: 'success',
232
+ },
233
+ };
234
+
235
+ export const Error: Story = {
236
+ args: {
237
+ ...Default.args,
238
+ variant: 'error',
239
+ },
240
+ };
241
+
242
+ export const Disabled: Story = {
243
+ args: {
244
+ ...Default.args,
245
+ disabled: true,
246
+ },
247
+ };`,
248
+
249
+ test: (name) => `import { describe, it, expect } from 'vitest';
250
+ import { render, screen } from '@testing-library/react';
251
+ import { ${name} } from './${name}';
252
+
253
+ describe('${name}', () => {
254
+ it('renders children correctly', () => {
255
+ render(<${name}>Test Content</${name}>);
256
+ expect(screen.getByText('Test Content')).toBeInTheDocument();
257
+ });
258
+
259
+ it('applies size variant classes', () => {
260
+ const { container } = render(<${name} size="lg">Content</${name}>);
261
+ const element = container.firstChild;
262
+ expect(element).toHaveClass('c-${name.toLowerCase()}--lg');
263
+ });
264
+
265
+ it('applies variant classes', () => {
266
+ const { container } = render(<${name} variant="success">Content</${name}>);
267
+ const element = container.firstChild;
268
+ expect(element).toHaveClass('c-${name.toLowerCase()}--success');
269
+ });
270
+
271
+ it('handles disabled state', () => {
272
+ const { container } = render(<${name} disabled>Content</${name}>);
273
+ const element = container.firstChild;
274
+ expect(element).toHaveAttribute('aria-disabled', 'true');
275
+ expect(element).toHaveClass('c-${name.toLowerCase()}--disabled');
276
+ });
277
+
278
+ it('forwards ref correctly', () => {
279
+ const ref = React.createRef<HTMLDivElement>();
280
+ render(<${name} ref={ref}>Content</${name}>);
281
+ expect(ref.current).toBeInstanceOf(HTMLDivElement);
282
+ });
283
+ });`,
284
+
285
+ scss: (name) => `// Component: ${name}
286
+ // =============================================================================
287
+ // Design system component following ITCSS architecture
288
+
289
+ @import '../../styles/01-settings';
290
+ @import '../../styles/02-tools';
291
+
292
+ // Block: Base component
293
+ // =============================================================================
294
+ .c-${name.toLowerCase()} {
295
+ // Layout
296
+ display: flex;
297
+ align-items: center;
298
+ justify-content: center;
299
+
300
+ // Spacing
301
+ padding: var(--atomix-space-3) var(--atomix-space-4);
302
+ gap: var(--atomix-space-2);
303
+
304
+ // Typography
305
+ font-family: var(--atomix-font-family-base);
306
+ font-size: var(--atomix-font-size-base);
307
+ font-weight: var(--atomix-font-weight-normal);
308
+ line-height: var(--atomix-line-height-base);
309
+
310
+ // Appearance
311
+ background-color: var(--atomix-color-background);
312
+ color: var(--atomix-color-text);
313
+ border: 1px solid var(--atomix-color-border);
314
+ border-radius: var(--atomix-radius-md);
315
+
316
+ // Interaction
317
+ cursor: default;
318
+ user-select: none;
319
+ transition: all 0.2s ease-in-out;
320
+
321
+ // Focus
322
+ &:focus-visible {
323
+ @include focus-ring;
324
+ }
325
+ }
326
+
327
+ // Size Modifiers
328
+ // =============================================================================
329
+ .c-${name.toLowerCase()}--sm {
330
+ padding: var(--atomix-space-2) var(--atomix-space-3);
331
+ font-size: var(--atomix-font-size-sm);
332
+ gap: var(--atomix-space-1);
333
+ }
334
+
335
+ .c-${name.toLowerCase()}--md {
336
+ // Default size - explicitly defined for clarity
337
+ padding: var(--atomix-space-3) var(--atomix-space-4);
338
+ font-size: var(--atomix-font-size-base);
339
+ gap: var(--atomix-space-2);
340
+ }
341
+
342
+ .c-${name.toLowerCase()}--lg {
343
+ padding: var(--atomix-space-4) var(--atomix-space-5);
344
+ font-size: var(--atomix-font-size-lg);
345
+ gap: var(--atomix-space-3);
346
+ }
347
+
348
+ // Color/Variant Modifiers
349
+ // =============================================================================
350
+ .c-${name.toLowerCase()}--primary {
351
+ background-color: var(--atomix-color-primary);
352
+ color: var(--atomix-color-primary-text);
353
+ border-color: var(--atomix-color-primary-dark);
354
+
355
+ &:hover:not(:disabled) {
356
+ background-color: var(--atomix-color-primary-dark);
357
+ }
358
+ }
359
+
360
+ .c-${name.toLowerCase()}--secondary {
361
+ background-color: var(--atomix-color-secondary);
362
+ color: var(--atomix-color-secondary-text);
363
+ border-color: var(--atomix-color-secondary-dark);
364
+
365
+ &:hover:not(:disabled) {
366
+ background-color: var(--atomix-color-secondary-dark);
367
+ }
368
+ }
369
+
370
+ .c-${name.toLowerCase()}--success {
371
+ background-color: var(--atomix-color-success);
372
+ color: var(--atomix-color-success-text);
373
+ border-color: var(--atomix-color-success-dark);
374
+
375
+ &:hover:not(:disabled) {
376
+ background-color: var(--atomix-color-success-dark);
377
+ }
378
+ }
379
+
380
+ .c-${name.toLowerCase()}--error {
381
+ background-color: var(--atomix-color-error);
382
+ color: var(--atomix-color-error-text);
383
+ border-color: var(--atomix-color-error-dark);
384
+
385
+ &:hover:not(:disabled) {
386
+ background-color: var(--atomix-color-error-dark);
387
+ }
388
+ }
389
+
390
+ // State Modifiers
391
+ // =============================================================================
392
+ .c-${name.toLowerCase()}--disabled {
393
+ @include disabled;
394
+ cursor: not-allowed;
395
+
396
+ &:hover {
397
+ transform: none;
398
+ }
399
+ }
400
+
401
+ // Elements (if component has child elements)
402
+ // =============================================================================
403
+ .c-${name.toLowerCase()}__icon {
404
+ display: flex;
405
+ align-items: center;
406
+ justify-content: center;
407
+ flex-shrink: 0;
408
+ }
409
+
410
+ .c-${name.toLowerCase()}__content {
411
+ flex: 1;
412
+ }
413
+
414
+ // Responsive Design
415
+ // =============================================================================
416
+ @include respond-to('tablet') {
417
+ .c-${name.toLowerCase()} {
418
+ // Tablet adjustments
419
+ }
420
+ }
421
+
422
+ @include respond-to('mobile') {
423
+ .c-${name.toLowerCase()} {
424
+ // Mobile adjustments
425
+ padding: var(--atomix-space-2) var(--atomix-space-3);
426
+ }
427
+ }
428
+
429
+ // Accessibility
430
+ // =============================================================================
431
+ @media (prefers-reduced-motion: reduce) {
432
+ .c-${name.toLowerCase()} {
433
+ transition: none;
434
+ }
435
+ }
436
+
437
+ @media (prefers-contrast: high) {
438
+ .c-${name.toLowerCase()} {
439
+ border-width: 2px;
440
+ }
441
+ }
442
+
443
+ // Dark Mode Support
444
+ // =============================================================================
445
+ [data-theme="dark"] {
446
+ .c-${name.toLowerCase()} {
447
+ background-color: var(--atomix-color-background-dark);
448
+ color: var(--atomix-color-text-dark);
449
+ border-color: var(--atomix-color-border-dark);
450
+ }
451
+ }`,
452
+
453
+ scssModule: (name) => `// Component: ${name}
454
+ // =============================================================================
455
+ // Design system component using CSS Modules
456
+
457
+ @import '../../styles/01-settings';
458
+ @import '../../styles/02-tools';
459
+
460
+ // Block: Base component
461
+ // =============================================================================
462
+ .${name.toLowerCase()} {
463
+ // Layout
464
+ display: flex;
465
+ align-items: center;
466
+ justify-content: center;
467
+
468
+ // Spacing
469
+ padding: var(--atomix-space-3) var(--atomix-space-4);
470
+ gap: var(--atomix-space-2);
471
+
472
+ // Typography
473
+ font-family: var(--atomix-font-family-base);
474
+ font-size: var(--atomix-font-size-base);
475
+ font-weight: var(--atomix-font-weight-normal);
476
+ line-height: var(--atomix-line-height-base);
477
+
478
+ // Appearance
479
+ background-color: var(--atomix-color-background);
480
+ color: var(--atomix-color-text);
481
+ border: 1px solid var(--atomix-color-border);
482
+ border-radius: var(--atomix-radius-md);
483
+
484
+ // Interaction
485
+ cursor: default;
486
+ user-select: none;
487
+ transition: all 0.2s ease-in-out;
488
+
489
+ // Focus
490
+ &:focus-visible {
491
+ outline: 2px solid var(--atomix-color-focus);
492
+ outline-offset: 2px;
493
+ }
494
+ }
495
+
496
+ // Size Modifiers
497
+ // =============================================================================
498
+ .${name.toLowerCase()}--sm {
499
+ composes: ${name.toLowerCase()};
500
+ padding: var(--atomix-space-2) var(--atomix-space-3);
501
+ font-size: var(--atomix-font-size-sm);
502
+ gap: var(--atomix-space-1);
503
+ }
504
+
505
+ .${name.toLowerCase()}--md {
506
+ composes: ${name.toLowerCase()};
507
+ }
508
+
509
+ .${name.toLowerCase()}--lg {
510
+ composes: ${name.toLowerCase()};
511
+ padding: var(--atomix-space-4) var(--atomix-space-5);
512
+ font-size: var(--atomix-font-size-lg);
513
+ gap: var(--atomix-space-3);
514
+ }
515
+
516
+ // Color/Variant Modifiers
517
+ // =============================================================================
518
+ .${name.toLowerCase()}--primary {
519
+ background-color: var(--atomix-color-primary);
520
+ color: var(--atomix-color-primary-text);
521
+ border-color: var(--atomix-color-primary-dark);
522
+
523
+ &:hover:not([aria-disabled="true"]) {
524
+ background-color: var(--atomix-color-primary-dark);
525
+ }
526
+ }
527
+
528
+ .${name.toLowerCase()}--secondary {
529
+ background-color: var(--atomix-color-secondary);
530
+ color: var(--atomix-color-secondary-text);
531
+ border-color: var(--atomix-color-secondary-dark);
532
+
533
+ &:hover:not([aria-disabled="true"]) {
534
+ background-color: var(--atomix-color-secondary-dark);
535
+ }
536
+ }
537
+
538
+ .${name.toLowerCase()}--success {
539
+ background-color: var(--atomix-color-success);
540
+ color: var(--atomix-color-success-text);
541
+ border-color: var(--atomix-color-success-dark);
542
+
543
+ &:hover:not([aria-disabled="true"]) {
544
+ background-color: var(--atomix-color-success-dark);
545
+ }
546
+ }
547
+
548
+ .${name.toLowerCase()}--error {
549
+ background-color: var(--atomix-color-error);
550
+ color: var(--atomix-color-error-text);
551
+ border-color: var(--atomix-color-error-dark);
552
+
553
+ &:hover:not([aria-disabled="true"]) {
554
+ background-color: var(--atomix-color-error-dark);
555
+ }
556
+ }
557
+
558
+ // State Modifiers
559
+ // =============================================================================
560
+ .${name.toLowerCase()}--disabled {
561
+ opacity: 0.5;
562
+ cursor: not-allowed;
563
+ pointer-events: none;
564
+ }`
565
+ }
566
+ };
567
+
568
+ // Initialize program
569
+ program
570
+ .name('atomix')
571
+ .description('Atomix Design System CLI - Enhanced Edition')
572
+ .version(packageJson.version)
573
+ .option('-d, --debug', 'Enable debug mode', false)
574
+ .hook('preAction', (thisCommand) => {
575
+ if (thisCommand.opts().debug) {
576
+ process.env.ATOMIX_DEBUG = 'true';
577
+ }
578
+ });
579
+
580
+ /**
581
+ * Enhanced Build Theme Command with Watch Mode
582
+ */
583
+ program
584
+ .command('build-theme <path>')
585
+ .description('Build a custom theme from SCSS')
586
+ .option('-o, --output <path>', 'Output directory', './dist')
587
+ .option('-m, --minify', 'Generate minified version', true)
588
+ .option('-s, --sourcemap', 'Generate source maps', false)
589
+ .option('-w, --watch', 'Watch for changes and rebuild', false)
590
+ .option('--analyze', 'Analyze bundle size', false)
591
+ .action(async (themePath, options) => {
592
+ let spinner = ora('Initializing theme build...').start();
593
+
594
+ try {
595
+ // Resolve paths
596
+ const indexPath = themePath.endsWith('.scss')
597
+ ? resolve(themePath)
598
+ : resolve(themePath, 'index.scss');
599
+
600
+ debug(`Building theme from: ${indexPath}`);
601
+
602
+ // Check if path exists
603
+ try {
604
+ await access(indexPath);
605
+ } catch (error) {
606
+ throw new AtomixCLIError(
607
+ `Theme file not found: ${indexPath}`,
608
+ 'THEME_NOT_FOUND',
609
+ [
610
+ 'Check if the file path is correct',
611
+ 'Ensure the file has a .scss extension',
612
+ 'Create a new theme with: atomix create-theme <name>'
613
+ ]
614
+ );
615
+ }
616
+
617
+ // Build function
618
+ const buildTheme = async () => {
619
+ const startTime = Date.now();
620
+
621
+ try {
622
+ // Compile SCSS
623
+ spinner.text = 'Compiling SCSS...';
624
+ debug('Starting SCSS compilation');
625
+
626
+ const result = sass.compile(indexPath, {
627
+ loadPaths: [
628
+ process.cwd(),
629
+ join(process.cwd(), 'node_modules'),
630
+ join(__dirname, '../src'),
631
+ join(__dirname, '../src/styles'),
632
+ dirname(indexPath)
633
+ ],
634
+ sourceMap: options.sourcemap,
635
+ style: 'expanded',
636
+ });
637
+
638
+ // Process with PostCSS
639
+ spinner.text = 'Processing with PostCSS...';
640
+ const processed = await postcss([
641
+ autoprefixer({
642
+ overrideBrowserslist: ['> 1%', 'last 2 versions', 'not dead'],
643
+ }),
644
+ ]).process(result.css, {
645
+ from: indexPath,
646
+ map: options.sourcemap,
647
+ });
648
+
649
+ // Ensure output directory exists
650
+ await mkdir(options.output, { recursive: true });
651
+
652
+ // Get theme name
653
+ const themeName = basename(dirname(indexPath));
654
+
655
+ // Write expanded CSS
656
+ const outputPath = join(options.output, `${themeName}.css`);
657
+ await writeFile(outputPath, processed.css, 'utf8');
658
+
659
+ // Get file size
660
+ const stats = await stat(outputPath);
661
+ const sizeKB = (stats.size / 1024).toFixed(2);
662
+
663
+ spinner.succeed(chalk.green(`✓ Built ${outputPath} (${sizeKB} KB)`));
664
+
665
+ // Write minified if requested
666
+ if (options.minify) {
667
+ const minifySpinner = ora('Minifying CSS...').start();
668
+ const minified = await postcss([
669
+ autoprefixer(),
670
+ cssnano({ preset: 'default' }),
671
+ ]).process(result.css, {
672
+ from: indexPath,
673
+ });
674
+
675
+ const minPath = join(options.output, `${themeName}.min.css`);
676
+ await writeFile(minPath, minified.css, 'utf8');
677
+
678
+ const minStats = await stat(minPath);
679
+ const minSizeKB = (minStats.size / 1024).toFixed(2);
680
+
681
+ minifySpinner.succeed(chalk.green(`✓ Built ${minPath} (${minSizeKB} KB)`));
682
+ }
683
+
684
+ // Analyze if requested
685
+ if (options.analyze) {
686
+ console.log(chalk.cyan('\n📊 Theme Analysis:'));
687
+ console.log(chalk.gray(` Original size: ${sizeKB} KB`));
688
+ if (options.minify) {
689
+ const minPath = join(options.output, `${themeName}.min.css`);
690
+ const minStats = await stat(minPath);
691
+ const minSizeKB = (minStats.size / 1024).toFixed(2);
692
+ const reduction = ((1 - minStats.size / stats.size) * 100).toFixed(1);
693
+ console.log(chalk.gray(` Minified size: ${minSizeKB} KB (${reduction}% reduction)`));
694
+ }
695
+ console.log(chalk.gray(` Build time: ${Date.now() - startTime}ms`));
696
+ }
697
+
698
+ if (!options.watch) {
699
+ console.log(chalk.bold.green('\n✨ Theme build complete!'));
700
+ }
701
+
702
+ } catch (error) {
703
+ if (options.watch) {
704
+ console.error(chalk.red(`Build error: ${error.message}`));
705
+ console.log(chalk.yellow('Waiting for changes...'));
706
+ } else {
707
+ throw error;
708
+ }
709
+ }
710
+ };
711
+
712
+ // Initial build
713
+ await buildTheme();
714
+ spinner.stop();
715
+
716
+ // Watch mode
717
+ if (options.watch) {
718
+ console.log(chalk.cyan('\n👁️ Watch mode enabled. Press Ctrl+C to exit.\n'));
719
+
720
+ const watcher = chokidar.watch([themePath], {
721
+ ignored: /node_modules/,
722
+ persistent: true,
723
+ ignoreInitial: true
724
+ });
725
+
726
+ watcher.on('change', async (path) => {
727
+ console.log(chalk.gray(`\n[${new Date().toLocaleTimeString()}] File changed: ${relative(process.cwd(), path)}`));
728
+ spinner = ora('Rebuilding theme...').start();
729
+ await buildTheme();
730
+ spinner.stop();
731
+ });
732
+
733
+ watcher.on('add', async (path) => {
734
+ console.log(chalk.gray(`\n[${new Date().toLocaleTimeString()}] File added: ${relative(process.cwd(), path)}`));
735
+ spinner = ora('Rebuilding theme...').start();
736
+ await buildTheme();
737
+ spinner.stop();
738
+ });
739
+
740
+ // Handle graceful shutdown
741
+ process.on('SIGINT', () => {
742
+ console.log(chalk.yellow('\n\nShutting down watch mode...'));
743
+ watcher.close();
744
+ process.exit(0);
745
+ });
746
+ }
747
+
748
+ } catch (error) {
749
+ handleError(error, spinner);
750
+ }
751
+ });
752
+
753
+ /**
754
+ * Generate Component Command - NEW
755
+ */
756
+ program
757
+ .command('generate <type> <name>')
758
+ .alias('g')
759
+ .description('Generate design system components, tokens, or themes')
760
+ .option('-t, --typescript', 'Use TypeScript (default)', true)
761
+ .option('-s, --story', 'Include Storybook story', true)
762
+ .option('--test', 'Include test file', false)
763
+ .option('--scss-module', 'Use SCSS modules', false)
764
+ .option('--path <path>', 'Custom output path', './src/components')
765
+ .option('-f, --force', 'Overwrite existing files', false)
766
+ .action(async (type, name, options) => {
767
+ const spinner = ora(`Generating ${type}: ${name}...`).start();
768
+
769
+ try {
770
+ debug(`Generating ${type} with name: ${name}`, options);
771
+
772
+ // Validate name
773
+ if (!/^[A-Z][a-zA-Z0-9]*$/.test(name)) {
774
+ throw new AtomixCLIError(
775
+ 'Component name must be in PascalCase (e.g., Button, CardHeader)',
776
+ 'INVALID_NAME',
777
+ [
778
+ 'Use PascalCase naming (e.g., MyComponent)',
779
+ 'Start with an uppercase letter',
780
+ 'Use only letters and numbers'
781
+ ]
782
+ );
783
+ }
784
+
785
+ if (type === 'component' || type === 'c') {
786
+ const componentPath = join(options.path, name);
787
+
788
+ // Check if component already exists
789
+ if (existsSync(componentPath) && !options.force) {
790
+ throw new AtomixCLIError(
791
+ `Component ${name} already exists`,
792
+ 'COMPONENT_EXISTS',
793
+ [
794
+ `Delete the existing component at ${componentPath}`,
795
+ 'Use --force flag to overwrite',
796
+ 'Choose a different component name'
797
+ ]
798
+ );
799
+ }
800
+
801
+ // Create component directory
802
+ await mkdir(componentPath, { recursive: true });
803
+
804
+ // Generate component file
805
+ const componentContent = componentTemplates.react.component(name, {
806
+ scssModule: options.scssModule,
807
+ types: false // We'll generate inline types for now
808
+ });
809
+
810
+ await writeFile(
811
+ join(componentPath, `${name}.tsx`),
812
+ componentContent,
813
+ 'utf8'
814
+ );
815
+ spinner.succeed(chalk.green(`✓ Created ${name}.tsx`));
816
+
817
+ // Generate index file
818
+ const indexContent = componentTemplates.react.index(name);
819
+ await writeFile(
820
+ join(componentPath, 'index.ts'),
821
+ indexContent,
822
+ 'utf8'
823
+ );
824
+ console.log(chalk.green(` ✓ Created index.ts`));
825
+
826
+ // Generate SCSS file
827
+ const scssContent = options.scssModule
828
+ ? componentTemplates.react.scssModule(name)
829
+ : componentTemplates.react.scss(name);
830
+
831
+ const scssFilename = options.scssModule ? `${name}.module.scss` : `_${name.toLowerCase()}.scss`;
832
+ await writeFile(
833
+ join(componentPath, scssFilename),
834
+ scssContent,
835
+ 'utf8'
836
+ );
837
+ console.log(chalk.green(` ✓ Created ${scssFilename}`));
838
+
839
+ // Generate Storybook story
840
+ if (options.story) {
841
+ const storyContent = componentTemplates.react.story(name);
842
+ await writeFile(
843
+ join(componentPath, `${name}.stories.tsx`),
844
+ storyContent,
845
+ 'utf8'
846
+ );
847
+ console.log(chalk.green(` ✓ Created ${name}.stories.tsx`));
848
+ }
849
+
850
+ // Generate test file
851
+ if (options.test) {
852
+ const testContent = componentTemplates.react.test(name);
853
+ await writeFile(
854
+ join(componentPath, `${name}.test.tsx`),
855
+ testContent,
856
+ 'utf8'
857
+ );
858
+ console.log(chalk.green(` ✓ Created ${name}.test.tsx`));
859
+ }
860
+
861
+ // Success message with next steps
862
+ console.log(boxen(
863
+ chalk.bold.green(`🎉 Component ${name} created successfully!\n\n`) +
864
+ chalk.cyan('Next steps:\n') +
865
+ chalk.gray(`1. Import in your app:\n`) +
866
+ chalk.white(` import { ${name} } from '${options.path}/${name}';\n\n`) +
867
+ chalk.gray(`2. Add to design system exports:\n`) +
868
+ chalk.white(` export { ${name} } from './${name}';\n\n`) +
869
+ chalk.gray(`3. Run Storybook to see your component:\n`) +
870
+ chalk.white(` npm run storybook`),
871
+ {
872
+ padding: 1,
873
+ margin: 1,
874
+ borderStyle: 'round',
875
+ borderColor: 'green'
876
+ }
877
+ ));
878
+
879
+ } else if (type === 'token' || type === 't') {
880
+ // Token generation logic (to be implemented)
881
+ throw new AtomixCLIError(
882
+ 'Token generation not yet implemented',
883
+ 'NOT_IMPLEMENTED',
884
+ [
885
+ 'This feature is coming soon',
886
+ 'For now, manually edit token files in src/styles/01-settings'
887
+ ]
888
+ );
889
+ } else {
890
+ throw new AtomixCLIError(
891
+ `Unknown generation type: ${type}`,
892
+ 'UNKNOWN_TYPE',
893
+ [
894
+ 'Valid types are: component (or c), token (or t)',
895
+ 'Example: atomix generate component Button',
896
+ 'Example: atomix g c Button'
897
+ ]
898
+ );
899
+ }
900
+
901
+ } catch (error) {
902
+ handleError(error, spinner);
903
+ }
904
+ });
905
+
906
+ /**
907
+ * Validate Command - NEW
908
+ */
909
+ program
910
+ .command('validate [target]')
911
+ .description('Validate themes, design tokens, or accessibility')
912
+ .option('--tokens', 'Validate design tokens', false)
913
+ .option('--theme <path>', 'Validate specific theme', '')
914
+ .option('--a11y, --accessibility', 'Check accessibility compliance', false)
915
+ .option('--fix', 'Attempt to fix issues automatically', false)
916
+ .action(async (target, options) => {
917
+ const spinner = ora('Running validation...').start();
918
+
919
+ try {
920
+ debug('Validation options:', options);
921
+
922
+ const issues = [];
923
+ const warnings = [];
924
+
925
+ // Token validation
926
+ if (options.tokens || target === 'tokens') {
927
+ spinner.text = 'Validating design tokens...';
928
+
929
+ const tokenFiles = [
930
+ 'src/styles/01-settings/_settings.colors.scss',
931
+ 'src/styles/01-settings/_settings.typography.scss',
932
+ 'src/styles/01-settings/_settings.spacing.scss',
933
+ 'src/styles/01-settings/_settings.radius.scss'
934
+ ];
935
+
936
+ for (const file of tokenFiles) {
937
+ const filePath = join(process.cwd(), file);
938
+ if (existsSync(filePath)) {
939
+ const content = await readFile(filePath, 'utf8');
940
+
941
+ // Check for hardcoded values
942
+ const hardcodedColors = content.match(/#[0-9a-fA-F]{3,8}(?![0-9a-fA-F])/g);
943
+ if (hardcodedColors && hardcodedColors.length > 0) {
944
+ warnings.push({
945
+ file: file,
946
+ issue: `Found ${hardcodedColors.length} hardcoded color values`,
947
+ suggestion: 'Use CSS custom properties or SCSS variables'
948
+ });
949
+ }
950
+
951
+ // Check for missing default flags
952
+ const variables = content.match(/\$[a-z-]+:/gi);
953
+ const defaultFlags = content.match(/!default/g);
954
+ if (variables && (!defaultFlags || defaultFlags.length < variables.length)) {
955
+ warnings.push({
956
+ file: file,
957
+ issue: 'Some variables missing !default flag',
958
+ suggestion: 'Add !default to all token variables for better theming'
959
+ });
960
+ }
961
+ } else {
962
+ issues.push({
963
+ file: file,
964
+ issue: 'Token file not found',
965
+ suggestion: 'Ensure all token files are present in src/styles/01-settings/'
966
+ });
967
+ }
968
+ }
969
+ }
970
+
971
+ // Theme validation
972
+ if (options.theme) {
973
+ spinner.text = `Validating theme: ${options.theme}...`;
974
+
975
+ const themePath = resolve(options.theme);
976
+ if (!existsSync(themePath)) {
977
+ issues.push({
978
+ file: options.theme,
979
+ issue: 'Theme file not found',
980
+ suggestion: 'Check the theme path is correct'
981
+ });
982
+ } else {
983
+ const content = await readFile(themePath, 'utf8');
984
+
985
+ // Check for required imports
986
+ const requiredImports = [
987
+ '@import.*settings',
988
+ '@use.*settings',
989
+ '@import.*tools',
990
+ '@use.*tools'
991
+ ];
992
+
993
+ let hasSettings = false;
994
+ for (const pattern of requiredImports) {
995
+ if (new RegExp(pattern).test(content)) {
996
+ hasSettings = true;
997
+ break;
998
+ }
999
+ }
1000
+
1001
+ if (!hasSettings) {
1002
+ issues.push({
1003
+ file: options.theme,
1004
+ issue: 'Missing design system imports',
1005
+ suggestion: 'Import settings and tools from the design system'
1006
+ });
1007
+ }
1008
+ }
1009
+ }
1010
+
1011
+ // Accessibility validation
1012
+ if (options.a11y || options.accessibility) {
1013
+ spinner.text = 'Checking accessibility compliance...';
1014
+
1015
+ // Check for focus styles
1016
+ const componentFiles = [
1017
+ 'src/styles/06-components'
1018
+ ];
1019
+
1020
+ for (const dir of componentFiles) {
1021
+ const dirPath = join(process.cwd(), dir);
1022
+ if (existsSync(dirPath)) {
1023
+ // This is a simplified check - in reality, we'd parse the CSS
1024
+ warnings.push({
1025
+ file: dir,
1026
+ issue: 'Manual accessibility review recommended',
1027
+ suggestion: 'Ensure all interactive components have :focus-visible styles'
1028
+ });
1029
+ }
1030
+ }
1031
+ }
1032
+
1033
+ spinner.stop();
1034
+
1035
+ // Display results
1036
+ if (issues.length === 0 && warnings.length === 0) {
1037
+ console.log(boxen(
1038
+ chalk.bold.green('✅ All validations passed!\n\n') +
1039
+ chalk.gray('Your design system is following best practices.'),
1040
+ {
1041
+ padding: 1,
1042
+ margin: 1,
1043
+ borderStyle: 'round',
1044
+ borderColor: 'green'
1045
+ }
1046
+ ));
1047
+ } else {
1048
+ if (issues.length > 0) {
1049
+ console.log(chalk.bold.red(`\n❌ Found ${issues.length} issue(s):\n`));
1050
+ issues.forEach((issue, index) => {
1051
+ console.log(chalk.red(` ${index + 1}. ${issue.file}`));
1052
+ console.log(chalk.gray(` Issue: ${issue.issue}`));
1053
+ console.log(chalk.yellow(` Fix: ${issue.suggestion}\n`));
1054
+ });
1055
+ }
1056
+
1057
+ if (warnings.length > 0) {
1058
+ console.log(chalk.bold.yellow(`\n⚠️ Found ${warnings.length} warning(s):\n`));
1059
+ warnings.forEach((warning, index) => {
1060
+ console.log(chalk.yellow(` ${index + 1}. ${warning.file}`));
1061
+ console.log(chalk.gray(` Warning: ${warning.issue}`));
1062
+ console.log(chalk.cyan(` Suggestion: ${warning.suggestion}\n`));
1063
+ });
1064
+ }
1065
+
1066
+ if (options.fix && issues.length > 0) {
1067
+ console.log(chalk.cyan('\n🔧 Auto-fix is not yet implemented. Please fix issues manually.'));
1068
+ }
1069
+ }
1070
+
1071
+ } catch (error) {
1072
+ handleError(error, spinner);
1073
+ }
1074
+ });
1075
+
1076
+ /**
1077
+ * Dev Command - NEW (Alias for build --watch)
1078
+ */
1079
+ program
1080
+ .command('dev <theme>')
1081
+ .description('Start development mode with hot reload')
1082
+ .option('-o, --output <path>', 'Output directory', './dist')
1083
+ .option('--open', 'Open in browser after build', false)
1084
+ .action(async (theme, options) => {
1085
+ console.log(boxen(
1086
+ chalk.bold.cyan('🚀 Starting Atomix Dev Mode\n\n') +
1087
+ chalk.gray('Watching for changes...\n') +
1088
+ chalk.gray('Press Ctrl+C to exit'),
1089
+ {
1090
+ padding: 1,
1091
+ margin: 1,
1092
+ borderStyle: 'round',
1093
+ borderColor: 'cyan'
1094
+ }
1095
+ ));
1096
+
1097
+ // Reuse build command with watch flag
1098
+ await program.parseAsync([
1099
+ ...process.argv.slice(0, 2),
1100
+ 'build-theme',
1101
+ theme,
1102
+ '--watch',
1103
+ '--output', options.output
1104
+ ]);
1105
+ });
1106
+
1107
+ // Keep existing commands (create-theme, list-themes, info)
1108
+ // ... [Previous create-theme, list-themes, and info commands remain the same]
1109
+
1110
+ /**
1111
+ * Migrate Command - NEW (Migration from other frameworks)
1112
+ */
1113
+ program
1114
+ .command('migrate <from>')
1115
+ .description('Migrate from other CSS frameworks to Atomix design system')
1116
+ .option('-s, --source <path>', 'Source directory to migrate', './src')
1117
+ .option('--dry-run', 'Preview changes without modifying files', false)
1118
+ .option('--create-backup', 'Create backup before migration', true)
1119
+ .action(async (from, options) => {
1120
+ const spinner = ora('Preparing migration...').start();
1121
+
1122
+ try {
1123
+ debug(`Migrating from ${from}`, options);
1124
+
1125
+ // Validate migration type
1126
+ const validMigrations = ['tailwind', 'bootstrap', 'scss-variables'];
1127
+ if (!validMigrations.includes(from.toLowerCase())) {
1128
+ throw new AtomixCLIError(
1129
+ `Unknown migration source: ${from}`,
1130
+ 'INVALID_MIGRATION',
1131
+ [
1132
+ 'Valid migration sources: tailwind, bootstrap, scss-variables',
1133
+ 'Example: atomix migrate tailwind',
1134
+ 'Example: atomix migrate bootstrap --source ./src'
1135
+ ]
1136
+ );
1137
+ }
1138
+
1139
+ // Check source directory
1140
+ const sourcePath = resolve(options.source);
1141
+ if (!existsSync(sourcePath)) {
1142
+ throw new AtomixCLIError(
1143
+ `Source directory not found: ${sourcePath}`,
1144
+ 'SOURCE_NOT_FOUND',
1145
+ [
1146
+ 'Check the source path is correct',
1147
+ 'Use --source flag to specify a different directory',
1148
+ 'Example: atomix migrate tailwind --source ./app'
1149
+ ]
1150
+ );
1151
+ }
1152
+
1153
+ spinner.stop();
1154
+
1155
+ // Show migration preview
1156
+ console.log(boxen(
1157
+ chalk.bold.cyan(`🔄 Migration Preview\n\n`) +
1158
+ chalk.gray(`From: ${chalk.white(from)}\n`) +
1159
+ chalk.gray(`Source: ${chalk.white(sourcePath)}\n`) +
1160
+ chalk.gray(`Mode: ${options.dryRun ? chalk.yellow('Dry Run') : chalk.green('Live')}\n`) +
1161
+ chalk.gray(`Backup: ${options.createBackup ? chalk.green('Yes') : chalk.red('No')}`),
1162
+ {
1163
+ padding: 1,
1164
+ margin: 1,
1165
+ borderStyle: 'round',
1166
+ borderColor: 'cyan'
1167
+ }
1168
+ ));
1169
+
1170
+ // Confirm migration
1171
+ if (!options.dryRun) {
1172
+ const { confirmMigration } = await inquirer.prompt([
1173
+ {
1174
+ type: 'confirm',
1175
+ name: 'confirmMigration',
1176
+ message: chalk.yellow('This will modify your files. Continue?'),
1177
+ default: false
1178
+ }
1179
+ ]);
1180
+
1181
+ if (!confirmMigration) {
1182
+ console.log(chalk.yellow('\n Migration cancelled.'));
1183
+ return;
1184
+ }
1185
+ }
1186
+
1187
+ // Create backup if requested
1188
+ if (options.createBackup && !options.dryRun) {
1189
+ const backupSpinner = ora('Creating backup...').start();
1190
+ const backupDir = `${sourcePath}.backup.${Date.now()}`;
1191
+
1192
+ try {
1193
+ const { execSync } = await import('child_process');
1194
+ execSync(`cp -r "${sourcePath}" "${backupDir}"`, { stdio: 'ignore' });
1195
+ backupSpinner.succeed(chalk.green(`✓ Backup created: ${backupDir}`));
1196
+ } catch (error) {
1197
+ backupSpinner.warn(chalk.yellow('Could not create backup, continuing anyway...'));
1198
+ }
1199
+ }
1200
+
1201
+ // Run migration
1202
+ let report;
1203
+
1204
+ switch (from.toLowerCase()) {
1205
+ case 'tailwind':
1206
+ report = await migrateTailwind(sourcePath, options);
1207
+ break;
1208
+
1209
+ case 'bootstrap':
1210
+ report = await migrateBootstrap(sourcePath, options);
1211
+ break;
1212
+
1213
+ case 'scss-variables':
1214
+ report = await migrateSCSSVariables(sourcePath, options);
1215
+ break;
1216
+ }
1217
+
1218
+ // Display report
1219
+ displayMigrationReport(report);
1220
+
1221
+ // Next steps
1222
+ if (!options.dryRun && report.filesProcessed > 0) {
1223
+ console.log(chalk.cyan('\n📝 Next Steps:'));
1224
+ console.log(chalk.gray(' 1. Review the changes in your code'));
1225
+ console.log(chalk.gray(' 2. Install Atomix: npm install @shohojdhara/atomix'));
1226
+ console.log(chalk.gray(' 3. Import Atomix styles: import "@shohojdhara/atomix/css"'));
1227
+ console.log(chalk.gray(' 4. Test your application thoroughly'));
1228
+ console.log(chalk.gray(' 5. Customize with your theme: atomix create-theme custom'));
1229
+ }
1230
+
1231
+ } catch (error) {
1232
+ handleError(error, spinner);
1233
+ }
1234
+ });
1235
+
1236
+ /**
1237
+ * Init Command - NEW (Interactive Setup Wizard)
1238
+ */
1239
+ program
1240
+ .command('init')
1241
+ .description('Interactive setup wizard for Atomix design system')
1242
+ .option('--skip-install', 'Skip dependency installation', false)
1243
+ .action(async (options) => {
1244
+ try {
1245
+ // Set environment variable for skip install if needed
1246
+ if (options.skipInstall) {
1247
+ process.env.ATOMIX_SKIP_INSTALL = 'true';
1248
+ }
1249
+
1250
+ // Run the interactive wizard
1251
+ await runInitWizard();
1252
+ } catch (error) {
1253
+ handleError(error);
1254
+ }
1255
+ });
1256
+
1257
+ /**
1258
+ * Tokens Command - NEW (Design Token Management)
1259
+ */
1260
+ program
1261
+ .command('tokens <action>')
1262
+ .description('Manage design tokens (list, validate, export, import)')
1263
+ .option('-c, --category <category>', 'Token category (colors, typography, spacing, etc.)')
1264
+ .option('-f, --format <format>', 'Export format (json, css, scss, js, ts)', 'json')
1265
+ .option('-o, --output <path>', 'Output file path')
1266
+ .option('--dry-run', 'Preview changes without modifying files', false)
1267
+ .action(async (action, options) => {
1268
+ try {
1269
+ debug(`Token action: ${action}`, options);
1270
+
1271
+ switch (action.toLowerCase()) {
1272
+ case 'list':
1273
+ case 'ls':
1274
+ await listTokens(options.category);
1275
+ break;
1276
+
1277
+ case 'validate':
1278
+ case 'check':
1279
+ const validationResult = await validateTokens(options);
1280
+ if (validationResult.issues.length > 0) {
1281
+ process.exit(1); // Exit with error if issues found
1282
+ }
1283
+ break;
1284
+
1285
+ case 'export':
1286
+ if (!options.format) {
1287
+ throw new AtomixCLIError(
1288
+ 'Export format is required',
1289
+ 'MISSING_FORMAT',
1290
+ [
1291
+ 'Specify format with --format flag',
1292
+ 'Valid formats: json, css, scss, js, ts',
1293
+ 'Example: atomix tokens export --format json'
1294
+ ]
1295
+ );
1296
+ }
1297
+ await exportTokens(options.format, options.output);
1298
+ break;
1299
+
1300
+ case 'import':
1301
+ if (!options.output) {
1302
+ throw new AtomixCLIError(
1303
+ 'Import file path is required',
1304
+ 'MISSING_PATH',
1305
+ [
1306
+ 'Specify file with --output flag',
1307
+ 'Example: atomix tokens import --output tokens.json'
1308
+ ]
1309
+ );
1310
+ }
1311
+ await importTokens(options.output, { dryRun: options.dryRun });
1312
+ break;
1313
+
1314
+ default:
1315
+ throw new AtomixCLIError(
1316
+ `Unknown token action: ${action}`,
1317
+ 'UNKNOWN_ACTION',
1318
+ [
1319
+ 'Valid actions: list, validate, export, import',
1320
+ 'Example: atomix tokens list',
1321
+ 'Example: atomix tokens export --format json'
1322
+ ]
1323
+ );
1324
+ }
1325
+
1326
+ } catch (error) {
1327
+ handleError(error);
1328
+ }
1329
+ });
1330
+
1331
+ /**
1332
+ * Doctor Command - NEW
1333
+ */
1334
+ program
1335
+ .command('doctor')
1336
+ .description('Diagnose common issues with your Atomix setup')
1337
+ .action(async () => {
1338
+ const spinner = ora('Running diagnostics...').start();
1339
+
1340
+ try {
1341
+ const checks = [];
1342
+
1343
+ // Check Node version
1344
+ const nodeVersion = process.version;
1345
+ const majorVersion = parseInt(nodeVersion.slice(1).split('.')[0]);
1346
+ checks.push({
1347
+ name: 'Node.js Version',
1348
+ status: majorVersion >= 16 ? '✅' : '❌',
1349
+ message: majorVersion >= 16
1350
+ ? `${nodeVersion} (supported)`
1351
+ : `${nodeVersion} (requires Node 16+)`,
1352
+ });
1353
+
1354
+ // Check Atomix installation
1355
+ const atomixPath = join(process.cwd(), 'node_modules', '@shohojdhara', 'atomix');
1356
+ checks.push({
1357
+ name: 'Atomix Installation',
1358
+ status: existsSync(atomixPath) ? '✅' : '❌',
1359
+ message: existsSync(atomixPath)
1360
+ ? 'Installed correctly'
1361
+ : 'Not found - run: npm install @shohojdhara/atomix',
1362
+ });
1363
+
1364
+ // Check for required dependencies
1365
+ const requiredDeps = ['react', 'react-dom', 'sass'];
1366
+ for (const dep of requiredDeps) {
1367
+ const depPath = join(process.cwd(), 'node_modules', dep);
1368
+ checks.push({
1369
+ name: `Dependency: ${dep}`,
1370
+ status: existsSync(depPath) ? '✅' : '⚠️',
1371
+ message: existsSync(depPath)
1372
+ ? 'Installed'
1373
+ : 'Missing (may be required for some features)',
1374
+ });
1375
+ }
1376
+
1377
+ // Check for configuration files
1378
+ const configFiles = ['.atomixrc', 'atomix.config.js', 'atomix.config.json'];
1379
+ let hasConfig = false;
1380
+ for (const file of configFiles) {
1381
+ if (existsSync(join(process.cwd(), file))) {
1382
+ hasConfig = true;
1383
+ break;
1384
+ }
1385
+ }
1386
+
1387
+ checks.push({
1388
+ name: 'Configuration File',
1389
+ status: hasConfig ? '✅' : '💡',
1390
+ message: hasConfig
1391
+ ? 'Configuration found'
1392
+ : 'No config file (using defaults)',
1393
+ });
1394
+
1395
+ spinner.stop();
1396
+
1397
+ // Display results
1398
+ console.log(chalk.bold('\n🏥 Atomix Doctor Report\n'));
1399
+ console.log(chalk.gray('=' .repeat(50)));
1400
+
1401
+ checks.forEach(check => {
1402
+ console.log(`${check.status} ${chalk.bold(check.name)}`);
1403
+ console.log(` ${chalk.gray(check.message)}\n`);
1404
+ });
1405
+
1406
+ const hasIssues = checks.some(c => c.status === '❌');
1407
+ const hasWarnings = checks.some(c => c.status === '⚠️');
1408
+
1409
+ if (hasIssues) {
1410
+ console.log(chalk.red('\n❌ Some issues need attention'));
1411
+ } else if (hasWarnings) {
1412
+ console.log(chalk.yellow('\n⚠️ Some optional improvements available'));
1413
+ } else {
1414
+ console.log(chalk.green('\n✅ Everything looks good!'));
1415
+ }
1416
+
1417
+ } catch (error) {
1418
+ handleError(error, spinner);
1419
+ }
1420
+ });
1421
+
1422
+ // Parse arguments
1423
+ program.parse(process.argv);
1424
+
1425
+ // Show help if no command provided
1426
+ if (!process.argv.slice(2).length) {
1427
+ program.outputHelp();
1428
+ }