@shohojdhara/atomix 0.3.14 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (343) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/build-tools/EXAMPLES.md +372 -0
  3. package/build-tools/README.md +242 -0
  4. package/build-tools/__tests__/error-handler.test.js +230 -0
  5. package/build-tools/__tests__/index.test.js +141 -0
  6. package/build-tools/__tests__/rollup-plugin.test.js +194 -0
  7. package/build-tools/__tests__/utils.test.js +161 -0
  8. package/build-tools/__tests__/vite-plugin.test.js +129 -0
  9. package/build-tools/__tests__/webpack-loader.test.js +190 -0
  10. package/build-tools/error-handler.js +308 -0
  11. package/build-tools/index.d.ts +44 -0
  12. package/build-tools/index.js +88 -0
  13. package/build-tools/package.json +50 -0
  14. package/build-tools/rollup-plugin.js +236 -0
  15. package/build-tools/types.d.ts +163 -0
  16. package/build-tools/utils.js +203 -0
  17. package/build-tools/vite-plugin.js +161 -0
  18. package/build-tools/webpack-loader.js +123 -0
  19. package/dist/atomix.css +21044 -2618
  20. package/dist/atomix.css.map +1 -1
  21. package/dist/atomix.min.css +77 -3
  22. package/dist/atomix.min.css.map +1 -1
  23. package/dist/build-tools/EXAMPLES.md +372 -0
  24. package/dist/build-tools/README.md +242 -0
  25. package/dist/build-tools/__tests__/error-handler.test.js +230 -0
  26. package/dist/build-tools/__tests__/index.test.js +141 -0
  27. package/dist/build-tools/__tests__/rollup-plugin.test.js +194 -0
  28. package/dist/build-tools/__tests__/utils.test.js +161 -0
  29. package/dist/build-tools/__tests__/vite-plugin.test.js +129 -0
  30. package/dist/build-tools/__tests__/webpack-loader.test.js +190 -0
  31. package/dist/build-tools/error-handler.js +308 -0
  32. package/dist/build-tools/index.d.ts +44 -0
  33. package/dist/build-tools/index.js +88 -0
  34. package/dist/build-tools/package.json +50 -0
  35. package/dist/build-tools/rollup-plugin.js +236 -0
  36. package/dist/build-tools/types.d.ts +163 -0
  37. package/dist/build-tools/utils.js +203 -0
  38. package/dist/build-tools/vite-plugin.js +161 -0
  39. package/dist/build-tools/webpack-loader.js +123 -0
  40. package/dist/charts.d.ts +1 -1
  41. package/dist/charts.js +86 -57
  42. package/dist/charts.js.map +1 -1
  43. package/dist/core.d.ts +1 -1
  44. package/dist/core.js +136 -112
  45. package/dist/core.js.map +1 -1
  46. package/dist/forms.d.ts +2 -5
  47. package/dist/forms.js +140 -128
  48. package/dist/forms.js.map +1 -1
  49. package/dist/heavy.d.ts +1 -1
  50. package/dist/heavy.js +136 -112
  51. package/dist/heavy.js.map +1 -1
  52. package/dist/index.d.ts +152 -78
  53. package/dist/index.esm.js +346 -340
  54. package/dist/index.esm.js.map +1 -1
  55. package/dist/index.js +359 -353
  56. package/dist/index.js.map +1 -1
  57. package/dist/index.min.js +1 -1
  58. package/dist/index.min.js.map +1 -1
  59. package/dist/layout.js.map +1 -1
  60. package/dist/theme.d.ts +9 -9
  61. package/dist/theme.js.map +1 -1
  62. package/package.json +23 -8
  63. package/scripts/atomix-cli.js +170 -73
  64. package/scripts/cli/__tests__/README.md +81 -0
  65. package/scripts/cli/__tests__/basic.test.js +115 -0
  66. package/scripts/cli/__tests__/component-generator.test.js +332 -0
  67. package/scripts/cli/__tests__/integration.test.js +327 -0
  68. package/scripts/cli/__tests__/test-setup.js +133 -0
  69. package/scripts/cli/__tests__/token-manager.test.js +251 -0
  70. package/scripts/cli/__tests__/utils.test.js +161 -0
  71. package/scripts/cli/component-generator.js +253 -299
  72. package/scripts/cli/dependency-checker.js +355 -0
  73. package/scripts/cli/interactive-init.js +46 -5
  74. package/scripts/cli/template-manager.js +0 -2
  75. package/scripts/cli/templates/common-templates.js +636 -0
  76. package/scripts/cli/templates/composable-templates.js +148 -126
  77. package/scripts/cli/templates/index.js +23 -16
  78. package/scripts/cli/templates/project-templates.js +151 -23
  79. package/scripts/cli/templates/react-templates.js +280 -210
  80. package/scripts/cli/templates/scss-templates.js +90 -91
  81. package/scripts/cli/templates/testing-templates.js +206 -27
  82. package/scripts/cli/templates/testing-utils.js +278 -0
  83. package/scripts/cli/templates/types-templates.js +70 -56
  84. package/scripts/cli/theme-bridge.js +8 -2
  85. package/scripts/cli/token-manager.js +318 -206
  86. package/scripts/cli/utils.js +0 -1
  87. package/src/components/Accordion/Accordion.stories.tsx +358 -850
  88. package/src/components/Accordion/Accordion.test.tsx +70 -50
  89. package/src/components/Accordion/Accordion.tsx +99 -94
  90. package/src/components/AtomixGlass/AtomixGlass.test.tsx +1 -1
  91. package/src/components/AtomixGlass/AtomixGlass.tsx +80 -39
  92. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +103 -81
  93. package/src/components/AtomixGlass/GlassFilter.tsx +9 -16
  94. package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +8 -7
  95. package/src/components/AtomixGlass/glass-utils.ts +6 -5
  96. package/src/components/AtomixGlass/shader-utils.ts +133 -52
  97. package/src/components/AtomixGlass/stories/Customization.stories.tsx +131 -0
  98. package/src/components/AtomixGlass/stories/Examples.stories.tsx +2957 -2853
  99. package/src/components/AtomixGlass/stories/Modes.stories.tsx +1 -1
  100. package/src/components/AtomixGlass/stories/Overview.stories.tsx +348 -0
  101. package/src/components/AtomixGlass/stories/Performance.stories.tsx +103 -0
  102. package/src/components/AtomixGlass/stories/Playground.stories.tsx +51 -36
  103. package/src/components/AtomixGlass/stories/{ShaderVariants.stories.tsx → Shaders.stories.tsx} +2 -2
  104. package/src/components/AtomixGlass/stories/shared-components.tsx +90 -190
  105. package/src/components/Avatar/Avatar.stories.tsx +195 -0
  106. package/src/components/Avatar/Avatar.tsx +58 -56
  107. package/src/components/Badge/Badge.stories.tsx +122 -352
  108. package/src/components/Badge/Badge.test.tsx +41 -41
  109. package/src/components/Badge/Badge.tsx +64 -62
  110. package/src/components/Block/Block.stories.tsx +30 -11
  111. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +142 -23
  112. package/src/components/Breadcrumb/Breadcrumb.tsx +62 -60
  113. package/src/components/Button/Button.stories.tsx +454 -1126
  114. package/src/components/Button/Button.test.tsx +123 -0
  115. package/src/components/Button/Button.tsx +88 -60
  116. package/src/components/Button/ButtonGroup.stories.tsx +376 -215
  117. package/src/components/Button/ButtonGroup.tsx +4 -15
  118. package/src/components/Callout/Callout.stories.tsx +316 -568
  119. package/src/components/Card/Card.stories.tsx +292 -81
  120. package/src/components/Card/Card.tsx +30 -14
  121. package/src/components/Chart/AreaChart.tsx +1 -1
  122. package/src/components/Chart/CandlestickChart.tsx +23 -16
  123. package/src/components/Chart/Chart.stories.tsx +153 -16
  124. package/src/components/Chart/Chart.tsx +40 -44
  125. package/src/components/Chart/ChartRenderer.tsx +39 -12
  126. package/src/components/Chart/ChartToolbar.tsx +21 -5
  127. package/src/components/Chart/DonutChart.tsx +1 -1
  128. package/src/components/Chart/FunnelChart.tsx +4 -1
  129. package/src/components/Chart/GaugeChart.tsx +3 -1
  130. package/src/components/Chart/HeatmapChart.tsx +50 -37
  131. package/src/components/Chart/LineChart.tsx +3 -2
  132. package/src/components/Chart/MultiAxisChart.tsx +24 -16
  133. package/src/components/Chart/RadarChart.tsx +19 -17
  134. package/src/components/Chart/ScatterChart.tsx +29 -21
  135. package/src/components/ColorModeToggle/ColorModeToggle.stories.tsx +152 -66
  136. package/src/components/ColorModeToggle/ColorModeToggle.tsx +15 -3
  137. package/src/components/Countdown/Countdown.stories.tsx +114 -7
  138. package/src/components/DataTable/DataTable.stories.tsx +349 -144
  139. package/src/components/DataTable/DataTable.test.tsx +26 -148
  140. package/src/components/DataTable/DataTable.tsx +485 -456
  141. package/src/components/DatePicker/DatePicker.stories.tsx +310 -1066
  142. package/src/components/DatePicker/DatePicker.tsx +31 -26
  143. package/src/components/Dropdown/Dropdown.stories.tsx +153 -36
  144. package/src/components/Dropdown/Dropdown.tsx +313 -299
  145. package/src/components/EdgePanel/EdgePanel.stories.tsx +221 -25
  146. package/src/components/EdgePanel/EdgePanel.tsx +1 -3
  147. package/src/components/Footer/Footer.stories.tsx +396 -327
  148. package/src/components/Footer/Footer.tsx +130 -128
  149. package/src/components/Footer/FooterLink.tsx +2 -2
  150. package/src/components/Form/Checkbox.stories.tsx +140 -6
  151. package/src/components/Form/Checkbox.test.tsx +63 -0
  152. package/src/components/Form/Checkbox.tsx +122 -78
  153. package/src/components/Form/Form.stories.tsx +110 -19
  154. package/src/components/Form/FormGroup.stories.tsx +127 -4
  155. package/src/components/Form/Input.stories.tsx +22 -39
  156. package/src/components/Form/Input.test.tsx +38 -44
  157. package/src/components/Form/Radio.stories.tsx +146 -17
  158. package/src/components/Form/Radio.tsx +68 -66
  159. package/src/components/Form/Select.stories.tsx +140 -8
  160. package/src/components/Form/Select.tsx +184 -182
  161. package/src/components/Form/Textarea.stories.tsx +149 -6
  162. package/src/components/Form/Textarea.test.tsx +27 -32
  163. package/src/components/Hero/Hero.stories.tsx +372 -38
  164. package/src/components/Hero/Hero.tsx +201 -55
  165. package/src/components/Icon/index.ts +7 -1
  166. package/src/components/List/List.stories.tsx +141 -3
  167. package/src/components/List/List.tsx +19 -23
  168. package/src/components/Modal/Modal.stories.tsx +183 -43
  169. package/src/components/Modal/Modal.tsx +130 -127
  170. package/src/components/Navigation/Menu/MegaMenu.tsx +70 -70
  171. package/src/components/Navigation/Nav/NavDropdown.tsx +1 -5
  172. package/src/components/Navigation/SideMenu/SideMenu.stories.tsx +128 -28
  173. package/src/components/Navigation/SideMenu/SideMenu.tsx +5 -7
  174. package/src/components/Navigation/SideMenu/SideMenuItem.tsx +4 -5
  175. package/src/components/Pagination/Pagination.stories.tsx +7 -4
  176. package/src/components/Pagination/Pagination.tsx +199 -202
  177. package/src/components/PhotoViewer/PhotoViewer.tsx +4 -1
  178. package/src/components/Popover/Popover.stories.tsx +354 -97
  179. package/src/components/Popover/Popover.tsx +41 -37
  180. package/src/components/Progress/Progress.stories.tsx +160 -7
  181. package/src/components/River/River.stories.tsx +3 -2
  182. package/src/components/SectionIntro/SectionIntro.stories.tsx +239 -47
  183. package/src/components/Slider/Slider.stories.tsx +12 -4
  184. package/src/components/Spinner/Spinner.stories.tsx +104 -8
  185. package/src/components/Spinner/Spinner.test.tsx +23 -23
  186. package/src/components/Spinner/Spinner.tsx +43 -46
  187. package/src/components/Steps/Steps.stories.tsx +173 -42
  188. package/src/components/Tabs/Tabs.stories.tsx +141 -12
  189. package/src/components/Tabs/Tabs.tsx +74 -72
  190. package/src/components/Testimonial/Testimonial.stories.tsx +120 -3
  191. package/src/components/Todo/Todo.stories.tsx +198 -9
  192. package/src/components/Toggle/Toggle.stories.tsx +137 -36
  193. package/src/components/Toggle/Toggle.test.tsx +65 -70
  194. package/src/components/Toggle/Toggle.tsx +4 -1
  195. package/src/components/Tooltip/Tooltip.stories.tsx +194 -100
  196. package/src/components/Tooltip/Tooltip.tsx +104 -106
  197. package/src/components/Upload/Upload.stories.tsx +241 -150
  198. package/src/components/Upload/Upload.tsx +287 -283
  199. package/src/components/VideoPlayer/VideoPlayer.tsx +6 -1
  200. package/src/components/index.ts +13 -2
  201. package/src/layouts/Grid/Grid.stories.tsx +9 -3
  202. package/src/layouts/MasonryGrid/MasonryGrid.tsx +5 -1
  203. package/src/lib/README.md +2 -2
  204. package/src/lib/__tests__/theme-tools.test.ts +219 -0
  205. package/src/lib/composables/index.ts +2 -2
  206. package/src/lib/composables/shared-mouse-tracker.ts +13 -14
  207. package/src/lib/composables/useAtomixGlass.ts +126 -97
  208. package/src/lib/composables/useChartExport.ts +3 -8
  209. package/src/lib/composables/useDataTable.ts +72 -43
  210. package/src/lib/composables/useHero.ts +58 -14
  211. package/src/lib/composables/useHeroBackgroundSlider.ts +2 -9
  212. package/src/lib/composables/useInput.ts +10 -8
  213. package/src/lib/composables/useSideMenu.ts +6 -5
  214. package/src/lib/composables/useTooltip.ts +1 -2
  215. package/src/lib/composables/useVideoPlayer.ts +44 -35
  216. package/src/lib/config/index.ts +154 -154
  217. package/src/lib/constants/components.ts +9 -32
  218. package/src/lib/constants/cssVariables.ts +29 -29
  219. package/src/lib/hooks/__tests__/useComponentCustomization.test.ts +2 -6
  220. package/src/lib/hooks/index.ts +1 -1
  221. package/src/lib/hooks/useComponentCustomization.ts +11 -17
  222. package/src/lib/hooks/usePerformanceMonitor.ts +6 -7
  223. package/src/lib/patterns/__tests__/slots.test.ts +1 -1
  224. package/src/lib/patterns/index.ts +1 -1
  225. package/src/lib/patterns/slots.tsx +8 -13
  226. package/src/lib/storybook/InteractiveDemo.tsx +13 -18
  227. package/src/lib/storybook/PreviewContainer.tsx +1 -1
  228. package/src/lib/storybook/VariantsGrid.tsx +3 -7
  229. package/src/lib/storybook/index.ts +1 -1
  230. package/src/lib/theme/adapters/cssVariableMapper.ts +47 -74
  231. package/src/lib/theme/adapters/index.ts +3 -9
  232. package/src/lib/theme/adapters/themeAdapter.ts +41 -26
  233. package/src/lib/theme/config/index.ts +1 -1
  234. package/src/lib/theme/config/types.ts +2 -2
  235. package/src/lib/theme/config/validator.ts +10 -5
  236. package/src/lib/theme/constants/constants.ts +2 -2
  237. package/src/lib/theme/constants/index.ts +1 -2
  238. package/src/lib/theme/core/__tests__/createTheme.test.ts +20 -22
  239. package/src/lib/theme/core/composeTheme.ts +32 -26
  240. package/src/lib/theme/core/createTheme.ts +1 -1
  241. package/src/lib/theme/core/createThemeObject.ts +308 -301
  242. package/src/lib/theme/core/index.ts +3 -3
  243. package/src/lib/theme/devtools/CLI.ts +107 -105
  244. package/src/lib/theme/devtools/Comparator.tsx +50 -32
  245. package/src/lib/theme/devtools/DesignTokensCustomizer.stories.tsx +50 -48
  246. package/src/lib/theme/devtools/DesignTokensCustomizer.tsx +257 -63
  247. package/src/lib/theme/devtools/Inspector.tsx +75 -60
  248. package/src/lib/theme/devtools/LiveEditor.tsx +97 -76
  249. package/src/lib/theme/devtools/Preview.tsx +150 -106
  250. package/src/lib/theme/devtools/ThemeValidator.ts +29 -21
  251. package/src/lib/theme/devtools/index.ts +3 -9
  252. package/src/lib/theme/devtools/useHistory.ts +23 -21
  253. package/src/lib/theme/errors/errors.ts +12 -11
  254. package/src/lib/theme/errors/index.ts +2 -7
  255. package/src/lib/theme/generators/generateCSS.ts +9 -13
  256. package/src/lib/theme/generators/generateCSSNested.ts +1 -6
  257. package/src/lib/theme/generators/generateCSSVariables.ts +673 -630
  258. package/src/lib/theme/generators/index.ts +1 -4
  259. package/src/lib/theme/i18n/index.ts +1 -1
  260. package/src/lib/theme/i18n/rtl.ts +13 -13
  261. package/src/lib/theme/index.ts +7 -16
  262. package/src/lib/theme/runtime/ThemeApplicator.ts +4 -4
  263. package/src/lib/theme/runtime/ThemeContext.tsx +1 -1
  264. package/src/lib/theme/runtime/ThemeErrorBoundary.tsx +19 -23
  265. package/src/lib/theme/runtime/ThemeProvider.tsx +230 -239
  266. package/src/lib/theme/runtime/__tests__/ThemeProvider.integration.test.tsx +1 -1
  267. package/src/lib/theme/runtime/__tests__/ThemeProvider.test.tsx +24 -29
  268. package/src/lib/theme/runtime/index.ts +2 -5
  269. package/src/lib/theme/runtime/useTheme.ts +18 -18
  270. package/src/lib/theme/runtime/useThemeTokens.ts +22 -22
  271. package/src/lib/theme/test/testTheme.ts +15 -16
  272. package/src/lib/theme/tokens/index.ts +2 -7
  273. package/src/lib/theme/tokens/tokens.ts +25 -24
  274. package/src/lib/theme/types.ts +428 -411
  275. package/src/lib/theme/utils/__tests__/themeValidation.test.ts +3 -3
  276. package/src/lib/theme/utils/componentTheming.ts +18 -18
  277. package/src/lib/theme/utils/domUtils.ts +277 -289
  278. package/src/lib/theme/utils/index.ts +1 -2
  279. package/src/lib/theme/utils/injectCSS.ts +10 -14
  280. package/src/lib/theme/utils/naming.ts +20 -16
  281. package/src/lib/theme/utils/themeHelpers.ts +10 -12
  282. package/src/lib/theme/utils/themeUtils.ts +85 -86
  283. package/src/lib/theme/utils/themeValidation.ts +82 -33
  284. package/src/lib/theme-tools.ts +8 -6
  285. package/src/lib/types/components.ts +172 -71
  286. package/src/lib/types/partProps.ts +1 -1
  287. package/src/lib/utils/__tests__/csv.test.ts +45 -0
  288. package/src/lib/utils/componentUtils.ts +8 -12
  289. package/src/lib/utils/csv.ts +19 -0
  290. package/src/lib/utils/dataTableExport.ts +2 -15
  291. package/src/lib/utils/fontPreloader.ts +10 -19
  292. package/src/lib/utils/icons.ts +4 -1
  293. package/src/lib/utils/index.ts +2 -6
  294. package/src/lib/utils/memoryMonitor.ts +10 -8
  295. package/src/lib/utils/themeNaming.ts +2 -2
  296. package/src/styles/01-settings/_index.scss +1 -1
  297. package/src/styles/01-settings/_settings.accordion.scss +28 -7
  298. package/src/styles/01-settings/_settings.colors.scss +11 -11
  299. package/src/styles/01-settings/_settings.design-tokens.scss +61 -50
  300. package/src/styles/01-settings/_settings.navbar.scss +1 -1
  301. package/src/styles/01-settings/_settings.spacing.scss +3 -4
  302. package/src/styles/01-settings/_settings.tooltip.scss +1 -1
  303. package/src/styles/01-settings/_settings.typography.scss +4 -4
  304. package/src/styles/02-tools/_tools.button.scss +51 -21
  305. package/src/styles/02-tools/_tools.utility-api.scss +38 -12
  306. package/src/styles/03-generic/_generic.root.scss +4 -3
  307. package/src/styles/06-components/_components.accordion.scss +56 -14
  308. package/src/styles/06-components/_components.atomix-glass.scss +13 -9
  309. package/src/styles/06-components/_components.button.scss +16 -4
  310. package/src/styles/06-components/_components.callout.scss +27 -21
  311. package/src/styles/06-components/_components.card.scss +5 -14
  312. package/src/styles/06-components/_components.chart.scss +22 -19
  313. package/src/styles/06-components/_components.checkbox.scss +25 -17
  314. package/src/styles/06-components/_components.color-mode-toggle.scss +3 -1
  315. package/src/styles/06-components/_components.edge-panel.scss +9 -2
  316. package/src/styles/06-components/_components.footer.scss +1 -1
  317. package/src/styles/06-components/_components.side-menu.scss +5 -5
  318. package/src/styles/06-components/_components.toggle.scss +18 -0
  319. package/src/styles/06-components/_index.scss +1 -1
  320. package/src/styles/06-components/old.chart.styles.scss +0 -2
  321. package/src/styles/99-utilities/_index.scss +2 -0
  322. package/src/styles/99-utilities/_utilities.border.scss +69 -27
  323. package/src/styles/99-utilities/_utilities.display.scss +1 -1
  324. package/src/styles/99-utilities/_utilities.opacity.scss +10 -0
  325. package/src/styles/99-utilities/_utilities.position.scss +16 -9
  326. package/src/styles/99-utilities/_utilities.scss +2 -0
  327. package/src/styles/99-utilities/_utilities.sizes.scss +47 -18
  328. package/src/styles/99-utilities/_utilities.spacing.scss +118 -66
  329. package/src/styles/99-utilities/_utilities.text-gradient.scss +45 -0
  330. package/src/styles/99-utilities/_utilities.text.scss +67 -46
  331. package/themes/dark-complementary/README.md +98 -0
  332. package/themes/dark-complementary/index.scss +158 -0
  333. package/themes/default-light/README.md +81 -0
  334. package/themes/default-light/index.scss +154 -0
  335. package/themes/high-contrast/README.md +105 -0
  336. package/themes/high-contrast/index.scss +172 -0
  337. package/themes/test-theme/README.md +38 -0
  338. package/themes/test-theme/index.scss +47 -0
  339. package/scripts/cli/templates-original-backup.js +0 -1655
  340. package/scripts/cli/templates_backup.js +0 -684
  341. package/src/components/AtomixGlass/stories/AtomixGlass.stories.tsx +0 -1438
  342. package/src/lib/composables/useButton.ts +0 -93
  343. package/src/lib/composables/useCheckbox.ts +0 -70
