@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,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 type { AtomixGlassProps } from '../../lib/types/components';
4
5
  import Modal from './Modal';
@@ -13,8 +14,75 @@ const meta = {
13
14
  layout: 'centered',
14
15
  docs: {
15
16
  description: {
16
- component:
17
- 'The Modal component displays content in a focused overlay dialog. It provides a way to present important information or actions that require user attention. Modals support various sizes, can include headers and footers, and support glass morphism effects.',
17
+ component: `
18
+ # Modal
19
+
20
+ ## Overview
21
+
22
+ Modal displays content in a focused overlay dialog. It provides a way to present important information or actions that require user attention. Modals support various sizes, can include headers and footers, and support glass morphism effects.
23
+
24
+ ## Features
25
+
26
+ - Multiple size options (sm, md, lg, xl)
27
+ - Backdrop click to close
28
+ - Keyboard (Escape) to close
29
+ - Close button visibility control
30
+ - Glass morphism effect
31
+ - Header and footer sections
32
+ - Accessible design
33
+ - Responsive behavior
34
+
35
+ ## Accessibility
36
+
37
+ - Keyboard support: Close with Escape key, tab navigation within modal
38
+ - Screen reader: Modal content and purpose announced properly
39
+ - ARIA support: Proper roles and properties for modal dialogs
40
+ - Focus management: Traps focus within the modal during open state
41
+
42
+ ## Usage Examples
43
+
44
+ ### Basic Usage
45
+
46
+ \`\`\`tsx
47
+ <Modal
48
+ isOpen={isOpen}
49
+ onOpenChange={setIsOpen}
50
+ title="Modal Title"
51
+ >
52
+ <p>Modal content goes here</p>
53
+ </Modal>
54
+ \`\`\`
55
+
56
+ ### With Glass Effect
57
+
58
+ \`\`\`tsx
59
+ <Modal
60
+ isOpen={isOpen}
61
+ onOpenChange={setIsOpen}
62
+ title="Modal Title"
63
+ glass={true}
64
+ >
65
+ <p>Modal content goes here</p>
66
+ </Modal>
67
+ \`\`\`
68
+
69
+ ## API Reference
70
+
71
+ ### Props
72
+
73
+ | Prop | Type | Default | Description |
74
+ | ---- | ---- | ------- | ----------- |
75
+ | size | 'sm' \\| 'md' \\| 'lg' \\| 'xl' | 'md' | Size of the modal |
76
+ | backdrop | boolean | true | Whether clicking the backdrop closes the modal |
77
+ | keyboard | boolean | true | Whether pressing Escape key closes the modal |
78
+ | closeButton | boolean | true | Whether to show the close button |
79
+ | glass | boolean \\| GlassProps | false | Enable glass morphism effect |
80
+ | title | string | - | Title of the modal |
81
+ | subtitle | string | - | Subtitle of the modal |
82
+ | isOpen | boolean | false | Whether the modal is open |
83
+ | onOpenChange | (open: boolean) => void | - | Callback when open state changes |
84
+ | children | ReactNode | - | Content of the modal |
85
+ `,
18
86
  },
19
87
  },
20
88
  },
@@ -24,26 +92,70 @@ const meta = {
24
92
  control: { type: 'select' },
25
93
  options: ['sm', 'md', 'lg', 'xl'],
26
94
  description: 'Size of the modal',
27
- defaultValue: 'md',
95
+ table: {
96
+ type: { summary: '"sm" | "md" | "lg" | "xl"' },
97
+ defaultValue: { summary: 'md' },
98
+ },
28
99
  },
29
100
  backdrop: {
30
101
  control: 'boolean',
31
102
  description: 'Whether clicking the backdrop closes the modal',
32
- defaultValue: true,
103
+ table: {
104
+ type: { summary: 'boolean' },
105
+ defaultValue: { summary: true },
106
+ },
33
107
  },
34
108
  keyboard: {
35
109
  control: 'boolean',
36
110
  description: 'Whether pressing Escape key closes the modal',
37
- defaultValue: true,
111
+ table: {
112
+ type: { summary: 'boolean' },
113
+ defaultValue: { summary: true },
114
+ },
38
115
  },
39
116
  closeButton: {
40
117
  control: 'boolean',
41
118
  description: 'Whether to show the close button',
42
- defaultValue: true,
119
+ table: {
120
+ type: { summary: 'boolean' },
121
+ defaultValue: { summary: true },
122
+ },
43
123
  },
