@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
@@ -1,92 +1,136 @@
1
- import React, { memo } from 'react';
1
+ import React, { memo, forwardRef, useRef, useEffect, useImperativeHandle } from 'react';
2
2
  import { CheckboxProps } from '../../lib/types/components';
3
- import { useCheckbox } from '../../lib/composables/useCheckbox';
4
3
  import { AtomixGlass } from '../AtomixGlass/AtomixGlass';
5
4
 
6
- /**
7
- * Checkbox - A component for checkbox inputs
8
- */
9
- export const Checkbox: React.FC<CheckboxProps> = memo(({
10
- label,
11
- checked = false,
12
- onChange,
13
- className = '',
14
- style,
15
- disabled = false,
16
- required = false,
17
- id,
18
- name,
19
- value,
20
- invalid = false,
21
- valid = false,
22
- indeterminate = false,
23
- 'aria-label': ariaLabel,
24
- 'aria-describedby': ariaDescribedBy,
25
- onClick,
26
- glass,
27
- }) => {
28
- const { generateCheckboxClass, checkboxRef } = useCheckbox({
29
- indeterminate,
30
- disabled,
31
- invalid,
32
- valid,
33
- });
5
+ const CHECKBOX_CLASSES = {
6
+ BASE: 'c-checkbox',
7
+ INVALID: 'is-error',
8
+ VALID: 'is-valid',
9
+ DISABLED: 'is-disabled',
10
+ MIXED: 'c-checkbox--mixed',
11
+ };
34
12
 
35
- const checkboxClass = generateCheckboxClass({
36
- className: `${className} ${glass ? 'c-checkbox--glass' : ''}`.trim(),
37
- disabled,
38
- invalid,
39
- valid,
40
- indeterminate,
41
- });
13
+ export const Checkbox = React.memo(
14
+ forwardRef<HTMLInputElement, CheckboxProps>(
15
+ (
16
+ {
17
+ label,
18
+ checked,
19
+ onChange,
20
+ className = '',
21
+ style,
22
+ disabled = false,
23
+ required = false,
24
+ id,
25
+ name,
26
+ value,
27
+ invalid = false,
28
+ valid = false,
29
+ indeterminate = false,
30
+ 'aria-label': ariaLabel,
31
+ 'aria-describedby': ariaDescribedBy,
32
+ onClick,
33
+ glass,
34
+ ...props
35
+ },
36
+ ref
37
+ ) => {
38
+ // Local ref to handle indeterminate state
39
+ const localRef = useRef<HTMLInputElement>(null);
42
40
 
43
- const checkboxContent = (
44
- <div className={checkboxClass} style={style}>
45
- <input
46
- ref={checkboxRef}
47
- type="checkbox"
48
- className="c-checkbox__input"
49
- checked={checked}
50
- onChange={onChange}
51
- onClick={onClick}
52
- disabled={disabled}
53
- required={required}
54
- id={id}
55
- name={name}
56
- value={value}
57
- aria-label={!label ? ariaLabel : undefined}
58
- aria-describedby={ariaDescribedBy}
59
- aria-invalid={invalid}
60
- />
61
- {label && (
62
- <label className="c-checkbox__label" htmlFor={id}>
63
- {label}
64
- </label>
65
- )}
66
- </div>
67
- );
41
+ // Merge refs
42
+ useImperativeHandle(ref, () => localRef.current as HTMLInputElement);
68
43
 
69
- if (glass) {
70
- // Default glass settings for checkboxes
71
- const defaultGlassProps = {
72
- displacementScale: 40,
73
- blurAmount: 1,
74
- saturation: 160,
75
- aberrationIntensity: 0.3,
76
- cornerRadius: 6,
77
- mode: 'shader' as const,
78
- };
44
+ // Handle indeterminate
45
+ useEffect(() => {
46
+ if (localRef.current) {
47
+ localRef.current.indeterminate = Boolean(indeterminate);
48
+ }
49
+ }, [indeterminate]);
79
50
 
80
- const glassProps = glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
51
+ // Generate classes
52
+ let validationClass = '';
53
+ if (invalid) {
54
+ validationClass = CHECKBOX_CLASSES.INVALID;
55
+ } else if (valid) {
56
+ validationClass = CHECKBOX_CLASSES.VALID;
57
+ }
81
58
 
82
- return <AtomixGlass {...glassProps}>{checkboxContent}</AtomixGlass>;
83
- }
59
+ const disabledClass = disabled ? CHECKBOX_CLASSES.DISABLED : '';
60
+ const indeterminateClass = indeterminate ? CHECKBOX_CLASSES.MIXED : '';
61
+ const glassClass = glass ? 'c-checkbox--glass' : '';
84
62
 
85
- return checkboxContent;
86
- });
63
+ const checkboxClass =
64
+ `${CHECKBOX_CLASSES.BASE} ${validationClass} ${disabledClass} ${indeterminateClass} ${glassClass} ${className}`.trim();
87
65
 
88
- export type { CheckboxProps };
66
+ const inputElement = (
67
+ <input
68
+ ref={localRef}
69
+ type="checkbox"
70
+ className="c-checkbox__input"
71
+ checked={checked}
72
+ onChange={onChange}
73
+ onClick={onClick}
74
+ disabled={disabled}
75
+ required={required}
76
+ id={id}
77
+ name={name}
78
+ value={value}
79
+ aria-label={!label ? ariaLabel : undefined}
80
+ aria-describedby={ariaDescribedBy}
81
+ aria-invalid={invalid}
82
+ {...props}
83
+ />
84
+ );
85
+
86
+ let content: React.ReactNode;
87
+
88
+ if (id && label) {
89
+ content = (
90
+ <div className={checkboxClass} style={style}>
91
+ {inputElement}
92
+ <label className="c-checkbox__label" htmlFor={id}>
93
+ {label}
94
+ </label>
95
+ </div>
96
+ );
97
+ } else if (label) {
98
+ // Wrap input in label for accessibility when no ID is provided
99
+ content = (
100
+ <label className={checkboxClass} style={style}>
101
+ {inputElement}
102
+ <span className="c-checkbox__label">{label}</span>
103
+ </label>
104
+ );
105
+ } else {
106
+ // No label
107
+ content = (
108
+ <div className={checkboxClass} style={style}>
109
+ {inputElement}
110
+ </div>
111
+ );
112
+ }
113
+
114
+ if (glass) {
115
+ const defaultGlassProps = {
116
+ displacementScale: 40,
117
+ blurAmount: 1,
118
+ saturation: 160,
119
+ aberrationIntensity: 0.3,
120
+ cornerRadius: 6,
121
+ mode: 'shader' as const,
122
+ };
123
+ const glassProps = glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
124
+ return <AtomixGlass {...glassProps}>{content}</AtomixGlass>;
125
+ }
126
+
127
+ return content;
128
+ }
129
+ )
130
+ );
89
131
 
