@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 { Select } from './Select';
4
5
  import { SIZES } from '../../lib/constants/components';
@@ -10,41 +11,155 @@ const meta = {
10
11
  layout: 'centered',
11
12
  docs: {
12
13
  description: {
13
- component:
14
- 'The Select component provides a dropdown menu for selecting one or more options from a list. It supports single and multiple selection modes, validation states, and can be customized with different sizes. Select components are essential for forms requiring user choice from predefined options.',
14
+ component: `
15
+ # Select
16
+
17
+ ## Overview
18
+
19
+ Select component provides a dropdown menu for selecting one or more options from a list. It supports single and multiple selection modes, validation states, and can be customized with different sizes. Select components are essential for forms requiring user choice from predefined options.
20
+
21
+ ## Features
22
+
23
+ - Single and multiple selection modes
24
+ - Various size options
25
+ - Validation states (valid/invalid)
26
+ - Placeholder support
27
+ - Disabled state
28
+ - Glass morphism effect
29
+ - Accessible design
30
+ - Responsive behavior
31
+
32
+ ## Accessibility
33
+
34
+ - Keyboard support: Navigate and select options with keyboard
35
+ - Screen reader: Options and selection announced properly
36
+ - ARIA support: Proper roles and properties for select components
37
+ - Focus management: Visible focus indicators maintained
38
+
39
+ ## Usage Examples
40
+
41
+ ### Basic Usage
42
+
43
+ \`\`\`tsx
44
+ <Select
45
+ options={[
46
+ { value: 'option1', label: 'Option 1' },
47
+ { value: 'option2', label: 'Option 2' },
48
+ ]}
49
+ placeholder="Select an option"
50
+ onChange={handleChange}
51
+ />
52
+ \`\`\`
53
+
54
+ ### Multiple Selection
55
+
56
+ \`\`\`tsx
57
+ <Select
58
+ options={options}
59
+ multiple={true}
60
+ placeholder="Select options"
61
+ onChange={handleChange}
62
+ />
63
+ \`\`\`
64
+
65
+ ## API Reference
66
+
67
+ ### Props
68
+
69
+ | Prop | Type | Default | Description |
70
+ | ---- | ---- | ------- | ----------- |
71
+ | options | Option[] | [] | Array of options to select from |
72
+ | size | 'sm' \\| 'md' \\| 'lg' | 'md' | Size of the select |
73
+ | disabled | boolean | false | Whether the select is disabled |
74
+ | invalid | boolean | false | Whether the select is invalid |
75
+ | valid | boolean | false | Whether the select is valid |
76
+ | placeholder | string | - | Placeholder text |
77
+ | multiple | boolean | false | Whether multiple options can be selected |
78
+ | glass | boolean | false | Enable glass morphism effect |
79
+ | value | string \\| string[] | - | Selected value(s) |
80
+ | onChange | (event: ChangeEvent) => void | - | Callback when selection changes |
81
+ `,
15
82
  },
16
83
  },
17
84
  },
18
85
  tags: ['autodocs'],
