@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
@@ -0,0 +1,230 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { AtomixBuildError, Validator, ErrorHandler } from '../error-handler.js';
3
+
4
+ describe('Atomix Build Error Handler', () => {
5
+ describe('AtomixBuildError', () => {
6
+ it('should create error with proper properties', () => {
7
+ const error = new AtomixBuildError(
8
+ 'Test error message',
9
+ 'TEST_ERROR',
10
+ { detail: 'test' },
11
+ ['Suggestion 1', 'Suggestion 2']
12
+ );
13
+
14
+ expect(error).toBeInstanceOf(Error);
15
+ expect(error.name).toBe('AtomixBuildError');
16
+ expect(error.message).toBe('Test error message');
17
+ expect(error.code).toBe('TEST_ERROR');
18
+ expect(error.details).toEqual({ detail: 'test' });
19
+ expect(error.suggestions).toEqual(['Suggestion 1', 'Suggestion 2']);
20
+ expect(error.timestamp).toBeDefined();
21
+ });
22
+
23
+ it('should format error message correctly', () => {
24
+ const error = new AtomixBuildError(
25
+ 'Simple error',
26
+ 'SIMPLE_ERROR'
27
+ );
28
+
29
+ const formatted = error.toString();
30
+ expect(formatted).toContain('[AtomixBuildError:SIMPLE_ERROR]');
31
+ expect(formatted).toContain('Simple error');
32
+ });
33
+ });
34
+
35
+ describe('Validator', () => {
36
+ describe('validateTheme', () => {
37
+ it('should validate valid theme', () => {
38
+ expect(() => {
39
+ Validator.validateTheme('default', ['default', 'dark']);
40
+ }).not.toThrow();
41
+ });
42
+
43
+ it('should throw error for invalid theme type', () => {
44
+ expect(() => {
45
+ Validator.validateTheme(123);
46
+ }).toThrow(AtomixBuildError);
47
+ });
48
+
49
+ it('should throw error for empty theme', () => {
50
+ expect(() => {
51
+ Validator.validateTheme('');
52
+ }).toThrow(AtomixBuildError);
53
+ });
54
+
55
+ it('should throw error for non-existent theme', () => {
56
+ expect(() => {
57
+ Validator.validateTheme('nonexistent', ['default', 'dark']);
58
+ }).toThrow(AtomixBuildError);
59
+ });
60
+ });
61
+
62
+ describe('validateComponents', () => {
63
+ it('should validate valid components array', () => {
64
+ expect(() => {
65
+ Validator.validateComponents(['Button', 'Card'], ['Button', 'Card', 'Input']);
66
+ }).not.toThrow();
67
+ });
68
+
69
+ it('should throw error for non-array components', () => {
70
+ expect(() => {
71
+ Validator.validateComponents('Button');
72
+ }).toThrow(AtomixBuildError);
73
+ });
74
+
75
+ it('should throw error for non-string component names', () => {
76
+ expect(() => {
77
+ Validator.validateComponents(['Button', 123]);
78
+ }).toThrow(AtomixBuildError);
79
+ });
80
+
81
+ it('should throw error for missing components', () => {
82
+ expect(() => {
83
+ Validator.validateComponents(['Button', 'Missing'], ['Button']);
84
+ }).toThrow(AtomixBuildError);
85
+ });
86
+ });
87
+
88
+ describe('validateBoolean', () => {
89
+ it('should validate valid boolean', () => {
90
+ expect(() => {
91
+ Validator.validateBoolean(true, 'testOption');
92
+ }).not.toThrow();
93
+ });
94
+
95
+ it('should throw error for non-boolean value', () => {
96
+ expect(() => {
97
+ Validator.validateBoolean('true', 'testOption');
98
+ }).toThrow(AtomixBuildError);
99
+ });
100
+ });
101
+
102
+ describe('validateString', () => {
103
+ it('should validate valid string', () => {
104
+ expect(() => {
105
+ Validator.validateString('test', 'testOption');
106
+ }).not.toThrow();
107
+ });
108
+
109
+ it('should throw error for non-string value', () => {
110
+ expect(() => {
111
+ Validator.validateString(123, 'testOption');
112
+ }).toThrow(AtomixBuildError);
113
+ });
114
+
115
+ it('should throw error for empty string when not allowed', () => {
116
+ expect(() => {
117
+ Validator.validateString('', 'testOption');
118
+ }).toThrow(AtomixBuildError);
119
+ });
120
+
121
+ it('should allow empty string when permitted', () => {
122
+ expect(() => {
123
+ Validator.validateString('', 'testOption', true);
124
+ }).not.toThrow();
125
+ });
126
+ });
127
+
128
+ describe('validateOptions', () => {
129
+ it('should validate complete options object', () => {
130
+ const options = {
131
+ theme: 'default',
132
+ components: ['Button'],
133
+ optimizeCss: true,
134
+ includeAtoms: false,
135
+ verbose: false
136
+ };
137
+
138
+ expect(() => {
139
+ Validator.validateOptions(options);
140
+ }).not.toThrow();
141
+ });
142
+
143
+ it('should throw error for invalid options object', () => {
144
+ expect(() => {
145
+ Validator.validateOptions('invalid');
146
+ }).toThrow(AtomixBuildError);
147
+ });
148
+
149
+ it('should warn about unknown options', () => {
150
+ const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
151
+
152
+ const options = {
153
+ theme: 'default',
154
+ unknownOption: 'value'
155
+ };
156
+
157
+ Validator.validateOptions(options);
158
+ expect(consoleSpy).toHaveBeenCalledWith('[AtomixBuildWarning] Unknown options provided: unknownOption');
159
+
160
+ consoleSpy.mockRestore();
161
+ });
162
+ });
163
+ });
164
+
165
+ describe('ErrorHandler', () => {
166
+ describe('withErrorHandling', () => {
167
+ it('should wrap function and handle errors', () => {
168
+ const failingFn = () => {
169
+ throw new Error('Original error');
170
+ };
171
+
172
+ const wrappedFn = ErrorHandler.withErrorHandling(failingFn, 'Test Context');
173
+
174
+ expect(() => {
175
+ wrappedFn();
176
+ }).toThrow(AtomixBuildError);
177
+ });
178
+
179
+ it('should preserve AtomixBuildError instances', () => {
180
+ const atomixError = new AtomixBuildError('Test', 'TEST_CODE');
181
+ const failingFn = () => {
182
+ throw atomixError;
183
+ };
184
+
185
+ const wrappedFn = ErrorHandler.withErrorHandling(failingFn, 'Test Context');
186
+
187
+ try {
188
+ wrappedFn();
189
+ expect.fail('Should have thrown');
190
+ } catch (error) {
191
+ expect(error).toBe(atomixError);
192
+ }
193
+ });
194
+ });
195
+
196
+ describe('logError', () => {
197
+ it('should log AtomixBuildError properly', () => {
198
+ const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
199
+ const error = new AtomixBuildError('Test error', 'TEST_CODE');
200
+
201
+ ErrorHandler.logError(error);
202
+ expect(consoleSpy).toHaveBeenCalled();
203
+
204
+ consoleSpy.mockRestore();
205
+ });
206
+
207
+ it('should log regular Error properly', () => {
208
+ const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
209
+ const error = new Error('Regular error');
210
+
211
+ ErrorHandler.logError(error);
212
+ expect(consoleSpy).toHaveBeenCalledWith('[Error] Regular error');
213
+
214
+ consoleSpy.mockRestore();
215
+ });
216
+ });
217
+
218
+ describe('getErrorCode', () => {
219
+ it('should get error code from AtomixBuildError', () => {
220
+ const error = new AtomixBuildError('Test', 'TEST_CODE');
221
+ expect(ErrorHandler.getErrorCode(error)).toBe('TEST_CODE');
222
+ });
223
+
224
+ it('should return null for regular Error', () => {
225
+ const error = new Error('Test');
226
+ expect(ErrorHandler.getErrorCode(error)).toBeNull();
227
+ });
228
+ });
229
+ });
230
+ });
@@ -0,0 +1,141 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import { detectBuildTool, getIntegration, initAutoIntegration } from '../index.js';
3
+ import fs from 'fs';
4
+
5
+ // Mock fs for detectBuildTool tests
6
+ vi.mock('fs', async (importOriginal) => {
7
+ const actual = await importOriginal();
8
+ return {
9
+ ...actual,
10
+ default: {
11
+ ...actual.default,
12
+ existsSync: vi.fn(),
13
+ readFileSync: vi.fn(),
14
+ },
15
+ existsSync: vi.fn(),
16
+ readFileSync: vi.fn(),
17
+ };
18
+ });
19
+
20
+ describe('Build-Tools Index (index.js)', () => {
21
+ beforeEach(() => {
22
+ vi.clearAllMocks();
23
+ });
24
+
25
+ afterEach(() => {
26
+ vi.restoreAllMocks();
27
+ });
28
+
29
+ describe('detectBuildTool', () => {
30
+ it('should detect vite when it is in devDependencies', () => {
31
+ fs.existsSync.mockReturnValue(true);
32
+ fs.readFileSync.mockReturnValue(JSON.stringify({
33
+ devDependencies: { vite: '^5.0.0' },
34
+ }));
35
+
36
+ expect(detectBuildTool()).toBe('vite');
37
+ });
38
+
39
+ it('should detect webpack when it is in dependencies', () => {
40
+ fs.existsSync.mockReturnValue(true);
41
+ fs.readFileSync.mockReturnValue(JSON.stringify({
42
+ dependencies: { webpack: '^5.0.0' },
43
+ }));
44
+
45
+ expect(detectBuildTool()).toBe('webpack');
46
+ });
47
+
48
+ it('should detect rollup', () => {
49
+ fs.existsSync.mockReturnValue(true);
50
+ fs.readFileSync.mockReturnValue(JSON.stringify({
51
+ devDependencies: { rollup: '^4.0.0' },
52
+ }));
53
+
54
+ expect(detectBuildTool()).toBe('rollup');
55
+ });
56
+
57
+ it('should return null when no build tool is detected', () => {
58
+ fs.existsSync.mockReturnValue(true);
59
+ fs.readFileSync.mockReturnValue(JSON.stringify({
60
+ dependencies: { react: '^18.0.0' },
61
+ }));
62
+
63
+ expect(detectBuildTool()).toBeNull();
64
+ });
65
+
66
+ it('should return null when package.json does not exist', () => {
67
+ fs.existsSync.mockReturnValue(false);
68
+
69
+ expect(detectBuildTool()).toBeNull();
70
+ });
71
+
72
+ it('should prioritize vite over webpack when both exist', () => {
73
+ fs.existsSync.mockReturnValue(true);
74
+ fs.readFileSync.mockReturnValue(JSON.stringify({
75
+ devDependencies: { vite: '^5.0.0', webpack: '^5.0.0' },
76
+ }));
77
+
78
+ expect(detectBuildTool()).toBe('vite');
79
+ });
80
+
81
+ it('should handle malformed package.json gracefully', () => {
82
+ fs.existsSync.mockReturnValue(true);
83
+ fs.readFileSync.mockReturnValue('not valid json');
84
+
85
+ const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
86
+ expect(detectBuildTool()).toBeNull();
87
+ consoleSpy.mockRestore();
88
+ });
89
+ });
90
+
91
+ describe('getIntegration', () => {
92
+ it('should return a plugin object for "vite"', () => {
93
+ const result = getIntegration('vite');
94
+ expect(result).toBeDefined();
95
+ expect(result.name).toBe('atomix');
96
+ });
97
+
98
+ it('should return a function for "webpack"', () => {
99
+ const result = getIntegration('webpack');
100
+ expect(typeof result).toBe('function');
101
+ });
102
+
103
+ it('should return a plugin object for "rollup"', () => {
104
+ const result = getIntegration('rollup');
105
+ expect(result).toBeDefined();
106
+ expect(result.name).toBe('atomix');
107
+ });
108
+
109
+ it('should return null for unknown build tool', () => {
110
+ const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
111
+ const result = getIntegration('parcel');
112
+ expect(result).toBeNull();
113
+ consoleSpy.mockRestore();
114
+ });
115
+
116
+ it('should return null for null build tool', () => {
117
+ const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
118
+ const result = getIntegration(null);
119
+ expect(result).toBeNull();
120
+ consoleSpy.mockRestore();
121
+ });
122
+
123
+ it('should be case-insensitive', () => {
124
+ const result = getIntegration('VITE');
125
+ expect(result).toBeDefined();
126
+ expect(result.name).toBe('atomix');
127
+ });
128
+ });
129
+
130
+ describe('initAutoIntegration', () => {
131
+ it('should return null when no build tool detected', () => {
132
+ fs.existsSync.mockReturnValue(false);
133
+ const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
134
+
135
+ const result = initAutoIntegration();
136
+ expect(result).toBeNull();
137
+
138
+ warnSpy.mockRestore();
139
+ });
140
+ });
141
+ });
@@ -0,0 +1,194 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import atomixRollupPlugin, { getAvailableThemes, getAtomixPackageLocation } from '../rollup-plugin.js';
3
+
4
+ describe('Atomix Rollup Plugin', () => {
5
+ beforeEach(() => {
6
+ vi.clearAllMocks();
7
+ });
8
+
9
+ afterEach(() => {
10
+ vi.restoreAllMocks();
11
+ });
12
+
13
+ describe('Plugin Creation', () => {
14
+ it('should create plugin with default options', () => {
15
+ const plugin = atomixRollupPlugin();
16
+ expect(plugin.name).toBe('atomix');
17
+ expect(typeof plugin.transform).toBe('function');
18
+ expect(typeof plugin.resolveId).toBe('function');
19
+ expect(typeof plugin.load).toBe('function');
20
+ });
21
+
22
+ it('should create plugin with custom options', () => {
23
+ const options = {
24
+ theme: 'dark-complementary',
25
+ components: ['Button', 'Card'],
26
+ optimize: false,
27
+ includeAtoms: true,
28
+ verbose: true
29
+ };
30
+
31
+ const plugin = atomixRollupPlugin(options);
32
+ expect(plugin.name).toBe('atomix');
33
+ });
34
+
35
+ it('should throw error for invalid theme type', () => {
36
+ expect(() => {
37
+ atomixRollupPlugin({ theme: 123 });
38
+ }).toThrow('Theme must be a string');
39
+ });
40
+
41
+ it('should throw error for invalid components type', () => {
42
+ expect(() => {
43
+ atomixRollupPlugin({ components: 'Button' });
44
+ }).toThrow('Components must be an array');
45
+ });
46
+ });
47
+
48
+ describe('Transform Hook', () => {
49
+ it('should process Atomix files', () => {
50
+ const plugin = atomixRollupPlugin();
51
+ const testCode = `
52
+ import { Button, Card } from '@shohojdhara/atomix/components';
53
+ import { AtomButton } from '@shohojdhara/atomix/atoms';
54
+ export default function Test() {
55
+ return <Button>Hello</Button>;
56
+ }
57
+ `;
58
+
59
+ const result = plugin.transform(testCode, '/test/node_modules/@shohojdhara/atomix/Button.js');
60
+
61
+ expect(result).toBeDefined();
62
+ expect(result.code).toContain('Button');
63
+ expect(result.map).toBeNull();
64
+ });
65
+
66
+ it('should filter components when specified', () => {
67
+ const plugin = atomixRollupPlugin({
68
+ components: ['Button'],
69
+ optimize: true
70
+ });
71
+
72
+ const testCode = `
73
+ import { Button, Card, Input } from '@shohojdhara/atomix/components';
74
+ export default function Test() {
75
+ return <Button>Hello</Button>;
76
+ }
77
+ `;
78
+
79
+ const result = plugin.transform(testCode, '/test/file.js');
80
+ expect(result.code).toContain('Button');
81
+ // Should filter out Card and Input
82
+ });
83
+
84
+ it('should remove atom imports when includeAtoms is false', () => {
85
+ const plugin = atomixRollupPlugin({
86
+ includeAtoms: false,
87
+ optimize: true
88
+ });
89
+
90
+ const testCode = `
91
+ import { Button } from '@shohojdhara/atomix/components';
92
+ import { AtomButton } from '@shohojdhara/atomix/atoms';
93
+ `;
94
+
95
+ const result = plugin.transform(testCode, '/test/file.js');
96
+ expect(result.code).not.toContain('AtomButton');
97
+ });
98
+
99
+ it('should return null for non-Atomix files', () => {
100
+ const plugin = atomixRollupPlugin();
101
+ const result = plugin.transform('console.log("hello");', '/test/other.js');
102
+ expect(result).toBeNull();
103
+ });
104
+ });
105
+
106
+ describe('ResolveId Hook', () => {
107
+ it('should resolve theme imports', () => {
108
+ const plugin = atomixRollupPlugin();
109
+ const result = plugin.resolveId('@shohojdhara/atomix/theme', '/test/importer.js');
110
+ // Should return null or the import path
111
+ expect(result === null || typeof result === 'string').toBe(true);
112
+ });
113
+
114
+ it('should resolve component imports', () => {
115
+ const plugin = atomixRollupPlugin();
116
+ const result = plugin.resolveId('@shohojdhara/atomix/components/Button', '/test/importer.js');
117
+ expect(result === null || typeof result === 'string').toBe(true);
118
+ });
119
+
120
+ it('should return null for non-Atomix imports', () => {
121
+ const plugin = atomixRollupPlugin();
122
+ const result = plugin.resolveId('react', '/test/importer.js');
123
+ expect(result).toBeNull();
124
+ });
125
+ });
126
+
127
+ describe('Load Hook', () => {
128
+ it('should load virtual theme modules', () => {
129
+ const plugin = atomixRollupPlugin();
130
+ const result = plugin.load('virtual:atomix-theme');
131
+ expect(typeof result).toBe('string');
132
+ });
133
+
134
+ it('should return null for unknown virtual modules', () => {
135
+ const plugin = atomixRollupPlugin();
136
+ const result = plugin.load('virtual:unknown');
137
+ expect(result).toBeNull();
138
+ });
139
+ });
140
+
141
+ describe('GenerateBundle Hook', () => {
142
+ it('should process CSS assets', () => {
143
+ const plugin = atomixRollupPlugin({ optimize: true });
144
+ const bundle = {
145
+ 'styles.css': {
146
+ type: 'asset',
147
+ fileName: 'atomix-styles.css',
148
+ source: 'body { color: red; }'
149
+ }
150
+ };
151
+
152
+ // This should not throw an error
153
+ expect(() => {
154
+ plugin.generateBundle({}, bundle);
155
+ }).not.toThrow();
156
+ });
157
+
158
+ it('should skip non-CSS assets', () => {
159
+ const plugin = atomixRollupPlugin({ optimize: true });
160
+ const bundle = {
161
+ 'script.js': {
162
+ type: 'chunk',
163
+ fileName: 'script.js',
164
+ code: 'console.log("hello");'
165
+ }
166
+ };
167
+
168
+ expect(() => {
169
+ plugin.generateBundle({}, bundle);
170
+ }).not.toThrow();
171
+ });
172
+ });
173
+
174
+ describe('BuildStart Hook', () => {
175
+ it('should have buildStart function', () => {
176
+ const plugin = atomixRollupPlugin();
177
+ expect(typeof plugin.buildStart).toBe('function');
178
+ });
179
+ });
180
+
181
+ describe('Helper Functions', () => {
182
+ it('should get available themes', () => {
183
+ const themes = getAvailableThemes(null);
184
+ expect(Array.isArray(themes)).toBe(true);
185
+ expect(themes).toEqual([]);
186
+ });
187
+
188
+ it('should get Atomix package location', () => {
189
+ const location = getAtomixPackageLocation();
190
+ // Should return null or valid path
191
+ expect(location === null || typeof location === 'string').toBe(true);
192
+ });
193
+ });
194
+ });