90
132
  Checkbox.displayName = 'Checkbox';
91
133
 
134
+ export type { CheckboxProps };
135
+
92
136
  export default Checkbox;
@@ -1,4 +1,5 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react';
2
+ import { fn } from '@storybook/test';
2
3
  import { useState } from 'react';
3
4
  import { Checkbox } from './Checkbox';
4
5
  import { Form } from './Form';
@@ -20,8 +21,69 @@ const meta = {
20
21
  layout: 'centered',
21
22
  docs: {
22
23
  description: {
23
- component:
24
- 'The Form component provides a semantic HTML form wrapper with enhanced functionality. It supports form validation, submission handling, and can be disabled as a whole. Forms work seamlessly with FormGroup and all form input components to create complete, accessible form experiences.',
24
+ component: `
25
+ # Form
26
+
27
+ ## Overview
28
+
29
+ Form component provides a semantic HTML form wrapper with enhanced functionality. It supports form validation, submission handling, and can be disabled as a whole. Forms work seamlessly with FormGroup and all form input components to create complete, accessible form experiences.
30
+
31
+ ## Features
32
+
33
+ - Semantic HTML form wrapper
34
+ - Form validation support
35
+ - Submission handling
36
+ - Disabled state
37
+ - Auto-complete control
38
+ - Method selection (GET/POST)
39
+ - Accessible design
40
+ - Responsive behavior
41
+
42
+ ## Accessibility
43
+
44
+ - Screen reader: Form structure and labels announced properly
45
+ - ARIA support: Proper roles and properties for form components
46
+ - Keyboard support: Navigate and submit forms with keyboard
47
+ - Focus management: Maintains focus on interactive elements
48
+
49
+ ## Usage Examples
50
+
51
+ ### Basic Usage
52
+
53
+ \`\`\`tsx
54
+ <Form onSubmit={handleSubmit}>
55
+ <FormGroup label="Name" htmlFor="name">
56
+ <Input id="name" placeholder="Enter your name" />
57
+ </FormGroup>
58
+ <button type="submit">Submit</button>
59
+ </Form>
60
+ \`\`\`
61
+
62
+ ### With Validation
63
+
64
+ \`\`\`tsx
65
+ <Form
66
+ onSubmit={handleSubmit}
67
+ noValidate={false}
68
+ autoComplete="on"
69
+ >
70
+ {/* Form fields */}
71
+ </Form>
72
+ \`\`\`
73
+
74
+ ## API Reference
75
+
76
+ ### Props
77
+
78
+ | Prop | Type | Default | Description |
79
+ | ---- | ---- | ------- | ----------- |
80
+ | disabled | boolean | false | Whether the form is disabled |
81
+ | method | 'get' \\| 'post' | 'get' | Form submission method |
82
+ | noValidate | boolean | false | Whether to disable browser validation |
83
+ | autoComplete | string | 'on' | Form autocomplete setting |
84
+ | className | string | - | Additional CSS class names |
85
+ | onSubmit | (event: FormEvent) => void | - | Callback when form is submitted |
86
+ `,
25
87
  },
26
88
  },
27
89
  },