19
86
  argTypes: {
87
+ options: {
88
+ control: 'object',
89
+ description: 'Array of options to select from',
90
+ table: {
91
+ type: { summary: 'Option[]' },
92
+ defaultValue: { summary: '[]' },
93
+ },
94
+ },
20
95
  size: {
21
96
  control: { type: 'select' },
22
97
  options: SIZES,
23
98
  description: 'Size of the select',
99
+ table: {
100
+ type: { summary: '"sm" | "md" | "lg"' },
101
+ defaultValue: { summary: 'md' },
102
+ },
24
103
  },
25
104
  disabled: {
26
105
  control: 'boolean',
27
106
  description: 'Whether the select is disabled',
107
+ table: {
108
+ type: { summary: 'boolean' },
109
+ defaultValue: { summary: false },
110
+ },
28
111
  },
29
112
  invalid: {
30
113
  control: 'boolean',
31
114
  description: 'Whether the select is invalid',
115
+ table: {
116
+ type: { summary: 'boolean' },
117
+ defaultValue: { summary: false },
118
+ },
32
119
  },
33
120
  valid: {
34
121
  control: 'boolean',
35
122
  description: 'Whether the select is valid',
123
+ table: {
124
+ type: { summary: 'boolean' },
125
+ defaultValue: { summary: false },
126
+ },
36
127
  },
37
128
  placeholder: {
38
129
  control: 'text',
39
130
  description: 'Placeholder text',
131
+ table: {
132
+ type: { summary: 'string' },
133
+ defaultValue: { summary: '-' },
134
+ },
40
135
  },
41
136
  multiple: {
42
137
  control: 'boolean',
43
138
  description: 'Whether multiple options can be selected',
139
+ table: {
140
+ type: { summary: 'boolean' },
141
+ defaultValue: { summary: false },
142
+ },
44
143
  },
45
144
  glass: {
46
145
  control: 'boolean',
47
146
  description: 'Enable glass morphism effect',
147
+ table: {
148
+ type: { summary: 'boolean' },
149
+ defaultValue: { summary: false },
150
+ },
151
+ },
152
+ value: {
153
+ control: 'text',
154
+ description: 'Selected value(s)',
155
+ table: {
156
+ type: { summary: 'string | string[]' },
157
+ defaultValue: { summary: '-' },
158
+ },
159
+ },
160
+ onChange: {
161
+ action: 'changed',
162
+ description: 'Callback when selection changes',
48
163
  },
49
164
  },
50
165
  } satisfies Meta<typeof Select>;
@@ -64,11 +179,18 @@ const countries = [
64
179
  ];
65
180
 
66
181
  // Basic select
67
- export const Basic: Story = {
182
+ export const BasicUsage: Story = {
68
183
  args: {
69
184
  options: countries,
70
185
  placeholder: 'Select a country',
71
186
  },
187
+ parameters: {
188
+ docs: {
189
+ description: {
190
+ story: 'Basic select component with placeholder.',
191
+ },
192
+ },
193
+ },
72
194
  };
73
195
 
74
196
  // With selected value
@@ -78,6 +200,13 @@ export const WithValue: Story = {
78
200
  value: 'ca',
79
201
  placeholder: 'Select a country',
80
202
  },
203
+ parameters: {
204
+ docs: {
205
+ description: {
206
+ story: 'Select component with a pre-selected value.',
207
+ },
208
+ },
209
+ },
81
210
  };
82
211
 
83
212
  // Interactive select
@@ -100,14 +229,17 @@ export const Interactive: Story = {
100
229
  value={selectedValue}
101
230
  onChange={handleChange}
102
231
  />
103
- {selectedValue && (
104
- <div className="u-mt-3">
105
- Selected value: <strong>{selectedValue}</strong>
106
- </div>
107
- )}
232
+ <div>Selected: {selectedValue || 'Nothing selected'}</div>
108
233
  </div>
109
234
  );
110
235
  },
236
+ parameters: {
237
+ docs: {
238
+ description: {
239
+ story: 'Interactive select component with state management.',
240
+ },
241
+ },
242
+ },
111
243
  };
112
244
 
113
245
  // Select sizes
@@ -7,204 +7,206 @@ import { AtomixGlass } from '../AtomixGlass/AtomixGlass';
7
7
  /**
8
8
  * Select - A component for dropdown selection
9
9
  */
