@shohojdhara/atomix 0.2.4 → 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 (211) hide show
  1. package/README.md +19 -0
  2. package/dist/atomix.css +1266 -1412
  3. package/dist/atomix.min.css +3 -3
  4. package/dist/index.d.ts +1232 -876
  5. package/dist/index.esm.js +16212 -26364
  6. package/dist/index.esm.js.map +1 -1
  7. package/dist/index.js +15652 -22298
  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 +1266 -1413
  14. package/dist/themes/boomdevs.min.css +3 -3
  15. package/dist/themes/esrar.css +1267 -1413
  16. package/dist/themes/esrar.min.css +3 -3
  17. package/dist/themes/flashtrade.css +15159 -0
  18. package/dist/themes/flashtrade.min.css +86 -0
  19. package/dist/themes/mashroom.css +1264 -1410
  20. package/dist/themes/mashroom.min.css +5 -5
  21. package/dist/themes/shaj-default.css +1266 -1412
  22. package/dist/themes/shaj-default.min.css +3 -3
  23. package/package.json +6 -17
  24. package/src/components/Accordion/Accordion.stories.tsx +4 -26
  25. package/src/components/Accordion/Accordion.tsx +21 -12
  26. package/src/components/AtomixGlass/AtomixGlass.test.tsx +106 -72
  27. package/src/components/AtomixGlass/AtomixGlass.tsx +487 -1215
  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 +404 -236
  34. package/src/components/AtomixGlass/{AtomixGlass.stories.tsx → stories/AtomixGlass.stories.tsx} +55 -35
  35. package/src/components/AtomixGlass/stories/Examples.stories.tsx +57 -89
  36. package/src/components/AtomixGlass/stories/Modes.stories.tsx +149 -149
  37. package/src/components/AtomixGlass/stories/Playground.stories.tsx +95 -32
  38. package/src/components/AtomixGlass/stories/ShaderVariants.stories.tsx +0 -2
  39. package/src/components/AtomixGlass/stories/shared-components.tsx +9 -18
  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 +74 -54
  44. package/src/components/Badge/Badge.tsx +8 -12
  45. package/src/components/Breadcrumb/Breadcrumb.tsx +23 -4
  46. package/src/components/Button/Button.tsx +3 -5
  47. package/src/components/Callout/Callout.stories.tsx +86 -35
  48. package/src/components/Callout/Callout.tsx +4 -0
  49. package/src/components/Card/Card.stories.tsx +89 -85
  50. package/src/components/Card/Card.tsx +15 -4
  51. package/src/components/Card/ElevationCard.tsx +2 -0
  52. package/src/components/Chart/AnimatedChart.tsx +179 -156
  53. package/src/components/Chart/AreaChart.tsx +123 -12
  54. package/src/components/Chart/BarChart.tsx +91 -100
  55. package/src/components/Chart/BaseChart.tsx +80 -0
  56. package/src/components/Chart/BubbleChart.tsx +114 -290
  57. package/src/components/Chart/CandlestickChart.tsx +282 -622
  58. package/src/components/Chart/Chart.stories.tsx +576 -179
  59. package/src/components/Chart/Chart.tsx +374 -75
  60. package/src/components/Chart/ChartRenderer.tsx +371 -220
  61. package/src/components/Chart/ChartToolbar.tsx +372 -61
  62. package/src/components/Chart/ChartTooltip.tsx +33 -18
  63. package/src/components/Chart/DonutChart.tsx +172 -254
  64. package/src/components/Chart/FunnelChart.tsx +169 -240
  65. package/src/components/Chart/GaugeChart.tsx +224 -392
  66. package/src/components/Chart/HeatmapChart.tsx +302 -440
  67. package/src/components/Chart/LineChart.tsx +148 -103
  68. package/src/components/Chart/MultiAxisChart.tsx +267 -395
  69. package/src/components/Chart/PieChart.tsx +114 -64
  70. package/src/components/Chart/RadarChart.tsx +202 -218
  71. package/src/components/Chart/ScatterChart.tsx +111 -97
  72. package/src/components/Chart/TreemapChart.tsx +147 -222
  73. package/src/components/Chart/WaterfallChart.tsx +253 -291
  74. package/src/components/Chart/index.ts +11 -9
  75. package/src/components/Chart/types.ts +85 -9
  76. package/src/components/Chart/utils.ts +66 -0
  77. package/src/components/ColorModeToggle/ColorModeToggle.tsx +6 -3
  78. package/src/components/Countdown/Countdown.tsx +4 -0
  79. package/src/components/DataTable/DataTable.tsx +2 -1
  80. package/src/components/DatePicker/DatePicker.stories.tsx +0 -11
  81. package/src/components/DatePicker/DatePicker.tsx +3 -9
  82. package/src/components/DatePicker/types.ts +5 -0
  83. package/src/components/Dropdown/Dropdown.stories.tsx +32 -25
  84. package/src/components/Dropdown/Dropdown.tsx +26 -28
  85. package/src/components/EdgePanel/EdgePanel.stories.tsx +13 -15
  86. package/src/components/EdgePanel/EdgePanel.tsx +20 -5
  87. package/src/components/Footer/Footer.stories.tsx +187 -60
  88. package/src/components/Footer/Footer.test.tsx +134 -0
  89. package/src/components/Footer/Footer.tsx +133 -34
  90. package/src/components/Footer/FooterLink.tsx +1 -1
  91. package/src/components/Footer/FooterSection.tsx +53 -36
  92. package/src/components/Footer/FooterSocialLink.tsx +32 -29
  93. package/src/components/Footer/README.md +82 -3
  94. package/src/components/Footer/index.ts +1 -1
  95. package/src/components/Form/Checkbox.stories.tsx +13 -5
  96. package/src/components/Form/Checkbox.tsx +3 -6
  97. package/src/components/Form/Form.stories.tsx +10 -3
  98. package/src/components/Form/Form.tsx +2 -0
  99. package/src/components/Form/FormGroup.tsx +2 -1
  100. package/src/components/Form/Input.stories.tsx +12 -11
  101. package/src/components/Form/Input.tsx +97 -95
  102. package/src/components/Form/Radio.stories.tsx +22 -7
  103. package/src/components/Form/Radio.tsx +3 -6
  104. package/src/components/Form/Select.stories.tsx +21 -6
  105. package/src/components/Form/Select.tsx +3 -5
  106. package/src/components/Form/Textarea.stories.tsx +13 -11
  107. package/src/components/Form/Textarea.tsx +88 -86
  108. package/src/components/Hero/Hero.stories.tsx +2 -3
  109. package/src/components/Hero/Hero.tsx +5 -6
  110. package/src/components/Icon/Icon.tsx +12 -1
  111. package/src/components/List/List.tsx +2 -1
  112. package/src/components/List/ListGroup.tsx +2 -1
  113. package/src/components/Messages/Messages.tsx +3 -2
  114. package/src/components/Modal/Modal.stories.tsx +48 -34
  115. package/src/components/Modal/Modal.tsx +19 -23
  116. package/src/components/Navigation/Menu/MegaMenu.tsx +2 -2
  117. package/src/components/Navigation/Menu/Menu.tsx +2 -2
  118. package/src/components/Navigation/Nav/Nav.tsx +6 -1
  119. package/src/components/Navigation/Nav/NavDropdown.tsx +10 -1
  120. package/src/components/Navigation/Navbar/Navbar.tsx +4 -1
  121. package/src/components/Navigation/SideMenu/SideMenu.tsx +3 -2
  122. package/src/components/Pagination/Pagination.stories.tsx +13 -6
  123. package/src/components/Pagination/Pagination.tsx +7 -6
  124. package/src/components/PhotoViewer/PhotoViewer.tsx +2 -1
  125. package/src/components/Popover/Popover.stories.tsx +32 -24
  126. package/src/components/Popover/Popover.tsx +4 -1
  127. package/src/components/ProductReview/ProductReview.tsx +8 -2
  128. package/src/components/Progress/Progress.tsx +2 -1
  129. package/src/components/Rating/Rating.stories.tsx +11 -6
  130. package/src/components/Rating/Rating.tsx +3 -5
  131. package/src/components/River/River.tsx +5 -5
  132. package/src/components/SectionIntro/SectionIntro.tsx +8 -2
  133. package/src/components/Slider/Slider.stories.tsx +4 -4
  134. package/src/components/Slider/Slider.tsx +4 -3
  135. package/src/components/Spinner/Spinner.tsx +2 -1
  136. package/src/components/Steps/Steps.stories.tsx +5 -4
  137. package/src/components/Steps/Steps.tsx +8 -5
  138. package/src/components/Tab/Tab.stories.tsx +4 -3
  139. package/src/components/Tab/Tab.tsx +8 -6
  140. package/src/components/Testimonial/Testimonial.tsx +8 -2
  141. package/src/components/Todo/Todo.tsx +2 -1
  142. package/src/components/Toggle/Toggle.stories.tsx +5 -4
  143. package/src/components/Toggle/Toggle.tsx +8 -5
  144. package/src/components/Tooltip/Tooltip.stories.tsx +40 -30
  145. package/src/components/Tooltip/Tooltip.tsx +9 -2
  146. package/src/components/Upload/Upload.stories.tsx +252 -0
  147. package/src/components/Upload/Upload.tsx +92 -53
  148. package/src/components/VideoPlayer/VideoPlayer.tsx +3 -1
  149. package/src/components/index.ts +0 -4
  150. package/src/layouts/Grid/Grid.stories.tsx +10 -23
  151. package/src/layouts/Grid/Grid.tsx +20 -1
  152. package/src/layouts/Grid/GridCol.tsx +76 -48
  153. package/src/lib/composables/useAtomixGlass.ts +861 -44
  154. package/src/lib/composables/useBarChart.ts +13 -6
  155. package/src/lib/composables/useChart.ts +17 -13
  156. package/src/lib/composables/useChartExport.ts +19 -78
  157. package/src/lib/composables/useChartToolbar.ts +0 -1
  158. package/src/lib/composables/useEdgePanel.ts +111 -103
  159. package/src/lib/composables/useFooter.ts +3 -3
  160. package/src/lib/composables/useGlassContainer.ts +16 -7
  161. package/src/lib/composables/useLineChart.ts +8 -1
  162. package/src/lib/composables/useRiver.ts +5 -0
  163. package/src/lib/composables/useSlider.ts +62 -24
  164. package/src/lib/composables/useVideoPlayer.ts +60 -63
  165. package/src/lib/constants/components.ts +146 -32
  166. package/src/lib/types/components.ts +258 -10
  167. package/src/lib/utils/displacement-generator.ts +55 -49
  168. package/src/lib/utils/icons.ts +1 -1
  169. package/src/lib/utils/index.ts +16 -10
  170. package/src/styles/01-settings/_settings.accordion.scss +19 -19
  171. package/src/styles/01-settings/_settings.animations.scss +5 -5
  172. package/src/styles/01-settings/_settings.avatar-group.scss +1 -1
  173. package/src/styles/01-settings/_settings.avatar.scss +17 -17
  174. package/src/styles/01-settings/_settings.background.scss +1 -4
  175. package/src/styles/01-settings/_settings.badge.scss +1 -1
  176. package/src/styles/01-settings/_settings.breadcrumb.scss +1 -1
  177. package/src/styles/01-settings/_settings.card.scss +1 -1
  178. package/src/styles/01-settings/_settings.chart.scss +65 -2
  179. package/src/styles/01-settings/_settings.dropdown.scss +1 -1
  180. package/src/styles/01-settings/_settings.footer.scss +35 -42
  181. package/src/styles/01-settings/_settings.input.scss +1 -1
  182. package/src/styles/01-settings/_settings.list.scss +1 -1
  183. package/src/styles/01-settings/_settings.rating.scss +1 -1
  184. package/src/styles/01-settings/_settings.tabs.scss +1 -1
  185. package/src/styles/01-settings/_settings.upload.scss +6 -5
  186. package/src/styles/02-tools/_tools.animations.scss +4 -5
  187. package/src/styles/02-tools/_tools.background.scss +1 -13
  188. package/src/styles/02-tools/_tools.glass.scss +0 -1
  189. package/src/styles/02-tools/_tools.utility-api.scss +42 -34
  190. package/src/styles/03-generic/_generic.root.scss +1 -4
  191. package/src/styles/04-elements/_elements.body.scss +0 -1
  192. package/src/styles/06-components/_components.atomix-glass.scss +216 -39
  193. package/src/styles/06-components/_components.badge.scss +6 -8
  194. package/src/styles/06-components/_components.button.scss +8 -3
  195. package/src/styles/06-components/_components.card.scss +2 -14
  196. package/src/styles/06-components/_components.chart.scss +969 -1449
  197. package/src/styles/06-components/_components.dropdown.scss +19 -7
  198. package/src/styles/06-components/_components.edge-panel.scss +4 -2
  199. package/src/styles/06-components/_components.footer.scss +166 -85
  200. package/src/styles/06-components/_components.input.scss +8 -9
  201. package/src/styles/06-components/_components.list.scss +1 -0
  202. package/src/styles/06-components/_components.modal.scss +5 -3
  203. package/src/styles/06-components/_components.skeleton.scss +8 -6
  204. package/src/styles/06-components/_components.upload.scss +219 -4
  205. package/src/styles/06-components/old.chart.styles.scss +1 -30
  206. package/src/styles/99-utilities/_utilities.opacity.scss +1 -1
  207. package/src/styles/99-utilities/_utilities.scss +1 -1
  208. package/src/components/Chart/AdvancedChart.tsx +0 -624
  209. package/src/components/Chart/LineChartNew.tsx +0 -167
  210. package/src/components/Chart/RealTimeChart.tsx +0 -436
  211. package/src/components/DatePicker/DatePicker copy.tsx +0 -551