@@ -30,23 +92,47 @@ const meta = {
30
92
  disabled: {
31
93
  control: 'boolean',
32
94
  description: 'Whether the form is disabled',
95
+ table: {
96
+ type: { summary: 'boolean' },
97
+ defaultValue: { summary: false },
98
+ },
33
99
  },
34
100
  className: {
35
101
  control: 'text',
36
102
  description: 'Additional CSS class names',
103
+ table: {
104
+ type: { summary: 'string' },
105
+ defaultValue: { summary: '-' },
106
+ },
37
107
  },
38
108
  method: {
39
109
  control: { type: 'select' },
40
110
  options: ['get', 'post'],
41
111
  description: 'Form submission method',
112
+ table: {
113
+ type: { summary: '"get" | "post"' },
114
+ defaultValue: { summary: 'get' },
115
+ },
42
116
  },
43
117
  noValidate: {
44
118
  control: 'boolean',
45
119
  description: 'Whether to disable browser validation',
120
+ table: {
121
+ type: { summary: 'boolean' },
122
+ defaultValue: { summary: false },
123
+ },
46
124
  },
47
125
  autoComplete: {
48
126
  control: 'text',
49
127
  description: 'Form autocomplete setting',
128
+ table: {
129
+ type: { summary: 'string' },
130
+ defaultValue: { summary: 'on' },
131
+ },
132
+ },
133
+ onSubmit: {
134
+ action: 'submitted',
135
+ description: 'Callback when form is submitted',
50
136
  },
51
137
  },
52
138
  } satisfies Meta<FormWithOptionalChildren>;
@@ -55,10 +141,10 @@ export default meta;
55
141
  type Story = StoryObj<typeof meta>;
56
142
 
57
143
  // Basic form
