@shohojdhara/atomix 0.3.15 → 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 (245) hide show
  1. package/build-tools/index.d.ts +31 -30
  2. package/build-tools/package.json +4 -21
  3. package/dist/atomix.css +20924 -2611
  4. package/dist/atomix.css.map +1 -1
  5. package/dist/atomix.min.css +76 -2
  6. package/dist/atomix.min.css.map +1 -1
  7. package/dist/build-tools/index.d.ts +31 -30
  8. package/dist/build-tools/package.json +4 -21
  9. package/dist/charts.js.map +1 -1
  10. package/dist/core.js.map +1 -1
  11. package/dist/forms.js.map +1 -1
  12. package/dist/heavy.js.map +1 -1
  13. package/dist/index.d.ts +144 -18
  14. package/dist/index.esm.js +110 -55
  15. package/dist/index.esm.js.map +1 -1
  16. package/dist/index.js +110 -55
  17. package/dist/index.js.map +1 -1
  18. package/dist/index.min.js +1 -1
  19. package/dist/index.min.js.map +1 -1
  20. package/dist/layout.js.map +1 -1
  21. package/dist/theme.d.ts +9 -9
  22. package/dist/theme.js.map +1 -1
  23. package/package.json +1 -1
  24. package/src/components/Accordion/Accordion.stories.tsx +32 -23
  25. package/src/components/Accordion/Accordion.test.tsx +70 -50
  26. package/src/components/Accordion/Accordion.tsx +99 -94
  27. package/src/components/AtomixGlass/AtomixGlass.test.tsx +1 -1
  28. package/src/components/AtomixGlass/GlassFilter.tsx +9 -16
  29. package/src/components/AtomixGlass/glass-utils.ts +4 -3
  30. package/src/components/AtomixGlass/shader-utils.ts +128 -52
  31. package/src/components/AtomixGlass/stories/Playground.stories.tsx +1 -1
  32. package/src/components/AtomixGlass/stories/Shaders.stories.tsx +1 -1
  33. package/src/components/Avatar/Avatar.stories.tsx +45 -62
  34. package/src/components/Avatar/Avatar.tsx +58 -56
  35. package/src/components/Badge/Badge.stories.tsx +20 -9
  36. package/src/components/Badge/Badge.test.tsx +41 -41
  37. package/src/components/Badge/Badge.tsx +64 -62
  38. package/src/components/Block/Block.stories.tsx +14 -4
  39. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +9 -8
  40. package/src/components/Breadcrumb/Breadcrumb.tsx +62 -60
  41. package/src/components/Button/Button.stories.tsx +13 -22
  42. package/src/components/Button/Button.test.tsx +97 -81
  43. package/src/components/Button/Button.tsx +46 -14
  44. package/src/components/Button/ButtonGroup.stories.tsx +37 -32
  45. package/src/components/Button/ButtonGroup.tsx +4 -15
  46. package/src/components/Callout/Callout.stories.tsx +109 -16
  47. package/src/components/Card/Card.stories.tsx +67 -36
  48. package/src/components/Card/Card.tsx +30 -14
  49. package/src/components/Chart/AreaChart.tsx +1 -1
  50. package/src/components/Chart/CandlestickChart.tsx +23 -16
  51. package/src/components/Chart/Chart.stories.tsx +4 -9
  52. package/src/components/Chart/Chart.tsx +40 -44
  53. package/src/components/Chart/ChartRenderer.tsx +39 -12
  54. package/src/components/Chart/ChartToolbar.tsx +21 -5
  55. package/src/components/Chart/DonutChart.tsx +1 -1
  56. package/src/components/Chart/FunnelChart.tsx +4 -1
  57. package/src/components/Chart/GaugeChart.tsx +3 -1
  58. package/src/components/Chart/HeatmapChart.tsx +50 -37
  59. package/src/components/Chart/LineChart.tsx +3 -2
  60. package/src/components/Chart/MultiAxisChart.tsx +24 -16
  61. package/src/components/Chart/RadarChart.tsx +19 -17
  62. package/src/components/Chart/ScatterChart.tsx +29 -21
  63. package/src/components/ColorModeToggle/ColorModeToggle.stories.tsx +6 -2
  64. package/src/components/ColorModeToggle/ColorModeToggle.tsx +15 -3
  65. package/src/components/Countdown/Countdown.stories.tsx +7 -7
  66. package/src/components/DataTable/DataTable.stories.tsx +43 -38
  67. package/src/components/DataTable/DataTable.test.tsx +26 -148
  68. package/src/components/DataTable/DataTable.tsx +485 -456
  69. package/src/components/DatePicker/DatePicker.stories.tsx +32 -47
  70. package/src/components/DatePicker/DatePicker.tsx +31 -26
  71. package/src/components/Dropdown/Dropdown.stories.tsx +2 -5
  72. package/src/components/Dropdown/Dropdown.tsx +313 -299
  73. package/src/components/EdgePanel/EdgePanel.stories.tsx +6 -19
  74. package/src/components/EdgePanel/EdgePanel.tsx +1 -3
  75. package/src/components/Footer/Footer.stories.tsx +21 -16
  76. package/src/components/Footer/Footer.tsx +130 -128
  77. package/src/components/Footer/FooterLink.tsx +2 -2
  78. package/src/components/Form/Checkbox.test.tsx +49 -49
  79. package/src/components/Form/Checkbox.tsx +108 -100
  80. package/src/components/Form/Form.stories.tsx +2 -10
  81. package/src/components/Form/Input.stories.tsx +22 -39
  82. package/src/components/Form/Input.test.tsx +38 -44
  83. package/src/components/Form/Radio.stories.tsx +6 -12
  84. package/src/components/Form/Radio.tsx +68 -66
  85. package/src/components/Form/Select.tsx +184 -182
  86. package/src/components/Form/Textarea.test.tsx +27 -32
  87. package/src/components/Hero/Hero.stories.tsx +56 -23
  88. package/src/components/Hero/Hero.tsx +201 -55
  89. package/src/components/Icon/index.ts +7 -1
  90. package/src/components/List/List.tsx +19 -23
  91. package/src/components/Modal/Modal.stories.tsx +2 -1
  92. package/src/components/Modal/Modal.tsx +130 -127
  93. package/src/components/Navigation/Menu/MegaMenu.tsx +70 -70
  94. package/src/components/Navigation/Nav/NavDropdown.tsx +1 -5
  95. package/src/components/Navigation/SideMenu/SideMenu.stories.tsx +128 -28
  96. package/src/components/Navigation/SideMenu/SideMenu.tsx +5 -7
  97. package/src/components/Navigation/SideMenu/SideMenuItem.tsx +4 -5
  98. package/src/components/Pagination/Pagination.stories.tsx +7 -4
  99. package/src/components/Pagination/Pagination.tsx +199 -202
  100. package/src/components/PhotoViewer/PhotoViewer.tsx +4 -1
  101. package/src/components/Popover/Popover.stories.tsx +99 -192
  102. package/src/components/Popover/Popover.tsx +41 -37
  103. package/src/components/Progress/Progress.stories.tsx +35 -44
  104. package/src/components/River/River.stories.tsx +2 -1
  105. package/src/components/SectionIntro/SectionIntro.stories.tsx +71 -71
  106. package/src/components/Slider/Slider.stories.tsx +12 -4
  107. package/src/components/Spinner/Spinner.stories.tsx +3 -1
  108. package/src/components/Spinner/Spinner.test.tsx +23 -23
  109. package/src/components/Spinner/Spinner.tsx +43 -46
  110. package/src/components/Steps/Steps.stories.tsx +8 -6
  111. package/src/components/Tabs/Tabs.stories.tsx +12 -9
  112. package/src/components/Tabs/Tabs.tsx +74 -72
  113. package/src/components/Toggle/Toggle.stories.tsx +27 -13
  114. package/src/components/Toggle/Toggle.test.tsx +65 -70
  115. package/src/components/Toggle/Toggle.tsx +4 -1
  116. package/src/components/Tooltip/Tooltip.stories.tsx +24 -20
  117. package/src/components/Tooltip/Tooltip.tsx +104 -106
  118. package/src/components/Upload/Upload.stories.tsx +129 -127
  119. package/src/components/Upload/Upload.tsx +287 -283
  120. package/src/components/VideoPlayer/VideoPlayer.tsx +6 -1
  121. package/src/components/index.ts +13 -2
  122. package/src/layouts/Grid/Grid.stories.tsx +9 -3
  123. package/src/layouts/MasonryGrid/MasonryGrid.tsx +5 -1
  124. package/src/lib/__tests__/theme-tools.test.ts +32 -6
  125. package/src/lib/composables/shared-mouse-tracker.ts +13 -14
  126. package/src/lib/composables/useAtomixGlass.ts +106 -49
  127. package/src/lib/composables/useChartExport.ts +1 -1
  128. package/src/lib/composables/useDataTable.ts +29 -17
  129. package/src/lib/composables/useHero.ts +58 -14
  130. package/src/lib/composables/useHeroBackgroundSlider.ts +2 -9
  131. package/src/lib/composables/useInput.ts +10 -8
  132. package/src/lib/composables/useSideMenu.ts +6 -5
  133. package/src/lib/composables/useTooltip.ts +1 -2
  134. package/src/lib/composables/useVideoPlayer.ts +44 -35
  135. package/src/lib/config/index.ts +154 -154
  136. package/src/lib/constants/cssVariables.ts +29 -29
  137. package/src/lib/hooks/__tests__/useComponentCustomization.test.ts +2 -6
  138. package/src/lib/hooks/index.ts +1 -1
  139. package/src/lib/hooks/useComponentCustomization.ts +11 -17
  140. package/src/lib/hooks/usePerformanceMonitor.ts +6 -7
  141. package/src/lib/patterns/__tests__/slots.test.ts +1 -1
  142. package/src/lib/patterns/index.ts +1 -1
  143. package/src/lib/patterns/slots.tsx +8 -13
  144. package/src/lib/storybook/InteractiveDemo.tsx +13 -18
  145. package/src/lib/storybook/PreviewContainer.tsx +1 -1
  146. package/src/lib/storybook/VariantsGrid.tsx +3 -7
  147. package/src/lib/storybook/index.ts +1 -1
  148. package/src/lib/theme/adapters/cssVariableMapper.ts +47 -74
  149. package/src/lib/theme/adapters/index.ts +3 -9
  150. package/src/lib/theme/adapters/themeAdapter.ts +41 -26
  151. package/src/lib/theme/config/index.ts +1 -1
  152. package/src/lib/theme/config/types.ts +2 -2
  153. package/src/lib/theme/config/validator.ts +10 -5
  154. package/src/lib/theme/constants/constants.ts +2 -2
  155. package/src/lib/theme/constants/index.ts +1 -2
  156. package/src/lib/theme/core/__tests__/createTheme.test.ts +20 -22
  157. package/src/lib/theme/core/composeTheme.ts +32 -26
  158. package/src/lib/theme/core/createTheme.ts +1 -1
  159. package/src/lib/theme/core/createThemeObject.ts +308 -301
  160. package/src/lib/theme/core/index.ts +3 -3
  161. package/src/lib/theme/devtools/CLI.ts +106 -104
  162. package/src/lib/theme/devtools/Comparator.tsx +50 -32
  163. package/src/lib/theme/devtools/DesignTokensCustomizer.stories.tsx +50 -48
  164. package/src/lib/theme/devtools/DesignTokensCustomizer.tsx +257 -63
  165. package/src/lib/theme/devtools/Inspector.tsx +75 -60
  166. package/src/lib/theme/devtools/LiveEditor.tsx +97 -76
  167. package/src/lib/theme/devtools/Preview.tsx +150 -106
  168. package/src/lib/theme/devtools/ThemeValidator.ts +29 -21
  169. package/src/lib/theme/devtools/index.ts +3 -9
  170. package/src/lib/theme/devtools/useHistory.ts +23 -21
  171. package/src/lib/theme/errors/errors.ts +12 -11
  172. package/src/lib/theme/errors/index.ts +2 -7
  173. package/src/lib/theme/generators/generateCSS.ts +9 -13
  174. package/src/lib/theme/generators/generateCSSNested.ts +1 -6
  175. package/src/lib/theme/generators/generateCSSVariables.ts +673 -630
  176. package/src/lib/theme/generators/index.ts +1 -4
  177. package/src/lib/theme/i18n/index.ts +1 -1
  178. package/src/lib/theme/i18n/rtl.ts +13 -13
  179. package/src/lib/theme/index.ts +7 -16
  180. package/src/lib/theme/runtime/ThemeApplicator.ts +4 -4
  181. package/src/lib/theme/runtime/ThemeContext.tsx +1 -1
  182. package/src/lib/theme/runtime/ThemeErrorBoundary.tsx +19 -23
  183. package/src/lib/theme/runtime/ThemeProvider.tsx +230 -239
  184. package/src/lib/theme/runtime/__tests__/ThemeProvider.integration.test.tsx +1 -1
  185. package/src/lib/theme/runtime/__tests__/ThemeProvider.test.tsx +24 -29
  186. package/src/lib/theme/runtime/index.ts +2 -5
  187. package/src/lib/theme/runtime/useTheme.ts +18 -18
  188. package/src/lib/theme/runtime/useThemeTokens.ts +22 -22
  189. package/src/lib/theme/test/testTheme.ts +15 -16
  190. package/src/lib/theme/tokens/index.ts +2 -7
  191. package/src/lib/theme/tokens/tokens.ts +25 -24
  192. package/src/lib/theme/types.ts +428 -411
  193. package/src/lib/theme/utils/__tests__/themeValidation.test.ts +3 -3
  194. package/src/lib/theme/utils/componentTheming.ts +18 -18
  195. package/src/lib/theme/utils/domUtils.ts +277 -289
  196. package/src/lib/theme/utils/index.ts +1 -2
  197. package/src/lib/theme/utils/injectCSS.ts +10 -14
  198. package/src/lib/theme/utils/naming.ts +20 -16
  199. package/src/lib/theme/utils/themeHelpers.ts +10 -12
  200. package/src/lib/theme/utils/themeUtils.ts +85 -86
  201. package/src/lib/theme/utils/themeValidation.ts +82 -33
  202. package/src/lib/theme-tools.ts +8 -6
  203. package/src/lib/types/components.ts +172 -71
  204. package/src/lib/types/partProps.ts +1 -1
  205. package/src/lib/utils/__tests__/csv.test.ts +1 -1
  206. package/src/lib/utils/componentUtils.ts +8 -12
  207. package/src/lib/utils/csv.ts +3 -1
  208. package/src/lib/utils/dataTableExport.ts +1 -5
  209. package/src/lib/utils/fontPreloader.ts +10 -19
  210. package/src/lib/utils/icons.ts +4 -1
  211. package/src/lib/utils/index.ts +2 -6
  212. package/src/lib/utils/memoryMonitor.ts +10 -8
  213. package/src/lib/utils/themeNaming.ts +2 -2
  214. package/src/styles/01-settings/_index.scss +0 -1
  215. package/src/styles/01-settings/_settings.colors.scss +8 -8
  216. package/src/styles/01-settings/_settings.design-tokens.scss +61 -50
  217. package/src/styles/01-settings/_settings.navbar.scss +1 -1
  218. package/src/styles/01-settings/_settings.spacing.scss +3 -4
  219. package/src/styles/01-settings/_settings.tooltip.scss +1 -1
  220. package/src/styles/01-settings/_settings.typography.scss +1 -1
  221. package/src/styles/02-tools/_tools.button.scss +51 -21
  222. package/src/styles/02-tools/_tools.utility-api.scss +30 -18
  223. package/src/styles/03-generic/_generic.root.scss +4 -3
  224. package/src/styles/06-components/_components.atomix-glass.scss +13 -9
  225. package/src/styles/06-components/_components.button.scss +16 -4
  226. package/src/styles/06-components/_components.callout.scss +27 -21
  227. package/src/styles/06-components/_components.card.scss +5 -14
  228. package/src/styles/06-components/_components.chart.scss +22 -19
  229. package/src/styles/06-components/_components.checkbox.scss +3 -1
  230. package/src/styles/06-components/_components.color-mode-toggle.scss +3 -1
  231. package/src/styles/06-components/_components.edge-panel.scss +9 -2
  232. package/src/styles/06-components/_components.footer.scss +1 -1
  233. package/src/styles/06-components/_components.side-menu.scss +5 -5
  234. package/src/styles/06-components/_components.toggle.scss +18 -0
  235. package/src/styles/06-components/_index.scss +1 -1
  236. package/src/styles/06-components/old.chart.styles.scss +0 -2
  237. package/src/styles/99-utilities/_utilities.border.scss +69 -27
  238. package/src/styles/99-utilities/_utilities.display.scss +1 -1
  239. package/src/styles/99-utilities/_utilities.opacity.scss +10 -0
  240. package/src/styles/99-utilities/_utilities.position.scss +16 -9
  241. package/src/styles/99-utilities/_utilities.scss +1 -1
  242. package/src/styles/99-utilities/_utilities.sizes.scss +47 -18
  243. package/src/styles/99-utilities/_utilities.spacing.scss +118 -66
  244. package/src/styles/99-utilities/_utilities.text-gradient.scss +30 -30
  245. package/src/styles/99-utilities/_utilities.text.scss +67 -46
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shohojdhara/atomix",
3
- "version": "0.3.15",
3
+ "version": "0.4.0",
4
4
  "description": "Atomix Design System - A modern component library for web applications",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import type { Meta, StoryObj } from '@storybook/react';