@@ -1,6 +1,7 @@
1
1
  import { forwardRef, memo, useCallback, useMemo, useState } from 'react';
2
- import { ChartProps } from '../../lib/types/components';
3
- import Chart from './Chart';
2
+ import BaseChart from './BaseChart';
3
+ import ChartTooltip from './ChartTooltip';
4
+ import { ChartProps, ChartRenderContentParams } from './types';
4
5
 
5
6
  interface HeatmapDataPoint {
6
7
  x: string | number;
@@ -10,7 +11,7 @@ interface HeatmapDataPoint {
10
11
  metadata?: Record<string, any>;
11
12
  }
12
13
 
13
- interface HeatmapChartProps extends Omit<ChartProps, 'type' | 'datasets' | 'variant'> {
14
+ interface HeatmapChartProps extends Omit<ChartProps, 'type' | 'datasets' | 'variant' | 'data'> {
14
15
  /**
15
16
  * Heatmap data points
16
17
  */
@@ -64,361 +65,255 @@ interface HeatmapChartProps extends Omit<ChartProps, 'type' | 'datasets' | 'vari
64
65
  */
65
66
  height?: number;
66
67
  /**
67
- * Cell border radius
68
+ * Spacing between cells
68
69
  */
69
- borderRadius?: number;
70
+ spacing?: number;
70
71
  /**
71
- * Cell spacing
72
+ * Border radius for cells
72
73
  */
73
- spacing?: number;
74
+ borderRadius?: number;
74
75
  /**
75
- * Show cell borders
76
+ * Whether to show cell labels
76
77
  */
77
- showBorders?: boolean;
78
+ showLabels?: boolean;
78
79
  };
79
80
 
80
- /**
81
- * Whether to show values in cells
82
- */
83
- showValues?: boolean;
84
-
85
- /**
86
- * Value formatter
87
- */
88
- valueFormatter?: (value: number) => string;
89
-
90
81
  /**
91
82
  * Whether to show color legend
92
83
  */
93
84
  showColorLegend?: boolean;
94
85
 
95
86
  /**
96
- * Tooltip configuration
97
- */
98
- tooltipConfig?: {
99
- enabled: boolean;
100
- formatter?: (dataPoint: HeatmapDataPoint) => string;
101
- };
102
-
103
- /**
104
- * Layout variant - grid or calendar style
87
+ * Whether to show grid lines
105
88
  */
106
- variant?: 'grid' | 'calendar';
107
-
108
- /**
109
- * Animation configuration
110
- */
111
- animationConfig?: {
112
- enabled?: boolean;
113
- duration?: number;
114
- delay?: number;
115
- easing?: string;
116
- };
89
+ showGrid?: boolean;
117
90
  }
118
91
 
92
+ // Predefined color schemes
93
+ const colorSchemes: Record<string, string[]> = {
94
+ viridis: [
95
+ '#440154',
96
+ '#482777',
97
+ '#3f4a8a',
98
+ '#31678e',
99
+ '#26838f',
100
+ '#1f9d8a',
101
+ '#6cce5a',
102
+ '#b6de2b',
103
+ '#fee825',
104
+ ],
105
+ plasma: ['#0d0887', '#5302a3', '#8b0aa5', '#b83289', '#db5c68', '#f48849', '#febd2a', '#f0f921'],
106
+ inferno: [
107
+ '#000004',
108
+ '#1b0c41',
109
+ '#4b0c6b',
110
+ '#781c6d',
111
+ '#a52c60',
112
+ '#cf4446',
113
+ '#ed6925',
114
+ '#fb9b06',
115
+ '#fcffa4',
116
+ ],
117
+ magma: [
118
+ '#000004',
119
+ '#1c1044',
120
+ '#4f127b',
121
+ '#812581',
122
+ '#b5367a',
123
+ '#e55964',
124
+ '#fb8761',
125
+ '#fec287',
126
+ '#fcfdbf',
127
+ ],
128
+ blues: [
129
+ 'var(--atomix-blue-1)',
130
+ 'var(--atomix-blue-2)',
131
+ 'var(--atomix-blue-3)',
132
+ 'var(--atomix-blue-4)',
133
+ 'var(--atomix-blue-5)',
134
+ 'var(--atomix-blue-6)',
135
+ 'var(--atomix-blue-7)',
136
+ 'var(--atomix-blue-8)',
137
+ 'var(--atomix-blue-9)',
138
+ ],
139
+ reds: [
140
+ 'var(--atomix-red-1)',
141
+ 'var(--atomix-red-2)',
142
+ 'var(--atomix-red-3)',
143
+ 'var(--atomix-red-4)',
144
+ 'var(--atomix-red-5)',
145
+ 'var(--atomix-red-6)',
146
+ 'var(--atomix-red-7)',
147
+ 'var(--atomix-red-8)',
148
+ 'var(--atomix-red-9)',
149
+ ],
150
+ greens: [
151
+ 'var(--atomix-green-1)',
152
+ 'var(--atomix-green-2)',
153
+ 'var(--atomix-green-3)',
154
+ 'var(--atomix-green-4)',
155
+ 'var(--atomix-green-5)',
156
+ 'var(--atomix-green-6)',
157
+ 'var(--atomix-green-7)',
158
+ 'var(--atomix-green-8)',
159
+ 'var(--atomix-green-9)',
160
+ ],
161
+ github: [
162
+ 'var(--atomix-gray-2)',
163
+ 'var(--atomix-green-3)',
164
+ 'var(--atomix-green-4)',
165
+ 'var(--atomix-green-5)',
166
+ 'var(--atomix-green-6)',
167
+ ],
168
+ };
169
+
119
170
  const HeatmapChart = memo(
120
171
  forwardRef<HTMLDivElement, HeatmapChartProps>(
121
172
  (
122
173
  {
123
174
  data = [],
124
- colorScale = { scheme: 'github', steps: 5 },
175
+ config = {},
176
+ colorScale = {
177
+ scheme: 'viridis',
178
+ steps: 9,
179
+ },
125
180
  cellConfig = {
126
- width: 12,
127
- height: 12,
128
- borderRadius: 2,
181
+ width: 40,
182
+ height: 40,
129
183
  spacing: 2,
130
- showBorders: false,
184
+ borderRadius: 4,
185
+ showLabels: false,
131
186
  },
132
- showValues = false,
133
- valueFormatter = v => v.toFixed(0),
134
187
  showColorLegend = true,
135
- tooltipConfig = { enabled: true },
136
- variant = 'grid',
137
- animationConfig = {
138
- enabled: true,
139
- duration: 800,
140
- delay: 50,
141
- easing: 'ease-out',
142
- },
143
- config = {},
188
+ showGrid = true,
189
+ onDataPointClick,
144
190
  ...props
145
191
  },
146
192
  ref
147
193
  ) => {
148
194
  const [hoveredCell, setHoveredCell] = useState<HeatmapDataPoint | null>(null);
149
- const [tooltipPosition, setTooltipPosition] = useState({ x: 0, y: 0 });
150
195
 
151
196
  // Process data into matrix format
152
197
  const processedData = useMemo(() => {
153
- console.log('HeatmapChart data:', data);
154
198
  if (!data.length) {
155
- console.log('No data provided to HeatmapChart');
156
- return { matrix: [], xLabels: [], yLabels: [], minValue: 0, maxValue: 1 };
199
+ return { matrix: [], xLabels: [], yLabels: [] };
157
200
  }
158
201
 
159
- // Get unique x and y values
160
- const xValues = [...new Set(data.map(d => d.x))].sort();
161
- const yValues = [...new Set(data.map(d => d.y))].sort();
162
-
163
- // Calculate value range
164
- const values = data.map(d => d.value);
165
- const minValue = colorScale.min ?? Math.min(...values);
166
- const maxValue = colorScale.max ?? Math.max(...values);
202
+ // Extract unique x and y labels
203
+ const xLabels = Array.from(new Set(data.map(d => d.x))).sort();
204
+ const yLabels = Array.from(new Set(data.map(d => d.y))).sort();
167
205
 
168
206
  // Create matrix
169
- const matrix: (HeatmapDataPoint | null)[][] = yValues.map(() =>
170
- new Array(xValues.length).fill(null)
171
- );
172
-
173
- // Fill matrix with data
174
- data.forEach(point => {
175
- const xIndex = xValues.indexOf(point.x);
176
- const yIndex = yValues.indexOf(point.y);
177
- if (xIndex >= 0 && yIndex >= 0 && matrix[yIndex]) {
178
- matrix[yIndex]![xIndex] = point;
179
- }
207
+ const matrix: (HeatmapDataPoint | null)[][] = [];
208
+ yLabels.forEach(y => {
209
+ const row: (HeatmapDataPoint | null)[] = [];
210
+ xLabels.forEach(x => {
211
+ const point = data.find(d => d.x === x && d.y === y);
212
+ row.push(point || null);
213
+ });
214
+ matrix.push(row);
180
215
  });
181
216
 
182
- return {
183
- matrix,
184
- xLabels: xValues,
185
- yLabels: yValues,
186
- minValue,
187
- maxValue,
188
- };
189
- }, [data, colorScale.min, colorScale.max]);
190
-
191
- // Enhanced color schemes with GitHub-style contribution colors
192
- const colorSchemes = {
193
- viridis: [
194
- '#440154',
195
- '#482777',
196
- '#3f4a8a',
197
- '#31678e',
198
- '#26838f',
199
- '#1f9d8a',
200
- '#6cce5a',
201
- '#b6de2b',
202
- '#fee825',
203
- ],
204
- plasma: [
205
- '#0d0887',
206
- '#5302a3',
207
- '#8b0aa5',
208
- '#b83289',
209
- '#db5c68',
210
- '#f48849',
211
- '#febd2a',
212
- '#f0f921',
213
- ],
214
- inferno: [
215
- '#000004',
216
- '#1b0c41',
217
- '#4a0c6b',
218
- '#781c6d',
219
- '#a52c60',
220
- '#cf4446',
221
- '#ed6925',
222
- '#fb9b06',
223
- '#fcffa4',
224
- ],
225
- magma: [
226
- '#000004',
227
- '#1c1044',
228
- '#4f127b',
229
- '#812581',
230
- '#b5367a',
231
- '#e55964',
232
- '#fb8761',
233
- '#fec287',
234
- '#fcfdbf',
235
- ],
236
- blues: [
237
- '#f7fbff',
238
- '#deebf7',
239
- '#c6dbef',
240
- '#9ecae1',
241
- '#6baed6',
242
- '#4292c6',
243
- '#2171b5',
244
- '#08519c',
245
- '#08306b',
246
- ],
247
- reds: [
248
- '#fff5f0',
249
- '#fee0d2',
250
- '#fcbba1',
251
- '#fc9272',
252
- '#fb6a4a',
253
- '#ef3b2c',
254
- '#cb181d',
255
- '#a50f15',
256
- '#67000d',
257
- ],
258
- greens: [
259
- '#f7fcf5',
260
- '#e5f5e0',
261
- '#c7e9c0',
262
- '#a1d99b',
263
- '#74c476',
264
- '#41ab5d',
265
- '#238b45',
266
- '#006d2c',
267
- '#00441b',
268
- ],
269
- github: ['#ebedf0', '#9be9a8', '#40c463', '#30a14e', '#216e39'],
270
- custom: colorScale.colors || ['#ffffff', '#000000'],
271
- };
217
+ return { matrix, xLabels, yLabels };
218
+ }, [data]);
272
219
 
273
- // Generate color scale
274
- const getColor = useCallback(
220
+ // Get color for a value
221
+ const getColorForValue = useCallback(
275
222
  (value: number) => {
276
- const { minValue, maxValue } = processedData;
277
- const range = maxValue - minValue;
278
- if (range === 0) return colorSchemes[colorScale.scheme][0];
223
+ if (!processedData.matrix.length) return 'var(--atomix-secondary-bg-subtle)';
224
+
225
+ // Determine min/max values
226
+ let minValue = colorScale.min;
227
+ let maxValue = colorScale.max;
228
+
229
+ if (minValue === undefined || maxValue === undefined) {
230
+ const allValues = data.filter(d => d.value !== undefined).map(d => d.value);
231
+ if (minValue === undefined) minValue = Math.min(...allValues);
232
+ if (maxValue === undefined) maxValue = Math.max(...allValues);
233
+ }
234
+
235
+ // Get color scheme
236
+ let colors: string[];
237
+ if (colorScale.scheme === 'custom' && colorScale.colors) {
238
+ colors = colorScale.colors;
239
+ } else {
240
+ const schemeKey = colorScale.scheme as keyof typeof colorSchemes;
241
+ colors = (colorSchemes[schemeKey] || colorSchemes.viridis) as string[];
242
+ }
279
243
 
280
- const normalizedValue = (value - minValue) / range;
281
- const colors = colorSchemes[colorScale.scheme];
244
+ // Calculate steps
282
245
  const steps = colorScale.steps || colors.length;
246
+ const valueRange = maxValue - minValue;
247
+ if (valueRange === 0) return colors[0];
283
248
 
249
+ // Normalize value and get color
250
+ const normalizedValue = (value - minValue) / valueRange;
284
251
  const colorIndex = Math.min(Math.floor(normalizedValue * steps), steps - 1);
285
252
  const scaledIndex = Math.floor((colorIndex / steps) * (colors.length - 1));
286
253
 
287
254
  return colors[scaledIndex];
288
255
  },
289
- [processedData, colorScale.scheme, colorScale.steps, colorSchemes]
256
+ [processedData, colorScale, data]
290
257
  );
291
258
 
292
- // Handle cell hover
293
- const handleCellHover = useCallback(
294
- (dataPoint: HeatmapDataPoint | null, event?: React.MouseEvent) => {
295
- setHoveredCell(dataPoint);
296
-
297
- if (event && dataPoint) {
298
- const rect = event.currentTarget.getBoundingClientRect();
299
- setTooltipPosition({
300
- x: event.clientX,
301
- y: event.clientY,
302
- });
303
- }
304
- },
305
- []
306
- );
307
-
308
- // Render heatmap content
309
- const renderContent = useCallback(
310
- ({ scales }: { scales: any }) => {
311
- const { matrix, xLabels, yLabels } = processedData;
312
- console.log(
313
- 'Rendering heatmap with matrix:',
314
- matrix,
315
- 'xLabels:',
316
- xLabels,
317
- 'yLabels:',
318
- yLabels
319
- );
320
- if (!matrix.length) {
321
- console.log('Matrix is empty, not rendering');
322
- return null;
323
- }
259
+ const renderContent = ({
260
+ scales,
261
+ colors,
262
+ datasets: renderedDatasets,
263
+ handlers,
264
+ hoveredPoint,
265
+ toolbarState,
266
+ config: renderConfig,
267
+ }: ChartRenderContentParams) => {
268
+ const { matrix, xLabels, yLabels } = processedData;
269
+
270
+ // Use toolbar state if available, fallback to config for backward compatibility
271
+ const showTooltips = toolbarState?.showTooltips ?? renderConfig?.showTooltips ?? true;
272
+ if (!matrix.length) {
273
+ return null;
274
+ }
324
275
 
325
- const cellWidth = cellConfig.width || 40;
326
- const cellHeight = cellConfig.height || 40;
327
- const spacing = cellConfig.spacing || 2;
328
- const borderRadius = cellConfig.borderRadius || 4;
276
+ const cellWidth = cellConfig.width || 40;
277
+ const cellHeight = cellConfig.height || 40;
278
+ const spacing = cellConfig.spacing || 2;
279
+ const borderRadius = cellConfig.borderRadius || 4;
329
280
 
330
- const totalWidth = xLabels.length * (cellWidth + spacing) - spacing;
331
- const totalHeight = yLabels.length * (cellHeight + spacing) - spacing;
281
+ const totalWidth = xLabels.length * (cellWidth + spacing) - spacing;
282
+ const totalHeight = yLabels.length * (cellHeight + spacing) - spacing;
332
283
 
333
- const startX = 100; // Leave space for y-axis labels
334
- const startY = 50; // Leave space for x-axis labels
284
+ const startX = 100; // Leave space for y-axis labels
285
+ const startY = 50; // Leave space for x-axis labels
335
286
 
336
- return (
287
+ return (
288
+ <>
337
289
  <g>
338
290
  {/* Gradient definitions */}
339
291
  <defs>
340
- {showColorLegend && (
341
- <linearGradient id="heatmap-legend-gradient" x1="0%" y1="100%" x2="0%" y2="0%">
342
- {colorSchemes[colorScale.scheme].map((color, i) => (
343
- <stop
344
- key={i}
345
- offset={`${(i / (colorSchemes[colorScale.scheme].length - 1)) * 100}%`}
346
- stopColor={color}
347
- />
348
- ))}
349
- </linearGradient>
350
- )}
292
+ {showColorLegend && (() => {
293
+ const schemeColors = colorSchemes[colorScale.scheme] || colorSchemes.viridis;
294
+ if (!schemeColors || schemeColors.length === 0) return null;
295
+ return (
296
+ <linearGradient id="heatmap-legend-gradient" x1="0%" y1="100%" x2="0%" y2="0%">
297
+ {schemeColors.map((color, i) => (
298
+ <stop
299
+ key={i}
300
+ offset={`${(i / (schemeColors.length - 1)) * 100}%`}
301
+ stopColor={color}
302
+ />
303
+ ))}
304
+ </linearGradient>
305
+ );
306
+ })()}
351
307
  </defs>
352
308
 
353
- {/* X-axis labels */}
354
- {xLabels.map((label, i) => {
355
- const showLabel =
356
- variant === 'calendar'
357
- ? i % 4 === 0
358
- : i % Math.max(1, Math.floor(xLabels.length / 12)) === 0;
359
- return showLabel ? (
360
- <text
361
- key={`x-label-${i}`}
362
- x={startX + i * (cellWidth + spacing) + cellWidth / 2}
363
- y={startY - 8}
364
- textAnchor="middle"
365
- className="c-chart__heatmap-axis-label"
366
- fontSize="11"
367
- fill="var(--atomix-gray-7)"
368
- >
369
- {String(label)}
370
- </text>
371
- ) : null;
372
- })}
309
+ {/* Grid cells */}
310
+ {matrix.map((row, rowIndex) => {
311
+ return row.map((cell, colIndex) => {
312
+ if (!cell) return null;
373
313
 
374
- {/* Y-axis labels */}
375
- {yLabels.map((label, i) => (
376
- <text
377
- key={`y-label-${i}`}
378
- x={startX - 8}
379
- y={startY + i * (cellHeight + spacing) + cellHeight / 2}
380
- textAnchor="end"
381
- dominantBaseline="middle"
382
- className="c-chart__heatmap-axis-label"
383
- fontSize="11"
384
- fill="var(--atomix-gray-7)"
385
- >
386
- {String(label)}
387
- </text>
388
- ))}
389
-
390
- {/* Heatmap cells */}
391
- {matrix.map((row, rowIndex) =>
392
- row.map((cell, colIndex) => {
393
314
  const x = startX + colIndex * (cellWidth + spacing);
394
315
  const y = startY + rowIndex * (cellHeight + spacing);
395
- const animationDelay = animationConfig.enabled
396
- ? (rowIndex * xLabels.length + colIndex) * (animationConfig.delay || 50)
397
- : 0;
398
-
399
- if (!cell) {
400
- return (
401
- <rect
402
- key={`empty-${rowIndex}-${colIndex}`}
403
- x={x}
404
- y={y}
405
- width={cellWidth}
406
- height={cellHeight}
407
- rx={borderRadius}
408
- fill="var(--atomix-gray-2)"
409
- stroke={cellConfig.showBorders ? 'var(--atomix-gray-3)' : 'none'}
410
- strokeWidth={cellConfig.showBorders ? 0.5 : 0}
411
- className="c-chart__heatmap-cell c-chart__heatmap-cell--empty"
412
- style={{
413
- animation: animationConfig.enabled
414
- ? `chart-fade-in ${animationConfig.duration}ms ${animationConfig.easing} ${animationDelay}ms both`
415
- : 'none',
416
- }}
417
- />
418
- );
419
- }
420
-
421
- const color = getColor(cell.value);
316
+ const color = getColorForValue(cell.value);
422
317
  const isHovered = hoveredCell === cell;
423
318
 
424
319
  return (
@@ -428,187 +323,154 @@ const HeatmapChart = memo(
428
323
  y={y}
429
324
  width={cellWidth}
430
325
  height={cellHeight}
431
- fill={color}
432
326
  rx={borderRadius}
433
- stroke={cellConfig.showBorders ? 'var(--atomix-gray-3)' : 'none'}
434
- strokeWidth={cellConfig.showBorders ? 0.5 : 0}
327
+ ry={borderRadius}
328
+ fill={color}
435
329
  className={`c-chart__heatmap-cell ${isHovered ? 'c-chart__heatmap-cell--hovered' : ''}`}
436
- onMouseEnter={e => handleCellHover(cell, e)}
437
- onMouseLeave={() => handleCellHover(null)}
438
330
  style={{
439
- cursor: 'pointer',
440
331
  transition: 'all 0.2s ease',
441
- animation: animationConfig.enabled
442
- ? `chart-scale-in ${animationConfig.duration}ms ${animationConfig.easing} ${animationDelay}ms both`
443
- : 'none',
444
- transform: isHovered ? 'scale(1.1)' : 'scale(1)',
445
- filter: isHovered ? 'drop-shadow(0 2px 4px rgba(0,0,0,0.2))' : 'none',
332
+ transform: isHovered ? 'scale(1.05)' : 'scale(1)',
333
+ transformOrigin: 'center',
334
+ }}
335
+ onClick={() => {
336
+ if (cell) {
337
+ handlers.onDataPointClick?.({
338
+ ...cell,
339
+ label: cell.label || `${cell.x}, ${cell.y}`,
340
+ value: cell.value,
341
+ } as any, rowIndex, colIndex);
342
+ }
343
+ }}
344
+ onMouseEnter={e => {
345
+ setHoveredCell(cell);
446
346
  }}
347
+ onMouseLeave={() => setHoveredCell(null)}
447
348
  />
448
-
449
- {/* Cell value */}
450
- {showValues && cell.value > 0 && (
349
+ {cellConfig.showLabels && cell.label && (
451
350
  <text
452
351
  x={x + cellWidth / 2}
453
352
  y={y + cellHeight / 2}
454
353
  textAnchor="middle"
455
354
  dominantBaseline="middle"
456
- fontSize="9"
457
- fontWeight="500"
458
- fill={
459
- cell.value > (processedData.minValue + processedData.maxValue) / 2
460
- ? 'white'
461
- : 'var(--atomix-gray-8)'
462
- }
463
- className="c-chart__heatmap-value"
464
- style={{ pointerEvents: 'none' }}
355
+ className="c-chart__heatmap-label"
465
356
  >
466
- {valueFormatter(cell.value)}
357
+ {cell.label}
467
358
  </text>
468
359
  )}
469
360
  </g>
470
361
  );
471
- })
472
- )}
362
+ });
363
+ })}
473
364
 
474
- {/* Enhanced color legend */}
475
- {showColorLegend && (
476
- <g transform={`translate(${startX + totalWidth + 40}, ${startY})`}>
477
- <text x="0" y="-15" fontSize="12" fontWeight="600" fill="var(--atomix-gray-8)">
478
- Activity
365
+ {/* X-axis labels */}
366
+ {xLabels.map((label, index) => {
367
+ const x = startX + index * (cellWidth + spacing) + cellWidth / 2;
368
+ const y = startY + matrix.length * (cellHeight + spacing) + 20;
369
+
370
+ return (
371
+ <text
372
+ key={`x-label-${index}`}
373
+ x={x}
374
+ y={y}
375
+ textAnchor="middle"
376
+ className="c-chart__heatmap-axis-label"
377
+ >
378
+ {String(label)}
479
379
  </text>
380
+ );
381
+ })}
480
382
 
481
- {/* Legend scale boxes */}
482
- <g transform="translate(0, 10)">
483
- <text x="-5" y="15" fontSize="10" fill="var(--atomix-gray-6)" textAnchor="end">
484
- Less
485
- </text>
383
+ {/* Y-axis labels */}
384
+ {yLabels.map((label, index) => {
385
+ const x = startX - 20;
386
+ const y = startY + index * (cellHeight + spacing) + cellHeight / 2;
486
387
 
487
- {colorSchemes[colorScale.scheme].map((color, i) => (
488
- <rect
489
- key={i}
490
- x={i * 14}
491
- y={0}
492
- width={12}
493
- height={12}
494
- fill={color}
495
- rx={2}
496
- stroke="var(--atomix-gray-3)"
497
- strokeWidth={0.5}
498
- />
499
- ))}
500
-
501
- <text
502
- x={colorSchemes[colorScale.scheme].length * 14 + 5}
503
- y="15"
504
- fontSize="10"
505
- fill="var(--atomix-gray-6)"
506
- >
507
- More
508
- </text>
509
- </g>
388
+ return (
389
+ <text
390
+ key={`y-label-${index}`}
391
+ x={x}
392
+ y={y}
393
+ textAnchor="end"
394
+ dominantBaseline="middle"
395
+ className="c-chart__heatmap-axis-label"
396
+ >
397
+ {String(label)}
398
+ </text>
399
+ );
400
+ })}
401
+
402
+ {/* Color legend */}
403
+ {showColorLegend && (
404
+ <g transform="translate(600, 100)">
405
+ <rect
406
+ x="0"
407
+ y="0"
408
+ width="20"
409
+ height="200"
410
+ fill="url(#heatmap-legend-gradient)"
411
+ stroke="var(--atomix-border-color)"
412
+ className="c-chart__grid"
413
+ />
414
+ <text x="-10" y="-10" className="c-chart__heatmap-legend-title">
415
+ Values
416
+ </text>
417
+ <text x="25" y="5" textAnchor="start" className="c-chart__heatmap-legend-label">
418
+ High
419
+ </text>
420
+ <text x="25" y="200" textAnchor="start" className="c-chart__heatmap-legend-label">
421
+ Low
422
+ </text>
510
423
  </g>
511
424
  )}
512
425
  </g>
513
- );
514
- },
515
- [
516
- processedData,
517
- cellConfig,
518
- showValues,
519
- valueFormatter,
520
- showColorLegend,
521
- getColor,
522
- hoveredCell,
523
- handleCellHover,
524
- colorScale.scheme,
525
- colorSchemes,
526
- ]
527
- );
528
-
529
- // Calculate optimal dimensions based on data
530
- const { matrix, xLabels, yLabels } = processedData;
531
- const cellWidth = cellConfig.width || 12;
532
- const cellHeight = cellConfig.height || 12;
533
- const spacing = cellConfig.spacing || 2;
426
+ {showTooltips && hoveredPoint && renderedDatasets[hoveredPoint.datasetIndex]?.data?.[hoveredPoint.pointIndex] && (
427
+ <ChartTooltip
428
+ dataPoint={
429
+ renderedDatasets[hoveredPoint.datasetIndex]!.data![hoveredPoint.pointIndex]!
430
+ }
431
+ datasetLabel={renderedDatasets[hoveredPoint.datasetIndex]?.label}
432
+ datasetColor={
433
+ renderedDatasets[hoveredPoint.datasetIndex]?.color ||
434
+ colors[hoveredPoint.datasetIndex % colors.length]
435
+ }
436
+ position={{
437
+ x: hoveredPoint.clientX,
438
+ y: hoveredPoint.clientY,
439
+ }}
440
+ visible={true}
441
+ />
442
+ )}
443
+ </>
444
+ );
445
+ };
534
446
 
535
- const chartWidth = Math.max(600, xLabels.length * (cellWidth + spacing) + 200);
536
- const chartHeight = Math.max(400, yLabels.length * (cellHeight + spacing) + 150);
447
+ // Convert data to datasets format for BaseChart
448
+ const datasets = [
449
+ {
450
+ label: 'Heatmap Data',
451
+ data: data.map(d => ({
452
+ ...d,
453
+ label: d.label || `${d.x}, ${d.y}`,
454
+ value: d.value,
455
+ })),
456
+ },
457
+ ];
537
458
 
538
459
  return (
539
- <Chart
460
+ <BaseChart
540
461
  ref={ref}
541
462
  type="heatmap"
542
- datasets={[]}
463
+ datasets={datasets}
543
464
  config={config}
544
- className={`c-chart--heatmap c-chart--${variant}`}
465
+ renderContent={renderContent}
466
+ onDataPointClick={onDataPointClick}
545
467
  {...props}
546
- >
547
- <svg
548
- width={chartWidth}
549
- height={chartHeight}
550
- viewBox={`0 0 ${chartWidth} ${chartHeight}`}
551
- className="c-chart__svg"
552
- style={{ width: '100%', height: '100%' }}
553
- >
554
- {renderContent({ scales: { width: chartWidth, height: chartHeight } })}
555
- </svg>
556
- {tooltipConfig.enabled && hoveredCell && (
557
- <div
558
- className="c-chart__tooltip"
559
- style={{
560
- position: 'fixed',
561
- left: tooltipPosition.x + 10,
562
- top: tooltipPosition.y - 10,
563
- }}
564
- >
565
- {tooltipConfig.formatter
566
- ? tooltipConfig.formatter(hoveredCell)
567
- : `${hoveredCell.label || `${hoveredCell.x}, ${hoveredCell.y}`}: ${hoveredCell.value}`}
568
- </div>
569
- )}
570
- </Chart>
468
+ />
571
469
  );
572
470
  }
573
471
  )
574
472
  );
575
473
 
576
474
  HeatmapChart.displayName = 'HeatmapChart';
577
-
578
- /**
579
- * Generate sample heatmap data for testing
580
- */
581
- export const generateHeatmapData = ({
582
- weeks = 52,
583
- daysPerWeek = 7,
584
- maxValue = 10,
585
- }: {
586
- weeks?: number;
587
- daysPerWeek?: number;
588
- maxValue?: number;
589
- } = {}): HeatmapDataPoint[] => {
590
- const data: HeatmapDataPoint[] = [];
591
- const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
592
-
593
- for (let week = 0; week < weeks; week++) {
594
- for (let day = 0; day < daysPerWeek; day++) {
595
- const value = Math.floor(Math.random() * (maxValue + 1));
596
- data.push({
597
- x: week,
598
- y: days[day] || `Day ${day}`,
599
- value,
600
- label: `Week ${week + 1}, ${days[day]}`,
601
- metadata: {
602
- week: week + 1,
603
- day: days[day],
604
- intensity: value > maxValue * 0.7 ? 'high' : value > maxValue * 0.3 ? 'medium' : 'low',
605
- },
606
- });
607
- }
608
- }
609
-
610
- return data;
611
- };
612
-
613
475
  export default HeatmapChart;
614
476
  export type { HeatmapChartProps, HeatmapDataPoint };