@shohojdhara/atomix 0.3.4 → 0.3.6

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 (237) hide show
  1. package/README.md +101 -199
  2. package/atomix.config.ts +241 -0
  3. package/dist/atomix.css +269 -189
  4. package/dist/atomix.css.map +1 -0
  5. package/dist/atomix.min.css +15179 -11
  6. package/dist/atomix.min.css.map +1 -0
  7. package/dist/charts.d.ts +1929 -0
  8. package/dist/charts.js +6477 -0
  9. package/dist/charts.js.map +1 -0
  10. package/dist/core.d.ts +1289 -0
  11. package/dist/core.js +3373 -0
  12. package/dist/core.js.map +1 -0
  13. package/dist/forms.d.ts +1085 -0
  14. package/dist/forms.js +2466 -0
  15. package/dist/forms.js.map +1 -0
  16. package/dist/heavy.d.ts +636 -0
  17. package/dist/heavy.js +4566 -0
  18. package/dist/heavy.js.map +1 -0
  19. package/dist/index.d.ts +5171 -4792
  20. package/dist/index.esm.js +6098 -4563
  21. package/dist/index.esm.js.map +1 -1
  22. package/dist/index.js +6291 -4747
  23. package/dist/index.js.map +1 -1
  24. package/dist/index.min.js +1 -1
  25. package/dist/index.min.js.map +1 -1
  26. package/dist/layout.d.ts +300 -0
  27. package/dist/layout.js +336 -0
  28. package/dist/layout.js.map +1 -0
  29. package/dist/theme.d.ts +2122 -0
  30. package/dist/theme.js +6084 -0
  31. package/dist/theme.js.map +1 -0
  32. package/package.json +59 -27
  33. package/scripts/atomix-cli.js +544 -16
  34. package/scripts/cli/__tests__/cli-commands.test.js +204 -0
  35. package/scripts/cli/__tests__/utils.test.js +201 -0
  36. package/scripts/cli/__tests__/vitest.config.js +26 -0
  37. package/scripts/cli/interactive-init.js +1 -1
  38. package/scripts/cli/token-manager.js +32 -7
  39. package/scripts/cli/utils.js +347 -0
  40. package/src/components/Accordion/Accordion.stories.tsx +50 -17
  41. package/src/components/Accordion/Accordion.tsx +5 -54
  42. package/src/components/Accordion/index.ts +1 -1
  43. package/src/components/AtomixGlass/AtomixGlass.tsx +65 -31
  44. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +11 -4
  45. package/src/components/AtomixGlass/stories/AtomixGlass.stories.tsx +1 -32
  46. package/src/components/AtomixGlass/stories/Examples.stories.tsx +2 -2
  47. package/src/components/AtomixGlass/stories/shared-components.tsx +0 -31
  48. package/src/components/Avatar/Avatar.stories.tsx +7 -0
  49. package/src/components/Avatar/Avatar.tsx +3 -3
  50. package/src/components/Badge/Badge.stories.tsx +91 -13
  51. package/src/components/Badge/Badge.tsx +3 -3
  52. package/src/components/Block/Block.stories.tsx +7 -23
  53. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +7 -0
  54. package/src/components/Breadcrumb/Breadcrumb.tsx +3 -3
  55. package/src/components/Button/Button.stories.tsx +141 -22
  56. package/src/components/Button/ButtonGroup.stories.tsx +315 -0
  57. package/src/components/Button/ButtonGroup.tsx +67 -0
  58. package/src/components/Button/index.ts +2 -0
  59. package/src/components/Callout/Callout.stories.tsx +8 -6
  60. package/src/components/Card/Card.stories.tsx +82 -28
  61. package/src/components/Card/ElevationCard.tsx +1 -1
  62. package/src/components/Chart/AnimatedChart.tsx +19 -18
  63. package/src/components/Chart/AreaChart.tsx +5 -2
  64. package/src/components/Chart/BarChart.tsx +1 -1
  65. package/src/components/Chart/BubbleChart.tsx +6 -6
  66. package/src/components/Chart/CandlestickChart.tsx +0 -1
  67. package/src/components/Chart/Chart.stories.tsx +5 -7
  68. package/src/components/Chart/Chart.tsx +0 -16
  69. package/src/components/Chart/ChartRenderer.tsx +1 -1
  70. package/src/components/Chart/ChartToolbar.tsx +1 -0
  71. package/src/components/Chart/DonutChart.tsx +0 -1
  72. package/src/components/Chart/FunnelChart.tsx +1 -2
  73. package/src/components/Chart/GaugeChart.tsx +0 -1
  74. package/src/components/Chart/HeatmapChart.tsx +0 -1
  75. package/src/components/Chart/LineChart.tsx +0 -1
  76. package/src/components/Chart/MultiAxisChart.tsx +0 -1
  77. package/src/components/Chart/PieChart.tsx +0 -1
  78. package/src/components/Chart/RadarChart.tsx +19 -13
  79. package/src/components/Chart/ScatterChart.tsx +3 -4
  80. package/src/components/Chart/TreemapChart.tsx +2 -1
  81. package/src/components/Chart/WaterfallChart.tsx +0 -2
  82. package/src/components/Chart/types.ts +12 -2
  83. package/src/components/Chart/utils.ts +4 -3
  84. package/src/components/ColorModeToggle/ColorModeToggle.stories.tsx +7 -0
  85. package/src/components/DataTable/DataTable.stories.tsx +23 -16
  86. package/src/components/DataTable/DataTable.tsx +3 -3
  87. package/src/components/DatePicker/DatePicker.stories.tsx +27 -19
  88. package/src/components/Dropdown/Dropdown.stories.tsx +11 -19
  89. package/src/components/Dropdown/Dropdown.tsx +12 -9
  90. package/src/components/EdgePanel/EdgePanel.stories.tsx +1 -0
  91. package/src/components/Footer/Footer.stories.tsx +8 -6
  92. package/src/components/Footer/FooterLink.tsx +9 -2
  93. package/src/components/Footer/FooterSection.tsx +3 -3
  94. package/src/components/Form/Checkbox.stories.tsx +7 -0
  95. package/src/components/Form/Checkbox.tsx +3 -3
  96. package/src/components/Form/Form.stories.tsx +7 -0
  97. package/src/components/Form/FormGroup.stories.tsx +9 -1
  98. package/src/components/Form/Input.stories.tsx +69 -16
  99. package/src/components/Form/Input.tsx +4 -2
  100. package/src/components/Form/Radio.stories.tsx +9 -1
  101. package/src/components/Form/Radio.tsx +3 -3
  102. package/src/components/Form/Select.stories.tsx +9 -1
  103. package/src/components/Form/Select.tsx +3 -3
  104. package/src/components/Form/Textarea.stories.tsx +10 -2
  105. package/src/components/Form/Textarea.tsx +4 -2
  106. package/src/components/Hero/Hero.stories.tsx +7 -0
  107. package/src/components/List/List.stories.tsx +10 -3
  108. package/src/components/List/List.tsx +3 -3
  109. package/src/components/List/ListGroup.tsx +3 -1
  110. package/src/components/Messages/Messages.stories.tsx +8 -7
  111. package/src/components/Modal/Modal.stories.tsx +17 -6
  112. package/src/components/Modal/Modal.tsx +3 -3
  113. package/src/components/Navigation/Menu/MegaMenu.tsx +9 -3
  114. package/src/components/Navigation/Menu/Menu.stories.tsx +7 -0
  115. package/src/components/Navigation/Menu/Menu.tsx +9 -3
  116. package/src/components/Navigation/Nav/Nav.stories.tsx +7 -0
  117. package/src/components/Navigation/Navbar/Navbar.stories.tsx +1 -0
  118. package/src/components/Navigation/SideMenu/SideMenu.stories.tsx +1 -1
  119. package/src/components/Pagination/Pagination.stories.tsx +188 -111
  120. package/src/components/Pagination/Pagination.tsx +88 -7
  121. package/src/components/PhotoViewer/PhotoViewer.stories.tsx +10 -5
  122. package/src/components/PhotoViewer/PhotoViewerImage.tsx +2 -2
  123. package/src/components/Popover/Popover.stories.tsx +191 -115
  124. package/src/components/Popover/Popover.tsx +4 -4
  125. package/src/components/ProductReview/ProductReview.stories.tsx +80 -58
  126. package/src/components/Progress/Progress.stories.tsx +79 -49
  127. package/src/components/Progress/Progress.tsx +6 -2
  128. package/src/components/Rating/Rating.stories.tsx +109 -84
  129. package/src/components/Rating/Rating.tsx +5 -2
  130. package/src/components/River/River.stories.tsx +194 -114
  131. package/src/components/SectionIntro/SectionIntro.stories.tsx +19 -9
  132. package/src/components/Slider/Slider.stories.tsx +7 -0
  133. package/src/components/Slider/Slider.tsx +10 -9
  134. package/src/components/Spinner/Spinner.stories.tsx +15 -11
  135. package/src/components/Spinner/Spinner.tsx +3 -3
  136. package/src/components/Steps/Steps.stories.tsx +132 -98
  137. package/src/components/Tabs/Tabs.stories.tsx +163 -112
  138. package/src/components/Tabs/Tabs.tsx +3 -3
  139. package/src/components/Testimonial/Testimonial.stories.tsx +114 -68
  140. package/src/components/Todo/Todo.stories.tsx +38 -12
  141. package/src/components/Toggle/Toggle.stories.tsx +61 -28
  142. package/src/components/Tooltip/Tooltip.stories.tsx +318 -200
  143. package/src/components/Tooltip/Tooltip.tsx +3 -3
  144. package/src/components/Upload/Upload.stories.tsx +122 -84
  145. package/src/components/VideoPlayer/VideoPlayer.stories.tsx +7 -24
  146. package/src/components/index.ts +6 -2
  147. package/src/layouts/MasonryGrid/MasonryGrid.tsx +2 -2
  148. package/src/lib/composables/useAtomixGlass.ts +2 -3
  149. package/src/lib/composables/useChartPerformance.ts +102 -78
  150. package/src/lib/composables/useChartScale.ts +10 -0
  151. package/src/lib/composables/useHero.ts +9 -2
  152. package/src/lib/composables/useHeroBackgroundSlider.ts +5 -3
  153. package/src/lib/composables/useNavbar.ts +0 -10
  154. package/src/lib/composables/useSideMenu.ts +1 -0
  155. package/src/lib/composables/useVideoPlayer.ts +3 -2
  156. package/src/lib/config/loader.ts +57 -14
  157. package/src/lib/constants/components.ts +10 -0
  158. package/src/lib/hooks/index.ts +0 -1
  159. package/src/lib/hooks/useComponentCustomization.ts +11 -15
  160. package/src/lib/hooks/usePerformanceMonitor.ts +149 -0
  161. package/src/lib/patterns/index.ts +2 -2
  162. package/src/lib/patterns/slots.tsx +2 -2
  163. package/src/lib/theme/README.md +174 -0
  164. package/src/lib/theme/adapters/index.ts +31 -0
  165. package/src/lib/theme/adapters/themeAdapter.ts +287 -0
  166. package/src/lib/theme/config/__tests__/configLoader.test.ts +207 -0
  167. package/src/lib/theme/config/configLoader.ts +254 -0
  168. package/src/lib/theme/config/loader.ts +37 -48
  169. package/src/lib/theme/config/types.ts +2 -2
  170. package/src/lib/theme/config/validator.ts +15 -91
  171. package/src/lib/theme/{constants.ts → constants/constants.ts} +0 -18
  172. package/src/lib/theme/constants/index.ts +8 -0
  173. package/src/lib/theme/core/ThemeRegistry.ts +19 -6
  174. package/src/lib/theme/core/__tests__/createTheme.test.ts +132 -0
  175. package/src/lib/theme/core/composeTheme.ts +155 -0
  176. package/src/lib/theme/core/createTheme.ts +94 -0
  177. package/src/lib/theme/{createTheme.ts → core/createThemeObject.ts} +10 -6
  178. package/src/lib/theme/core/index.ts +5 -19
  179. package/src/lib/theme/devtools/Comparator.tsx +346 -22
  180. package/src/lib/theme/devtools/IMPROVEMENTS.md +139 -38
  181. package/src/lib/theme/devtools/Inspector.tsx +335 -51
  182. package/src/lib/theme/devtools/LiveEditor.tsx +489 -112
  183. package/src/lib/theme/devtools/Preview.tsx +471 -221
  184. package/src/lib/theme/{core → devtools}/ThemeValidator.ts +6 -3
  185. package/src/lib/theme/devtools/index.ts +14 -4
  186. package/src/lib/theme/devtools/useHistory.ts +130 -0
  187. package/src/lib/theme/errors/index.ts +12 -0
  188. package/src/lib/theme/generators/cssFile.ts +79 -0
  189. package/src/lib/theme/generators/generateCSS.ts +89 -0
  190. package/src/lib/theme/{generateCSSVariables.ts → generators/generateCSSVariables.ts} +4 -14
  191. package/src/lib/theme/generators/index.ts +19 -0
  192. package/src/lib/theme/i18n/rtl.ts +7 -7
  193. package/src/lib/theme/index.ts +120 -15
  194. package/src/lib/theme/runtime/ThemeApplicator.ts +53 -95
  195. package/src/lib/theme/{ThemeContext.tsx → runtime/ThemeContext.tsx} +1 -1
  196. package/src/lib/theme/runtime/ThemeErrorBoundary.tsx +4 -4
  197. package/src/lib/theme/runtime/ThemeProvider.tsx +456 -179
  198. package/src/lib/theme/runtime/index.ts +1 -2
  199. package/src/lib/theme/runtime/useTheme.ts +1 -2
  200. package/src/lib/theme/test/testTheme.ts +385 -0
  201. package/src/lib/theme/tokens/index.ts +12 -0
  202. package/src/lib/theme/tokens/tokens.ts +721 -0
  203. package/src/lib/theme/types.ts +6 -42
  204. package/src/lib/theme/{utils.ts → utils/domUtils.ts} +2 -2
  205. package/src/lib/theme/utils/index.ts +11 -0
  206. package/src/lib/theme/utils/injectCSS.ts +90 -0
  207. package/src/lib/theme/utils/themeHelpers.ts +78 -0
  208. package/src/lib/theme/{themeUtils.ts → utils/themeUtils.ts} +1 -1
  209. package/src/lib/theme-tools.ts +8 -9
  210. package/src/lib/types/components.ts +93 -34
  211. package/src/lib/types/partProps.ts +0 -16
  212. package/src/lib/utils/componentUtils.ts +1 -1
  213. package/src/lib/utils/fontPreloader.ts +148 -0
  214. package/src/lib/utils/index.ts +11 -0
  215. package/src/lib/utils/memoryMonitor.ts +189 -0
  216. package/src/styles/01-settings/_settings.design-tokens.scss +4 -1
  217. package/src/styles/01-settings/_settings.fonts.scss +2 -5
  218. package/src/styles/02-tools/_tools.button.scss +66 -79
  219. package/src/styles/06-components/_components.atomix-glass.scss +13 -3
  220. package/src/styles/06-components/_components.navbar.scss +0 -6
  221. package/src/styles/06-components/_components.pagination.scss +88 -0
  222. package/scripts/build-themes.js +0 -208
  223. package/scripts/sync-theme-config.js +0 -309
  224. package/src/components/AtomixGlass/atomixGLass.old.tsx +0 -1263
  225. package/src/lib/theme/composeTheme.ts +0 -370
  226. package/src/lib/theme/core/ThemeCache.ts +0 -283
  227. package/src/lib/theme/core/ThemeEngine.test.ts +0 -146
  228. package/src/lib/theme/core/ThemeEngine.ts +0 -657
  229. package/src/lib/theme/createThemeFromConfig.ts +0 -132
  230. package/src/lib/theme/devtools/CLI.ts +0 -364
  231. package/src/lib/theme/runtime/ThemeManager.test.ts +0 -192
  232. package/src/lib/theme/runtime/ThemeManager.ts +0 -442
  233. package/src/styles/03-generic/_generated-root.css +0 -5
  234. package/src/themes/README.md +0 -442
  235. package/src/themes/themes.config.js +0 -35
  236. /package/src/lib/theme/{cssVariableMapper.ts → adapters/cssVariableMapper.ts} +0 -0
  237. /package/src/lib/theme/{errors.ts → errors/errors.ts} +0 -0
