@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
@@ -149,143 +149,145 @@ export const Footer = forwardRef<HTMLElement, FooterProps>(
149
149
 
150
150
  const footerContent = (
151
151
  <div className={containerClass}>
152
- {/* Main Footer Content */}
153
- <Grid
154
- className={sectionsClass}
155
- alignItems="start"
156
- justifyContent={layout === 'centered' ? 'center' : undefined}
157
- >
158
- {/* Brand Section */}
159
- {(brand || brandLogo || brandDescription) && (
160
- <GridCol {...(getResponsiveColumnProps('brand') as any)} className={brandClass}>
161
- {brandLogo && (
162
- <div className="c-footer__brand-logo">
163
- {typeof brandLogo === 'string' ? (
164
- <img src={brandLogo} alt={'Brand Logo'} />
165
- ) : (
166
- brandLogo
167
- )}
168
- </div>
169
- )}
170
- {brand && (
171
- <div className="c-footer__brand-name">
172
- {typeof brand === 'string' ? <h3>{brand}</h3> : brand}
173
- </div>
174
- )}
175
- {brandDescription && (
176
- <div className="c-footer__brand-description">{brandDescription}</div>
177
- )}
178
- {socialLinks.length > 0 && (
179
- <div className="c-footer__social" data-testid="footer-social-links">
180
- {socialLinks.map((link, index) => (
181
- <FooterSocialLink
182
- key={`${link.platform}-${index}`}
183
- platform={link.platform}
184
- url={link.url}
185
- icon={link.icon}
186
- label={link.label}
187
- size={size}
188
- />
189
- ))}
190
- </div>
191
- )}
192
- </GridCol>
193
- )}
194
-
195
- {/* Footer Sections */}
196
- {children && (
197
- <GridCol
198
- {...(getResponsiveColumnProps('content') as any)}
199
- className="c-footer__content"
200
- >
201
- <Grid
202
- className="c-footer__sections"
203
- alignItems={layout === 'centered' || layout === 'stacked' ? 'center' : undefined}
204
- >
205
- {React.Children.map(children, child => {
206
- // Check if the child is a valid React element
207
- if (React.isValidElement(child)) {
208
- // Clone the element and pass the showNewsletter prop
209
- return React.cloneElement(child, { showNewsletter } as any);
210
- }
211
- return child;
212
- })}
213
- </Grid>
214
- </GridCol>
215
- )}
152
+ {/* Main Footer Content */}
153
+ <Grid
154
+ className={sectionsClass}
155
+ alignItems="start"
156
+ justifyContent={layout === 'centered' ? 'center' : undefined}
157
+ >
158
+ {/* Brand Section */}
159
+ {(brand || brandLogo || brandDescription) && (
160
+ <GridCol {...(getResponsiveColumnProps('brand') as any)} className={brandClass}>
161
+ {brandLogo && (
162
+ <div className="c-footer__brand-logo">
163
+ {typeof brandLogo === 'string' ? (
164
+ <img src={brandLogo} alt={'Brand Logo'} />
165
+ ) : (
166
+ brandLogo
167
+ )}
168
+ </div>
169
+ )}
170
+ {brand && (
171
+ <div className="c-footer__brand-name">
172
+ {typeof brand === 'string' ? <h3>{brand}</h3> : brand}
173
+ </div>
174
+ )}
175
+ {brandDescription && (
176
+ <div className="c-footer__brand-description">{brandDescription}</div>
177
+ )}
178
+ {socialLinks.length > 0 && (
179
+ <div className="c-footer__social" data-testid="footer-social-links">
180
+ {socialLinks.map((link, index) => (
181
+ <FooterSocialLink
182
+ key={`${link.platform}-${index}`}
183
+ platform={link.platform}
184
+ url={link.url}
185
+ icon={link.icon}
186
+ label={link.label}
187
+ size={size}
188
+ />
189
+ ))}
190
+ </div>
191
+ )}
192
+ </GridCol>
193
+ )}
216
194
 
217
- {/* Newsletter Section */}
218
- {showNewsletter && (
219
- <GridCol
220
- {...(getResponsiveColumnProps('newsletter') as any)}
221
- className="c-footer__newsletter"
195
+ {/* Footer Sections */}
196
+ {children && (
197
+ <GridCol
198
+ {...(getResponsiveColumnProps('content') as any)}
199
+ className="c-footer__content"
200
+ >
201
+ <Grid
202
+ className="c-footer__sections"
203
+ alignItems={layout === 'centered' || layout === 'stacked' ? 'center' : undefined}
222
204
  >
223
- <h4 className="c-footer__newsletter-title">{newsletterTitle}</h4>
224
- {newsletterDescription && (
225
- <p className="c-footer__newsletter-description">{newsletterDescription}</p>
226
- )}
227
- <Form
228
- className="c-footer__newsletter-form"
229
- onSubmit={e => {
230
- e.preventDefault();
231
- const formData = new FormData(e.currentTarget);
232
- const email = formData.get('email') as string;
233
- if (email) handleNewsletterSubmit(email);
234
- }}
235
- >
236
- <div className="c-footer__newsletter-input-group">
237
- <Input
238
- type="email"
239
- name="email"
240
- className="c-footer__newsletter-input"
241
- placeholder={newsletterPlaceholder}
242
- required
243
- />
244
- <Button type="submit" className="c-footer__newsletter-button">
245
- {newsletterButtonText}
246
- </Button>
247
- </div>
248
- </Form>
249
- </GridCol>
250
- )}
251
- </Grid>
205
+ {React.Children.map(children, child => {
206
+ // Check if the child is a valid React element
207
+ if (React.isValidElement(child)) {
208
+ // Clone the element and pass the showNewsletter prop
209
+ return React.cloneElement(child, { showNewsletter } as any);
210
+ }
211
+ return child;
212
+ })}
213
+ </Grid>
214
+ </GridCol>
215
+ )}
252
216
 
253
- {(copyright || showBackToTop) && (
254
- <div className={bottomClass}>
255
- {copyright && <div className="c-footer__copyright">{copyright}</div>}
256
- {showBackToTop && (
257
- <Button
258
- variant="ghost"
259
- className="c-footer__back-to-top"
260
- onClick={handleBackToTop}
261
- disabled={disabled}
262
- aria-label={backToTopText}
263
- >
264
- <span className="c-footer__back-to-top-icon">↑</span>
265
- <span className="c-footer__back-to-top-text">{backToTopText}</span>
266
- </Button>
217
+ {/* Newsletter Section */}
218
+ {showNewsletter && (
219
+ <GridCol
220
+ {...(getResponsiveColumnProps('newsletter') as any)}
221
+ className="c-footer__newsletter"
222
+ >
223
+ <h4 className="c-footer__newsletter-title">{newsletterTitle}</h4>
224
+ {newsletterDescription && (
225
+ <p className="c-footer__newsletter-description">{newsletterDescription}</p>
267
226
  )}
268
- </div>
227
+ <Form
228
+ className="c-footer__newsletter-form"
229
+ onSubmit={e => {
230
+ e.preventDefault();
231
+ const formData = new FormData(e.currentTarget);
232
+ const email = formData.get('email') as string;
233
+ if (email) handleNewsletterSubmit(email);
234
+ }}
235
+ >
236
+ <div className="c-footer__newsletter-input-group">
237
+ <Input
238
+ type="email"
239
+ name="email"
240
+ className="c-footer__newsletter-input"
241
+ placeholder={newsletterPlaceholder}
242
+ required
243
+ />
244
+ <Button type="submit" className="c-footer__newsletter-button">
245
+ {newsletterButtonText}
246
+ </Button>
247
+ </div>
248
+ </Form>
249
+ </GridCol>
269
250
  )}
270
- </div>
251
+ </Grid>
252
+
253
+ {(copyright || showBackToTop) && (
254
+ <div className={bottomClass}>
255
+ {copyright && <div className="c-footer__copyright">{copyright}</div>}
256
+ {showBackToTop && (
257
+ <Button
258
+ variant="ghost"
259
+ className="c-footer__back-to-top"
260
+ onClick={handleBackToTop}
261
+ disabled={disabled}
262
+ aria-label={backToTopText}
263
+ >
264
+ <span className="c-footer__back-to-top-icon">↑</span>
265
+ <span className="c-footer__back-to-top-text">{backToTopText}</span>
266
+ </Button>
267
+ )}
268
+ </div>
269
+ )}
270
+ </div>
271
271
  );
272
272
 
273
273
  return (
274
- <footer ref={ref} className={footerClass + ` c-footer ${glass ? 'c-footer--glass' : ''}`} {...props}>
275
- {glass ? (
276
- <AtomixGlass {...(glass as unknown as AtomixGlassProps)} elasticity={0}>
277
- <div className="c-footer__glass">
278
- {footerContent}
279
- </div>
280
- </AtomixGlass>
281
- ) : (
282
- footerContent
283
- )}
284
- </footer>
285
- );
286
- }
274
+ <footer
275
+ ref={ref}
276
+ className={footerClass + ` c-footer ${glass ? 'c-footer--glass' : ''}`}
277
+ {...props}
278
+ >
279
+ {glass ? (
280
+ <AtomixGlass {...(glass as unknown as AtomixGlassProps)} elasticity={0}>
281
+ <div className="c-footer__glass">{footerContent}</div>
282
+ </AtomixGlass>
283
+ ) : (
284
+ footerContent
285
+ )}
286
+ </footer>
287
+ );
288
+ }
287
289
  );
288
290
 
289
291
  Footer.displayName = 'Footer';
290
292
 
291
- export default Footer;
293
+ export default Footer;
@@ -55,7 +55,7 @@ export const FooterLink = forwardRef<HTMLAnchorElement, FooterLinkProps>(
55
55
  ...(href && !disabled ? { to: href } : {}),
56
56
  ...linkProps,
57
57
  };
58
-
58
+
59
59
  return (
60
60
  <Component {...componentProps}>
61
61
  {icon && <span className="c-footer__link-icon">{icon}</span>}
@@ -77,4 +77,4 @@ export const FooterLink = forwardRef<HTMLAnchorElement, FooterLinkProps>(
77
77
 
78
78
  FooterLink.displayName = 'FooterLink';
79
79
 
80
- export default FooterLink;
80
+ export default FooterLink;
@@ -1,6 +1,11 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react';
2
+ import { fn } from '@storybook/test';
3
+ import { useState } from 'react';
2
4
  import { Checkbox } from './Checkbox';
3
5
 
6
+ // Mock event handlers
7
+ const mockOnChange = fn();
8
+
4
9
  const meta = {
5
10
  title: 'Components/Form/Checkbox',
6
11
  component: Checkbox,
@@ -8,8 +13,66 @@ const meta = {
8
13
  layout: 'centered',
9
14
  docs: {
10
15
  description: {
11
- component:
12
- 'The Checkbox component allows users to select one or more options from a set. It supports checked, unchecked, and indeterminate states, and can be used in forms or as standalone controls. Checkboxes provide clear visual feedback and support keyboard navigation.',
16
+ component: `
17
+ # Checkbox
18
+
19
+ ## Overview
20
+
21
+ Checkbox component allows users to select one or more options from a set. It supports checked, unchecked, and indeterminate states, and can be used in forms or as standalone controls. Checkboxes provide clear visual feedback and support keyboard navigation.
22
+
23
+ ## Features
24
+
25
+ - Checked, unchecked, and indeterminate states
26
+ - Label support
27
+ - Disabled state
28
+ - Validation states (valid/invalid)
29
+ - Glass morphism effect
30
+ - Accessible design
31
+ - Responsive behavior
32
+
33
+ ## Accessibility
34
+
35
+ - Keyboard support: Navigate and toggle with keyboard
36
+ - Screen reader: State and label announced properly
37
+ - ARIA support: Proper roles and properties for checkbox components
38
+ - Focus management: Visible focus indicators maintained
39
+
40
+ ## Usage Examples
41
+
42
+ ### Basic Usage
43
+
44
+ \`\`\`tsx
45
+ <Checkbox
46
+ label="Option label"
47
+ checked={isChecked}
48
+ onChange={setChecked}
49
+ />
50
+ \`\`\`
51
+
52
+ ### Indeterminate State
53
+
54
+ \`\`\`tsx
55
+ <Checkbox
56
+ label="Option label"
57
+ indeterminate={true}
58
+ />
59
+ \`\`\`
60
+
61
+ ## API Reference
62
+
63
+ ### Props
64
+
65
+ | Prop | Type | Default | Description |
66
+ | ---- | ---- | ------- | ----------- |
67
+ | label | ReactNode | - | Checkbox label text or element |
68
+ | checked | boolean | false | Whether the checkbox is checked |
69
+ | disabled | boolean | false | Whether the checkbox is disabled |
70
+ | invalid | boolean | false | Whether the checkbox is invalid |
71
+ | valid | boolean | false | Whether the checkbox is valid |
72
+ | indeterminate | boolean | false | Whether the checkbox is in indeterminate state |
73
+ | glass | boolean \| AtomixGlassProps | false | Enable glass morphism effect |
74
+ | onChange | (event: ChangeEvent<HTMLInputElement>) => void | - | Callback when checkbox state changes |
75
+ `,
13
76
  },
14
77
  },
15
78
  },
@@ -17,31 +80,63 @@ const meta = {
17
80
  argTypes: {
18
81
  label: {
19
82
  control: 'text',
20
- description: 'Checkbox label text',
83
+ description: 'Checkbox label text or element',
84
+ table: {
85
+ type: { summary: 'ReactNode' },
86
+ defaultValue: { summary: '-' },
87
+ },
21
88
  },
22
89
  checked: {
23
90
  control: 'boolean',
24
91
  description: 'Whether the checkbox is checked',
92
+ table: {
93
+ type: { summary: 'boolean' },
94
+ defaultValue: { summary: 'false' },
95
+ },
25
96
  },
26
97
  disabled: {
27
98
  control: 'boolean',
28
99
  description: 'Whether the checkbox is disabled',
100
+ table: {
101
+ type: { summary: 'boolean' },
102
+ defaultValue: { summary: 'false' },
103
+ },
29
104
  },
30
105
  invalid: {
31
106
  control: 'boolean',
32
107
  description: 'Whether the checkbox is invalid',
108
+ table: {
109
+ type: { summary: 'boolean' },
110
+ defaultValue: { summary: 'false' },
111
+ },
33
112
  },
34
113
  valid: {
35
114
  control: 'boolean',
36
115
  description: 'Whether the checkbox is valid',
116
+ table: {
117
+ type: { summary: 'boolean' },
118
+ defaultValue: { summary: 'false' },
119
+ },
37
120
  },
38
121
  indeterminate: {
39
122
  control: 'boolean',
40
123
  description: 'Whether the checkbox is in indeterminate state',
124
+ table: {
125
+ type: { summary: 'boolean' },
126
+ defaultValue: { summary: 'false' },
127
+ },
41
128
  },
42
129
  glass: {
43
- control: 'boolean',
130
+ control: { type: 'boolean' },
44
131
  description: 'Enable glass morphism effect',
132
+ table: {
133
+ type: { summary: 'boolean | AtomixGlassProps' },
134
+ defaultValue: { summary: 'false' },
135
+ },
136
+ },
137
+ onChange: {
138
+ action: 'changed',
139
+ description: 'Callback when checkbox state changes',
45
140
  },
46
141
  },
47
142
  } satisfies Meta<typeof Checkbox>;
@@ -50,9 +145,17 @@ export default meta;
50
145
  type Story = StoryObj<typeof meta>;
51
146
 
52
147
  // Basic checkbox
53
- export const Basic: Story = {
148
+ export const BasicUsage: Story = {
54
149
  args: {
55
150
  label: 'Accept terms and conditions',
151
+ onChange: mockOnChange,
152
+ },
153
+ parameters: {
154
+ docs: {
155
+ description: {
156
+ story: 'Basic checkbox with label.',
157
+ },
158
+ },
56
159
  },
57
160
  };
58
161
 
@@ -61,11 +164,19 @@ export const Checked: Story = {
61
164
  args: {
62
165
  label: 'Accept terms and conditions',
63
166
  checked: true,
167
+ onChange: mockOnChange,
168
+ },
169
+ parameters: {
170
+ docs: {
171
+ description: {
172
+ story: 'Checked checkbox state.',
173
+ },
174
+ },
64
175
  },
65
176
  };
66
177
 
67
178
  // Checkbox states
68
- export const States: Story = {
179
+ export const AllStates: Story = {
69
180
  render: (args: any) => (
70
181
  <div className="u-flex u-flex-column u-gap-3">
71
182
  <Checkbox label="Default checkbox" />
@@ -77,12 +188,27 @@ export const States: Story = {
77
188
  <Checkbox label="Indeterminate checkbox" indeterminate />
78
189
  </div>
79
190
  ),
191
+ parameters: {
192
+ docs: {
193
+ description: {
194
+ story: 'Checkbox in all available states.',
195
+ },
196
+ },
197
+ },
80
198
  };
81
199
 
82
200
  // Without label
83
201
  export const WithoutLabel: Story = {
84
202
  args: {
85
203
  'aria-label': 'Checkbox without visible label',
204
+ onChange: mockOnChange,
205
+ },
206
+ parameters: {
207
+ docs: {
208
+ description: {
209
+ story: 'Checkbox without visible label, using aria-label.',
210
+ },
211
+ },
86
212
  },
87
213
  };
88
214
 
@@ -91,6 +217,7 @@ export const Glass: Story = {
91
217
  args: {
92
218
  label: 'Glass Checkbox',
93
219
  glass: true,
220
+ onChange: mockOnChange,
94
221
  },
95
222
  render: (args: any) => (
96
223
  <div
@@ -107,6 +234,13 @@ export const Glass: Story = {
107
234
  <Checkbox {...args} />
108
235
  </div>
109
236
  ),
237
+ parameters: {
238
+ docs: {
239
+ description: {
240
+ story: 'Checkbox with glass morphism effect.',
241
+ },
242
+ },
243
+ },
110
244
  };
111
245
 
112
246
  // Glass with custom settings
@@ -0,0 +1,63 @@
1
+ import { render, screen, fireEvent } from '@testing-library/react';
2
+ import { describe, it, expect, vi } from 'vitest';
3
+ import { axe, toHaveNoViolations } from 'jest-axe';
4
+ import { Checkbox } from './Checkbox';
5
+ import React from 'react';
6
+
7
+ expect.extend(toHaveNoViolations);
8
+
9
+ // Mock AtomixGlass
10
+ vi.mock('../AtomixGlass/AtomixGlass', () => ({
11
+ AtomixGlass: ({ children }: any) => <div>{children}</div>,
12
+ }));
13
+
14
+ describe('Checkbox Component', () => {
15
+ it('renders correctly with label', () => {
16
+ render(<Checkbox label="Accept Terms" />);
17
+ // In current implementation, if no ID is provided, htmlFor is undefined, so label is not associated.
18
+ // screen.getByLabelText might fail or might not find the input.
19
+ // Let's see.
20
+ expect(screen.getByText('Accept Terms')).toBeInTheDocument();
21
+ });
22
+
23
+ it('associates label with input when ID is provided', () => {
24
+ render(<Checkbox label="Subscribe" id="subscribe-check" />);
25
+ expect(screen.getByLabelText('Subscribe')).toBeInTheDocument();
26
+ });
27
+
28
+ it('associates label with input WITHOUT ID', () => {
29
+ // This tests my proposed improvement: wrapping input in label or auto-ID
30
+ render(<Checkbox label="No ID Checkbox" />);
31
+ // If not associated, this throws
32
+ expect(screen.getByLabelText('No ID Checkbox')).toBeInTheDocument();
33
+ });
34
+
35
+ it('handles checked state', () => {
36
+ const handleChange = vi.fn();
37
+ render(<Checkbox checked onChange={handleChange} label="Checked" id="checked-id" />);
38
+ const input = screen.getByLabelText('Checked');
39
+ expect(input).toBeChecked();
40
+
41
+ fireEvent.click(input);
42
+ expect(handleChange).toHaveBeenCalledTimes(1);
43
+ });
44
+
45
+ it('forwards ref', () => {
46
+ const ref = React.createRef<HTMLInputElement>();
47
+ render(<Checkbox ref={ref} label="Ref Checkbox" />);
48
+ expect(ref.current).toBeInstanceOf(HTMLInputElement);
49
+ });
50
+
51
+ it('handles indeterminate state', () => {
52
+ // This might need manual DOM check as indeterminate is a property, not attribute
53
+ const { getByRole } = render(<Checkbox indeterminate label="Indeterminate" id="indet" />);
54
+ const input = getByRole('checkbox') as HTMLInputElement;
55
+ expect(input.indeterminate).toBe(true);
56
+ });
57
+
58
+ it('should have no accessibility violations', async () => {
59
+ const { container } = render(<Checkbox label="Accessible Checkbox" id="a11y-check" />);
60
+ const results = await axe(container);
61
+ expect(results).toHaveNoViolations();
62
+ });
63
+ });