3
3
  import { fn } from '@storybook/test';
4
- import { Accordion } from './Accordion';
4
+ import { Accordion } from './Accordion';
5
5
  import { ACCORDION } from '../../lib/constants/components';
6
6
  import type { AtomixGlassProps } from '../../lib/types/components';
7
7
 
@@ -29,9 +29,7 @@ const mockHandlers = {
29
29
  // Sample content for stories
30
30
  const sampleContent = (
31
31
  <div>
32
- <p>
33
- This accordion contains rich HTML content including headings, paragraphs, and lists.
34
- </p>
32
+ <p>This accordion contains rich HTML content including headings, paragraphs, and lists.</p>
35
33
  <ul>
36
34
  <li>
37
35
  List item with <a href="#">link</a>
@@ -396,28 +394,22 @@ export const ControlledState: Story = {
396
394
  title: 'Controlled Accordion',
397
395
  children: <p>This accordion is controlled by external state.</p>,
398
396
  },
399
- render: (args) => {
397
+ render: args => {
400
398
  const [open, setOpen] = React.useState(false);
401
399
  return (
402
400
  <div>
403
- <button
404
- className="c-btn c-btn--primary u-mb-3"
405
- onClick={() => setOpen(prev => !prev)}
406
- >
401
+ <button className="c-btn c-btn--primary u-mb-3" onClick={() => setOpen(prev => !prev)}>
407
402
  Toggle Accordion (Controlled)
408
403
  </button>
409
- <Accordion
410
- {...args}
411
- isOpen={open}
412
- onOpenChange={setOpen}
413
- />
404
+ <Accordion {...args} isOpen={open} onOpenChange={setOpen} />
414
405
  </div>
415
406
  );
416
407
  },
417
408
  parameters: {
418
409
  docs: {
419
410
  description: {
420
- story: 'This story demonstrates a controlled Accordion using the `isOpen` and `onOpenChange` props.',
411
+ story:
412
+ 'This story demonstrates a controlled Accordion using the `isOpen` and `onOpenChange` props.',
421
413
  },
422
414
  },
423
415
  },
@@ -489,8 +481,14 @@ export const GlassEffect: Story = {
489
481
  children: <p>This accordion has a glass morphism effect applied.</p>,
490
482
  glass: true,
491
483
  },
492
- render: (args) => (
493
- <div className="u-bg-cover u-bg-center u-p-8 u-rounded-xl u-min-h-97vh u-flex u-items-center u-justify-center" style={{backgroundImage: 'url(https://images.unsplash.com/photo-1759915995309-404c743bfbf9?q=80&w=3270&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D)'}}>
484
+ render: args => (
485
+ <div
486
+ className="u-bg-cover u-bg-center u-p-8 u-rounded-xl u-min-h-97vh u-flex u-items-center u-justify-center"
487
+ style={{
488
+ backgroundImage:
489
+ 'url(https://images.unsplash.com/photo-1759915995309-404c743bfbf9?q=80&w=3270&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D)',
490
+ }}
491
+ >
494
492
  <div className="u-w-full u-max-w-md">
495
493
  <Accordion {...args} />
496
494
  </div>
@@ -499,7 +497,8 @@ export const GlassEffect: Story = {
499
497
  parameters: {
500
498
  docs: {
501
499
  description: {
502
- story: 'This story demonstrates an Accordion with glass morphism effect enabled against a gradient background.',
500
+ story:
501
+ 'This story demonstrates an Accordion with glass morphism effect enabled against a gradient background.',
503
502
  },
504
503
  },
505
504
  },
@@ -516,8 +515,16 @@ export const GlassCustom: Story = {
516
515
  mode: 'polar',
517
516
  } as GlassProps,
518
517
  },
519
- render: (args) => (
520
- <div className="u-bg-cover u-bg-center u-p-8 u-rounded-xl u-min-h-97vh u-flex u-items-center u-justify-center" style={{backgroundImage: 'url(https://images.unsplash.com/photo-1754147965582-edcb63324a81?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D)', backgroundSize: '120%', animation: 'gradient 15s ease infinite'}}>
518
+ render: args => (
519
+ <div
520
+ className="u-bg-cover u-bg-center u-p-8 u-rounded-xl u-min-h-97vh u-flex u-items-center u-justify-center"
521
+ style={{
522
+ backgroundImage:
523
+ 'url(https://images.unsplash.com/photo-1754147965582-edcb63324a81?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D)',
524
+ backgroundSize: '120%',
525
+ animation: 'gradient 15s ease infinite',
526
+ }}
527
+ >
521
528
  <style>
522
529
  {`
523
530
  @keyframes gradient {
@@ -538,7 +545,8 @@ export const GlassCustom: Story = {
538
545
  parameters: {
539
546
  docs: {
540
547
  description: {
541
- story: 'This story demonstrates an Accordion with custom glass morphism settings against a scenic background image.',
548
+ story:
549
+ 'This story demonstrates an Accordion with custom glass morphism settings against a scenic background image.',
542
550
  },
543
551
  },
544
552
  },
@@ -567,7 +575,8 @@ export const KeyboardNavigation: Story = {
567
575
  title: 'Keyboard Accessible',
568
576
  children: (
569
577
  <p>
570
- This accordion is fully operable via keyboard navigation. Press Tab to focus and Enter/Space to toggle.
578
+ This accordion is fully operable via keyboard navigation. Press Tab to focus and Enter/Space
579
+ to toggle.
571
580
  </p>
572
581
  ),
573
582
  },
@@ -578,4 +587,4 @@ export const KeyboardNavigation: Story = {
578
587
  },
579
588
  },
580
589
  },
581
- };
590
+ };
@@ -4,54 +4,74 @@ import { Accordion } from './Accordion';
4
4
  import React from 'react';
5
5
 
6
6
  describe('Accordion Component', () => {
7
- it('renders correctly with title', () => {
8
- render(<Accordion title="Test Accordion">Content</Accordion>);
9
- expect(screen.getByText('Test Accordion')).toBeInTheDocument();
10
- expect(screen.getByText('Content')).toBeInTheDocument();
11
- });
12
-
13
- it('toggles when clicked', () => {
14
- const onOpenChange = vi.fn();
15
- render(<Accordion title="Test" onOpenChange={onOpenChange}>Content</Accordion>);
16
- const button = screen.getByRole('button');
17
-
18
- fireEvent.click(button);
19
- expect(onOpenChange).toHaveBeenCalledWith(true);
20
- expect(button).toHaveAttribute('aria-expanded', 'true');
21
-
22
- fireEvent.click(button);
23
- expect(onOpenChange).toHaveBeenCalledWith(false);
24
- expect(button).toHaveAttribute('aria-expanded', 'false');
25
- });
26
-
27
- it('calls legacy onOpen/onClose handlers', () => {
28
- const onOpen = vi.fn();
29
- const onClose = vi.fn();
30
- render(<Accordion title="Test" onOpen={onOpen} onClose={onClose}>Content</Accordion>);
31
- const button = screen.getByRole('button');
32
-
33
- fireEvent.click(button);
34
- expect(onOpen).toHaveBeenCalled();
35
-
36
- fireEvent.click(button);
37
- expect(onClose).toHaveBeenCalled();
38
- });
39
-
40
- it('handles controlled state', () => {
41
- const onOpenChange = vi.fn();
42
- const { rerender } = render(<Accordion title="Test" isOpen={false} onOpenChange={onOpenChange}>Content</Accordion>);
43
- const button = screen.getByRole('button');
44
-
45
- fireEvent.click(button);
46
- expect(onOpenChange).toHaveBeenCalledWith(true);
47
- expect(button).toHaveAttribute('aria-expanded', 'false'); // Should not change internally
48
-
49
- rerender(<Accordion title="Test" isOpen={true} onOpenChange={onOpenChange}>Content</Accordion>);
50
- expect(button).toHaveAttribute('aria-expanded', 'true');
51
- });
52
-
53
- it('supports glass effect', () => {
54
- const { container } = render(<Accordion title="Test" glass>Content</Accordion>);
55
- expect(container.querySelector('.c-accordion--glass')).toBeInTheDocument();
56
- });
7
+ it('renders correctly with title', () => {
8
+ render(<Accordion title="Test Accordion">Content</Accordion>);
9
+ expect(screen.getByText('Test Accordion')).toBeInTheDocument();
10
+ expect(screen.getByText('Content')).toBeInTheDocument();
11
+ });
12
+
13
+ it('toggles when clicked', () => {
14
+ const onOpenChange = vi.fn();
15
+ render(
16
+ <Accordion title="Test" onOpenChange={onOpenChange}>
17
+ Content
18
+ </Accordion>
19
+ );
20
+ const button = screen.getByRole('button');
21
+
22
+ fireEvent.click(button);
23
+ expect(onOpenChange).toHaveBeenCalledWith(true);
24
+ expect(button).toHaveAttribute('aria-expanded', 'true');
25
+
26
+ fireEvent.click(button);
27
+ expect(onOpenChange).toHaveBeenCalledWith(false);
28
+ expect(button).toHaveAttribute('aria-expanded', 'false');
29
+ });
30
+
31
+ it('calls legacy onOpen/onClose handlers', () => {
32
+ const onOpen = vi.fn();
33
+ const onClose = vi.fn();
34
+ render(
35
+ <Accordion title="Test" onOpen={onOpen} onClose={onClose}>
36
+ Content
37
+ </Accordion>
38
+ );
39
+ const button = screen.getByRole('button');
40
+
41
+ fireEvent.click(button);
42
+ expect(onOpen).toHaveBeenCalled();
43
+
44
+ fireEvent.click(button);
45
+ expect(onClose).toHaveBeenCalled();
46
+ });
47
+
48
+ it('handles controlled state', () => {
49
+ const onOpenChange = vi.fn();
50
+ const { rerender } = render(
51
+ <Accordion title="Test" isOpen={false} onOpenChange={onOpenChange}>
52
+ Content
53
+ </Accordion>
54
+ );
55
+ const button = screen.getByRole('button');
56
+
57
+ fireEvent.click(button);
58
+ expect(onOpenChange).toHaveBeenCalledWith(true);
59
+ expect(button).toHaveAttribute('aria-expanded', 'false'); // Should not change internally
60
+
61
+ rerender(
62
+ <Accordion title="Test" isOpen={true} onOpenChange={onOpenChange}>
63
+ Content
64
+ </Accordion>
65
+ );
66
+ expect(button).toHaveAttribute('aria-expanded', 'true');
67
+ });
68
+
69
+ it('supports glass effect', () => {
70
+ const { container } = render(
71
+ <Accordion title="Test" glass>
72
+ Content
73
+ </Accordion>
74
+ );
75
+ expect(container.querySelector('.c-accordion--glass')).toBeInTheDocument();
76
+ });
57
77
  });
@@ -1,120 +1,125 @@
1
1
  import React, { ReactNode, useId, memo } from 'react';
2
2
  import { ACCORDION } from '../../lib/constants/components';
3
3
  import { useAccordion } from '../../lib/composables/useAccordion';
4
- import type { AccordionProps as AccordionPropsType, AtomixGlassProps } from '../../lib/types/components';
4
+ import type {
5
+ AccordionProps as AccordionPropsType,
6
+ AtomixGlassProps,
7
+ } from '../../lib/types/components';
5
8
  import { AtomixGlass } from '../AtomixGlass/AtomixGlass';
6
9
 
7
10
  export type AccordionProps = AccordionPropsType;
8
11
 
9
- export const Accordion: React.FC<AccordionProps> = memo(({
10
- title,
11
- children,
12
- defaultOpen = false,
13
- isOpen: controlledOpen,
14
- onOpenChange,
15
- onOpen,
16
- onClose,
17
- disabled = false,
18
- iconPosition = 'right',
19
- icon,
20
- className = '',
21
- style,
22
- glass,
23
- }) => {
24
- // Generate unique IDs for accessibility
25
- const instanceId = useId();
26
- const buttonId = `accordion-header-${instanceId}`;
27
- const panelId = `accordion-panel-${instanceId}`;
28
-
29
- // Use composable hook for logic/state
30
- const {
31
- state,
32
- toggle,
33
- updatePanelHeight,
34
- panelRef,
35
- contentRef,
36
- generateClassNames,
37
- generateHeaderClassNames,
38
- } = useAccordion({
39
- defaultOpen,
40
- disabled,
41
- iconPosition,
12
+ export const Accordion: React.FC<AccordionProps> = memo(
13
+ ({
14
+ title,
15
+ children,
16
+ defaultOpen = false,
42
17
  isOpen: controlledOpen,
43
18
  onOpenChange,
44
19
  onOpen,
45
20
  onClose,
46
- });
21
+ disabled = false,
22
+ iconPosition = 'right',
23
+ icon,
24
+ className = '',
25
+ style,
26
+ glass,
27
+ }) => {
28
+ // Generate unique IDs for accessibility
29
+ const instanceId = useId();
30
+ const buttonId = `accordion-header-${instanceId}`;
31
+ const panelId = `accordion-panel-${instanceId}`;
47
32
 
48
- // Default icon
49
- const defaultIcon = (
50
- <i className="c-accordion__icon" aria-hidden="true">
51
- <svg
52
- xmlns="http://www.w3.org/2000/svg"
53
- width="24"
54
- height="24"
55
- viewBox="0 0 24 24"
56
- fill="none"
57
- stroke="currentColor"
58
- strokeWidth="2"
59
- strokeLinecap="round"
60
- strokeLinejoin="round"
61
- aria-hidden="true"
62
- focusable="false"
63
- >
64
- <polyline points="6 9 12 15 18 9"></polyline>
65
- </svg>
66
- </i>
67
- );
33
+ // Use composable hook for logic/state
34
+ const {
35
+ state,
36
+ toggle,
37
+ updatePanelHeight,
38
+ panelRef,
39
+ contentRef,
40
+ generateClassNames,
41
+ generateHeaderClassNames,
42
+ } = useAccordion({
43
+ defaultOpen,
44
+ disabled,
45
+ iconPosition,
46
+ isOpen: controlledOpen,
47
+ onOpenChange,
48
+ onOpen,
49
+ onClose,
50
+ });
68
51
 
69
- const accordionContent = (
70
- <div
71
- className={generateClassNames(className) + (glass ? ' c-accordion--glass' : '')}
72
- style={style}
73
- >
74
- <button
75
- id={buttonId}
76
- className={generateHeaderClassNames()}
77
- onClick={toggle}
78
- aria-expanded={state.isOpen}
79
- aria-controls={panelId}
80
- aria-disabled={disabled}
81
- disabled={disabled}
82
- type="button"
83
- >
84
- <span className="c-accordion__title">{title}</span>
85
- {icon || defaultIcon}
86
- </button>
52
+ // Default icon
53
+ const defaultIcon = (
54
+ <i className="c-accordion__icon" aria-hidden="true">
55
+ <svg
56
+ xmlns="http://www.w3.org/2000/svg"
57
+ width="24"
58
+ height="24"
59
+ viewBox="0 0 24 24"
60
+ fill="none"
61
+ stroke="currentColor"
62
+ strokeWidth="2"
63
+ strokeLinecap="round"
64
+ strokeLinejoin="round"
65
+ aria-hidden="true"
66
+ focusable="false"
67
+ >
68
+ <polyline points="6 9 12 15 18 9"></polyline>
69
+ </svg>
70
+ </i>
71
+ );
72
+
73
+ const accordionContent = (
87
74
  <div
88
- id={panelId}
89
- className={ACCORDION.SELECTORS.PANEL.replace('.', '')}
90
- ref={panelRef as React.RefObject<HTMLDivElement>}
91
- role="region"
92
- aria-labelledby={buttonId}
75
+ className={generateClassNames(className) + (glass ? ' c-accordion--glass' : '')}
76
+ style={style}
93
77
  >
78
+ <button
79
+ id={buttonId}
80
+ className={generateHeaderClassNames()}
81
+ onClick={toggle}
82
+ aria-expanded={state.isOpen}
83
+ aria-controls={panelId}
84
+ aria-disabled={disabled}
85
+ disabled={disabled}
86
+ type="button"
87
+ >
88
+ <span className="c-accordion__title">{title}</span>
89
+ {icon || defaultIcon}
90
+ </button>
94
91
  <div
95
- className={ACCORDION.SELECTORS.BODY.replace('.', '')}
96
- ref={contentRef as React.RefObject<HTMLDivElement>}
92
+ id={panelId}
93
+ className={ACCORDION.SELECTORS.PANEL.replace('.', '')}
94
+ ref={panelRef as React.RefObject<HTMLDivElement>}
95
+ role="region"
96
+ aria-labelledby={buttonId}
97
97
  >
98
- {children}
98
+ <div
99
+ className={ACCORDION.SELECTORS.BODY.replace('.', '')}
100
+ ref={contentRef as React.RefObject<HTMLDivElement>}
101
+ >
102
+ {children}
103
+ </div>
99
104
  </div>
100
105
  </div>
101
- </div>
102
- );
106
+ );
103
107
 
104
- if (glass) {
105
- // Default glass settings for accordions
106
- const defaultGlassProps = {
107
- displacementScale: 20,
108
- elasticity: 0,
109
- };
108
+ if (glass) {
109
+ // Default glass settings for accordions
110
+ const defaultGlassProps = {
111
+ displacementScale: 20,
112
+ elasticity: 0,
113
+ };
110
114
 
111
- const glassProps = glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
115
+ const glassProps = glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
112
116
 
113
- return <AtomixGlass {...glassProps}>{accordionContent}</AtomixGlass>;
114
- }
117
+ return <AtomixGlass {...glassProps}>{accordionContent}</AtomixGlass>;
118
+ }
115
119
 
116
- return accordionContent;
117
- });
120
+ return accordionContent;
121
+ }
122
+ );
118
123
 
119
124
  // Set display name for debugging
120
125
  Accordion.displayName = 'Accordion';
@@ -10,7 +10,7 @@ vi.mock('./shader-utils', () => ({
10
10
  updateShader() {
11
11
  return 'data:image/png;base64,mockBase64String';
12
12
  }
13
- destroy() { }
13
+ destroy() {}
14
14
  },
15
15
  fragmentShaders: {
16
16
  liquidGlass: vi.fn(),
@@ -35,12 +35,7 @@ const GlassFilterComponent: React.FC<GlassFilterProps> = ({
35
35
  aria-hidden="true"
36
36
  >
37
37
  <defs>
38
- <radialGradient
39
- id={`${id}-edge-mask`}
40
- cx="50%"
41
- cy="50%"
42
- r="50%"
43
- >
38
+ <radialGradient id={`${id}-edge-mask`} cx="50%" cy="50%" r="50%">
44
39
  <stop offset="0%" stopColor="black" stopOpacity="0" />
45
40
  <stop
46
41
  offset={`${Math.max(30, 80 - aberrationIntensity * 2)}%`}
@@ -49,14 +44,7 @@ const GlassFilterComponent: React.FC<GlassFilterProps> = ({
49
44
  />
50
45
  <stop offset="100%" stopColor="white" stopOpacity="1" />
51
46
  </radialGradient>
52
- <filter
53
- id={id}
54
- x="-35%"
55
- y="-35%"
56
- width="170%"
57
- height="170%"
58
- colorInterpolationFilters="sRGB"
59
- >
47
+ <filter id={id} x="-35%" y="-35%" width="170%" height="170%" colorInterpolationFilters="sRGB">
60
48
  <feImage
61
49
  id={`${id}-image`}
62
50
  x="0"
@@ -64,7 +52,13 @@ const GlassFilterComponent: React.FC<GlassFilterProps> = ({
64
52
  width="100%"
65
53
  height="100%"
66
54
  result="DISPLACEMENT_MAP"
67
- href={getDisplacementMap(mode, displacementMap, polarDisplacementMap, prominentDisplacementMap, shaderMapUrl)}
55
+ href={getDisplacementMap(
56
+ mode,
57
+ displacementMap,
58
+ polarDisplacementMap,
59
+ prominentDisplacementMap,
60
+ shaderMapUrl
61
+ )}
68
62
  preserveAspectRatio="xMidYMid slice"
69
63
  />
70
64
 
@@ -178,4 +172,3 @@ export const GlassFilter = memo(GlassFilterComponent, (prevProps, nextProps) =>
178
172
  prevProps.blurAmount === nextProps.blurAmount
179
173
  );
180
174
  });
181
-
@@ -45,7 +45,9 @@ export const calculateMouseInfluence = (mouseOffset: MousePosition): number => {
45
45
  return 0;
46
46
  }
47
47
  // Bounded calculation — keeps the glass effect subtle and stable
48
- const influence = Math.sqrt(mouseOffset.x * mouseOffset.x + mouseOffset.y * mouseOffset.y) / CONSTANTS.MOUSE_INFLUENCE_DIVISOR;
48
+ const influence =
49
+ Math.sqrt(mouseOffset.x * mouseOffset.x + mouseOffset.y * mouseOffset.y) /
50
+ CONSTANTS.MOUSE_INFLUENCE_DIVISOR;
49
51
  return Math.min(0.8, influence); // Tighter cap to prevent blur/filter blow-out
50
52
  };
51
53
 
@@ -59,7 +61,7 @@ export const calculateOverLightIntensity = (
59
61
  if (!mouseOffset || typeof mouseOffset.x !== 'number' || typeof mouseOffset.y !== 'number') {
60
62
  return baseIntensity;
61
63
  }
62
-
64
+
63
65
  // Calculate additional intensity based on mouse position
64
66
  const mouseInfluence = calculateMouseInfluence(mouseOffset);
65
67
  return Math.min(1.0, baseIntensity * (1 + mouseInfluence * 0.3));
@@ -260,4 +262,3 @@ export const getDisplacementMap = (
260
262
  return displacementMap;
261
263
  }
262
264
  };
263
-