44
124
  glass: {
45
125
  control: 'boolean',
46
126
  description: 'Enable glass morphism effect',
127
+ table: {
128
+ type: { summary: 'boolean | GlassProps' },
129
+ defaultValue: { summary: false },
130
+ },
131
+ },
132
+ title: {
133
+ control: 'text',
134
+ description: 'Title of the modal',
135
+ table: {
136
+ type: { summary: 'string' },
137
+ defaultValue: { summary: '-' },
138
+ },
139
+ },
140
+ subtitle: {
141
+ control: 'text',
142
+ description: 'Subtitle of the modal',
143
+ table: {
144
+ type: { summary: 'string' },
145
+ defaultValue: { summary: '-' },
146
+ },
147
+ },
148
+ isOpen: {
149
+ control: 'boolean',
150
+ description: 'Whether the modal is open',
151
+ table: {
152
+ type: { summary: 'boolean' },
153
+ defaultValue: { summary: false },
154
+ },
155
+ },
156
+ onOpenChange: {
157
+ action: 'open state changed',
158
+ description: 'Callback when open state changes',
47
159
  },
48
160
  },
49
161
  } satisfies Meta<typeof Modal>;
@@ -51,10 +163,7 @@ const meta = {
51
163
  export default meta;
52
164
  type Story = StoryObj<typeof meta>;
53
165
 
54
- /**
55
- * Basic modal example with a button to trigger opening.
56
- */
57
- export const Basic: Story = {
166
+ export const BasicUsage: Story = {
58
167
  render: args => {
59
168
  const [isOpen, setIsOpen] = useState(false);
60
169
 
@@ -85,11 +194,15 @@ export const Basic: Story = {
85
194
  </>
86
195
  );
87
196
  },
197
+ parameters: {
198
+ docs: {
199
+ description: {
200
+ story: 'Basic modal example with a button to trigger opening.',
201
+ },
202
+ },
203
+ },
88
204
  };
89
205
 
90
- /**
91
- * Modal with a title, subtitle, and footer actions.
92
- */
93
206
  export const WithFooter: Story = {
94
207
  render: args => {
95
208
  const [isOpen, setIsOpen] = useState(false);
@@ -109,40 +222,66 @@ export const WithFooter: Story = {
109
222
  isOpen={isOpen}
110
223
  onOpenChange={setIsOpen}
111
224
  title="Modal with Footer"
112
- subtitle="This is some description text. This text is only a placeholder and should be replaced with the actual content of the modal."
113
- footer={
114
- <>
115
- <div
116
- className="c-btn c-btn--outline-secondary"
117
- onClick={() => setIsOpen(false)}
118
- style={{
119
- cursor: 'pointer',
120
- padding: '8px 16px',
121
- display: 'inline-block',
122
- marginRight: '8px',
123
- }}
124
- >
125
- Cancel
126
- </div>
127
- <div
128
- className="c-btn c-btn--primary"
129
- onClick={() => {
130
- alert('Action confirmed!');
131
- setIsOpen(false);
132
- }}
133
- style={{ cursor: 'pointer', padding: '8px 16px', display: 'inline-block' }}
134
- >
135
- Confirm
136
- </div>
137
- </>
138
- }
225
+ subtitle="This modal includes footer actions for user interaction."
139
226
  >
140
- <p>This modal has a title, subtitle, and footer with action buttons.</p>
141
- <p>The footer is ideal for placing action buttons or other controls.</p>
227
+ <p>
228
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam auctor, odio vitae
229
+ faucibus luctus, elit nisi tincidunt justo, in malesuada enim nisl eget nisl.
230
+ Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis
231
+ egestas.
232
+ </p>
142
233
  </Modal>
143
234
  </>
144
235
  );
145
236
  },
237
+ parameters: {
238
+ docs: {
239
+ description: {
240
+ story: 'Modal with a title, subtitle, and footer actions.',
241
+ },
242
+ },
243
+ },
244
+ };
245
+
246
+ export const WithGlassEffect: Story = {
247
+ render: args => {
248
+ const [isOpen, setIsOpen] = useState(false);
249
+
250
+ return (
251
+ <>
252
+ <div
253
+ className="c-btn c-btn--primary"
254
+ onClick={() => setIsOpen(true)}
255
+ style={{ cursor: 'pointer', padding: '8px 16px', display: 'inline-block' }}
256
+ >
257
+ Open Glass Modal
258
+ </div>
259
+
260
+ <Modal
261
+ {...args}
262
+ isOpen={isOpen}
263
+ onOpenChange={setIsOpen}
264
+ title="Glass Modal"
265
+ subtitle="This modal has a glass morphism effect applied."
266
+ glass={true}
267
+ >
268
+ <p>
269
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam auctor, odio vitae
270
+ faucibus luctus, elit nisi tincidunt justo, in malesuada enim nisl eget nisl.
271
+ Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis
272
+ egestas.
273
+ </p>
274
+ </Modal>
275
+ </>
276
+ );
277
+ },
278
+ parameters: {
279
+ docs: {
280
+ description: {
281
+ story: 'Modal with glass morphism effect applied.',
282
+ },
283
+ },
284
+ },
146
285
  };
147
286
 
148
287
  /**
@@ -510,7 +649,8 @@ export const GlassModalSizes: Story = {
510
649
  The glass effect adapts to different modal sizes while maintaining its visual appeal.
511
650
  </p>
512
651
  <p>
513
- The glass effect enhances the modal's appearance, making it visually appealing and easier to read.
652
+ The glass effect enhances the modal's appearance, making it visually appealing and
653
+ easier to read.
514
654
  </p>
515
655
  </Modal>
516
656
  </div>
@@ -76,144 +76,147 @@ function useModal({
76
76
  /**
77
77
  * Modal component for displaying overlay content
78
78
  */
79
- export const Modal: React.FC<ModalProps> = memo(({
80
- children,
81
- isOpen = false,
82
- onOpenChange,
83
- onClose,
84
- onOpen,
85
- title,
86
- subtitle,
87
- size = 'md',
88
- backdrop = true,
89
- keyboard = true,
90
- className = '',
91
- style,
92
- closeButton = true,
93
- footer,
94
- glass,
95
- ...props
96
- }) => {
97
- const modalRef = useRef<HTMLDivElement>(null);
98
- const dialogRef = useRef<HTMLDivElement>(null);
99
- const backdropRef = useRef<HTMLDivElement>(null);
100
-
101
- const {
102
- isOpen: isOpenState,
103
- open,
104
- close,
105
- } = useModal({
106
- isOpen,
79
+ export const Modal: React.FC<ModalProps> = memo(
80
+ ({
81
+ children,
82
+ isOpen = false,
107
83
  onOpenChange,
108
84
  onClose,
109
85
  onOpen,
110
- });
111
-
112
- // Handle keyboard events for Escape key
113
- useEffect(() => {
114
- if (!keyboard) return undefined;
115
-
116
- const handleKeydown = (event: KeyboardEvent) => {
117
- if (event.key === 'Escape' && isOpenState) {
86
+ title,
87
+ subtitle,
88
+ size = 'md',
89
+ backdrop = true,
90
+ keyboard = true,
91
+ className = '',
92
+ style,
93
+ closeButton = true,
94
+ footer,
95
+ glass,
96
+ ...props
97
+ }) => {
98
+ const modalRef = useRef<HTMLDivElement>(null);
99
+ const dialogRef = useRef<HTMLDivElement>(null);
100
+ const backdropRef = useRef<HTMLDivElement>(null);
101
+
102
+ const {
103
+ isOpen: isOpenState,
104
+ open,
105
+ close,
106
+ } = useModal({
107
+ isOpen,
108
+ onOpenChange,
109
+ onClose,
110
+ onOpen,
111
+ });
112
+
113
+ // Handle keyboard events for Escape key
114
+ useEffect(() => {
115
+ if (!keyboard) return undefined;
116
+
117
+ const handleKeydown = (event: KeyboardEvent) => {
118
+ if (event.key === 'Escape' && isOpenState) {
119
+ close();
120
+ }
121
+ };
122
+
123
+ document.addEventListener('keydown', handleKeydown);
124
+ return () => {
125
+ document.removeEventListener('keydown', handleKeydown);
126
+ };
127
+ }, [isOpenState, close, keyboard]);
128
+
129
+ // Handle backdrop click
130
+ const handleBackdropClick = (event: React.MouseEvent<HTMLDivElement>) => {
131
+ if (backdrop && event.target === event.currentTarget) {
118
132
  close();
119
133
  }
120
134
  };
121
135
 
122
- document.addEventListener('keydown', handleKeydown);
123
- return () => {
124
- document.removeEventListener('keydown', handleKeydown);
125
- };
126
- }, [isOpenState, close, keyboard]);
127
-
128
- // Handle backdrop click
129
- const handleBackdropClick = (event: React.MouseEvent<HTMLDivElement>) => {
130
- if (backdrop && event.target === event.currentTarget) {
131
- close();
132
- }
133
- };
134
-
135
- // Assemble classes
136
- const modalClasses = [
137
- 'c-modal',
138
- isOpenState ? MODAL.CLASSES.IS_OPEN : '',
139
- size ? `c-modal--${size}` : '',
140
- glass ? 'c-modal--glass' : '',
141
- className,
142
- ]
143
- .filter(Boolean)
144
- .join(' ');
145
-
146
- const modalContent = (
147
- <div className="c-modal__content">
148
- {(title || closeButton) && (
149
- <div className="c-modal__header">
150
- <div className="c-modal__header-content">
151
- {title && <h3 className="c-modal__title">{title}</h3>}
152
- {subtitle && <p className="c-modal__sub">{subtitle}</p>}
153
- </div>
154
- {closeButton && (
155
- <button
156
- type="button"
157
- className="c-modal__close c-btn js-modal-close"
158
- onClick={close}
159
- aria-label="Close modal"
160
- >
161
- <svg
162
- width="20"
163
- height="20"
164
- viewBox="0 0 20 20"
165
- fill="none"
166
- xmlns="http://www.w3.org/2000/svg"
136
+ // Assemble classes
137
+ const modalClasses = [
138
+ 'c-modal',
139
+ isOpenState ? MODAL.CLASSES.IS_OPEN : '',
140
+ size ? `c-modal--${size}` : '',
141
+ glass ? 'c-modal--glass' : '',
142
+ className,
143
+ ]
144
+ .filter(Boolean)
145
+ .join(' ');
146
+
147
+ const modalContent = (
148
+ <div className="c-modal__content">
149
+ {(title || closeButton) && (
150
+ <div className="c-modal__header">
151
+ <div className="c-modal__header-content">
152
+ {title && <h3 className="c-modal__title">{title}</h3>}
153
+ {subtitle && <p className="c-modal__sub">{subtitle}</p>}
154
+ </div>
155
+ {closeButton && (
156
+ <button
157
+ type="button"
158
+ className="c-modal__close c-btn js-modal-close"
159
+ onClick={close}
160
+ aria-label="Close modal"
167
161
  >
168
- <path
169
- d="M16.0672 15.1828C16.1253 15.2409 16.1713 15.3098 16.2028 15.3857C16.2342 15.4615 16.2504 15.5429 16.2504 15.625C16.2504 15.7071 16.2342 15.7884 16.2028 15.8643C16.1713 15.9402 16.1253 16.0091 16.0672 16.0672C16.0091 16.1252 15.9402 16.1713 15.8643 16.2027C15.7885 16.2342 15.7071 16.2503 15.625 16.2503C15.5429 16.2503 15.4616 16.2342 15.3857 16.2027C15.3098 16.1713 15.2409 16.1252 15.1828 16.0672L10 10.8836L4.8172 16.0672C4.69992 16.1844 4.54086 16.2503 4.37501 16.2503C4.20916 16.2503 4.0501 16.1844 3.93282 16.0672C3.81555 15.9499 3.74966 15.7908 3.74966 15.625C3.74966 15.4591 3.81555 15.3001 3.93282 15.1828L9.11642 9.99998L3.93282 4.81717C3.81555 4.69989 3.74966 4.54083 3.74966 4.37498C3.74966 4.20913 3.81555 4.05007 3.93282 3.93279C4.0501 3.81552 4.20916 3.74963 4.37501 3.74963C4.54086 3.74963 4.69992 3.81552 4.8172 3.93279L10 9.11639L15.1828 3.93279C15.3001 3.81552 15.4592 3.74963 15.625 3.74963C15.7909 3.74963 15.9499 3.81552 16.0672 3.93279C16.1845 4.05007 16.2504 4.20913 16.2504 4.37498C16.2504 4.54083 16.1845 4.69989 16.0672 4.81717L10.8836 9.99998L16.0672 15.1828Z"
170
- fill="#141414"
171
- />
172
- </svg>
173
- </button>
174
- )}
175
- </div>
176
- )}
177
-
178
- <div className="c-modal__body">{children}</div>
162
+ <svg
163
+ width="20"
164
+ height="20"
165
+ viewBox="0 0 20 20"
166
+ fill="none"
167
+ xmlns="http://www.w3.org/2000/svg"
168
+ >
169
+ <path
170
+ d="M16.0672 15.1828C16.1253 15.2409 16.1713 15.3098 16.2028 15.3857C16.2342 15.4615 16.2504 15.5429 16.2504 15.625C16.2504 15.7071 16.2342 15.7884 16.2028 15.8643C16.1713 15.9402 16.1253 16.0091 16.0672 16.0672C16.0091 16.1252 15.9402 16.1713 15.8643 16.2027C15.7885 16.2342 15.7071 16.2503 15.625 16.2503C15.5429 16.2503 15.4616 16.2342 15.3857 16.2027C15.3098 16.1713 15.2409 16.1252 15.1828 16.0672L10 10.8836L4.8172 16.0672C4.69992 16.1844 4.54086 16.2503 4.37501 16.2503C4.20916 16.2503 4.0501 16.1844 3.93282 16.0672C3.81555 15.9499 3.74966 15.7908 3.74966 15.625C3.74966 15.4591 3.81555 15.3001 3.93282 15.1828L9.11642 9.99998L3.93282 4.81717C3.81555 4.69989 3.74966 4.54083 3.74966 4.37498C3.74966 4.20913 3.81555 4.05007 3.93282 3.93279C4.0501 3.81552 4.20916 3.74963 4.37501 3.74963C4.54086 3.74963 4.69992 3.81552 4.8172 3.93279L10 9.11639L15.1828 3.93279C15.3001 3.81552 15.4592 3.74963 15.625 3.74963C15.7909 3.74963 15.9499 3.81552 16.0672 3.93279C16.1845 4.05007 16.2504 4.20913 16.2504 4.37498C16.2504 4.54083 16.1845 4.69989 16.0672 4.81717L10.8836 9.99998L16.0672 15.1828Z"
171
+ fill="#141414"
172
+ />
173
+ </svg>
174
+ </button>
175
+ )}
176
+ </div>
177
+ )}
179
178
 
180
- {footer && <div className="c-modal__footer">{footer}</div>}
181
- </div>
182
- );
179
+ <div className="c-modal__body">{children}</div>
183
180
 
184
- return (
185
- <div
186
- ref={modalRef}
187
- className={modalClasses}
188
- style={{ display: isOpenState ? 'block' : 'none', ...style }}
189
- role="dialog"
190
- aria-modal="true"
191
- aria-hidden={!isOpenState}
192
- {...props}
193
- >
194
- <div ref={backdropRef} className="c-modal__backdrop" onClick={handleBackdropClick} />
195
- <div ref={dialogRef} className="c-modal__dialog">
196
- {glass
197
- ? // Default glass settings for modals
198
- (() => {
199
- const defaultGlassProps = {
200
- displacementScale: document.querySelector('.c-modal---glass .c-modal__content')?.clientHeight,
201
- blurAmount: 2.2,
202
- elasticity: 0,
203
- mode: 'shader' as const,
204
- shaderMode: 'premiumGlass'
205
- };
206
-
207
- const glassProps =
208
- glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
209
-
210
- return <AtomixGlass {...glassProps}>{modalContent}</AtomixGlass>;
211
- })()
212
- : modalContent}
181
+ {footer && <div className="c-modal__footer">{footer}</div>}
213
182
  </div>
214
- </div>
215
- );
216
- });
183
+ );
184
+
185
+ return (
186
+ <div
187
+ ref={modalRef}
188
+ className={modalClasses}
189
+ style={{ display: isOpenState ? 'block' : 'none', ...style }}
190
+ role="dialog"
191
+ aria-modal="true"
192
+ aria-hidden={!isOpenState}
193
+ {...props}
194
+ >
195
+ <div ref={backdropRef} className="c-modal__backdrop" onClick={handleBackdropClick} />
196
+ <div ref={dialogRef} className="c-modal__dialog">
197
+ {glass
198
+ ? // Default glass settings for modals
199
+ (() => {
200
+ const defaultGlassProps = {
201
+ displacementScale: document.querySelector('.c-modal---glass .c-modal__content')
202
+ ?.clientHeight,
203
+ blurAmount: 2.2,
204
+ elasticity: 0,
205
+ mode: 'shader' as const,
206
+ shaderMode: 'premiumGlass',
207
+ };
208
+
209
+ const glassProps =
210
+ glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
211
+
212
+ return <AtomixGlass {...glassProps}>{modalContent}</AtomixGlass>;
213
+ })()
214
+ : modalContent}
215
+ </div>
216
+ </div>
217
+ );
218
+ }
219
+ );
217
220
 
218
221
  Modal.displayName = 'Modal';
219
222