@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,10 +1,4 @@
1
- import React, {
2
- useCallback,
3
- useEffect,
4
- useMemo,
5
- useRef,
6
- useState,
7
- } from 'react';
1
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
8
2
  import type {
9
3
  AtomixGlassProps,
10
4
  DisplacementMode,
@@ -41,10 +35,7 @@ const backgroundDetectionCache = new WeakMap<HTMLElement, BackgroundDetectionCac
41
35
  * Compare two OverLightConfig values for equality
42
36
  * Handles primitives (boolean, 'auto') and objects with deep comparison
43
37
  */
44
- const compareOverLightConfig = (
45
- config1: OverLightConfig,
46
- config2: OverLightConfig
47
- ): boolean => {
38
+ const compareOverLightConfig = (config1: OverLightConfig, config2: OverLightConfig): boolean => {
48
39
  // Primitive comparison for boolean and 'auto'
49
40
  if (typeof config1 !== 'object' || config1 === null) {
50
41
  return config1 === config2;
@@ -235,18 +226,12 @@ export function useAtomixGlass({
235
226
  const effectiveCornerRadius = useMemo(() => {
236
227
  if (cornerRadius !== undefined) {
237
228
  const result = Math.max(0, cornerRadius);
238
- // if (process.env.NODE_ENV !== 'production' && debugCornerRadius) {
239
- // console.log('[AtomixGlass] Using manual cornerRadius prop:', result);
240
- // }
241
229
  return result;
242
230
  }
243
231
 
244
232
  const result = Math.max(0, dynamicCornerRadius);
245
- // if (process.env.NODE_ENV !== 'production' && debugCornerRadius) {
246
- // console.log('[AtomixGlass] Using dynamic cornerRadius:', result);
247
- // }
248
233
  return result;
249
- }, [cornerRadius, dynamicCornerRadius, debugCornerRadius]);
234
+ }, [cornerRadius, dynamicCornerRadius]);
250
235
 
251
236
  const effectiveReducedMotion = useMemo(
252
237
  () => reducedMotion || userPrefersReducedMotion,
@@ -278,7 +263,6 @@ export function useAtomixGlass({
278
263
  const extractRadius = () => {
279
264
  try {
280
265
  let extractedRadius: number | null = null;
281
- let extractionSource = 'default';
282
266
 
283
267
  if (contentRef.current) {
284
268
  const firstChild = contentRef.current.firstElementChild as HTMLElement;
@@ -286,7 +270,6 @@ export function useAtomixGlass({
286
270
  const domRadius = extractBorderRadiusFromDOMElement(firstChild);
287
271
  if (domRadius !== null && domRadius > 0) {
288
272
  extractedRadius = domRadius;
289
- extractionSource = 'DOM element';
290
273
  }
291
274
  }
292
275
  }
@@ -295,28 +278,17 @@ export function useAtomixGlass({
295
278
  const childRadius = extractBorderRadiusFromChildren(children);
296
279
  if (childRadius > 0 && childRadius !== CONSTANTS.DEFAULT_CORNER_RADIUS) {
297
280
  extractedRadius = childRadius;
298
- extractionSource = 'React children';
299
281
  }
300
282
  }
301
283
 
302
284
  if (extractedRadius !== null && extractedRadius > 0) {
303
285
  setDynamicCornerRadius(extractedRadius);
304
-
305
- // if (process.env.NODE_ENV !== 'production' && debugCornerRadius) {
306
- // console.log('[AtomixGlass] Corner radius extracted:', {
307
- // value: extractedRadius,
308
- // source: extractionSource,
309
- // timestamp: new Date().toISOString(),
310
- // });
311
- // }
312
- } else if ((typeof process === 'undefined' || process.env?.NODE_ENV !== 'production') && debugCornerRadius) {
313
- // console.log(
314
- // '[AtomixGlass] No corner radius found, using default:',
315
- // CONSTANTS.DEFAULT_CORNER_RADIUS
316
- // );
317
286
  }
318
287
  } catch (error) {
319
- if ((typeof process === 'undefined' || process.env?.NODE_ENV !== 'production') && debugCornerRadius) {
288
+ if (
289
+ (typeof process === 'undefined' || process.env?.NODE_ENV !== 'production') &&
290
+ debugCornerRadius
291
+ ) {
320
292
  console.error('[AtomixGlass] Error extracting corner radius:', error);
321
293
  }
322
294
  }
@@ -330,7 +302,8 @@ export function useAtomixGlass({
330
302
  // Media query handlers and background detection
331
303
  useEffect(() => {
332
304
  // Only run auto-detection for 'auto' mode or object config (which uses auto-detection)
333
- const shouldDetect = (overLight === 'auto' || (typeof overLight === 'object' && overLight !== null));
305
+ const shouldDetect =
306
+ overLight === 'auto' || (typeof overLight === 'object' && overLight !== null);
334
307
 
335
308
  if (shouldDetect && glassRef.current) {
336
309
  const element = glassRef.current;
@@ -379,7 +352,13 @@ export function useAtomixGlass({
379
352
  const bgImage = computedStyle.backgroundImage;
380
353
 
381
354
  // Check for solid color backgrounds
382
- if (bgColor && bgColor !== 'rgba(0, 0, 0, 0)' && bgColor !== 'transparent' && bgColor !== 'initial' && bgColor !== 'none') {
355
+ if (
356
+ bgColor &&
357
+ bgColor !== 'rgba(0, 0, 0, 0)' &&
358
+ bgColor !== 'transparent' &&
359
+ bgColor !== 'initial' &&
360
+ bgColor !== 'none'
361
+ ) {
383
362
  const rgb = bgColor.match(/\d+/g);
384
363
  if (rgb && rgb.length >= 3) {
385
364
  const r = Number(rgb[0]);
@@ -387,9 +366,20 @@ export function useAtomixGlass({
387
366
  const b = Number(rgb[2]);
388
367
 
389
368
  // Validate RGB values are valid numbers
390
- if (!isNaN(r) && !isNaN(g) && !isNaN(b) &&
391
- isFinite(r) && isFinite(g) && isFinite(b) &&
392
- r >= 0 && r <= 255 && g >= 0 && g <= 255 && b >= 0 && b <= 255) {
369
+ if (
370
+ !isNaN(r) &&
371
+ !isNaN(g) &&
372
+ !isNaN(b) &&
373
+ isFinite(r) &&
374
+ isFinite(g) &&
375
+ isFinite(b) &&
376
+ r >= 0 &&
377
+ r <= 255 &&
378
+ g >= 0 &&
379
+ g <= 255 &&
380
+ b >= 0 &&
381
+ b <= 255
382
+ ) {
393
383
  // Only consider if it's not pure black or very dark
394
384
  if (r > 10 || g > 10 || b > 10) {
395
385
  const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
@@ -436,11 +426,12 @@ export function useAtomixGlass({
436
426
  if (typeof overLight === 'object' && overLight !== null) {
437
427
  const objConfig = overLight as OverLightObjectConfig;
438
428
  if (objConfig.threshold !== undefined) {
439
- const configThreshold = typeof objConfig.threshold === 'number' &&
429
+ const configThreshold =
430
+ typeof objConfig.threshold === 'number' &&
440
431
  !isNaN(objConfig.threshold) &&
441
432
  isFinite(objConfig.threshold)
442
- ? objConfig.threshold
443
- : 0.7;
433
+ ? objConfig.threshold
434
+ : 0.7;
444
435
  threshold = Math.min(0.9, Math.max(0.1, configThreshold));
445
436
  }
446
437
  }
@@ -448,37 +439,31 @@ export function useAtomixGlass({
448
439
  const isOverLightDetected = avgLuminance > threshold;
449
440
 
450
441
  // Cache the result in shared cache
451
- setCachedBackgroundDetection(element.parentElement, overLight, isOverLightDetected, threshold);
442
+ setCachedBackgroundDetection(
443
+ element.parentElement,
444
+ overLight,
445
+ isOverLightDetected,
446
+ threshold
447
+ );
452
448
 
453
449
  setDetectedOverLight(isOverLightDetected);
454
-
455
- // Debug logging
456
- // if (process.env.NODE_ENV !== 'production' && debugOverLight) {
457
- // console.log('[AtomixGlass] OverLight Detection:', {
458
- // avgLuminance: avgLuminance.toFixed(3),
459
- // threshold: threshold.toFixed(3),
460
- // detected: isOverLightDetected,
461
- // validSamples,
462
- // totalLuminance: totalLuminance.toFixed(3),
463
- // configType: typeof overLight === 'object' ? 'object' : typeof overLight,
464
- // timestamp: new Date().toISOString(),
465
- // });
466
- // }
467
450
  } else {
468
451
  // Invalid luminance calculation, default to false
469
452
  const result = false;
470
- const threshold = typeof overLight === 'object' && overLight !== null
471
- ? (overLight as OverLightObjectConfig).threshold || 0.7
472
- : 0.7;
453
+ const threshold =
454
+ typeof overLight === 'object' && overLight !== null
455
+ ? (overLight as OverLightObjectConfig).threshold || 0.7
456
+ : 0.7;
473
457
  setCachedBackgroundDetection(element.parentElement, overLight, result, threshold);
474
458
  setDetectedOverLight(result);
475
459
  }
476
460
  } else {
477
461
  // Default to false if no valid background found
478
462
  const result = false;
479
- const threshold = typeof overLight === 'object' && overLight !== null
480
- ? (overLight as OverLightObjectConfig).threshold || 0.7
481
- : 0.7;
463
+ const threshold =
464
+ typeof overLight === 'object' && overLight !== null
465
+ ? (overLight as OverLightObjectConfig).threshold || 0.7
466
+ : 0.7;
482
467
  setCachedBackgroundDetection(element.parentElement, overLight, result, threshold);
483
468
  setDetectedOverLight(result);
484
469
  }
@@ -489,9 +474,10 @@ export function useAtomixGlass({
489
474
  }
490
475
  const result = false;
491
476
  if (element && element.parentElement) {
492
- const threshold = typeof overLight === 'object' && overLight !== null
493
- ? (overLight as OverLightObjectConfig).threshold || 0.7
494
- : 0.7;
477
+ const threshold =
478
+ typeof overLight === 'object' && overLight !== null
479
+ ? (overLight as OverLightObjectConfig).threshold || 0.7
480
+ : 0.7;
495
481
  setCachedBackgroundDetection(element.parentElement, overLight, result, threshold);
496
482
  }
497
483
  setDetectedOverLight(result);
@@ -501,17 +487,7 @@ export function useAtomixGlass({
501
487
  return () => clearTimeout(timeoutId);
502
488
  } else if (typeof overLight === 'boolean') {
503
489
  // For boolean values, disable auto-detection
504
- // Cache is automatically managed by WeakMap (no manual clearing needed)
505
490
  setDetectedOverLight(false);
506
-
507
- // Debug logging for boolean mode
508
- // if (process.env.NODE_ENV !== 'production' && debugOverLight) {
509
- // console.log('[AtomixGlass] OverLight Mode: boolean', {
510
- // value: overLight,
511
- // autoDetection: false,
512
- // timestamp: new Date().toISOString(),
513
- // });
514
- // }
515
491
  }
516
492
 
517
493
  if (typeof window.matchMedia !== 'function') {
@@ -607,9 +583,12 @@ export function useAtomixGlass({
607
583
  setInternalMouseOffset(newOffset);
608
584
  setInternalGlobalMousePosition(globalPos);
609
585
 
610
- if ((typeof process === 'undefined' || process.env?.NODE_ENV !== 'production') && enablePerformanceMonitoring) {
586
+ if (
587
+ (typeof process === 'undefined' || process.env?.NODE_ENV !== 'production') &&
588
+ enablePerformanceMonitoring
589
+ ) {
611
590
  const endTime = performance.now();
612
- const duration = endTime - startTime;
591
+ // const duration = endTime - startTime;
613
592
  // if (duration > 5) {
614
593
  // console.warn(`AtomixGlass: Mouse tracking took ${duration.toFixed(2)}ms`);
615
594
  // }
@@ -684,6 +663,16 @@ export function useAtomixGlass({
684
663
 
685
664
  // Transform calculations
686
665
  const calculateDirectionalScale = useCallback(() => {
666
+ // Disable directional scaling if overLight is active (to prevent zooming/distorting the premium glass effect)
667
+ const isOverLightActive =
668
+ overLight === true ||
669
+ (overLight === 'auto' && detectedOverLight) ||
670
+ (typeof overLight === 'object' && overLight !== null && detectedOverLight);
671
+
672
+ if (isOverLightActive) {
673
+ return 'scale(1)';
674
+ }
675
+
687
676
  if (
688
677
  !globalMousePosition.x ||
689
678
  !globalMousePosition.y ||
@@ -727,7 +716,7 @@ export function useAtomixGlass({
727
716
  Math.abs(normalizedX) * stretchIntensity * 0.15;
728
717
 
729
718
  return `scaleX(${Math.max(0.8, scaleX)}) scaleY(${Math.max(0.8, scaleY)})`;
730
- }, [globalMousePosition, elasticity, glassSize, glassRef]);
719
+ }, [globalMousePosition, elasticity, glassSize, glassRef, overLight, detectedOverLight]);
731
720
 
732
721
  const calculateFadeInFactor = useCallback(() => {
733
722
  if (
@@ -752,7 +741,9 @@ export function useAtomixGlass({
752
741
  );
753
742
  const edgeDistance = calculateDistance({ x: edgeDistanceX, y: edgeDistanceY }, { x: 0, y: 0 });
754
743
 
755
- return edgeDistance > CONSTANTS.ACTIVATION_ZONE ? 0 : 1 - edgeDistance / CONSTANTS.ACTIVATION_ZONE;
744
+ return edgeDistance > CONSTANTS.ACTIVATION_ZONE
745
+ ? 0
746
+ : 1 - edgeDistance / CONSTANTS.ACTIVATION_ZONE;
756
747
  }, [globalMousePosition, glassSize, glassRef]);
757
748
 
758
749
  const calculateElasticTranslation = useCallback(() => {
@@ -797,7 +788,9 @@ export function useAtomixGlass({
797
788
  element !== null && element instanceof HTMLElement && element.isConnected;
798
789
 
799
790
  const validateSize = (size: GlassSize): boolean =>
800
- validateGlassSize(size) && size.width <= CONSTANTS.MAX_SIZE && size.height <= CONSTANTS.MAX_SIZE;
791
+ validateGlassSize(size) &&
792
+ size.width <= CONSTANTS.MAX_SIZE &&
793
+ size.height <= CONSTANTS.MAX_SIZE;
801
794
 
802
795
  let rafId: number | null = null;
803
796
  let lastSize = { width: 0, height: 0 };
@@ -931,40 +924,65 @@ export function useAtomixGlass({
931
924
  const activeIntensity = isActive ? 1.6 : 1;
932
925
 
933
926
  // More robust overlight configuration with better defaults and clamping
934
- const baseOpacity = isOverLight ? Math.min(0.6, Math.max(0.2, 0.5 * hoverIntensity * activeIntensity)) : 0;
927
+ const baseOpacity = isOverLight
928
+ ? Math.min(0.6, Math.max(0.2, 0.5 * hoverIntensity * activeIntensity))
929
+ : 0;
935
930
 
936
931
  const baseConfig = {
937
932
  isOverLight,
938
933
  threshold: 0.7,
939
934
  opacity: baseOpacity,
940
- contrast: Math.min(1.8, Math.max(1.0, 1.4 + mouseInfluence * 0.3)),
941
- brightness: Math.min(1.2, Math.max(0.7, 0.85 + mouseInfluence * 0.15)),
942
- saturationBoost: Math.min(2.0, Math.max(1.0, 1.3 + mouseInfluence * 0.4)),
943
- shadowIntensity: Math.min(1.5, Math.max(0.5, 0.9 + mouseInfluence * 0.5)),
944
- borderOpacity: Math.min(1.0, Math.max(0.3, 0.7 + mouseInfluence * 0.3)),
935
+ contrast: Math.min(1.6, Math.max(1.0, 1.4 + mouseInfluence * 0.1)),
936
+ brightness: Math.min(1.1, Math.max(0.8, 0.9 + mouseInfluence * 0.05)),
937
+ saturationBoost: 1.3, // Fixed value dynamic saturation amplifies perceived displacement
938
+ shadowIntensity: Math.min(1.2, Math.max(0.5, 0.9 + mouseInfluence * 0.2)),
939
+ borderOpacity: Math.min(1.0, Math.max(0.3, 0.7 + mouseInfluence * 0.1)),
945
940
  };
946
941
 
947
942
  if (typeof overLight === 'object' && overLight !== null) {
948
943
  const objConfig = overLight as OverLightObjectConfig;
949
944
 
950
945
  // Validate and apply object config values with proper clamping
951
- const validatedThreshold = validateConfigValue(objConfig.threshold, 0.1, 1.0, baseConfig.threshold);
946
+ const validatedThreshold = validateConfigValue(
947
+ objConfig.threshold,
948
+ 0.1,
949
+ 1.0,
950
+ baseConfig.threshold
951
+ );
952
952
  const validatedOpacity = validateConfigValue(objConfig.opacity, 0.1, 1.0, baseConfig.opacity);
953
- const validatedContrast = validateConfigValue(objConfig.contrast, 0.5, 2.5, baseConfig.contrast);
954
- const validatedBrightness = validateConfigValue(objConfig.brightness, 0.5, 2.0, baseConfig.brightness);
955
- const validatedSaturationBoost = validateConfigValue(objConfig.saturationBoost, 0.5, 3.0, baseConfig.saturationBoost);
953
+ const validatedContrast = validateConfigValue(
954
+ objConfig.contrast,
955
+ 0.5,
956
+ 2.5,
957
+ baseConfig.contrast
958
+ );
959
+ const validatedBrightness = validateConfigValue(
960
+ objConfig.brightness,
961
+ 0.5,
962
+ 2.0,
963
+ baseConfig.brightness
964
+ );
965
+ const validatedSaturationBoost = validateConfigValue(
966
+ objConfig.saturationBoost,
967
+ 0.5,
968
+ 3.0,
969
+ baseConfig.saturationBoost
970
+ );
956
971
 
957
972
  const finalConfig = {
958
973
  ...baseConfig,
959
974
  threshold: validatedThreshold,
960
975
  opacity: validatedOpacity * hoverIntensity * activeIntensity,
961
- contrast: validatedContrast + mouseInfluence * 0.3,
962
- brightness: validatedBrightness + mouseInfluence * 0.15,
963
- saturationBoost: validatedSaturationBoost + mouseInfluence * 0.4,
976
+ contrast: Math.min(1.6, validatedContrast + mouseInfluence * 0.1),
977
+ brightness: Math.min(1.1, validatedBrightness + mouseInfluence * 0.05),
978
+ saturationBoost: validatedSaturationBoost, // Use validated value directly, no mouse influence
964
979
  };
965
980
 
966
981
  // Debug logging
967
- if ((typeof process === 'undefined' || process.env?.NODE_ENV !== 'production') && debugOverLight) {
982
+ if (
983
+ (typeof process === 'undefined' || process.env?.NODE_ENV !== 'production') &&
984
+ debugOverLight
985
+ ) {
968
986
  console.log('[AtomixGlass] OverLight Config:', {
969
987
  isOverLight,
970
988
  config: {
@@ -996,7 +1014,10 @@ export function useAtomixGlass({
996
1014
  }
997
1015
 
998
1016
  // Debug logging for non-object configs
999
- if ((typeof process === 'undefined' || process.env?.NODE_ENV !== 'production') && debugOverLight) {
1017
+ if (
1018
+ (typeof process === 'undefined' || process.env?.NODE_ENV !== 'production') &&
1019
+ debugOverLight
1020
+ ) {
1000
1021
  console.log('[AtomixGlass] OverLight Config:', {
1001
1022
  isOverLight,
1002
1023
  configType: typeof overLight === 'boolean' ? (overLight ? 'true' : 'false') : overLight,
@@ -1019,7 +1040,15 @@ export function useAtomixGlass({
1019
1040
  }
1020
1041
 
1021
1042
  return baseConfig;
1022
- }, [overLight, getEffectiveOverLight, mouseOffset, isHovered, isActive, validateConfigValue, debugOverLight]);
1043
+ }, [
1044
+ overLight,
1045
+ getEffectiveOverLight,
1046
+ mouseOffset,
1047
+ isHovered,
1048
+ isActive,
1049
+ validateConfigValue,
1050
+ debugOverLight,
1051
+ ]);
1023
1052
 
1024
1053
  // Event handlers
1025
1054
  const handleMouseEnter = useCallback(() => setIsHovered(true), []);
@@ -1,4 +1,5 @@
1
1
  import { useCallback, useRef } from 'react';
2
+ import { sanitizeCSVCell } from '../utils/csv';
2
3
 
3
4
  export interface ExportOptions {
4
5
  /**
@@ -180,13 +181,7 @@ export function useChartExport() {
180
181
 
181
182
  // Convert to CSV string with sanitization
182
183
  const csvContent = rows
183
- .map(row => row.map(cell => {
184
- // Sanitize cell content to prevent CSV injection
185
- const sanitized = String(cell).replace(/[\r\n\t]/g, ' ').replace(/"/g, '""');
186
- // Prevent formula injection by prefixing dangerous characters
187
- const dangerous = /^[=+\-@]/;
188
- return `"${dangerous.test(sanitized) ? `'${sanitized}` : sanitized}"`;
189
- }).join(','))
184
+ .map(row => row.map(cell => `"${sanitizeCSVCell(cell)}"`).join(','))
190
185
  .join('\n');
191
186
 
192
187
  // Download
@@ -330,4 +325,4 @@ export function useChartExport() {
330
325
  exportChart,
331
326
  shareChart,
332
327
  };
333
- }
328
+ }
@@ -274,7 +274,9 @@ export function useDataTable({
274
274
  const visibleColumns = useMemo(() => {
275
275
  return columnOrder
276
276
  .map(key => columns.find(col => col.key === key))
277
- .filter((col): col is DataTableColumn => col !== undefined && columnVisibility[col.key] !== false);
277
+ .filter(
278
+ (col): col is DataTableColumn => col !== undefined && columnVisibility[col.key] !== false
279
+ );
278
280
  }, [columns, columnOrder, columnVisibility]);
279
281
 
280
282
  // Handle sorting
@@ -299,13 +301,10 @@ export function useDataTable({
299
301
  );
300
302
 
301
303
  // Handle page change
302
- const handlePageChange = useCallback(
303
- (page: number) => {
304
- if (page < 1) return;
305
- setCurrentPage(page);
306
- },
307
- []
308
- );
304
+ const handlePageChange = useCallback((page: number) => {
305
+ if (page < 1) return;
306
+ setCurrentPage(page);
307
+ }, []);
309
308
 
310
309
  // Handle search
311
310
  const handleSearch = useCallback((query: string) => {
@@ -328,47 +327,73 @@ export function useDataTable({
328
327
  setCurrentPage(1);
329
328
  }, []);
330
329
 
330
+ // Pre-process column filters to avoid redundant lookups and transformations
331
+ const activeColumnFilters = useMemo(() => {
332
+ if (!columnFilters)
333
+ return [] as Array<{
334
+ key: string;
335
+ value: string;
336
+ lowercaseValue: string;
337
+ column: DataTableColumn;
338
+ }>;
339
+
340
+ return Object.entries(columnFilterValues)
341
+ .filter(([, value]) => value !== undefined && value !== null && value !== '')
342
+ .map(([columnKey, value]) => {
343
+ const column = columns.find(col => col.key === columnKey);
344
+ if (!column || !column.filterable) return null;
345
+
346
+ return {
347
+ key: columnKey,
348
+ value,
349
+ lowercaseValue:
350
+ typeof value === 'string' ? value.toLowerCase() : String(value).toLowerCase(),
351
+ column,
352
+ };
353
+ })
354
+ .filter((f): f is NonNullable<typeof f> => f !== null);
355
+ }, [columnFilters, columnFilterValues, columns]);
356
+
331
357
  // Filter data based on search query and column filters
332
358
  const filteredData = useMemo(() => {
333
- let result = data;
359
+ if (!searchQuery && activeColumnFilters.length === 0) {
360
+ return data;
361
+ }
334
362
 
335
- // Apply global search
336
- if (searchQuery) {
337
- const lowercaseQuery = searchQuery.toLowerCase();
338
- result = result.filter(row => {
339
- return visibleColumns.some(column => {
363
+ const lowercaseQuery = searchQuery ? searchQuery.toLowerCase() : '';
364
+
365
+ return data.filter(row => {
366
+ // Apply global search
367
+ if (searchQuery) {
368
+ const matchesGlobal = visibleColumns.some(column => {
340
369
  const value = row[column.key];
341
370
  if (value == null) return false;
342
371
  return String(value).toLowerCase().includes(lowercaseQuery);
343
372
  });
344
- });
345
- }
346
-
347
- // Apply column-specific filters
348
- if (columnFilters) {
349
- result = result.filter(row => {
350
- return Object.entries(columnFilterValues).every(([columnKey, filterValue]) => {
351
- if (!filterValue) return true;
352
-
353
- const column = columns.find(col => col.key === columnKey);
354
- if (!column || !column.filterable) return true;
373
+ if (!matchesGlobal) return false;
374
+ }
355
375
 
356
- const cellValue = row[columnKey];
357
- if (cellValue == null) return false;
376
+ // Apply column-specific filters
377
+ for (let i = 0; i < activeColumnFilters.length; i++) {
378
+ const filter = activeColumnFilters[i];
379
+ if (!filter) continue;
380
+ const { key, value, lowercaseValue, column } = filter;
381
+ const cellValue = row[key];
358
382
 
359
- // Use custom filter function if provided
360
- if (column.filterFunction) {
361
- return column.filterFunction(cellValue, filterValue);
362
- }
383
+ if (cellValue == null) return false;
363
384
 
385
+ // Use custom filter function if provided
386
+ if (column.filterFunction) {
387
+ if (!column.filterFunction(cellValue, value)) return false;
388
+ } else {
364
389
  // Default text filter
365
- return String(cellValue).toLowerCase().includes(filterValue.toLowerCase());
366
- });
367
- });
368
- }
390
+ if (!String(cellValue).toLowerCase().includes(lowercaseValue)) return false;
391
+ }
392
+ }
369
393
 
370
- return result;
371
- }, [data, visibleColumns, searchQuery, columnFilterValues, columnFilters, columns]);
394
+ return true;
395
+ });
396
+ }, [data, visibleColumns, searchQuery, activeColumnFilters]);
372
397
 
373
398
  // Sort data
374
399
  const sortedData = useMemo(() => {
@@ -434,7 +459,9 @@ export function useDataTable({
434
459
  }
435
460
 
436
461
  if (onSelectionChange) {
437
- const selectedRowsData = sortedData.filter(row => newSelectedIds.includes(getRowId(row, rowKey)));
462
+ const selectedRowsData = sortedData.filter(row =>
463
+ newSelectedIds.includes(getRowId(row, rowKey))
464
+ );
438
465
  onSelectionChange(selectedRowsData, newSelectedIds);
439
466
  }
440
467
  },
@@ -446,16 +473,16 @@ export function useDataTable({
446
473
  (selected: boolean) => {
447
474
  if (selectionMode !== 'multiple') return;
448
475
 
449
- const newSelectedIds = selected
450
- ? paginatedData.map(row => getRowId(row, rowKey))
451
- : [];
476
+ const newSelectedIds = selected ? paginatedData.map(row => getRowId(row, rowKey)) : [];
452
477
 
453
478
  if (!controlledSelectedRowIds) {
454
479
  setInternalSelectedRowIds(newSelectedIds);
455
480
  }
456
481
 
457
482
  if (onSelectionChange) {
458
- const selectedRowsData = sortedData.filter(row => newSelectedIds.includes(getRowId(row, rowKey)));
483
+ const selectedRowsData = sortedData.filter(row =>
484
+ newSelectedIds.includes(getRowId(row, rowKey))
485
+ );
459
486
  onSelectionChange(selectedRowsData, newSelectedIds);
460
487
  }
461
488
  },
@@ -471,7 +498,9 @@ export function useDataTable({
471
498
  // Check if some rows are selected (indeterminate)
472
499
  const isIndeterminate = useMemo(() => {
473
500
  if (selectionMode !== 'multiple' || paginatedData.length === 0) return false;
474
- const selectedCount = paginatedData.filter(row => selectedRowIds.includes(getRowId(row, rowKey))).length;
501
+ const selectedCount = paginatedData.filter(row =>
502
+ selectedRowIds.includes(getRowId(row, rowKey))
503
+ ).length;
475
504
  return selectedCount > 0 && selectedCount < paginatedData.length;
476
505
  }, [selectionMode, paginatedData, selectedRowIds, rowKey]);
477
506