@shohojdhara/atomix 0.2.3 → 0.2.5

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 (225) hide show
  1. package/README.md +19 -0
  2. package/dist/atomix.css +1703 -1544
  3. package/dist/atomix.min.css +4 -4
  4. package/dist/index.d.ts +1465 -963
  5. package/dist/index.esm.js +16289 -25908
  6. package/dist/index.esm.js.map +1 -1
  7. package/dist/index.js +15650 -21780
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.min.js +1 -1
  10. package/dist/index.min.js.map +1 -1
  11. package/dist/themes/applemix.css +15008 -0
  12. package/dist/themes/applemix.min.css +72 -0
  13. package/dist/themes/boomdevs.css +1608 -1450
  14. package/dist/themes/boomdevs.min.css +5 -5
  15. package/dist/themes/esrar.css +1702 -1543
  16. package/dist/themes/esrar.min.css +4 -4
  17. package/dist/themes/flashtrade.css +15159 -0
  18. package/dist/themes/flashtrade.min.css +86 -0
  19. package/dist/themes/mashroom.css +1699 -1540
  20. package/dist/themes/mashroom.min.css +7 -7
  21. package/dist/themes/shaj-default.css +1693 -1534
  22. package/dist/themes/shaj-default.min.css +4 -4
  23. package/package.json +6 -17
  24. package/src/components/Accordion/Accordion.stories.tsx +662 -21
  25. package/src/components/Accordion/Accordion.tsx +21 -14
  26. package/src/components/AtomixGlass/AtomixGlass.test.tsx +106 -72
  27. package/src/components/AtomixGlass/AtomixGlass.tsx +529 -1195
  28. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +400 -0
  29. package/src/components/AtomixGlass/GlassFilter.tsx +156 -0
  30. package/src/components/AtomixGlass/README.md +124 -2
  31. package/src/components/AtomixGlass/atomixGLass.old.tsx +1266 -0
  32. package/src/components/AtomixGlass/glass-utils.ts +263 -0
  33. package/src/components/AtomixGlass/shader-utils.ts +792 -68
  34. package/src/components/AtomixGlass/stories/AtomixGlass.stories.tsx +1250 -0
  35. package/src/components/AtomixGlass/stories/Examples.stories.tsx +5768 -0
  36. package/src/components/AtomixGlass/stories/Modes.stories.tsx +1065 -0
  37. package/src/components/AtomixGlass/stories/Playground.stories.tsx +1129 -0
  38. package/src/components/AtomixGlass/stories/ShaderVariants.stories.tsx +395 -0
  39. package/src/components/AtomixGlass/stories/shared-components.tsx +301 -0
  40. package/src/components/AtomixGlass/utils.ts +3 -3
  41. package/src/components/Avatar/Avatar.tsx +3 -0
  42. package/src/components/Avatar/AvatarGroup.tsx +2 -1
  43. package/src/components/Badge/Badge.stories.tsx +76 -55
  44. package/src/components/Badge/Badge.tsx +12 -14
  45. package/src/components/Breadcrumb/Breadcrumb.tsx +23 -4
  46. package/src/components/Button/Button.stories.tsx +501 -20
  47. package/src/components/Button/Button.tsx +5 -8
  48. package/src/components/Callout/Callout.stories.tsx +86 -35
  49. package/src/components/Callout/Callout.tsx +31 -9
  50. package/src/components/Card/Card.stories.tsx +565 -2
  51. package/src/components/Card/Card.tsx +15 -4
  52. package/src/components/Card/ElevationCard.tsx +2 -0
  53. package/src/components/Chart/AnimatedChart.tsx +179 -156
  54. package/src/components/Chart/AreaChart.tsx +123 -12
  55. package/src/components/Chart/BarChart.tsx +91 -100
  56. package/src/components/Chart/BaseChart.tsx +80 -0
  57. package/src/components/Chart/BubbleChart.tsx +114 -290
  58. package/src/components/Chart/CandlestickChart.tsx +282 -622
  59. package/src/components/Chart/Chart.stories.tsx +576 -179
  60. package/src/components/Chart/Chart.tsx +374 -75
  61. package/src/components/Chart/ChartRenderer.tsx +371 -220
  62. package/src/components/Chart/ChartToolbar.tsx +372 -61
  63. package/src/components/Chart/ChartTooltip.tsx +33 -18
  64. package/src/components/Chart/DonutChart.tsx +172 -254
  65. package/src/components/Chart/FunnelChart.tsx +169 -240
  66. package/src/components/Chart/GaugeChart.tsx +224 -392
  67. package/src/components/Chart/HeatmapChart.tsx +302 -440
  68. package/src/components/Chart/LineChart.tsx +148 -103
  69. package/src/components/Chart/MultiAxisChart.tsx +267 -395
  70. package/src/components/Chart/PieChart.tsx +114 -64
  71. package/src/components/Chart/RadarChart.tsx +202 -218
  72. package/src/components/Chart/ScatterChart.tsx +111 -97
  73. package/src/components/Chart/TreemapChart.tsx +147 -222
  74. package/src/components/Chart/WaterfallChart.tsx +253 -291
  75. package/src/components/Chart/index.ts +11 -9
  76. package/src/components/Chart/types.ts +85 -9
  77. package/src/components/Chart/utils.ts +66 -0
  78. package/src/components/ColorModeToggle/ColorModeToggle.tsx +6 -3
  79. package/src/components/Countdown/Countdown.tsx +4 -0
  80. package/src/components/DataTable/DataTable.tsx +2 -1
  81. package/src/components/DatePicker/DatePicker.stories.tsx +689 -12
  82. package/src/components/DatePicker/DatePicker.tsx +3 -9
  83. package/src/components/DatePicker/types.ts +5 -0
  84. package/src/components/Dropdown/Dropdown.stories.tsx +32 -25
  85. package/src/components/Dropdown/Dropdown.tsx +26 -28
  86. package/src/components/EdgePanel/EdgePanel.stories.tsx +473 -2
  87. package/src/components/EdgePanel/EdgePanel.tsx +101 -13
  88. package/src/components/Footer/Footer.stories.tsx +187 -60
  89. package/src/components/Footer/Footer.test.tsx +134 -0
  90. package/src/components/Footer/Footer.tsx +133 -34
  91. package/src/components/Footer/FooterLink.tsx +1 -1
  92. package/src/components/Footer/FooterSection.tsx +53 -36
  93. package/src/components/Footer/FooterSocialLink.tsx +32 -29
  94. package/src/components/Footer/README.md +82 -3
  95. package/src/components/Footer/index.ts +1 -1
  96. package/src/components/Form/Checkbox.stories.tsx +13 -5
  97. package/src/components/Form/Checkbox.tsx +3 -6
  98. package/src/components/Form/Form.stories.tsx +10 -3
  99. package/src/components/Form/Form.tsx +2 -0
  100. package/src/components/Form/FormGroup.tsx +2 -1
  101. package/src/components/Form/Input.stories.tsx +12 -11
  102. package/src/components/Form/Input.tsx +97 -95
  103. package/src/components/Form/Radio.stories.tsx +22 -7
  104. package/src/components/Form/Radio.tsx +3 -6
  105. package/src/components/Form/Select.stories.tsx +21 -6
  106. package/src/components/Form/Select.tsx +3 -5
  107. package/src/components/Form/Textarea.stories.tsx +13 -11
  108. package/src/components/Form/Textarea.tsx +88 -86
  109. package/src/components/Hero/Hero.stories.tsx +2 -3
  110. package/src/components/Hero/Hero.tsx +5 -6
  111. package/src/components/Icon/Icon.tsx +12 -1
  112. package/src/components/List/List.tsx +2 -1
  113. package/src/components/List/ListGroup.tsx +2 -1
  114. package/src/components/Messages/Messages.stories.tsx +113 -0
  115. package/src/components/Messages/Messages.tsx +52 -9
  116. package/src/components/Modal/Modal.stories.tsx +48 -32
  117. package/src/components/Modal/Modal.tsx +19 -24
  118. package/src/components/Navigation/Menu/MegaMenu.tsx +2 -2
  119. package/src/components/Navigation/Menu/Menu.tsx +2 -2
  120. package/src/components/Navigation/Nav/Nav.stories.tsx +469 -0
  121. package/src/components/Navigation/Nav/Nav.tsx +22 -4
  122. package/src/components/Navigation/Nav/NavDropdown.tsx +10 -1
  123. package/src/components/Navigation/Navbar/Navbar.stories.tsx +413 -0
  124. package/src/components/Navigation/Navbar/Navbar.tsx +70 -29
  125. package/src/components/Navigation/SideMenu/SideMenu.stories.tsx +340 -0
  126. package/src/components/Navigation/SideMenu/SideMenu.tsx +29 -2
  127. package/src/components/Pagination/Pagination.stories.tsx +13 -6
  128. package/src/components/Pagination/Pagination.tsx +7 -6
  129. package/src/components/PhotoViewer/PhotoViewer.tsx +2 -1
  130. package/src/components/Popover/Popover.stories.tsx +32 -24
  131. package/src/components/Popover/Popover.tsx +4 -1
  132. package/src/components/ProductReview/ProductReview.tsx +8 -2
  133. package/src/components/Progress/Progress.tsx +19 -3
  134. package/src/components/Rating/Rating.stories.tsx +11 -6
  135. package/src/components/Rating/Rating.tsx +3 -5
  136. package/src/components/River/River.tsx +5 -5
  137. package/src/components/SectionIntro/SectionIntro.tsx +8 -2
  138. package/src/components/Slider/Slider.stories.tsx +4 -4
  139. package/src/components/Slider/Slider.tsx +4 -3
  140. package/src/components/Spinner/Spinner.tsx +19 -3
  141. package/src/components/Steps/Steps.stories.tsx +5 -4
  142. package/src/components/Steps/Steps.tsx +8 -5
  143. package/src/components/Tab/Tab.stories.tsx +4 -3
  144. package/src/components/Tab/Tab.tsx +8 -6
  145. package/src/components/Testimonial/Testimonial.tsx +8 -2
  146. package/src/components/Todo/Todo.tsx +2 -1
  147. package/src/components/Toggle/Toggle.stories.tsx +5 -4
  148. package/src/components/Toggle/Toggle.tsx +8 -5
  149. package/src/components/Tooltip/Tooltip.stories.tsx +40 -30
  150. package/src/components/Tooltip/Tooltip.tsx +9 -2
  151. package/src/components/Upload/Upload.stories.tsx +252 -0
  152. package/src/components/Upload/Upload.tsx +92 -53
  153. package/src/components/VideoPlayer/VideoPlayer.tsx +3 -1
  154. package/src/components/index.ts +0 -4
  155. package/src/layouts/Grid/Grid.stories.tsx +10 -23
  156. package/src/layouts/Grid/Grid.tsx +20 -1
  157. package/src/layouts/Grid/GridCol.tsx +76 -48
  158. package/src/lib/composables/useAtomixGlass.ts +861 -44
  159. package/src/lib/composables/useBarChart.ts +21 -4
  160. package/src/lib/composables/useChart.ts +227 -370
  161. package/src/lib/composables/useChartExport.ts +19 -78
  162. package/src/lib/composables/useChartToolbar.ts +11 -21
  163. package/src/lib/composables/useEdgePanel.ts +125 -71
  164. package/src/lib/composables/useFooter.ts +3 -3
  165. package/src/lib/composables/useGlassContainer.ts +16 -7
  166. package/src/lib/composables/useLineChart.ts +11 -2
  167. package/src/lib/composables/usePieChart.ts +4 -14
  168. package/src/lib/composables/useRiver.ts +5 -0
  169. package/src/lib/composables/useSlider.ts +62 -24
  170. package/src/lib/composables/useVideoPlayer.ts +60 -63
  171. package/src/lib/constants/components.ts +147 -32
  172. package/src/lib/types/components.ts +355 -25
  173. package/src/lib/utils/displacement-generator.ts +55 -49
  174. package/src/lib/utils/icons.ts +1 -1
  175. package/src/lib/utils/index.ts +16 -10
  176. package/src/styles/01-settings/_settings.accordion.scss +19 -19
  177. package/src/styles/01-settings/_settings.animations.scss +5 -5
  178. package/src/styles/01-settings/_settings.avatar-group.scss +1 -1
  179. package/src/styles/01-settings/_settings.avatar.scss +17 -17
  180. package/src/styles/01-settings/_settings.background.scss +0 -3
  181. package/src/styles/01-settings/_settings.badge.scss +1 -1
  182. package/src/styles/01-settings/_settings.breadcrumb.scss +1 -1
  183. package/src/styles/01-settings/_settings.card.scss +1 -1
  184. package/src/styles/01-settings/_settings.chart.scss +65 -2
  185. package/src/styles/01-settings/_settings.dropdown.scss +1 -1
  186. package/src/styles/01-settings/_settings.edge-panel.scss +1 -1
  187. package/src/styles/01-settings/_settings.footer.scss +35 -42
  188. package/src/styles/01-settings/_settings.input.scss +1 -1
  189. package/src/styles/01-settings/_settings.list.scss +1 -1
  190. package/src/styles/01-settings/_settings.rating.scss +1 -1
  191. package/src/styles/01-settings/_settings.tabs.scss +1 -1
  192. package/src/styles/01-settings/_settings.upload.scss +6 -5
  193. package/src/styles/02-tools/_tools.animations.scss +4 -5
  194. package/src/styles/02-tools/_tools.background.scss +1 -13
  195. package/src/styles/02-tools/_tools.glass.scss +0 -1
  196. package/src/styles/02-tools/_tools.utility-api.scss +91 -48
  197. package/src/styles/03-generic/_generic.root.scss +1 -4
  198. package/src/styles/04-elements/_elements.body.scss +0 -1
  199. package/src/styles/06-components/_components.atomix-glass.scss +249 -0
  200. package/src/styles/06-components/_components.badge.scss +8 -23
  201. package/src/styles/06-components/_components.button.scss +8 -3
  202. package/src/styles/06-components/_components.callout.scss +10 -5
  203. package/src/styles/06-components/_components.card.scss +2 -14
  204. package/src/styles/06-components/_components.chart.scss +969 -1449
  205. package/src/styles/06-components/_components.dropdown.scss +19 -7
  206. package/src/styles/06-components/_components.edge-panel.scss +103 -0
  207. package/src/styles/06-components/_components.footer.scss +166 -85
  208. package/src/styles/06-components/_components.input.scss +8 -9
  209. package/src/styles/06-components/_components.list.scss +1 -0
  210. package/src/styles/06-components/_components.messages.scss +176 -0
  211. package/src/styles/06-components/_components.modal.scss +16 -4
  212. package/src/styles/06-components/_components.navbar.scss +12 -1
  213. package/src/styles/06-components/_components.side-menu.scss +5 -0
  214. package/src/styles/06-components/_components.skeleton.scss +8 -6
  215. package/src/styles/06-components/_components.upload.scss +219 -4
  216. package/src/styles/06-components/old.chart.styles.scss +1 -30
  217. package/src/styles/99-utilities/_index.scss +1 -0
  218. package/src/styles/99-utilities/_utilities.glass-fixes.scss +1 -0
  219. package/src/styles/99-utilities/_utilities.scss +1 -1
  220. package/src/components/AtomixGlass/AtomixGlass.stories.tsx +0 -3011
  221. package/src/components/AtomixGlass/AtomixGlassComprehensivePreview.stories.tsx +0 -1369
  222. package/src/components/Chart/AdvancedChart.tsx +0 -624
  223. package/src/components/Chart/LineChartNew.tsx +0 -167
  224. package/src/components/Chart/RealTimeChart.tsx +0 -436
  225. package/src/components/DatePicker/DatePicker copy.tsx +0 -551