10
- export const Select: React.FC<SelectProps> = memo(({
11
- options = [],
12
- value,
13
- onChange,
14
- onBlur,
15
- onFocus,
16
- placeholder = 'Select an option',
17
- className = '',
18
- style,
19
- disabled = false,
20
- required = false,
21
- id,
22
- name,
23
- size = 'md',
24
- invalid = false,
25
- valid = false,
26
- multiple = false,
27
- 'aria-label': ariaLabel,
28
- 'aria-describedby': ariaDescribedBy,
29
- glass,
30
- }) => {
31
- const { generateSelectClass } = useSelect({
32
- size,
33
- disabled,
34
- invalid,
35
- valid,
36
- });
37
-
38
- const selectClass = generateSelectClass({
39
- className: `${className} ${glass ? 'c-select--glass' : ''}`.trim(),
40
- size,
41
- disabled,
42
- invalid,
43
- valid,
44
- });
45
-
46
- const [isOpen, setIsOpen] = useState(false);
47
- const [selectedLabel, setSelectedLabel] = useState(placeholder);
48
- const dropdownRef = useRef<HTMLDivElement>(null);
49
- const panelRef = useRef<HTMLDivElement>(null);
50
- const bodyRef = useRef<HTMLDivElement>(null);
51
- const nativeSelectRef = useRef<HTMLSelectElement>(null);
52
-
53
- // Update selected label when value changes
54
- useEffect(() => {
55
- if (value) {
56
- const selectedOption = options.find(opt => opt.value === value);
57
- if (selectedOption) {
58
- setSelectedLabel(selectedOption.label);
10
+ export const Select: React.FC<SelectProps> = memo(
11
+ ({
12
+ options = [],
13
+ value,
14
+ onChange,
15
+ onBlur,
16
+ onFocus,
17
+ placeholder = 'Select an option',
18
+ className = '',
19
+ style,
20
+ disabled = false,
21
+ required = false,
22
+ id,
23
+ name,
24
+ size = 'md',
25
+ invalid = false,
26
+ valid = false,
27
+ multiple = false,
28
+ 'aria-label': ariaLabel,
29
+ 'aria-describedby': ariaDescribedBy,
30
+ glass,
31
+ }) => {
32
+ const { generateSelectClass } = useSelect({
33
+ size,
34
+ disabled,
35
+ invalid,
36
+ valid,
37
+ });
38
+
39
+ const selectClass = generateSelectClass({
40
+ className: `${className} ${glass ? 'c-select--glass' : ''}`.trim(),
41
+ size,
42
+ disabled,
43
+ invalid,
44
+ valid,
45
+ });
46
+
47
+ const [isOpen, setIsOpen] = useState(false);
48
+ const [selectedLabel, setSelectedLabel] = useState(placeholder);
49
+ const dropdownRef = useRef<HTMLDivElement>(null);
50
+ const panelRef = useRef<HTMLDivElement>(null);
51
+ const bodyRef = useRef<HTMLDivElement>(null);
52
+ const nativeSelectRef = useRef<HTMLSelectElement>(null);
53
+
54
+ // Update selected label when value changes
55
+ useEffect(() => {
56
+ if (value) {
57
+ const selectedOption = options.find(opt => opt.value === value);
58
+ if (selectedOption) {
59
+ setSelectedLabel(selectedOption.label);
60
+ }
61
+ } else {
62
+ setSelectedLabel(placeholder);
59
63
  }
60
- } else {
61
- setSelectedLabel(placeholder);
62
- }
63
- }, [value, options, placeholder]);
64
-
65
- // Handle click outside to close dropdown
66
- useEffect(() => {
67
- const handleClickOutside = (event: MouseEvent) => {
68
- if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
69
- setIsOpen(false);
70
- if (bodyRef.current) {
64
+ }, [value, options, placeholder]);
65
+
66
+ // Handle click outside to close dropdown
67
+ useEffect(() => {
68
+ const handleClickOutside = (event: MouseEvent) => {
69
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
70
+ setIsOpen(false);
71
+ if (bodyRef.current) {
72
+ bodyRef.current.style.height = '0px';
73
+ }
74
+ }
75
+ };
76
+
77
+ document.addEventListener('mousedown', handleClickOutside);
78
+ return () => {
79
+ document.removeEventListener('mousedown', handleClickOutside);
80
+ };
81
+ }, []);
82
+
83
+ // Toggle dropdown
84
+ const handleToggle = () => {
85
+ if (!disabled) {
86
+ if (!isOpen && bodyRef.current && panelRef.current) {
87
+ bodyRef.current.style.height = `${panelRef.current.clientHeight}px`;
88
+ } else if (bodyRef.current) {
71
89
  bodyRef.current.style.height = '0px';
72
90
  }
91
+ setIsOpen(!isOpen);
73
92
  }
74
93
  };
75
94
 
76
- document.addEventListener('mousedown', handleClickOutside);
77
- return () => {
78
- document.removeEventListener('mousedown', handleClickOutside);
79
- };
80
- }, []);
81
-
82
- // Toggle dropdown
83
- const handleToggle = () => {
84
- if (!disabled) {
85
- if (!isOpen && bodyRef.current && panelRef.current) {
86
- bodyRef.current.style.height = `${panelRef.current.clientHeight}px`;
87
- } else if (bodyRef.current) {
95
+ // Handle item selection
96
+ const handleItemClick = (option: { value: string; label: string }) => {
97
+ setSelectedLabel(option.label);
98
+ setIsOpen(false);
99
+ if (bodyRef.current) {
88
100
  bodyRef.current.style.height = '0px';
89
101
  }
90
- setIsOpen(!isOpen);
91
- }
92
- };
93
-
94
- // Handle item selection
95
- const handleItemClick = (option: { value: string; label: string }) => {
96
- setSelectedLabel(option.label);
97
- setIsOpen(false);
98
- if (bodyRef.current) {
99
- bodyRef.current.style.height = '0px';
100
- }
101
102
 
102
- if (nativeSelectRef.current) {
103
- nativeSelectRef.current.value = option.value;
104
- }
103
+ if (nativeSelectRef.current) {
104
+ nativeSelectRef.current.value = option.value;
105
+ }
105
106
 
106
- if (onChange) {
107
- // Create a synthetic event
108
- const event = {
109
- target: {
110
- name,
111
- value: option.value,
112
- },
113
- } as React.ChangeEvent<HTMLSelectElement>;
114
- onChange(event);
115
- }
116
- };
117
-
118
- const selectContent = (
119
- <div
120
- className={`${selectClass} ${isOpen ? SELECT.CLASSES.IS_OPEN : ''}`}
121
- ref={dropdownRef}
122
- style={style}
123
- aria-expanded={isOpen}
124
- >
125
- {/* Native select for accessibility and form submission */}
126
- <select
127
- ref={nativeSelectRef}
128
- value={value}
129
- onChange={onChange}
130
- onBlur={onBlur}
131
- onFocus={onFocus}
132
- disabled={disabled}
133
- required={required}
134
- id={id}
135
- name={name}
136
- multiple={multiple}
137
- aria-label={ariaLabel}
138
- aria-describedby={ariaDescribedBy}
139
- aria-invalid={invalid}
140
- style={{ display: 'none' }}
107
+ if (onChange) {
108
+ // Create a synthetic event
109
+ const event = {
110
+ target: {
111
+ name,
112
+ value: option.value,
113
+ },
114
+ } as React.ChangeEvent<HTMLSelectElement>;
115
+ onChange(event);
116
+ }
117
+ };
118
+
119
+ const selectContent = (
120
+ <div
121
+ className={`${selectClass} ${isOpen ? SELECT.CLASSES.IS_OPEN : ''}`}
122
+ ref={dropdownRef}
123
+ style={style}
124
+ aria-expanded={isOpen}
141
125
  >
142
- {placeholder && (
143
- <option value="" disabled>
144
- {placeholder}
145
- </option>
146
- )}
147
- {options.map(option => (
148
- <option key={option.value} value={option.value} disabled={option.disabled}>
149
- {option.label}
150
- </option>
151
- ))}
152
- </select>
153
-
154
- {/* Custom Select UI */}
155
- <div className={SELECT.CLASSES.SELECTED} onClick={handleToggle} aria-disabled={disabled}>
156
- {selectedLabel}
157
- </div>
126
+ {/* Native select for accessibility and form submission */}
127
+ <select
128
+ ref={nativeSelectRef}
129
+ value={value}
130
+ onChange={onChange}
131
+ onBlur={onBlur}
132
+ onFocus={onFocus}
133
+ disabled={disabled}
134
+ required={required}
135
+ id={id}
136
+ name={name}
137
+ multiple={multiple}
138
+ aria-label={ariaLabel}
139
+ aria-describedby={ariaDescribedBy}
140
+ aria-invalid={invalid}
141
+ style={{ display: 'none' }}
142
+ >
143
+ {placeholder && (
144
+ <option value="" disabled>
145
+ {placeholder}
146
+ </option>
147
+ )}
148
+ {options.map(option => (
149
+ <option key={option.value} value={option.value} disabled={option.disabled}>
150
+ {option.label}
151
+ </option>
152
+ ))}
153
+ </select>
154
+
155
+ {/* Custom Select UI */}
156
+ <div className={SELECT.CLASSES.SELECTED} onClick={handleToggle} aria-disabled={disabled}>
157
+ {selectedLabel}
158
+ </div>
158
159
 
159
- <i className={`${SELECT.CLASSES.ICON_CARET} ${SELECT.CLASSES.TOGGLE_ICON}`} />
160
-
161
- <div className={SELECT.CLASSES.SELECT_BODY} ref={bodyRef} style={{ height: 0 }}>
162
- <div className={SELECT.CLASSES.SELECT_PANEL} ref={panelRef}>
163
- <ul className={SELECT.CLASSES.SELECT_ITEMS}>
164
- {options.map((option, index) => (
165
- <li
166
- key={option.value}
167
- className={SELECT.CLASSES.SELECT_ITEM}
168
- data-value={option.value}
169
- onClick={() => !option.disabled && handleItemClick(option)}
170
- >
171
- <label htmlFor={`SelectItem${index}`} className="c-checkbox">
172
- <input
173
- type="checkbox"
174
- id={`SelectItem${index}`}
175
- className="c-checkbox__input c-select__item-input"
176
- checked={value === option.value}
177
- readOnly
178
- disabled={option.disabled}
179
- />
180
- <div className="c-select__item-label">{option.label}</div>
181
- </label>
182
- </li>
183
- ))}
184
- </ul>
160
+ <i className={`${SELECT.CLASSES.ICON_CARET} ${SELECT.CLASSES.TOGGLE_ICON}`} />
161
+
162
+ <div className={SELECT.CLASSES.SELECT_BODY} ref={bodyRef} style={{ height: 0 }}>
163
+ <div className={SELECT.CLASSES.SELECT_PANEL} ref={panelRef}>
164
+ <ul className={SELECT.CLASSES.SELECT_ITEMS}>
165
+ {options.map((option, index) => (
166
+ <li
167
+ key={option.value}
168
+ className={SELECT.CLASSES.SELECT_ITEM}
169
+ data-value={option.value}
170
+ onClick={() => !option.disabled && handleItemClick(option)}
171
+ >
172
+ <label htmlFor={`SelectItem${index}`} className="c-checkbox">
173
+ <input
174
+ type="checkbox"
175
+ id={`SelectItem${index}`}
176
+ className="c-checkbox__input c-select__item-input"
177
+ checked={value === option.value}
178
+ readOnly
179
+ disabled={option.disabled}
180
+ />
181
+ <div className="c-select__item-label">{option.label}</div>
182
+ </label>
183
+ </li>
184
+ ))}
185
+ </ul>
186
+ </div>
185
187
  </div>
186
188
  </div>
187
- </div>
188
- );
189
-
190
- if (glass) {
191
- // Default glass settings for select components
192
- const defaultGlassProps = {
193
- displacementScale: 60,
194
- blurAmount: 1,
195
- saturation: 180,
196
- aberrationIntensity: 0.2,
197
- cornerRadius: 12,
198
- mode: 'shader' as const,
199
- };
200
-
201
- const glassProps = glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
189
+ );
190
+
191
+ if (glass) {
192
+ // Default glass settings for select components
193
+ const defaultGlassProps = {
194
+ displacementScale: 60,
195
+ blurAmount: 1,
196
+ saturation: 180,
197
+ aberrationIntensity: 0.2,
198
+ cornerRadius: 12,
199
+ mode: 'shader' as const,
200
+ };
201
+
202
+ const glassProps = glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
203
+
204
+ return <AtomixGlass {...glassProps}>{selectContent}</AtomixGlass>;
205
+ }
202
206
 
203
- return <AtomixGlass {...glassProps}>{selectContent}</AtomixGlass>;
207
+ return selectContent;
204
208
  }
205
-
206
- return selectContent;
207
- });
209
+ );
208
210
 
209
211
  export type { SelectProps };
210
212