@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,161 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import {
3
+ filterComponents,
4
+ removeAtomImports,
5
+ shouldProcessFile,
6
+ getAvailableThemes,
7
+ createLogger,
8
+ generateThemeModule,
9
+ applyThemeToCSS,
10
+ } from '../utils.js';
11
+
12
+ describe('Shared Utilities (utils.js)', () => {
13
+ describe('filterComponents', () => {
14
+ const sampleCode = `
15
+ import { Button, Card, Input } from '@shohojdhara/atomix/components';
16
+ export default function App() {}
17
+ `;
18
+
19
+ it('should keep only selected components', () => {
20
+ const result = filterComponents(sampleCode, ['Button'], false);
21
+ expect(result).toContain('Button');
22
+ expect(result).not.toContain('Card');
23
+ expect(result).not.toContain('Input');
24
+ });
25
+
26
+ it('should keep Atom-prefixed imports when includeAtoms is true', () => {
27
+ const code = `import { Button, AtomIcon } from '@shohojdhara/atomix/components';`;
28
+ const result = filterComponents(code, ['Button'], true);
29
+ expect(result).toContain('Button');
30
+ expect(result).toContain('AtomIcon');
31
+ });
32
+
33
+ it('should return empty string when no components match', () => {
34
+ const result = filterComponents(sampleCode, ['NonExistent'], false);
35
+ expect(result).not.toContain('import');
36
+ expect(result).not.toContain('Button');
37
+ });
38
+
39
+ it('should not modify non-Atomix imports', () => {
40
+ const code = `import { useState } from 'react';`;
41
+ const result = filterComponents(code, ['Button'], false);
42
+ expect(result).toBe(code);
43
+ });
44
+
45
+ it('should handle multiple import statements', () => {
46
+ const code = `
47
+ import { Button } from '@shohojdhara/atomix/components';
48
+ import { Card } from '@shohojdhara/atomix/components';
49
+ `;
50
+ const result = filterComponents(code, ['Button'], false);
51
+ expect(result).toContain('Button');
52
+ expect(result).not.toContain('Card');
53
+ });
54
+ });
55
+
56
+ describe('removeAtomImports', () => {
57
+ it('should remove atom imports', () => {
58
+ const code = `
59
+ import { Button } from '@shohojdhara/atomix/components';
60
+ import { AtomButton } from '@shohojdhara/atomix/atoms';
61
+ `;
62
+ const result = removeAtomImports(code);
63
+ expect(result).toContain('Button');
64
+ expect(result).not.toContain('AtomButton');
65
+ });
66
+
67
+ it('should leave non-atom imports intact', () => {
68
+ const code = `import { Button } from '@shohojdhara/atomix/components';`;
69
+ const result = removeAtomImports(code);
70
+ expect(result).toContain('Button');
71
+ });
72
+ });
73
+
74
+ describe('shouldProcessFile', () => {
75
+ it('should return true for files importing @shohojdhara/atomix', () => {
76
+ expect(shouldProcessFile('/src/App.js', "import { Button } from '@shohojdhara/atomix';")).toBe(true);
77
+ });
78
+
79
+ it('should return true for files inside atomix node_modules', () => {
80
+ expect(shouldProcessFile('/project/node_modules/@shohojdhara/atomix/Button.js', '')).toBe(true);
81
+ });
82
+
83
+ it('should return false for unrelated files', () => {
84
+ expect(shouldProcessFile('/src/App.js', 'console.log("hello");')).toBe(false);
85
+ });
86
+
87
+ it('should NOT match files that merely contain "atomix" in their path', () => {
88
+ // This was a bug in the old implementation
89
+ expect(shouldProcessFile('/my-atomix-app/src/App.js', 'console.log("hello");')).toBe(false);
90
+ });
91
+ });
92
+
93
+ describe('getAvailableThemes', () => {
94
+ it('should return empty array when path is null', () => {
95
+ expect(getAvailableThemes(null)).toEqual([]);
96
+ });
97
+
98
+ it('should return empty array when path is undefined', () => {
99
+ expect(getAvailableThemes(undefined)).toEqual([]);
100
+ });
101
+
102
+ it('should return empty array for non-existent path', () => {
103
+ expect(getAvailableThemes('/nonexistent/path')).toEqual([]);
104
+ });
105
+ });
106
+
107
+ describe('createLogger', () => {
108
+ let consoleSpy;
109
+
110
+ beforeEach(() => {
111
+ consoleSpy = {
112
+ log: vi.spyOn(console, 'log').mockImplementation(() => {}),
113
+ warn: vi.spyOn(console, 'warn').mockImplementation(() => {}),
114
+ error: vi.spyOn(console, 'error').mockImplementation(() => {}),
115
+ };
116
+ });
117
+
118
+ afterEach(() => {
119
+ vi.restoreAllMocks();
120
+ });
121
+
122
+ it('should log messages when verbose is true', () => {
123
+ const log = createLogger('[Test]', true);
124
+ log.log('hello');
125
+ expect(consoleSpy.log).toHaveBeenCalledWith('[Test] hello');
126
+ });
127
+
128
+ it('should NOT log messages when verbose is false', () => {
129
+ const log = createLogger('[Test]', false);
130
+ log.log('hello');
131
+ expect(consoleSpy.log).not.toHaveBeenCalled();
132
+ });
133
+
134
+ it('should always emit warnings regardless of verbose flag', () => {
135
+ const log = createLogger('[Test]', false);
136
+ log.warn('danger');
137
+ expect(consoleSpy.warn).toHaveBeenCalledWith('[Test] danger');
138
+ });
139
+
140
+ it('should always emit errors regardless of verbose flag', () => {
141
+ const log = createLogger('[Test]', false);
142
+ log.error('failure');
143
+ expect(consoleSpy.error).toHaveBeenCalled();
144
+ });
145
+ });
146
+
147
+ describe('generateThemeModule', () => {
148
+ it('should return error module when atomixRoot is null', () => {
149
+ const result = generateThemeModule('dark', null);
150
+ expect(result).toContain('Error generating theme module');
151
+ });
152
+ });
153
+
154
+ describe('applyThemeToCSS', () => {
155
+ it('should return comment fallback when theme cannot be loaded', () => {
156
+ const result = applyThemeToCSS('body { color: red; }', 'missing', null);
157
+ expect(result).toContain('Error loading theme CSS');
158
+ expect(result).toContain('body { color: red; }');
159
+ });
160
+ });
161
+ });
@@ -0,0 +1,129 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import atomixVitePlugin, { getAtomixPackageLocation, getAvailableThemes } from '../vite-plugin.js';
3
+
4
+ describe('Atomix Vite 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 = atomixVitePlugin();
16
+ expect(plugin.name).toBe('atomix');
17
+ expect(typeof plugin.transform).toBe('function');
18
+ expect(typeof plugin.configureServer).toBe('function');
19
+ });
20
+
21
+ it('should create plugin with custom options', () => {
22
+ const options = {
23
+ theme: 'dark-complementary',
24
+ components: ['Button', 'Card'],
25
+ optimizeCss: false,
26
+ includeAtoms: true,
27
+ verbose: true
28
+ };
29
+
30
+ const plugin = atomixVitePlugin(options);
31
+ expect(plugin.name).toBe('atomix');
32
+ });
33
+
34
+ it('should throw error for invalid theme type', () => {
35
+ expect(() => {
36
+ atomixVitePlugin({ theme: 123 });
37
+ }).toThrow('Theme must be a string');
38
+ });
39
+
40
+ it('should throw error for invalid components type', () => {
41
+ expect(() => {
42
+ atomixVitePlugin({ components: 'Button' });
43
+ }).toThrow('Components must be an array');
44
+ });
45
+ });
46
+
47
+ describe('Transform Hook', () => {
48
+ it('should process Atomix imports', async () => {
49
+ const plugin = atomixVitePlugin();
50
+
51
+ // Mock configResolved to set atomixRoot
52
+ plugin.configResolved({
53
+ root: '/test/project'
54
+ });
55
+
56
+ const testCode = `
57
+ import { Button, Card } from '@shohojdhara/atomix/components';
58
+ import { AtomButton } from '@shohojdhara/atomix/atoms';
59
+ export default function Test() {
60
+ return <Button>Hello</Button>;
61
+ }
62
+ `;
63
+
64
+ const result = await plugin.transform(testCode, '/test/file.js');
65
+
66
+ expect(result).toBeDefined();
67
+ expect(result.code).toContain('Button');
68
+ expect(result.map).toBeNull();
69
+ });
70
+
71
+ it('should filter components when specified', async () => {
72
+ const plugin = atomixVitePlugin({
73
+ components: ['Button']
74
+ });
75
+
76
+ const testCode = `
77
+ import { Button, Card, Input } from '@shohojdhara/atomix/components';
78
+ export default function Test() {
79
+ return <Button>Hello</Button>;
80
+ }
81
+ `;
82
+
83
+ const result = await plugin.transform(testCode, '/test/file.js');
84
+ expect(result.code).toContain('Button');
85
+ // Should filter out Card and Input
86
+ });
87
+
88
+ it('should remove atom imports when includeAtoms is false', async () => {
89
+ const plugin = atomixVitePlugin({
90
+ includeAtoms: false
91
+ });
92
+
93
+ const testCode = `
94
+ import { Button } from '@shohojdhara/atomix/components';
95
+ import { AtomButton } from '@shohojdhara/atomix/atoms';
96
+ `;
97
+
98
+ const result = await plugin.transform(testCode, '/test/file.js');
99
+ expect(result.code).not.toContain('AtomButton');
100
+ });
101
+
102
+ it('should return null for non-Atomix files', async () => {
103
+ const plugin = atomixVitePlugin();
104
+ const result = await plugin.transform('console.log("hello");', '/test/other.js');
105
+ expect(result).toBeNull();
106
+ });
107
+ });
108
+
109
+ describe('Helper Functions', () => {
110
+ it('should get Atomix package location', () => {
111
+ const location = getAtomixPackageLocation();
112
+ // Should return null or valid path
113
+ expect(location === null || typeof location === 'string').toBe(true);
114
+ });
115
+
116
+ it('should get available themes', () => {
117
+ const themes = getAvailableThemes(null);
118
+ expect(Array.isArray(themes)).toBe(true);
119
+ expect(themes).toEqual([]);
120
+ });
121
+ });
122
+
123
+ describe('Build Hooks', () => {
124
+ it('should have buildStart hook', () => {
125
+ const plugin = atomixVitePlugin();
126
+ expect(typeof plugin.buildStart).toBe('function');
127
+ });
128
+ });
129
+ });
@@ -0,0 +1,190 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import atomixLoader, { pitch, getAtomixConfig, getAvailableThemes } from '../webpack-loader.js';
3
+
4
+ // Mock Webpack loader context
5
+ const createMockContext = (options = {}, resourcePath = '/test/file.js') => {
6
+ return {
7
+ getOptions: () => options,
8
+ resourcePath: resourcePath,
9
+ async: () => (err, result) => {
10
+ if (err) throw err;
11
+ return result;
12
+ }
13
+ };
14
+ };
15
+
16
+ describe('Atomix Webpack Loader', () => {
17
+ beforeEach(() => {
18
+ vi.clearAllMocks();
19
+ });
20
+
21
+ afterEach(() => {
22
+ vi.restoreAllMocks();
23
+ });
24
+
25
+ describe('Loader Function', () => {
26
+ it('should process files with Atomix imports', () => {
27
+ const context = createMockContext({}, '/test/component.js');
28
+ const source = `
29
+ import { Button, Card } from '@shohojdhara/atomix/components';
30
+ export default function Test() {
31
+ return <Button>Test</Button>;
32
+ }
33
+ `;
34
+
35
+ const result = atomixLoader.call(context, source);
36
+
37
+ expect(result).toContain('Button');
38
+ expect(result).toContain('Card');
39
+ });
40
+
41
+ it('should filter components when specified', () => {
42
+ const context = createMockContext({
43
+ components: ['Button']
44
+ }, '/test/component.js');
45
+
46
+ const source = `
47
+ import { Button, Card, Input } from '@shohojdhara/atomix/components';
48
+ export default function Test() {
49
+ return <Button>Test</Button>;
50
+ }
51
+ `;
52
+
53
+ const result = atomixLoader.call(context, source);
54
+
55
+ expect(result).toContain('Button');
56
+ expect(result).not.toContain('Card');
57
+ expect(result).not.toContain('Input');
58
+ });
59
+
60
+ it('should remove atom imports when includeAtoms is false', () => {
61
+ const context = createMockContext({
62
+ includeAtoms: false
63
+ }, '/test/component.js');
64
+
65
+ const source = `
66
+ import { Button } from '@shohojdhara/atomix/components';
67
+ import { AtomButton } from '@shohojdhara/atomix/atoms';
68
+ export default function Test() {
69
+ return <Button>Test</Button>;
70
+ }
71
+ `;
72
+
73
+ const result = atomixLoader.call(context, source);
74
+
75
+ expect(result).toContain('Button');
76
+ expect(result).not.toContain('AtomButton');
77
+ });
78
+
79
+ it('should keep atom imports when includeAtoms is true', () => {
80
+ const context = createMockContext({
81
+ includeAtoms: true
82
+ }, '/test/component.js');
83
+
84
+ const source = `
85
+ import { Button } from '@shohojdhara/atomix/components';
86
+ import { AtomButton } from '@shohojdhara/atomix/atoms';
87
+ export default function Test() {
88
+ return <Button>Test</Button>;
89
+ }
90
+ `;
91
+
92
+ const result = atomixLoader.call(context, source);
93
+
94
+ expect(result).toContain('Button');
95
+ expect(result).toContain('AtomButton');
96
+ });
97
+
98
+ it('should return source unchanged for non-Atomix files', () => {
99
+ const context = createMockContext({}, '/test/regular.js');
100
+ const source = 'console.log("hello world");';
101
+
102
+ const result = atomixLoader.call(context, source);
103
+
104
+ expect(result).toBe(source);
105
+ });
106
+
107
+ it('should throw error for invalid components type', () => {
108
+ const context = createMockContext({
109
+ components: 'Button' // Should be array
110
+ }, '/test/component.js');
111
+
112
+ const source = 'import { Button } from "@shohojdhara/atomix/components";';
113
+
114
+ expect(() => {
115
+ atomixLoader.call(context, source);
116
+ }).toThrow('Components must be an array');
117
+ });
118
+
119
+ it('should handle verbose logging', () => {
120
+ const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
121
+ const context = createMockContext({
122
+ verbose: true,
123
+ components: ['Button']
124
+ }, '/test/component.js');
125
+
126
+ const source = `
127
+ import { Button, Card } from '@shohojdhara/atomix/components';
128
+ export default function Test() {
129
+ return <Button>Test</Button>;
130
+ }
131
+ `;
132
+
133
+ atomixLoader.call(context, source);
134
+
135
+ expect(consoleSpy).toHaveBeenCalledWith('[Atomix Webpack Loader] Processing: /test/component.js');
136
+ expect(consoleSpy).toHaveBeenCalledWith('[Atomix Webpack Loader] Selected components: Button');
137
+
138
+ consoleSpy.mockRestore();
139
+ });
140
+ });
141
+
142
+ describe('Pitch Function', () => {
143
+ it('should process Atomix files in pitch phase', () => {
144
+ const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
145
+ const context = createMockContext({
146
+ verbose: true
147
+ }, '/project/node_modules/@shohojdhara/atomix/Button.js');
148
+
149
+ pitch.call(context);
150
+
151
+ expect(consoleSpy).toHaveBeenCalledWith('[Atomix Webpack Loader - Pitch] Will process: /project/node_modules/@shohojdhara/atomix/Button.js');
152
+
153
+ consoleSpy.mockRestore();
154
+ });
155
+
156
+ it('should skip non-Atomix files in pitch phase', () => {
157
+ const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
158
+ const context = createMockContext({
159
+ verbose: true
160
+ }, '/project/src/App.js');
161
+
162
+ const result = pitch.call(context);
163
+
164
+ expect(result).toBeUndefined();
165
+ expect(consoleSpy).not.toHaveBeenCalled();
166
+
167
+ consoleSpy.mockRestore();
168
+ });
169
+ });
170
+
171
+ describe('Helper Functions', () => {
172
+ it('should get Atomix configuration with defaults', () => {
173
+ const config = getAtomixConfig('/test/project');
174
+
175
+ expect(config).toEqual({
176
+ theme: 'default',
177
+ optimize: true,
178
+ includeAtoms: false,
179
+ components: []
180
+ });
181
+ });
182
+
183
+ it('should get available themes', () => {
184
+ const themes = getAvailableThemes('/test/project');
185
+
186
+ expect(Array.isArray(themes)).toBe(true);
187
+ expect(themes).toEqual([]);
188
+ });
189
+ });
190
+ });