@@ -1,8 +1,8 @@
1
1
  import { forwardRef, memo, useCallback, useEffect, useRef } from 'react';
2
- import Chart from './Chart';
3
- import { ChartProps } from './types';
2
+ import BaseChart from './BaseChart';
3
+ import { ChartProps, ChartRenderContentParams } from './types';
4
4
 
5
- interface AnimatedChartProps extends Omit<ChartProps, 'type'> {
5
+ export interface AnimatedChartProps extends Omit<ChartProps, 'type'> {
6
6
  chartType?: 'line' | 'bar' | 'area';
7
7
  animationConfig?: {
8
8
  duration?: number;
@@ -19,8 +19,17 @@ interface AnimatedChartProps extends Omit<ChartProps, 'type'> {
19
19
 
20
20
  const AnimatedChart = memo(
21
21
  forwardRef<HTMLDivElement, AnimatedChartProps>(
22
- ({ datasets = [], config = {}, chartType = 'line', particleEffects, ...props }, ref) => {
23
- const canvasRef = useRef<HTMLCanvasElement>(null);
22
+ (
23
+ {
24
+ datasets = [],
25
+ config = {},
26
+ chartType = 'line',
27
+ particleEffects,
28
+ onDataPointClick,
29
+ ...props
30
+ },
31
+ ref
32
+ ) => {
24
33
  const animationRef = useRef<number>(0);
25
34
  const timeRef = useRef(0);
26
35
  const particlesRef = useRef<
@@ -36,166 +45,181 @@ const AnimatedChart = memo(
36
45
  }>
37
46
  >([]);
38
47
 
39
- const animate = useCallback(
40
- (timestamp?: number) => {
41
- const canvas = canvasRef.current;
42
- if (!canvas) return;
43
-
44
- const ctx = canvas.getContext('2d');
45
- if (!ctx) return;
46
-
47
- const { width, height } = canvas;
48
- const time = timeRef.current * 0.02;
49
-
50
- // Create gradient background
51
- const gradient = ctx.createLinearGradient(0, 0, 0, height);
52
- gradient.addColorStop(0, '#0a0a0a');
53
- gradient.addColorStop(0.5, '#1a1a2e');
54
- gradient.addColorStop(1, '#16213e');
55
-
56
- ctx.fillStyle = gradient;
57
- ctx.fillRect(0, 0, width, height);
58
-
59
- // Calculate data-based wave positions
60
- const dataPoints = datasets[0]?.data || [];
61
- const maxValue = Math.max(...dataPoints.map(d => d.value));
62
- const minValue = Math.min(...dataPoints.map(d => d.value));
63
- const valueRange = maxValue - minValue || 1;
64
-
65
- // Generate particles based on data
66
- if (particlesRef.current.length < (particleEffects?.count || 800)) {
67
- for (let i = 0; i < 3; i++) {
68
- const dataIndex = Math.floor(Math.random() * dataPoints.length);
69
- const dataPoint = dataPoints[dataIndex];
70
-
71
- if (dataPoint) {
72
- const normalizedValue = (dataPoint.value - minValue) / valueRange;
73
- const dataX = (dataIndex / (dataPoints.length - 1)) * width;
74
- const dataY = height - normalizedValue * height * 0.6 - height * 0.2;
75
-
76
- particlesRef.current.push({
77
- x: dataX + (Math.random() - 0.5) * 50,
78
- y: dataY + (Math.random() - 0.5) * 30,
79
- vx: (Math.random() - 0.5) * (particleEffects?.speed || 2),
80
- vy: -Math.random() * 2 - 0.5,
81
- life: 1,
82
- size: (particleEffects?.size || 2) * (0.5 + normalizedValue * 0.5),
83
- color:
84
- particleEffects?.colors?.[dataIndex % (particleEffects.colors.length || 1)] ||
85
- '#22c55e',
86
- dataIndex,
87
- });
48
+ const renderContent = useCallback(
49
+ ({
50
+ scales,
51
+ colors,
52
+ datasets: chartDatasets,
53
+ handlers,
54
+ hoveredPoint,
55
+ toolbarState,
56
+ config: renderConfig,
57
+ }: ChartRenderContentParams) => {
58
+ // Use toolbar state if available, fallback to config for backward compatibility
59
+ const shouldAnimate = toolbarState?.animationsEnabled ?? renderConfig?.animate ?? true;
60
+ // Animation time tracking
61
+ useEffect(() => {
62
+ const animateFrame = (timestamp: number) => {
63
+ timeRef.current = timestamp;
64
+ animationRef.current = requestAnimationFrame(animateFrame);
65
+ };
66
+
67
+ animationRef.current = requestAnimationFrame(animateFrame);
68
+
69
+ return () => {
70
+ if (animationRef.current) {
71
+ cancelAnimationFrame(animationRef.current);
88
72
  }
73
+ };
74
+ }, []);
75
+
76
+ if (!chartDatasets.length) return null;
77
+
78
+ const padding = 40;
79
+ const chartWidth = scales.width - padding * 2;
80
+ const chartHeight = scales.height - padding * 2;
81
+
82
+ // Create animated elements based on chart type
83
+ const elements: React.ReactNode[] = [];
84
+
85
+ chartDatasets.forEach((dataset: any, datasetIndex: number) => {
86
+ const color = dataset.color || colors[datasetIndex % colors.length];
87
+
88
+ switch (chartType) {
89
+ case 'bar':
90
+ // Create animated bars
91
+ dataset.data.forEach((point: any, pointIndex: number) => {
92
+ const barWidth = (chartWidth / dataset.data.length) * 0.8;
93
+ const x =
94
+ padding +
95
+ pointIndex * (chartWidth / dataset.data.length) +
96
+ (chartWidth / dataset.data.length - barWidth) / 2;
97
+ const height = (point.value / 100) * chartHeight; // Assuming normalized values
98
+ const y = padding + chartHeight - height;
99
+
100
+ elements.push(
101
+ <rect
102
+ key={`bar-${datasetIndex}-${pointIndex}`}
103
+ x={x}
104
+ y={y}
105
+ width={barWidth}
106
+ height={height}
107
+ fill={color}
108
+ style={{
109
+ transform: `scaleY(${Math.sin(timeRef.current * 0.01 + pointIndex * 0.2) * 0.1 + 0.9})`,
110
+ transformOrigin: 'bottom',
111
+ }}
112
+ onClick={() => handlers.onDataPointClick?.(point, datasetIndex, pointIndex)}
113
+ />
114
+ );
115
+ });
116
+ break;
117
+
118
+ case 'area':
119
+ case 'line':
120
+ default:
121
+ // Create animated line/area
122
+ const points = dataset.data.map((point: any, pointIndex: number) => ({
123
+ x: padding + (pointIndex / (dataset.data.length - 1)) * chartWidth,
124
+ y: padding + chartHeight - (point.value / 100) * chartHeight, // Assuming normalized values
125
+ }));
126
+
127
+ if (points.length > 0) {
128
+ const linePath = `M ${points.map((p: any) => `${p.x},${p.y}`).join(' L ')}`;
129
+
130
+ // Area for area chart
131
+ if (chartType === 'area') {
132
+ const areaPath = `${linePath} L ${padding + chartWidth},${padding + chartHeight} L ${padding},${padding + chartHeight} Z`;
133
+ elements.push(
134
+ <path
135
+ key={`area-${datasetIndex}`}
136
+ d={areaPath}
137
+ fill={color}
138
+ fillOpacity="0.3"
139
+ style={{
140
+ transform: `translateY(${Math.sin(timeRef.current * 0.01) * 2}px)`,
141
+ }}
142
+ />
143
+ );
144
+ }
145
+
146
+ // Line
147
+ elements.push(
148
+ <path
149
+ key={`line-${datasetIndex}`}
150
+ d={linePath}
151
+ stroke={color}
152
+ fill="none"
153
+ className="c-chart__data-line"
154
+ style={{
155
+ transform: `translateY(${Math.sin(timeRef.current * 0.01) * 2}px)`,
156
+ }}
157
+ />
158
+ );
159
+
160
+ // Data points
161
+ points.forEach((point: any, pointIndex: number) => {
162
+ elements.push(
163
+ <circle
164
+ key={`point-${datasetIndex}-${pointIndex}`}
165
+ cx={point.x}
166
+ cy={point.y}
167
+ r="4"
168
+ fill={color}
169
+ style={{
170
+ transform: `scale(${1 + Math.sin(timeRef.current * 0.01 + pointIndex) * 0.2})`,
171
+ }}
172
+ onClick={() =>
173
+ handlers.onDataPointClick?.(
174
+ dataset.data[pointIndex],
175
+ datasetIndex,
176
+ pointIndex
177
+ )
178
+ }
179
+ />
180
+ );
181
+ });
182
+ }
183
+ break;
89
184
  }
90
- }
91
-
92
- // Update and draw particles
93
- particlesRef.current = particlesRef.current.filter(particle => {
94
- particle.x += particle.vx;
95
- particle.y += particle.vy;
96
- particle.life -= 0.008;
97
- particle.vy += 0.015;
98
-
99
- if (particle.life <= 0 || particle.y > height + 50) return false;
100
-
101
- // Data-influenced wave effect
102
- const dataInfluence =
103
- particle.dataIndex !== undefined && dataPoints[particle.dataIndex]
104
- ? (dataPoints[particle.dataIndex]?.value || 0) / maxValue
105
- : 0.5;
106
-
107
- const waveOffset =
108
- Math.sin(particle.x * 0.01 + time) * 20 * dataInfluence +
109
- Math.sin(particle.x * 0.008 + time * 1.2) * 15;
110
- const finalY = particle.y + waveOffset;
111
-
112
- ctx.save();
113
- ctx.globalAlpha = particle.life * 0.8;
114
- ctx.beginPath();
115
- ctx.arc(particle.x, finalY, particle.size, 0, Math.PI * 2);
116
- ctx.fillStyle = particle.color;
117
- ctx.fill();
118
-
119
- ctx.shadowBlur = 8;
120
- ctx.shadowColor = particle.color;
121
- ctx.fill();
122
- ctx.restore();
123
-
124
- return true;
125
185
  });
126
186
 
127
- // Draw data-based flowing lines
128
- if (dataPoints.length > 1) {
129
- const colors = particleEffects?.colors || ['#22c55e'];
130
- colors.forEach((color, index) => {
131
- ctx.strokeStyle = color;
132
- ctx.lineWidth = 2;
133
- ctx.globalAlpha = 0.6;
134
- ctx.beginPath();
135
-
136
- dataPoints.forEach((point, i) => {
137
- const x = (i / (dataPoints.length - 1)) * width;
138
- const normalizedValue = (point.value - minValue) / valueRange;
139
- const baseY = height - normalizedValue * height * 0.6 - height * 0.2;
140
- const y = baseY + Math.sin(x * 0.008 + time + index) * 30;
141
-
142
- if (i === 0) ctx.moveTo(x, y);
143
- else ctx.lineTo(x, y);
144
- });
145
- ctx.stroke();
146
- });
147
- }
148
-
149
- // Draw grid
150
- ctx.strokeStyle = 'rgba(34, 197, 94, 0.1)';
151
- ctx.lineWidth = 1;
152
- ctx.globalAlpha = 0.2;
153
-
154
- for (let x = 0; x < width; x += 60) {
155
- ctx.beginPath();
156
- ctx.moveTo(x, 0);
157
- ctx.lineTo(x, height);
158
- ctx.stroke();
187
+ // Particle effects
188
+ if (particleEffects?.enabled) {
189
+ for (let i = 0; i < particleEffects.count; i++) {
190
+ const particle = particlesRef.current[i];
191
+ if (particle) {
192
+ elements.push(
193
+ <circle
194
+ key={`particle-${i}`}
195
+ cx={particle.x}
196
+ cy={particle.y}
197
+ r={particle.size}
198
+ fill={particle.color}
199
+ style={{
200
+ opacity: particle.life,
201
+ }}
202
+ />
203
+ );
204
+ }
205
+ }
159
206
  }
160
207
 
161
- timeRef.current += 1;
162
- animationRef.current = requestAnimationFrame(animate);
208
+ return <g>{elements}</g>;
163
209
  },
164
- [particleEffects, datasets]
210
+ [chartType, particleEffects]
165
211
  );
166
212
 
167
- useEffect(() => {
168
- const canvas = canvasRef.current;
169
- if (!canvas) return undefined;
170
-
171
- const resizeCanvas = () => {
172
- canvas.width = canvas.offsetWidth;
173
- canvas.height = canvas.offsetHeight;
174
- };
175
-
176
- resizeCanvas();
177
- window.addEventListener('resize', resizeCanvas);
178
- animate(0);
179
-
180
- return () => {
181
- window.removeEventListener('resize', resizeCanvas);
182
- if (animationRef.current) {
183
- cancelAnimationFrame(animationRef.current);
184
- }
185
- };
186
- }, [animate]);
187
-
188
213
  return (
189
- <Chart ref={ref} type={chartType} datasets={datasets} config={config} {...props}>
190
- <canvas
191
- ref={canvasRef}
192
- style={{
193
- width: '100%',
194
- height: '100%',
195
- borderRadius: '8px',
196
- }}
197
- />
198
- </Chart>
214
+ <BaseChart
215
+ ref={ref}
216
+ type="animated"
217
+ datasets={datasets}
218
+ config={config}
219
+ renderContent={renderContent}
220
+ onDataPointClick={onDataPointClick}
221
+ {...props}
222
+ />
199
223
  );
200
224
  }
201
225
  )
@@ -203,4 +227,3 @@ const AnimatedChart = memo(
203
227
 
204
228
  AnimatedChart.displayName = 'AnimatedChart';
205
229
  export default AnimatedChart;
206
- export type { AnimatedChartProps };
@@ -1,5 +1,8 @@
1
1
  import { forwardRef, memo } from 'react';
2
- import LineChart, { LineChartProps } from './LineChart';
2
+ import BaseChart from './BaseChart';
3
+ import ChartTooltip from './ChartTooltip';
4
+ import { LineChartProps } from './LineChart';
5
+ import { ChartRenderContentParams, ChartDataset, ChartDataPoint } from './types';
3
6
 
4
7
  interface AreaChartProps extends Omit<LineChartProps, 'lineOptions'> {
5
8
  /**
@@ -9,17 +12,125 @@ interface AreaChartProps extends Omit<LineChartProps, 'lineOptions'> {
9
12
  }
10
13
 
11
14
  const AreaChart = memo(
12
- forwardRef<HTMLDivElement, AreaChartProps>(({ areaOptions = {}, ...props }, ref) => {
13
- // Area chart is essentially a line chart with area fill enabled
14
- const enhancedAreaOptions = {
15
- showArea: true,
16
- fillOpacity: 0.3,
17
- useGradient: true,
18
- ...areaOptions,
19
- };
20
-
21
- return <LineChart ref={ref} lineOptions={enhancedAreaOptions} {...props} />;
22
- })
15
+ forwardRef<HTMLDivElement, AreaChartProps>(
16
+ ({ datasets = [], config = {}, areaOptions = {}, onDataPointClick, ...props }, ref) => {
17
+ // Area chart is essentially a line chart with area fill enabled
18
+ const enhancedAreaOptions = {
19
+ showArea: true,
20
+ fillOpacity: 0.3,
21
+ useGradient: true,
22
+ ...areaOptions,
23
+ };
24
+
25
+ const renderContent = ({
26
+ scales,
27
+ colors,
28
+ datasets: renderedDatasets,
29
+ handlers,
30
+ hoveredPoint,
31
+ toolbarState,
32
+ config: renderConfig,
33
+ }: ChartRenderContentParams) => {
34
+ if (!renderedDatasets.length) return null;
35
+
36
+ // Use toolbar state if available, fallback to config for backward compatibility
37
+ const showTooltips = toolbarState?.showTooltips ?? renderConfig?.showTooltips ?? true;
38
+
39
+ return (
40
+ <>
41
+ {renderedDatasets.map((dataset: ChartDataset, datasetIndex: number) => {
42
+ const color = dataset.color || colors[datasetIndex];
43
+ const data = dataset.data || [];
44
+
45
+ if (data.length === 0) return null;
46
+
47
+ // Generate area path
48
+ const areaPoints = data.map((point: ChartDataPoint, index: number) => ({
49
+ x: scales.xScale(index, data.length),
50
+ y: scales.yScale(point.value),
51
+ }));
52
+
53
+ const areaPath = `M ${areaPoints.map((p) => `${p.x},${p.y}`).join(' L ')} L ${areaPoints[areaPoints.length - 1]?.x},${scales.height} L ${areaPoints[0]?.x},${scales.height} Z`;
54
+
55
+ return (
56
+ <g key={`dataset-${datasetIndex}`}>
57
+ <path
58
+ d={areaPath}
59
+ fill={color}
60
+ fillOpacity={enhancedAreaOptions.fillOpacity || 0.3}
61
+ className="c-chart__area-fill"
62
+ />
63
+ {data.map((point: ChartDataPoint, index: number) => {
64
+ const x = scales.xScale(index, data.length);
65
+ const y = scales.yScale(point.value);
66
+ const isHovered =
67
+ hoveredPoint?.datasetIndex === datasetIndex &&
68
+ hoveredPoint?.pointIndex === index;
69
+
70
+ return (
71
+ <circle
72
+ key={`point-${index}`}
73
+ cx={x}
74
+ cy={y}
75
+ r={isHovered ? 6 : 4}
76
+ fill={color}
77
+ stroke="white"
78
+ strokeWidth={isHovered ? 2 : 1}
79
+ className={`c-chart__area-point ${isHovered ? 'c-chart__area-point--hovered' : ''}`}
80
+ onClick={() => handlers.onDataPointClick?.(point, datasetIndex, index)}
81
+ onMouseEnter={e => {
82
+ const rect = e.currentTarget.getBoundingClientRect();
83
+ handlers.onPointHover(
84
+ datasetIndex,
85
+ index,
86
+ x,
87
+ y,
88
+ rect.left + rect.width / 2,
89
+ rect.top + rect.height / 2
90
+ );
91
+ }}
92
+ onMouseLeave={handlers.onPointLeave}
93
+ style={{ cursor: 'pointer' }}
94
+ />
95
+ );
96
+ })}
97
+ </g>
98
+ );
99
+ })}
100
+ {showTooltips && hoveredPoint && (
101
+ <ChartTooltip
102
+ dataPoint={
103
+ renderedDatasets[hoveredPoint.datasetIndex]?.data?.[hoveredPoint.pointIndex]
104
+ }
105
+ datasetLabel={renderedDatasets[hoveredPoint.datasetIndex]?.label}
106
+ datasetColor={
107
+ renderedDatasets[hoveredPoint.datasetIndex]?.color ||
108
+ colors[hoveredPoint.datasetIndex]
109
+ }
110
+ position={{
111
+ x: hoveredPoint.clientX,
112
+ y: hoveredPoint.clientY,
113
+ }}
114
+ visible={true}
115
+ />
116
+ )}
117
+ </>
118
+ );
119
+ };
120
+
121
+ return (
122
+ <BaseChart
123
+ ref={ref}
124
+ type="area"
125
+ datasets={datasets}
126
+ config={config}
127
+ renderContent={renderContent}
128
+ onDataPointClick={onDataPointClick}
129
+ {...props}
130
+ />
131
+ );
132
+ }
133
+ )
23
134
  );
24
135
 
25
136
  AreaChart.displayName = 'AreaChart';