58
- export const Basic: Story = {
144
+ export const BasicUsage: Story = {
59
145
  args: { children: undefined },
60
146
  render: args => (
61
- <Form {...args}>
147
+ <Form {...args} onSubmit={fn()}>
62
148
  <FormGroup label="Name" htmlFor="name">
63
149
  <Input id="name" placeholder="Enter your name" />
64
150
  </FormGroup>
@@ -70,6 +156,13 @@ export const Basic: Story = {
70
156
  </button>
71
157
  </Form>
72
158
  ),
159
+ parameters: {
160
+ docs: {
161
+ description: {
162
+ story: 'Basic form with name and email fields.',
163
+ },
164
+ },
165
+ },
73
166
  };
74
167
 
75
168
  // Complete form with all input types
@@ -77,7 +170,7 @@ export const CompleteForm: Story = {
77
170
  args: { children: undefined },
78
171
  render: () => (
79
172
  <div style={{ width: '500px' }}>
80
- <Form>
173
+ <Form onSubmit={fn()}>
81
174
  <h2 className="u-mb-4">Registration Form</h2>
82
175
 
83
176
  <FormGroup label="Full Name" htmlFor="fullName" required>
@@ -109,42 +202,40 @@ export const CompleteForm: Story = {
109
202
  id="country"
110
203
  name="country"
111
204
  options={[
205
+ { value: '', label: 'Select a country' },
112
206
  { value: 'us', label: 'United States' },
113
207
  { value: 'ca', label: 'Canada' },
114
- { value: 'mx', label: 'Mexico' },
115
208
  { value: 'uk', label: 'United Kingdom' },
116
209
  ]}
117
- placeholder="Select your country"
118
210
  />
119
211
  </FormGroup>
120
212
 
121
- <FormGroup label="About yourself" htmlFor="bio">
213
+ <FormGroup label="Bio" htmlFor="bio">
122
214
  <Textarea id="bio" name="bio" placeholder="Tell us about yourself" rows={4} />
123
215
  </FormGroup>
124
216
 
125
- <FormGroup>
126
- <Checkbox id="terms" name="terms" label="I agree to the Terms and Conditions" required />
127
- </FormGroup>
128
-
129
- <FormGroup label="Preferred contact method">
130
- <div className="u-flex u-flex-column u-gap-2">
131
- <Radio id="contact-email" name="contactMethod" value="email" label="Email" checked />
132
- <Radio id="contact-phone" name="contactMethod" value="phone" label="Phone" />
133
- <Radio id="contact-mail" name="contactMethod" value="mail" label="Mail" />
134
- </div>
217
+ <FormGroup label="Subscribe to newsletter">
218
+ <Checkbox name="newsletter" label="Yes, I would like to receive updates" />
135
219
  </FormGroup>
136
220
 
137
221
  <div className="u-flex u-gap-3 u-mt-4">
138
222
  <button type="submit" className="c-btn c-btn--primary">
139
223
  Register
140
224
  </button>
141
- <button type="reset" className="c-btn c-btn--outline-secondary">
225
+ <button type="reset" className="c-btn c-btn--secondary">
142
226
  Reset
143
227
  </button>
144
228
  </div>
145
229
  </Form>
146
230
  </div>
147
231
  ),
232
+ parameters: {
233
+ docs: {
234
+ description: {
235
+ story: 'Complete registration form with various input types.',
236
+ },
237
+ },
238
+ },
148
239
  };
149
240
 
150
241
  // Interactive form
@@ -1,4 +1,5 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react';
2
+ import { fn } from '@storybook/test';
2
3
  import { Checkbox } from './Checkbox';
3
4
  import { FormGroup } from './FormGroup';
4
5
  import { Input } from './Input';
@@ -14,8 +15,73 @@ const meta = {
14
15
  layout: 'centered',
15
16
  docs: {
16
17
  description: {
17
- component:
18
- 'The FormGroup component provides a structured wrapper for form fields, including labels, inputs, helper text, and error messages. It ensures proper accessibility, consistent spacing, and validation state display. FormGroups are essential for creating well-organized and accessible forms.',
18
+ component: `
19
+ # FormGroup
20
+
21
+ ## Overview
22
+
23
+ FormGroup component provides a structured wrapper for form fields, including labels, inputs, helper text, and error messages. It ensures proper accessibility, consistent spacing, and validation state display. FormGroups are essential for creating well-organized and accessible forms.
24
+
25
+ ## Features
26
+
27
+ - Structured form field wrapper
28
+ - Label support
29
+ - Helper text display
30
+ - Validation states (valid/invalid)
31
+ - Required field indicator
32
+ - Consistent spacing
33
+ - Accessible design
34
+ - Responsive behavior
35
+
36
+ ## Accessibility
37
+
38
+ - Screen reader: Labels and form controls announced properly
39
+ - ARIA support: Proper associations between labels and controls
40
+ - Keyboard support: Navigate form with keyboard
41
+ - Focus management: Maintains focus on interactive elements
42
+
43
+ ## Usage Examples
44
+
45
+ ### Basic Usage
46
+
47
+ \`\`\`tsx
48
+ <FormGroup
49
+ label="Field Label"
50
+ htmlFor="fieldId"
51
+ helperText="Helper text"
52
+ >
53
+ <Input id="fieldId" placeholder="Placeholder" />
54
+ </FormGroup>
55
+ \`\`\`
56
+
57
+ ### With Validation
58
+
59
+ \`\`\`tsx
60
+ <FormGroup
61
+ label="Field Label"
62
+ htmlFor="fieldId"
63
+ required={true}
64
+ valid={isValid}
65
+ >
66
+ <Input id="fieldId" placeholder="Placeholder" />
67
+ </FormGroup>
68
+ \`\`\`
69
+
70
+ ## API Reference
71
+
72
+ ### Props
73
+
74
+ | Prop | Type | Default | Description |
75
+ | ---- | ---- | ------- | ----------- |
76
+ | label | string | - | Label for the form group |
77
+ | helperText | string | - | Helper text displayed below the input |
78
+ | htmlFor | string | - | ID of the form control this label is for |
79
+ | required | boolean | false | Whether the field is required |
80
+ | invalid | boolean | false | Whether the field is invalid |
81
+ | valid | boolean | false | Whether the field is valid |
82
+ | size | 'sm' \\| 'md' \\| 'lg' | 'md' | Size variant |
83
+ | children | ReactNode | - | Form control element to wrap |
84
+ `,
19
85
  },
20
86
  },
21
87
  },
@@ -24,31 +90,67 @@ const meta = {
24
90
  label: {
25
91
  control: 'text',
26
92
  description: 'Label for the form group',
93
+ table: {
94
+ type: { summary: 'string' },
95
+ defaultValue: { summary: '-' },
96
+ },
27
97
  },
28
98
  helperText: {
29
99
  control: 'text',
30
100
  description: 'Helper text displayed below the input',
101
+ table: {
102
+ type: { summary: 'string' },
103
+ defaultValue: { summary: '-' },
104
+ },
31
105
  },
32
106
  htmlFor: {
33
107
  control: 'text',
34
108
  description: 'ID of the form control this label is for',
109
+ table: {
110
+ type: { summary: 'string' },
111
+ defaultValue: { summary: '-' },
112
+ },
35
113
  },
36
114
  required: {
37
115
  control: 'boolean',
38
116
  description: 'Whether the field is required',
117
+ table: {
118
+ type: { summary: 'boolean' },
119
+ defaultValue: { summary: false },
120
+ },
39
121
  },
40
122
  invalid: {
41
123
  control: 'boolean',
42
124
  description: 'Whether the field is invalid',
125
+ table: {
126
+ type: { summary: 'boolean' },
127
+ defaultValue: { summary: false },
128
+ },
43
129
  },
44
130
  valid: {
45
131
  control: 'boolean',
46
132
  description: 'Whether the field is valid',
133
+ table: {
134
+ type: { summary: 'boolean' },
135
+ defaultValue: { summary: false },
136
+ },
47
137
  },
48
138
  size: {
49
139
  control: { type: 'select' },
50
140
  options: SIZES,
51
141
  description: 'Size variant',
142
+ table: {
143
+ type: { summary: '"sm" | "md" | "lg"' },
144
+ defaultValue: { summary: 'md' },
145
+ },
146
+ },
147
+ children: {
148
+ control: 'object',
149
+ description: 'Form control element to wrap',
150
+ table: {
151
+ type: { summary: 'ReactNode' },
152
+ defaultValue: { summary: '-' },
153
+ },
52
154
  },
53
155
  },
54
156
  } satisfies Meta<typeof FormGroup>;
@@ -57,7 +159,7 @@ export default meta;
57
159
  type Story = StoryObj<typeof meta>;
58
160
 
59
161
  // Basic form group with text
60
- export const Basic: Story = {
162
+ export const BasicUsage: Story = {
61
163
  args: {
62
164
  label: 'Username',
63
165
  htmlFor: 'username',
@@ -65,6 +167,13 @@ export const Basic: Story = {
65
167
  required: true,
66
168
  children: <Input id="username" placeholder="Enter username" />,
67
169
  },
170
+ parameters: {
171
+ docs: {
172
+ description: {
173
+ story: 'Basic form group with label, helper text and required indicator.',
174
+ },
175
+ },
176
+ },
68
177
  };
69
178
 
70
179
  // Required field
@@ -76,6 +185,13 @@ export const Required: Story = {
76
185
  helperText: 'We will never share your email',
77
186
  children: <Input id="email" type="email" placeholder="name@example.com" required />,
78
187
  },
188
+ parameters: {
189
+ docs: {
190
+ description: {
191
+ story: 'Form group with required field indicator.',
192
+ },
193
+ },
194
+ },
79
195
  };
80
196
 
81
197
  // With validation states
@@ -99,10 +215,17 @@ export const ValidationStates: Story = {
99
215
  helperText="Password must be at least 8 characters"
100
216
  invalid
101
217
  >
102
- <Input id="password" type="password" value="1234" invalid />
218
+ <Input id="password" type="password" value="123" invalid />
103
219
  </FormGroup>
104
220
  </div>
105
221
  ),
222
+ parameters: {
223
+ docs: {
224
+ description: {
225
+ story: 'Form group with different validation states.',
226
+ },
227
+ },
228
+ },
106
229
  };
107
230
 
108
231
  // Different form control types