@@ -1,22 +1,25 @@
1
- import { Meta, StoryFn } from '@storybook/react';
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
2
  import React, { useState } from 'react';
3
3
  import { Upload } from './Upload';
4
+ import { SIZES } from '../../lib/constants/components';
4
5
 
5
- export default {
6
+ const meta = {
6
7
  title: 'Components/Upload',
7
8
  component: Upload,
8
9
  parameters: {
10
+ layout: 'centered',
9
11
  docs: {
10
12
  description: {
11
13
  component:
12
- 'A modern file upload component with drag & drop functionality, progress tracking, and multiple size variants.',
14
+ 'The Upload component provides a modern file upload interface with drag & drop functionality, progress tracking, file preview, and validation. It supports single and multiple file uploads, custom file size limits, and provides visual feedback throughout the upload process. Ideal for forms requiring file attachments or media uploads.',
13
15
  },
14
16
  },
15
17
  },
18
+ tags: ['autodocs'],
16
19
  argTypes: {
17
20
  size: {
18
21
  control: { type: 'select' },
19
- options: ['sm', 'md', 'lg'],
22
+ options: SIZES,
20
23
  defaultValue: 'md',
21
24
  description: 'Size variant of the upload component',
22
25
  },
@@ -56,33 +59,37 @@ export default {
56
59
  description: 'Helper text displayed below the button',
57
60
  },
58
61
  },
59
- } as Meta<typeof Upload>;
62
+ } satisfies Meta<typeof Upload>;
60
63
 