@@ -5,9 +5,9 @@
5
5
 
6
6
  import inquirer from 'inquirer';
7
7
  import chalk from 'chalk';
8
- import { readFile, writeFile, mkdir, access } from 'fs/promises';
8
+ import { readFile, writeFile, mkdir } from 'fs/promises';
9
9
  import { existsSync } from 'fs';
10
- import { join, dirname, basename } from 'path';
10
+ import { join } from 'path';
11
11
  import ora from 'ora';
12
12
  import boxen from 'boxen';
13
13
 
@@ -15,7 +15,6 @@ import {
15
15
  validatePath,
16
16
  validateComponentName,
17
17
  sanitizeInput,
18
- fileExists,
19
18
  AtomixCLIError
20
19
  } from './utils.js';
21
20
  import { componentTemplates } from './templates.js';
@@ -112,239 +111,21 @@ export const COMPONENT_FEATURES = {
112
111
  * Simple component template
113
112
  */
114
113
  function getSimpleTemplate(name) {
115
- return `import React from 'react';
116
- import type { ${name}Props } from './${name}.types';
117
-
118
- /**
119
- * ${name} - Simple Presentational Component
120
- *
121
- * A basic component for rendering content with minimal overhead.
122
- */
123
- export const ${name} = ({ children, className, ...props }: ${name}Props) => {
124
- return (
125
- <div className={\`c-${name.toLowerCase()} \${className || ''}\`} {...props}>
126
- {children}
127
- </div>
128
- );
129
- };
130
-
131
- ${name}.displayName = '${name}';
132
- `;
114
+ return componentTemplates.react.simple(name);
133
115
  }
134
116
 
135
117
  /**
136
118
  * Medium component template
137
119
  */
138
120
  function getMediumTemplate(name) {
139
- return `import React, { useState, useCallback } from 'react';
140
- import { cn } from '../../lib/utils';
141
- import type { ${name}Props, ${name}State } from './${name}.types';
142
- import { use${name} } from '../../lib/composables/use${name}';
143
-
144
- /**
145
- * ${name} - Component with State and Interactions
146
- *
147
- * A component with internal state management and event handling.
148
- */
149
- export const ${name} = React.forwardRef<HTMLDivElement, ${name}Props>(
150
- ({
151
- children,
152
- className,
153
- defaultOpen = false,
154
- onOpenChange,
155
- disabled = false,
156
- ...props
157
- }, ref) => {
158
- const {
159
- isOpen,
160
- toggle,
161
- setIsOpen
162
- } = use${name}({
163
- defaultOpen,
164
- onOpenChange
165
- });
166
-
167
- const handleKeyDown = useCallback((e: React.KeyboardEvent) => {
168
- if (disabled) return;
169
-
170
- switch (e.key) {
171
- case 'Enter':
172
- case ' ':
173
- e.preventDefault();
174
- toggle();
175
- break;
176
- case 'Escape':
177
- setIsOpen(false);
178
- break;
179
- }
180
- }, [disabled, toggle, setIsOpen]);
181
-
182
- return (
183
- <div
184
- ref={ref}
185
- className={cn(
186
- 'c-' + '${name.toLowerCase()}',
187
- isOpen && 'is-open',
188
- disabled && 'is-disabled',
189
- className
190
- )}
191
- data-state={isOpen ? 'open' : 'closed'}
192
- data-disabled={disabled}
193
- onKeyDown={handleKeyDown}
194
- tabIndex={disabled ? -1 : 0}
195
- role="button"
196
- aria-pressed={isOpen}
197
- aria-disabled={disabled}
198
- {...props}
199
- >
200
- {children}
201
- </div>
202
- );
203
- }
204
- );
205
-
206
- ${name}.displayName = '${name}';
207
- `;
121
+ return componentTemplates.react.medium(name);
208
122
  }
209
123
 
210
124
  /**
211
125
  * Complex component template
212
126
  */
213
127
  function getComplexTemplate(name) {
214
- return `import React, { useState, useCallback, useEffect, useRef } from 'react';
215
- import { cn } from '../../lib/utils';
216
- import type { ${name}Props, ${name}ContextValue } from './${name}.types';
217
- import { use${name} } from '../../lib/composables/use${name}';
218
- import { ${name}Context } from './${name}.context';
219
-
220
- /**
221
- * ${name} - Advanced Component with Context and Animations
222
- *
223
- * A feature-rich component with context integration, animations,
224
- * accessibility, and validation.
225
- */
226
-
227
- // Root Component
228
- export const ${name} = React.forwardRef<HTMLDivElement, ${name}Props>(
229
- ({
230
- children,
231
- className,
232
- defaultOpen = false,
233
- onOpenChange,
234
- disabled = false,
235
- required = false,
236
- validate,
237
- animation = true,
238
- ...props
239
- }, ref) => {
240
- const [isOpen, setIsOpen] = useState(defaultOpen);
241
- const [isValid, setIsValid] = useState(true);
242
- const [validationMessage, setValidationMessage] = useState('');
243
- const elementRef = useRef<HTMLDivElement>(null);
244
-
245
- const toggle = useCallback(() => {
246
- if (disabled) return;
247
-
248
- const newState = !isOpen;
249
-
250
- // Validation before opening
251
- if (newState && validate) {
252
- const result = validate();
253
- setIsValid(result.valid);
254
- setValidationMessage(result.message || '');
255
-
256
- if (!result.valid) {
257
- return;
258
- }
259
- }
260
-
261
- setIsOpen(newState);
262
- onOpenChange?.(newState);
263
- }, [isOpen, disabled, validate, onOpenChange]);
264
-
265
- const contextValue: ${name}ContextValue = React.useMemo(() => ({
266
- isOpen,
267
- toggle,
268
- setIsOpen,
269
- disabled,
270
- required,
271
- isValid,
272
- validationMessage
273
- }), [isOpen, toggle, disabled, required, isValid, validationMessage]);
274
-
275
- // Focus management
276
- useEffect(() => {
277
- if (isOpen && elementRef.current) {
278
- elementRef.current.focus();
279
- }
280
- }, [isOpen]);
281
-
282
- // Keyboard navigation
283
- const handleKeyDown = useCallback((e: React.KeyboardEvent) => {
284
- if (disabled) return;
285
-
286
- switch (e.key) {
287
- case 'Enter':
288
- case ' ':
289
- e.preventDefault();
290
- toggle();
291
- break;
292
- case 'Escape':
293
- setIsOpen(false);
294
- break;
295
- case 'ArrowDown':
296
- if (isOpen) e.preventDefault();
297
- break;
298
- }
299
- }, [disabled, isOpen, toggle]);
300
-
301
- return (
302
- <${name}Context.Provider value={contextValue}>
303
- <div
304
- ref={(node) => {
305
- elementRef.current = node;
306
- if (typeof ref === 'function') ref(node);
307
- else if (ref) ref.current = node;
308
- }}
309
- className={cn(
310
- 'c-${name.toLowerCase()}',
311
- isOpen && 'is-open',
312
- disabled && 'is-disabled',
313
- !isValid && 'is-invalid',
314
- animation && 'has-animation',
315
- className
316
- )}
317
- data-state={isOpen ? 'open' : 'closed'}
318
- data-disabled={disabled}
319
- data-valid={isValid}
320
- onKeyDown={handleKeyDown}
321
- role="region"
322
- aria-expanded={isOpen}
323
- aria-disabled={disabled}
324
- aria-invalid={!isValid}
325
- aria-describedby={!isValid ? \`${name.toLowerCase()}-error\` : undefined}
326
- {...props}
327
- >
328
- {children}
329
-
330
- {!isValid && validationMessage && (
331
- <div
332
- id={\`${name.toLowerCase()}-error\`}
333
- className="c-${name.toLowerCase()}__error"
334
- role="alert"
335
- aria-live="polite"
336
- >
337
- {validationMessage}
338
- </div>
339
- )}
340
- </div>
341
- </${name}Context.Provider>
342
- );
343
- }
344
- );
345
-
346
- ${name}.displayName = '${name}';
347
- `;
128
+ return componentTemplates.react.complex(name);
348
129
  }
349
130
 
350
131
  /**
@@ -380,81 +161,246 @@ export function generateComponentByComplexity(name, complexity, options = {}) {
380
161
  * Interactive component generation
381
162
  */
382
163
  export async function interactiveComponentGeneration() {
383
- console.log(boxen(
384
- chalk.bold.cyan('🎨 Interactive Component Generator\n\n') +
385
- chalk.gray('Let\'s create a new component for your design system'),
386
- {
387
- padding: 1,
388
- margin: 1,
389
- borderStyle: 'round',
390
- borderColor: 'cyan'
391
- }
392
- ));
393
-
394
- // Step 1: Component name
395
- const { componentName } = await inquirer.prompt([
396
- {
397
- type: 'input',
398
- name: 'componentName',
399
- message: 'What is your component name?',
400
- validate: (input) => {
401
- const validation = validateComponentName(input);
402
- return validation.isValid || validation.error;
403
- },
404
- filter: (input) => sanitizeInput(input)
405
- }
406
- ]);
407
-
408
- // Step 2: Complexity level
409
- const { complexity } = await inquirer.prompt([
410
- {
411
- type: 'list',
412
- name: 'complexity',
413
- message: 'What is the complexity level?',
414
- choices: Object.values(COMPLEXITY_LEVELS).map(level => ({
415
- name: `${chalk.bold(level.name.charAt(0).toUpperCase() + level.name.slice(1))} - ${level.description}`,
416
- value: level.name,
417
- short: level.name
418
- })),
419
- default: 'medium'
420
- }
421
- ]);
422
-
423
- // Step 3: Features
424
- const { features } = await inquirer.prompt([
425
- {
426
- type: 'checkbox',
427
- name: 'features',
428
- message: 'Select features to include:',
429
- choices: Object.values(COMPONENT_FEATURES).map(feature => ({
430
- name: `${feature.description}`,
431
- value: feature.name,
432
- checked: feature.default
433
- }))
434
- }
435
- ]);
436
-
437
- // Step 4: Output path
438
- const { outputPath } = await inquirer.prompt([
439
- {
440
- type: 'input',
441
- name: 'outputPath',
442
- message: 'Output directory:',
443
- default: './src/components',
444
- validate: (input) => {
445
- const validation = validatePath(sanitizeInput(input));
446
- return validation.isValid || validation.error;
447
- },
448
- filter: (input) => sanitizeInput(input)
164
+ try {
165
+ console.log(boxen(
166
+ chalk.bold.cyan('🎨 Interactive Component Generator\n\n') +
167
+ chalk.gray('Let\'s create a new component for your design system'),
168
+ {
169
+ padding: 1,
170
+ margin: 1,
171
+ borderStyle: 'round',
172
+ borderColor: 'cyan'
173
+ }
174
+ ));
175
+
176
+ // Step 1: Component name
177
+ const { componentName } = await inquirer.prompt([
178
+ {
179
+ type: 'input',
180
+ name: 'componentName',
181
+ message: 'What is your component name?',
182
+ validate: (input) => {
183
+ const validation = validateComponentName(input);
184
+ return validation.isValid || validation.error;
185
+ },
186
+ filter: (input) => sanitizeInput(input)
187
+ }
188
+ ]);
189
+
190
+ // Step 2: Complexity level
191
+ const { complexity } = await inquirer.prompt([
192
+ {
193
+ type: 'list',
194
+ name: 'complexity',
195
+ message: 'What is the complexity level?',
196
+ choices: Object.values(COMPLEXITY_LEVELS).map(level => ({
197
+ name: `${chalk.bold(level.name.charAt(0).toUpperCase() + level.name.slice(1))} - ${level.description}`,
198
+ value: level.name,
199
+ short: level.name
200
+ })),
201
+ default: 'medium'
202
+ }
203
+ ]);
204
+
205
+ // Step 3: Features
206
+ const { features } = await inquirer.prompt([
207
+ {
208
+ type: 'checkbox',
209
+ name: 'features',
210
+ message: 'Select features to include:',
211
+ choices: Object.values(COMPONENT_FEATURES).map(feature => ({
212
+ name: `${feature.description}`,
213
+ value: feature.name,
214
+ checked: feature.default
215
+ }))
216
+ }
217
+ ]);
218
+
219
+ // Step 4: Output path
220
+ const { outputPath } = await inquirer.prompt([
221
+ {
222
+ type: 'input',
223
+ name: 'outputPath',
224
+ message: 'Output directory:',
225
+ default: './src/components',
226
+ validate: (input) => {
227
+ const validation = validatePath(sanitizeInput(input));
228
+ return validation.isValid || validation.error;
229
+ },
230
+ filter: (input) => sanitizeInput(input)
231
+ }
232
+ ]);
233
+
234
+ return {
235
+ name: componentName,
236
+ complexity,
237
+ features,
238
+ outputPath
239
+ };
240
+ } catch (error) {
241
+ if (error.message === 'User cancelled') {
242
+ return null;
449
243
  }
450
- ]);
244
+ throw error;
245
+ }
246
+ }
451
247
 
452
- return {
453
- name: componentName,
454
- complexity,
455
- features,
456
- outputPath
457
- };
248
+ /**
249
+ * Generate all component files
250
+ */
251
+ export async function generateComponentFiles(name, options = {}) {
252
+ const {
253
+ outputPath = './src/components',
254
+ complexity = 'medium',
255
+ features = [],
256
+ spinner
257
+ } = options;
258
+
259
+ const componentPath = join(outputPath, name);
260
+
261
+ // Create component directory
262
+ await mkdir(componentPath, { recursive: true });
263
+
264
+ // Determine if we need to generate a composable hook
265
+ const hasComposable = features.includes('HOOK') || COMPONENT_FEATURES.HOOK.default;
266
+
267
+ // Determine if we need glass effect
268
+ const hasGlass = features.includes('STYLES') || COMPONENT_FEATURES.STYLES.default;
269
+
270
+ // Generate main component file
271
+ const componentContent = generateComponentByComplexity(name, complexity, {
272
+ hasComposable,
273
+ hasGlass
274
+ });
275
+
276
+ await writeFile(
277
+ join(componentPath, `${name}.tsx`),
278
+ componentContent
279
+ );
280
+
281
+ if (spinner) spinner.text = `Generating ${name}.tsx...`;
282
+
283
+ // Generate index file
284
+ const indexContent = componentTemplates.react.index(name);
285
+ await writeFile(
286
+ join(componentPath, 'index.ts'),
287
+ indexContent
288
+ );
289
+
290
+ if (spinner) spinner.text = `Generating index.ts...`;
291
+
292
+ // Generate storybook file if feature is enabled
293
+ if (features.includes('storybook') || COMPONENT_FEATURES.STORYBOOK.default) {
294
+ const storyContent = componentTemplates.react.story(name);
295
+ await writeFile(
296
+ join(componentPath, `${name}.stories.tsx`),
297
+ storyContent
298
+ );
299
+
300
+ if (spinner) spinner.text = `Generating ${name}.stories.tsx...`;
301
+ }
302
+
303
+ // Generate test file if feature is enabled
304
+ if (features.includes('tests') || COMPONENT_FEATURES.TESTS.default) {
305
+ const testContent = componentTemplates.react.test(name);
306
+ await writeFile(
307
+ join(componentPath, `${name}.test.tsx`),
308
+ testContent
309
+ );
310
+
311
+ if (spinner) spinner.text = `Generating ${name}.test.tsx...`;
312
+ }
313
+
314
+ // Generate composable hook if feature is enabled
315
+ if (hasComposable) {
316
+ const composableDir = join(outputPath, '..', 'lib', 'composables');
317
+ await mkdir(composableDir, { recursive: true });
318
+
319
+ const composableContent = componentTemplates.composable.useHook(name);
320
+ await writeFile(
321
+ join(composableDir, `use${name}.ts`),
322
+ composableContent
323
+ );
324
+
325
+ if (spinner) spinner.text = `Generating use${name}.ts...`;
326
+ }
327
+
328
+ // Generate constants and types if TypeScript feature is enabled
329
+ if (features.includes('typescript') || COMPONENT_FEATURES.TYPESCRIPT.default) {
330
+ // Note: In a real implementation, we'd append to existing files rather than overwrite
331
+ // This is simplified for demonstration purposes
332
+ const constantsContent = componentTemplates.types.constants(name);
333
+ const typesContent = componentTemplates.types.types(name);
334
+
335
+ // In a real scenario, these would be appended to existing files
336
+ // For now, we'll just show what would be added
337
+ console.log(chalk.blue(`\n💡 Remember to add these to the appropriate files:`));
338
+ console.log(chalk.gray(`Constants to src/lib/constants/components.ts:`));
339
+ console.log(chalk.gray(constantsContent.substring(0, 100) + '...'));
340
+ console.log(chalk.gray(`Types to src/lib/types/components.ts:`));
341
+ console.log(chalk.gray(typesContent.substring(0, 100) + '...'));
342
+ }
343
+
344
+ // Generate SCSS files if styles feature is enabled
345
+ if (features.includes('styles') || COMPONENT_FEATURES.STYLES.default) {
346
+ const stylesBasePath = join(outputPath, '..', 'styles');
347
+
348
+ // Create settings file
349
+ const settingsPath = join(stylesBasePath, '01-settings');
350
+ await mkdir(settingsPath, { recursive: true });
351
+
352
+ const settingsContent = componentTemplates.scss.settings(name);
353
+ await writeFile(
354
+ join(settingsPath, `_settings.${name.toLowerCase()}.scss`),
355
+ settingsContent
356
+ );
357
+
358
+ if (spinner) spinner.text = `Generating _settings.${name.toLowerCase()}.scss...`;
359
+
360
+ // Create components file
361
+ const componentsPath = join(stylesBasePath, '06-components');
362
+ await mkdir(componentsPath, { recursive: true });
363
+
364
+ const componentStylesContent = componentTemplates.scss.component(name);
365
+ await writeFile(
366
+ join(componentsPath, `_components.${name.toLowerCase()}.scss`),
367
+ componentStylesContent
368
+ );
369
+
370
+ if (spinner) spinner.text = `Generating _components.${name.toLowerCase()}.scss...`;
371
+ }
372
+
373
+ return componentPath;
374
+ }
375
+
376
+ /**
377
+ * Generate a new component
378
+ */
379
+ export async function generateComponent(options) {
380
+ const { name, complexity, features, outputPath } = options;
381
+
382
+ const spinner = ora({
383
+ text: chalk.blue('Generating component...'),
384
+ spinner: 'clock'
385
+ });
386
+
387
+ try {
388
+ spinner.start();
389
+
390
+ const componentPath = await generateComponentFiles(name, {
391
+ complexity,
392
+ features,
393
+ outputPath,
394
+ spinner
395
+ });
396
+
397
+ spinner.succeed(chalk.green(`Component ${name} generated successfully!\n${chalk.gray('Location:')} ${componentPath}`));
398
+
399
+ return componentPath;
400
+ } catch (error) {
401
+ spinner.fail(chalk.red(`Failed to generate component: ${error.message}`));
402
+ throw error;
403
+ }
458
404
  }
459
405
 
460
406
  /**
@@ -504,6 +450,15 @@ export async function validateGeneratedComponent(name, componentPath) {
504
450
  suggestion: 'Add ARIA attributes and roles for better accessibility'
505
451
  });
506
452
  }
453
+
454
+ // Check for hardcoded styles
455
+ if (content.match(/#[0-9a-fA-F]{3,6}|rgb\(|rgba\(/)) {
456
+ warnings.push({
457
+ file: `${name}.tsx`,
458
+ issue: 'Using hardcoded values instead of design tokens',
459
+ suggestion: 'Use design tokens (e.g., var(--color-primary)) or utility classes'
460
+ });
461
+ }
507
462
  } else {
508
463
  issues.push({
509
464
  file: `${name}.tsx`,
@@ -513,7 +468,6 @@ export async function validateGeneratedComponent(name, componentPath) {
513
468
  }
514
469
 
515
470
  // Check for SCSS file
516
- const scssFile = join(componentPath, `${name}.scss`);
517
471
  if (existsSync(componentPath)) {
518
472
  // Check in styles directory
519
473
  const globalScss = join(process.cwd(), 'src/styles/06-components', `_components.${name.toLowerCase()}.scss`);
@@ -592,7 +546,7 @@ export function displayValidationReport(result) {
592
546
  console.log(chalk.bold.yellow(`\n⚠️ Found ${result.warnings.length} warning(s):\n`));
593
547
  result.warnings.forEach((warning, index) => {
594
548
  console.log(chalk.yellow(` ${index + 1}. ${warning.file}`));
595
- console.log(chalk.gray(` Warning: ${warning.warning}`));
549
+ console.log(chalk.gray(` Warning: ${warning.issue}`));
596
550
  console.log(chalk.cyan(` Suggestion: ${warning.suggestion}\n`));
597
551
  });
598
552
  }