61
- const Template: StoryFn<typeof Upload> = args => (
62
- <div style={{ padding: '30px', maxWidth: '600px' }}>
63
- <Upload {...args} />
64
- </div>
65
- );
64
+ export default meta;
65
+ type Story = StoryObj<typeof meta>;
66
66
 
67
67
  // Default upload component
68
- export const Default = Template.bind({});
69
- Default.args = {
70
- size: 'md',
71
- title: 'Drag and Drop files here',
72
- supportedFilesText: 'Files supported: PDF, XSLS, JPEG, PNG, Scanner',
73
- buttonText: 'Choose File',
74
- helperText: 'Maximum size: 5MB',
75
- };
76
- Default.parameters = {
77
- docs: {
78
- description: {
79
- story: 'The default upload component with medium size and standard styling.',
68
+ export const Default: Story = {
69
+ render: args => (
70
+ <div style={{ padding: '30px', maxWidth: '600px' }}>
71
+ <Upload {...args} />
72
+ </div>
73
+ ),
74
+ args: {
75
+ size: 'md',
76
+ title: 'Drag and Drop files here',
77
+ supportedFilesText: 'Files supported: PDF, XSLS, JPEG, PNG, Scanner',
78
+ buttonText: 'Choose File',
79
+ helperText: 'Maximum size: 5MB',
80
+ },
81
+ parameters: {
82
+ docs: {
83
+ description: {
84
+ story: 'The default upload component with medium size and standard styling.',
85
+ },
80
86
  },
81
87
  },
82
88
  };
83
89
 
84
90
  // Size Variants
85
- export const SizeVariants: StoryFn<typeof Upload> = () => (
91
+ export const SizeVariants: Story = {
92
+ render: () => (
86
93
  <div style={{ padding: '30px' }}>
87
94
  <div style={{ marginBottom: '40px' }}>
88
95
  <h3 style={{ marginBottom: '20px', fontSize: '18px', fontWeight: '600' }}>Small Size</h3>
@@ -125,25 +132,36 @@ export const SizeVariants: StoryFn<typeof Upload> = () => (
125
132
  </div>
126
133
  </div>
127
134
  </div>
128
- );
129
- SizeVariants.parameters = {
130
- docs: {
131
- description: {
132
- story: 'Upload component in different sizes: small (sm), medium (md), and large (lg).',
135
+ ),
136
+ parameters: {
137
+ docs: {
138
+ description: {
139
+ story: 'Upload component in different sizes: small (sm), medium (md), and large (lg).',
140
+ },
133
141
  },
134
142
  },
135
143
  };
136
144
 
137
145
  // Disabled state
138
- export const Disabled = Template.bind({});
139
- Disabled.args = {
140
- ...Default.args,
141
- disabled: true,
142
- };
143
- Disabled.parameters = {
144
- docs: {
145
- description: {
146
- story: 'Upload component in disabled state with reduced opacity and no interactions.',
146
+ export const Disabled: Story = {
147
+ render: args => (
148
+ <div style={{ padding: '30px', maxWidth: '600px' }}>
149
+ <Upload {...args} />
150
+ </div>
151
+ ),
152
+ args: {
153
+ size: 'md',
154
+ title: 'Drag and Drop files here',
155
+ supportedFilesText: 'Files supported: PDF, XSLS, JPEG, PNG, Scanner',
156
+ buttonText: 'Choose File',
157
+ helperText: 'Maximum size: 5MB',
158
+ disabled: true,
159
+ },
160
+ parameters: {
161
+ docs: {
162
+ description: {
163
+ story: 'Upload component in disabled state with reduced opacity and no interactions.',
164
+ },
147
165
  },
148
166
  },
149
167
  };
@@ -299,54 +317,71 @@ const WithStateControls: React.FC = () => {
299
317
  );
300
318
  };
301
319
 
302
- export const WithControls: StoryFn<typeof Upload> = () => <WithStateControls />;
303
- WithControls.parameters = {
304
- docs: {
305
- description: {
306
- story:
307
- 'Interactive example showing different upload states: default, uploading with progress, success, and error states.',
320
+ export const WithControls: Story = {
321
+ render: () => <WithStateControls />,
322
+ parameters: {
323
+ docs: {
324
+ description: {
325
+ story:
326
+ 'Interactive example showing different upload states: default, uploading with progress, success, and error states.',
327
+ },
308
328
  },
309
329
  },
310
330
  };
311
331
 
312
332
  // Custom Icon
313
- export const CustomIcon = Template.bind({});
314
- CustomIcon.args = {
315
- ...Default.args,
316
- icon: <i className="icon-lux-upload-cloud"></i>,
317
- title: 'Upload your documents',
318
- supportedFilesText: 'Drag files here or click to browse',
319
- };
320
- CustomIcon.parameters = {
321
- docs: {
322
- description: {
323
- story: 'Upload component with a custom icon and personalized text content.',
333
+ export const CustomIcon: Story = {
334
+ render: args => (
335
+ <div style={{ padding: '30px', maxWidth: '600px' }}>
336
+ <Upload {...args} />
337
+ </div>
338
+ ),
339
+ args: {
340
+ size: 'md',
341
+ title: 'Upload your documents',
342
+ supportedFilesText: 'Drag files here or click to browse',
343
+ buttonText: 'Choose File',
344
+ helperText: 'Maximum size: 5MB',
345
+ icon: <i className="icon-lux-upload-cloud"></i>,
346
+ },
347
+ parameters: {
348
+ docs: {
349
+ description: {
350
+ story: 'Upload component with a custom icon and personalized text content.',
351
+ },
324
352
  },
325
353
  },
326
354
  };
327
355
 
328
356
  // Multiple file upload
329
- export const MultipleFiles = Template.bind({});
330
- MultipleFiles.args = {
331
- ...Default.args,
332
- multiple: true,
333
- buttonText: 'Choose Files',
334
- title: 'Upload multiple files',
335
- supportedFilesText: 'Select multiple files at once',
336
- helperText: 'Maximum size: 5MB per file',
337
- };
338
- MultipleFiles.parameters = {
339
- docs: {
340
- description: {
341
- story: 'Upload component configured to accept multiple files at once.',
357
+ export const MultipleFiles: Story = {
358
+ render: args => (
359
+ <div style={{ padding: '30px', maxWidth: '600px' }}>
360
+ <Upload {...args} />
361
+ </div>
362
+ ),
363
+ args: {
364
+ size: 'md',
365
+ multiple: true,
366
+ buttonText: 'Choose Files',
367
+ title: 'Upload multiple files',
368
+ supportedFilesText: 'Select multiple files at once',
369
+ helperText: 'Maximum size: 5MB per file',
370
+ },
371
+ parameters: {
372
+ docs: {
373
+ description: {
374
+ story: 'Upload component configured to accept multiple files at once.',
375
+ },
342
376
  },
343
377
  },
344
378
  };
345
379
 
346
380
  // Drag and Drop Demo
347
- export const DragDropDemo: StoryFn<typeof Upload> = () => {
348
- const [dragState, setDragState] = useState<'idle' | 'dragging'>('idle');
349
- const [uploadedFiles, setUploadedFiles] = useState<string[]>([]);
381
+ export const DragDropDemo: Story = {
382
+ render: () => {
383
+ const [dragState, setDragState] = useState<'idle' | 'dragging'>('idle');
384
+ const [uploadedFiles, setUploadedFiles] = useState<string[]>([]);
350
385
 
351
386
  const handleFileSelect = (files: File[]) => {
352
387
  const fileNames = files.map(file => file.name);
@@ -415,20 +450,22 @@ export const DragDropDemo: StoryFn<typeof Upload> = () => {
415
450
  </div>
416
451
  )}
417
452
  </div>
418
- );
419
- };
420
- DragDropDemo.parameters = {
421
- docs: {
422
- description: {
423
- story:
424
- 'Interactive demonstration of drag & drop functionality with visual feedback and file tracking.',
453
+ );
454
+ },
455
+ parameters: {
456
+ docs: {
457
+ description: {
458
+ story:
459
+ 'Interactive demonstration of drag & drop functionality with visual feedback and file tracking.',
460
+ },
425
461
  },
426
462
  },
427
463
  };
428
464
 
429
465
  // Different File Types
430
- export const FileTypeRestrictions: StoryFn<typeof Upload> = () => (
431
- <div style={{ padding: '30px' }}>
466
+ export const FileTypeRestrictions: Story = {
467
+ render: () => (
468
+ <div style={{ padding: '30px' }}>
432
469
  <div style={{ marginBottom: '40px' }}>
433
470
  <h3 style={{ marginBottom: '20px', fontSize: '18px', fontWeight: '600' }}>Images Only</h3>
434
471
  <div style={{ maxWidth: '500px' }}>
@@ -462,11 +499,12 @@ export const FileTypeRestrictions: StoryFn<typeof Upload> = () => (
462
499
  </div>
463
500
  </div>
464
501
  </div>
465
- );
466
- FileTypeRestrictions.parameters = {
467
- docs: {
468
- description: {
469
- story: 'Upload components configured for specific file types with appropriate messaging.',
502
+ ),
503
+ parameters: {
504
+ docs: {
505
+ description: {
506
+ story: 'Upload components configured for specific file types with appropriate messaging.',
507
+ },
470
508
  },
471
509
  },
472
510
  };
@@ -9,10 +9,10 @@
9
9
  * @component VideoPlayer
10
10
  */
11
11
 
12
- import { Meta, StoryObj } from '@storybook/react';
12
+ import type { Meta, StoryObj } from '@storybook/react';
13
+ import { fn } from '@storybook/test';
13
14
  import { useState, useEffect, useCallback, useMemo, useRef } from 'react';
14
15
  import React from 'react';
15
- import { fn } from '@storybook/test';
16
16
  import { VideoPlayerProps } from '../../lib/types/components';
17
17
  import { VideoPlayer } from './VideoPlayer';
18
18
  import type { RefObject } from 'react';
@@ -23,31 +23,15 @@ import type { RefObject } from 'react';
23
23
  * This defines the component's metadata, documentation, and controls
24
24
  * for the Storybook interface.
25
25
  */
26
- const meta: Meta<typeof VideoPlayer> = {
26
+ const meta = {
27
27
  title: 'Components/VideoPlayer',
28
28
  component: VideoPlayer,
29
29
  parameters: {
30
30
  layout: 'centered',
31
31
  docs: {
32
32
  description: {
33
- component: `
34
- # VideoPlayer Component
35
-
36
- An advanced, modern video player with comprehensive features, accessibility support, and optional glass morphism effects. Supports both regular video files and YouTube embeds with seamless integration.
37
-
38
- ## Key Features
33
+ component: `The VideoPlayer component provides an advanced, modern video player with comprehensive features including custom controls, YouTube integration, glass morphism effects, and full accessibility support. It supports both regular video files and YouTube embeds with seamless auto-detection and provides a rich, interactive viewing experience.
39
34
 
40
- ### 🎥 **Dual Video Support**
41
- - **Regular Videos**: Native HTML5 video with custom controls
42
- - **YouTube Integration**: Seamless YouTube embedding with auto-detection
43
-
44
- ### ✨ **Glass Morphism Effects**
45
- - **Configurable Glass Overlay**: Optional frosted glass effects with AtomixGlass integration
46
- - **Custom Content Support**: Interactive overlays and call-to-action elements
47
- - **Multiple Glass Modes**: Standard, polar, prominent, and shader effects
48
-
49
- ### 🎛️ **Advanced Controls**
50
- - **Custom UI**: Modern, responsive control interface
51
35
  - **Quality Selection**: Multiple video resolution options
52
36
  - **Playback Speed**: Adjustable speed controls (0.25x to 4x)
53
37
  - **Subtitle Support**: Multi-language subtitle tracks with WebVTT
@@ -69,8 +53,7 @@ An advanced, modern video player with comprehensive features, accessibility supp
69
53
  ### 📱 **Multi-Platform**
70
54
  - **Cross-Browser**: Works on all modern browsers
71
55
  - **Mobile Optimized**: Touch-friendly controls and responsive layout
72
- - **Performance**: Optimized for smooth playback and effects
73
- `,
56
+ - **Performance**: Optimized for smooth playback and effects`,
74
57
  },
75
58
  },
76
59
  },
@@ -164,10 +147,10 @@ An advanced, modern video player with comprehensive features, accessibility supp
164
147
  description: 'Additional CSS class names',
165
148
  },
166
149
  },
167
- };
150
+ } satisfies Meta<typeof VideoPlayer>;
168
151
 
169
152
  export default meta;
170
- type Story = StoryObj<VideoPlayerProps>;
153
+ type Story = StoryObj<typeof meta>;
171
154
 
172
155
  /**
173
156
  * Background Wrapper Component
@@ -1,5 +1,6 @@
1
1
  export type { SliderProps, VideoPlayerProps } from '../lib/types/components';
2
- export { default as Accordion, type AccordionProps } from './Accordion/Accordion';
2
+ export { default as Accordion } from './Accordion/Accordion';
3
+ export type { AccordionProps } from '../lib/types/components';
3
4
  export { default as AtomixLogo, type AtomixLogoProps } from './AtomixLogo/AtomixLogo';
4
5
  export { default as AtomixGlass, type AtomixGlassProps } from './AtomixGlass';
5
6
  export { default as Avatar, type AvatarProps } from './Avatar/Avatar';
@@ -8,6 +9,7 @@ export { default as Badge, type BadgeProps } from './Badge/Badge';
8
9
  export { default as Block, type BlockProps } from './Block';
9
10
  export { default as Breadcrumb, type BreadcrumbProps } from './Breadcrumb/Breadcrumb';
10
11
  export { default as Button, type ButtonProps } from './Button/Button';
12
+ export { default as ButtonGroup, type ButtonGroupProps } from './Button/ButtonGroup';
11
13
  export { default as Callout, type CalloutProps } from './Callout/Callout';
12
14
  export { default as Card, type CardProps } from './Card/Card';
13
15
  // Card sub-components
@@ -37,7 +39,7 @@ export {
37
39
  type BubbleDataPoint,
38
40
  type CandlestickChartProps,
39
41
  type CandlestickDataPoint,
40
- type ChartProps,
42
+ // ChartProps exported separately from lib/types/components to avoid conflict
41
43
  type DonutChartProps,
42
44
  type FunnelChartProps,
43
45
  type FunnelDataPoint,
@@ -56,6 +58,8 @@ export {
56
58
  type WaterfallChartProps,
57
59
  type WaterfallDataPoint,
58
60
  } from './Chart';
61
+ // Export ChartProps from lib/types/components to avoid duplicate export conflict
62
+ export type { ChartProps } from '../lib/types/components';
59
63
  export {
60
64
  default as ColorModeToggle,
61
65
  type ColorModeToggleProps,
@@ -374,7 +374,7 @@ export const MasonryGrid = forwardRef<HTMLDivElement, MasonryGridProps>(
374
374
  const position = positions[index];
375
375
  if (!position) {
376
376
  return (
377
- <div key={item.id} ref={item.ref} style={{ opacity: 0, position: 'absolute' }}>
377
+ <div key={item.id} ref={item.ref as React.LegacyRef<HTMLDivElement>} style={{ opacity: 0, position: 'absolute' }}>
378
378
  {item.element}
379
379
  </div>
380
380
  );
@@ -382,7 +382,7 @@ export const MasonryGrid = forwardRef<HTMLDivElement, MasonryGridProps>(
382
382
  return (
383
383
  <div
384
384
  key={item.id}
385
- ref={item.ref}
385
+ ref={item.ref as React.LegacyRef<HTMLDivElement>}
386
386
  className="o-masonry-grid__item"
387
387
  style={{
388
388
  position: 'absolute',
@@ -1037,10 +1037,9 @@ export function useAtomixGlass({
1037
1037
  [onClick]
1038
1038
  );
1039
1039
 
1040
- // No-op handler for backward compatibility (mouse tracking now handled by shared tracker)
1040
+ // Mouse tracking is now handled by shared global tracker
1041
1041
  const handleMouseMove = useCallback((_e: MouseEvent) => {
1042
- // Mouse tracking is now handled by shared global tracker
1043
- // This handler is kept for backward compatibility with existing code
1042
+ // Mouse tracking handled by shared global tracker
1044
1043
  }, []);
1045
1044
 
1046
1045
  return {
@@ -70,35 +70,33 @@ export function useChartPerformance() {
70
70
  height: number,
71
71
  padding: { top: number; right: number; bottom: number; left: number }
72
72
  ) => {
73
- return useMemo(() => {
74
- if (!datasets.length) return null;
75
-
76
- const innerWidth = width - padding.left - padding.right;
77
- const innerHeight = height - padding.top - padding.bottom;
78
-
79
- // Calculate bounds efficiently
80
- const allValues = datasets.flatMap(dataset => dataset.data.map(d => d.value));
81
- const minValue = Math.min(...allValues);
82
- const maxValue = Math.max(...allValues);
83
- const valueRange = maxValue - minValue;
84
-
85
- // Pre-calculate scale functions for better performance
86
- const xScale = (i: number, dataLength: number) =>
87
- padding.left + (i / (dataLength - 1)) * innerWidth;
88
-
89
- const yScale = (value: number) =>
90
- padding.top + innerHeight - ((value - minValue) / valueRange) * innerHeight;
91
-
92
- return {
93
- xScale,
94
- yScale,
95
- minValue,
96
- maxValue,
97
- valueRange,
98
- innerWidth,
99
- innerHeight,
100
- };
101
- }, [datasets, width, height, padding.top, padding.right, padding.bottom, padding.left]);
73
+ if (!datasets.length) return null;
74
+
75
+ const innerWidth = width - padding.left - padding.right;
76
+ const innerHeight = height - padding.top - padding.bottom;
77
+
78
+ // Calculate bounds efficiently
79
+ const allValues = datasets.flatMap(dataset => dataset.data.map(d => d.value));
80
+ const minValue = Math.min(...allValues);
81
+ const maxValue = Math.max(...allValues);
82
+ const valueRange = maxValue - minValue;
83
+
84
+ // Pre-calculate scale functions for better performance
85
+ const xScale = (i: number, dataLength: number) =>
86
+ padding.left + (i / (dataLength - 1)) * innerWidth;
87
+
88
+ const yScale = (value: number) =>
89
+ padding.top + innerHeight - ((value - minValue) / valueRange) * innerHeight;
90
+
91
+ return {
92
+ xScale,
93
+ yScale,
94
+ minValue,
95
+ maxValue,
96
+ valueRange,
97
+ innerWidth,
98
+ innerHeight,
99
+ };
102
100
  },
103
101
  []
104
102
  );
@@ -113,47 +111,65 @@ export function useChartPerformance() {
113
111
  viewportEnd: number,
114
112
  bufferSize: number = 50
115
113
  ) => {
116
- return useMemo(() => {
117
- if (data.length <= 1000) {
118
- // No virtualization needed for small datasets
119
- return {
120
- visibleData: data,
121
- startIndex: 0,
122
- endIndex: data.length - 1,
123
- isVirtualized: false,
124
- };
125
- }
126
-
127
- const start = Math.max(0, viewportStart - bufferSize);
128
- const end = Math.min(data.length - 1, viewportEnd + bufferSize);
129
-
114
+ if (data.length <= 1000) {
115
+ // No virtualization needed for small datasets
130
116
  return {
131
- visibleData: data.slice(start, end + 1),
132
- startIndex: start,
133
- endIndex: end,
134
- isVirtualized: true,
135
- totalLength: data.length,
117
+ visibleData: data,
118
+ startIndex: 0,
119
+ endIndex: data.length - 1,
120
+ isVirtualized: false,
136
121
  };
137
- }, [data, viewportStart, viewportEnd, bufferSize]);
122
+ }
123
+
124
+ const start = Math.max(0, viewportStart - bufferSize);
125
+ const end = Math.min(data.length - 1, viewportEnd + bufferSize);
126
+
127
+ return {
128
+ visibleData: data.slice(start, end + 1),
129
+ startIndex: start,
130
+ endIndex: end,
131
+ isVirtualized: true,
132
+ totalLength: data.length,
133
+ };
138
134
  },
139
135
  []
140
136
  );
141
137
 
142
138
  /**
143
139
  * Debounced data updates for real-time charts
140
+ * Returns a debounced function that maintains timeout state across calls
141
+ * Uses a closure to maintain state - each call to useDebouncedUpdates creates
142
+ * a new debounced function with its own persistent timeout state
144
143
  */
145
144
  const useDebouncedUpdates = useCallback((updateFunction: () => void, delay: number = 100) => {
146
- const timeoutRef = useRef<NodeJS.Timeout | null>(null);
147
-
148
- return useCallback(() => {
149
- if (timeoutRef.current) {
150
- clearTimeout(timeoutRef.current);
145
+ // Use a closure variable to maintain timeout state across multiple calls to the returned function
146
+ // This variable is created once when useDebouncedUpdates is called and persists
147
+ // across all invocations of the returned debounced function
148
+ let timeoutId: NodeJS.Timeout | null = null;
149
+
150
+ const debouncedFn: (() => void) & { cancel: () => void } = () => {
151
+ // Clear any existing timeout before setting a new one
152
+ if (timeoutId !== null) {
153
+ clearTimeout(timeoutId);
154
+ timeoutId = null;
151
155
  }
152
156
 
153
- timeoutRef.current = setTimeout(() => {
157
+ // Set new timeout and store the ID
158
+ timeoutId = setTimeout(() => {
154
159
  updateFunction();
160
+ timeoutId = null;
155
161
  }, delay);
156
- }, [updateFunction, delay]);
162
+ };
163
+
164
+ // Add cleanup method to cancel pending debounced calls
165
+ debouncedFn.cancel = () => {
166
+ if (timeoutId !== null) {
167
+ clearTimeout(timeoutId);
168
+ timeoutId = null;
169
+ }
170
+ };
171
+
172
+ return debouncedFn;
157
173
  }, []);
158
174
 
159
175
  /**
@@ -192,32 +208,40 @@ export function useChartPerformance() {
192
208
 
193
209
  /**
194
210
  * Optimized animation frame handling
211
+ * Returns animation control functions that maintain state across calls
212
+ * Uses closures to maintain state - each call to useAnimationFrame creates
213
+ * a new animation controller with its own persistent state
195
214
  */
196
215
  const useAnimationFrame = useCallback((callback: () => void) => {
197
- const requestRef = useRef<number | null>(null);
198
- const previousTimeRef = useRef<number | null>(null);
199
-
200
- const animate = useCallback(
201
- (time: number) => {
202
- if (previousTimeRef.current !== undefined) {
203
- const deltaTime = time - (previousTimeRef.current || 0);
204
- callback();
205
- }
206
- previousTimeRef.current = time;
207
- requestRef.current = requestAnimationFrame(animate);
208
- },
209
- [callback]
210
- );
211
-
212
- const startAnimation = useCallback(() => {
213
- requestRef.current = requestAnimationFrame(animate);
214
- }, [animate]);
216
+ // Use closure variables to maintain animation state across multiple calls
217
+ // These variables are created once when useAnimationFrame is called and persist
218
+ // across all invocations of the returned animation control functions
219
+ let requestId: number | null = null;
220
+ let previousTime: number | null = null;
221
+
222
+ const animate = (time: number) => {
223
+ if (previousTime !== null && previousTime !== undefined) {
224
+ const deltaTime = time - previousTime;
225
+ callback();
226
+ }
227
+ previousTime = time;
228
+ requestId = requestAnimationFrame(animate);
229
+ };
230
+
231
+ const startAnimation = () => {
232
+ // Only start if not already running
233
+ if (requestId === null) {
234
+ requestId = requestAnimationFrame(animate);
235
+ }
236
+ };
215
237
 
216
- const stopAnimation = useCallback(() => {
217
- if (requestRef.current) {
218
- cancelAnimationFrame(requestRef.current);
238
+ const stopAnimation = () => {
239
+ if (requestId !== null) {
240
+ cancelAnimationFrame(requestId);
241
+ requestId = null;
219
242
  }
220
- }, []);
243
+ previousTime = null;
244
+ };
221
245
 
222
246
  return { startAnimation, stopAnimation };
223
247
  }, []);