@shohojdhara/atomix 0.2.4 → 0.2.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.
- package/README.md +19 -0
- package/dist/atomix.css +1300 -1418
- package/dist/atomix.min.css +3 -3
- package/dist/index.d.ts +1259 -874
- package/dist/index.esm.js +16256 -26366
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +15691 -22295
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/themes/applemix.css +15036 -0
- package/dist/themes/applemix.min.css +72 -0
- package/dist/themes/boomdevs.css +1300 -1419
- package/dist/themes/boomdevs.min.css +3 -3
- package/dist/themes/esrar.css +1301 -1419
- package/dist/themes/esrar.min.css +3 -3
- package/dist/themes/flashtrade.css +15187 -0
- package/dist/themes/flashtrade.min.css +86 -0
- package/dist/themes/mashroom.css +1299 -1417
- package/dist/themes/mashroom.min.css +5 -5
- package/dist/themes/shaj-default.css +1300 -1418
- package/dist/themes/shaj-default.min.css +3 -3
- package/package.json +6 -17
- package/src/components/Accordion/Accordion.stories.tsx +4 -26
- package/src/components/Accordion/Accordion.tsx +21 -12
- package/src/components/AtomixGlass/AtomixGlass.test.tsx +106 -72
- package/src/components/AtomixGlass/AtomixGlass.tsx +485 -1215
- package/src/components/AtomixGlass/AtomixGlassContainer.tsx +399 -0
- package/src/components/AtomixGlass/GlassFilter.tsx +156 -0
- package/src/components/AtomixGlass/README.md +124 -2
- package/src/components/AtomixGlass/atomixGLass.old.tsx +1266 -0
- package/src/components/AtomixGlass/glass-utils.ts +263 -0
- package/src/components/AtomixGlass/shader-utils.ts +404 -236
- package/src/components/AtomixGlass/{AtomixGlass.stories.tsx → stories/AtomixGlass.stories.tsx} +55 -35
- package/src/components/AtomixGlass/stories/Examples.stories.tsx +57 -89
- package/src/components/AtomixGlass/stories/Modes.stories.tsx +149 -149
- package/src/components/AtomixGlass/stories/Playground.stories.tsx +95 -32
- package/src/components/AtomixGlass/stories/ShaderVariants.stories.tsx +0 -2
- package/src/components/AtomixGlass/stories/shared-components.tsx +9 -18
- package/src/components/AtomixGlass/utils.ts +3 -3
- package/src/components/Avatar/Avatar.tsx +3 -0
- package/src/components/Avatar/AvatarGroup.tsx +2 -1
- package/src/components/Badge/Badge.stories.tsx +74 -54
- package/src/components/Badge/Badge.tsx +8 -12
- package/src/components/Breadcrumb/Breadcrumb.tsx +23 -4
- package/src/components/Button/Button.tsx +3 -5
- package/src/components/Callout/Callout.stories.tsx +86 -35
- package/src/components/Callout/Callout.tsx +4 -0
- package/src/components/Card/Card.stories.tsx +89 -85
- package/src/components/Card/Card.tsx +15 -4
- package/src/components/Card/ElevationCard.tsx +2 -0
- package/src/components/Chart/AnimatedChart.tsx +179 -156
- package/src/components/Chart/AreaChart.tsx +123 -12
- package/src/components/Chart/BarChart.tsx +91 -100
- package/src/components/Chart/BaseChart.tsx +80 -0
- package/src/components/Chart/BubbleChart.tsx +114 -290
- package/src/components/Chart/CandlestickChart.tsx +282 -622
- package/src/components/Chart/Chart.stories.tsx +576 -179
- package/src/components/Chart/Chart.tsx +374 -75
- package/src/components/Chart/ChartRenderer.tsx +371 -220
- package/src/components/Chart/ChartToolbar.tsx +372 -61
- package/src/components/Chart/ChartTooltip.tsx +33 -18
- package/src/components/Chart/DonutChart.tsx +172 -254
- package/src/components/Chart/FunnelChart.tsx +169 -240
- package/src/components/Chart/GaugeChart.tsx +224 -392
- package/src/components/Chart/HeatmapChart.tsx +302 -440
- package/src/components/Chart/LineChart.tsx +148 -103
- package/src/components/Chart/MultiAxisChart.tsx +267 -395
- package/src/components/Chart/PieChart.tsx +114 -64
- package/src/components/Chart/RadarChart.tsx +202 -218
- package/src/components/Chart/ScatterChart.tsx +111 -97
- package/src/components/Chart/TreemapChart.tsx +147 -222
- package/src/components/Chart/WaterfallChart.tsx +253 -291
- package/src/components/Chart/index.ts +11 -9
- package/src/components/Chart/types.ts +85 -9
- package/src/components/Chart/utils.ts +66 -0
- package/src/components/ColorModeToggle/ColorModeToggle.stories.tsx +121 -11
- package/src/components/ColorModeToggle/ColorModeToggle.tsx +149 -45
- package/src/components/ColorModeToggle/index.ts +1 -1
- package/src/components/Countdown/Countdown.tsx +4 -0
- package/src/components/DataTable/DataTable.tsx +2 -1
- package/src/components/DatePicker/DatePicker.stories.tsx +0 -11
- package/src/components/DatePicker/DatePicker.tsx +3 -9
- package/src/components/DatePicker/types.ts +5 -0
- package/src/components/Dropdown/Dropdown.stories.tsx +32 -25
- package/src/components/Dropdown/Dropdown.tsx +26 -28
- package/src/components/EdgePanel/EdgePanel.stories.tsx +13 -15
- package/src/components/EdgePanel/EdgePanel.tsx +20 -5
- package/src/components/Footer/Footer.stories.tsx +187 -60
- package/src/components/Footer/Footer.test.tsx +134 -0
- package/src/components/Footer/Footer.tsx +133 -34
- package/src/components/Footer/FooterLink.tsx +1 -1
- package/src/components/Footer/FooterSection.tsx +53 -36
- package/src/components/Footer/FooterSocialLink.tsx +32 -29
- package/src/components/Footer/README.md +82 -3
- package/src/components/Footer/index.ts +1 -1
- package/src/components/Form/Checkbox.stories.tsx +13 -5
- package/src/components/Form/Checkbox.tsx +3 -6
- package/src/components/Form/Form.stories.tsx +10 -3
- package/src/components/Form/Form.tsx +2 -0
- package/src/components/Form/FormGroup.tsx +2 -1
- package/src/components/Form/Input.stories.tsx +12 -11
- package/src/components/Form/Input.tsx +97 -95
- package/src/components/Form/Radio.stories.tsx +22 -7
- package/src/components/Form/Radio.tsx +3 -6
- package/src/components/Form/Select.stories.tsx +21 -6
- package/src/components/Form/Select.tsx +3 -5
- package/src/components/Form/Textarea.stories.tsx +13 -11
- package/src/components/Form/Textarea.tsx +88 -86
- package/src/components/Hero/Hero.stories.tsx +2 -3
- package/src/components/Hero/Hero.tsx +5 -6
- package/src/components/Icon/Icon.tsx +12 -1
- package/src/components/List/List.tsx +2 -1
- package/src/components/List/ListGroup.tsx +2 -1
- package/src/components/Messages/Messages.tsx +3 -2
- package/src/components/Modal/Modal.stories.tsx +48 -34
- package/src/components/Modal/Modal.tsx +19 -23
- package/src/components/Navigation/Menu/MegaMenu.tsx +2 -2
- package/src/components/Navigation/Menu/Menu.tsx +2 -2
- package/src/components/Navigation/Nav/Nav.tsx +6 -1
- package/src/components/Navigation/Nav/NavDropdown.tsx +10 -1
- package/src/components/Navigation/Navbar/Navbar.tsx +4 -1
- package/src/components/Navigation/SideMenu/SideMenu.tsx +3 -2
- package/src/components/Pagination/Pagination.stories.tsx +13 -6
- package/src/components/Pagination/Pagination.tsx +7 -6
- package/src/components/PhotoViewer/PhotoViewer.tsx +2 -1
- package/src/components/Popover/Popover.stories.tsx +32 -24
- package/src/components/Popover/Popover.tsx +4 -1
- package/src/components/ProductReview/ProductReview.tsx +8 -2
- package/src/components/Progress/Progress.tsx +2 -1
- package/src/components/Rating/Rating.stories.tsx +11 -6
- package/src/components/Rating/Rating.tsx +3 -5
- package/src/components/River/River.tsx +5 -5
- package/src/components/SectionIntro/SectionIntro.tsx +8 -2
- package/src/components/Slider/Slider.stories.tsx +4 -4
- package/src/components/Slider/Slider.tsx +4 -3
- package/src/components/Spinner/Spinner.tsx +2 -1
- package/src/components/Steps/Steps.stories.tsx +5 -4
- package/src/components/Steps/Steps.tsx +8 -5
- package/src/components/Tab/Tab.stories.tsx +4 -3
- package/src/components/Tab/Tab.tsx +8 -6
- package/src/components/Testimonial/Testimonial.tsx +8 -2
- package/src/components/Todo/Todo.tsx +2 -1
- package/src/components/Toggle/Toggle.stories.tsx +5 -4
- package/src/components/Toggle/Toggle.tsx +8 -5
- package/src/components/Tooltip/Tooltip.stories.tsx +40 -30
- package/src/components/Tooltip/Tooltip.tsx +9 -2
- package/src/components/Upload/Upload.stories.tsx +252 -0
- package/src/components/Upload/Upload.tsx +92 -53
- package/src/components/VideoPlayer/VideoPlayer.tsx +3 -1
- package/src/components/index.ts +0 -4
- package/src/layouts/Grid/Grid.stories.tsx +10 -23
- package/src/layouts/Grid/Grid.tsx +20 -1
- package/src/layouts/Grid/GridCol.tsx +76 -48
- package/src/lib/composables/useAtomixGlass.ts +861 -44
- package/src/lib/composables/useBarChart.ts +13 -6
- package/src/lib/composables/useChart.ts +17 -13
- package/src/lib/composables/useChartExport.ts +19 -78
- package/src/lib/composables/useChartToolbar.ts +0 -1
- package/src/lib/composables/useEdgePanel.ts +111 -103
- package/src/lib/composables/useFooter.ts +3 -3
- package/src/lib/composables/useGlassContainer.ts +16 -7
- package/src/lib/composables/useLineChart.ts +8 -1
- package/src/lib/composables/useRiver.ts +5 -0
- package/src/lib/composables/useSlider.ts +62 -24
- package/src/lib/composables/useVideoPlayer.ts +60 -63
- package/src/lib/constants/components.ts +146 -32
- package/src/lib/types/components.ts +258 -10
- package/src/lib/utils/displacement-generator.ts +55 -49
- package/src/lib/utils/icons.ts +1 -1
- package/src/lib/utils/index.ts +16 -10
- package/src/styles/01-settings/_settings.accordion.scss +19 -19
- package/src/styles/01-settings/_settings.animations.scss +5 -5
- package/src/styles/01-settings/_settings.avatar-group.scss +1 -1
- package/src/styles/01-settings/_settings.avatar.scss +17 -17
- package/src/styles/01-settings/_settings.background.scss +1 -4
- package/src/styles/01-settings/_settings.badge.scss +1 -1
- package/src/styles/01-settings/_settings.breadcrumb.scss +1 -1
- package/src/styles/01-settings/_settings.card.scss +1 -1
- package/src/styles/01-settings/_settings.chart.scss +65 -2
- package/src/styles/01-settings/_settings.dropdown.scss +1 -1
- package/src/styles/01-settings/_settings.footer.scss +35 -42
- package/src/styles/01-settings/_settings.input.scss +1 -1
- package/src/styles/01-settings/_settings.list.scss +1 -1
- package/src/styles/01-settings/_settings.rating.scss +1 -1
- package/src/styles/01-settings/_settings.tabs.scss +1 -1
- package/src/styles/01-settings/_settings.upload.scss +6 -5
- package/src/styles/02-tools/_tools.animations.scss +4 -5
- package/src/styles/02-tools/_tools.background.scss +1 -13
- package/src/styles/02-tools/_tools.glass.scss +0 -1
- package/src/styles/02-tools/_tools.utility-api.scss +42 -34
- package/src/styles/03-generic/_generic.root.scss +1 -4
- package/src/styles/04-elements/_elements.body.scss +0 -1
- package/src/styles/06-components/_components.atomix-glass.scss +217 -39
- package/src/styles/06-components/_components.badge.scss +6 -8
- package/src/styles/06-components/_components.button.scss +8 -3
- package/src/styles/06-components/_components.card.scss +2 -14
- package/src/styles/06-components/_components.chart.scss +969 -1449
- package/src/styles/06-components/_components.color-mode-toggle.scss +43 -6
- package/src/styles/06-components/_components.dropdown.scss +19 -7
- package/src/styles/06-components/_components.edge-panel.scss +4 -2
- package/src/styles/06-components/_components.footer.scss +166 -85
- package/src/styles/06-components/_components.input.scss +8 -9
- package/src/styles/06-components/_components.list.scss +1 -0
- package/src/styles/06-components/_components.modal.scss +5 -3
- package/src/styles/06-components/_components.skeleton.scss +8 -6
- package/src/styles/06-components/_components.upload.scss +219 -4
- package/src/styles/06-components/old.chart.styles.scss +1 -30
- package/src/styles/99-utilities/_utilities.opacity.scss +1 -1
- package/src/styles/99-utilities/_utilities.scss +1 -1
- package/src/components/Chart/AdvancedChart.tsx +0 -624
- package/src/components/Chart/LineChartNew.tsx +0 -167
- package/src/components/Chart/RealTimeChart.tsx +0 -436
- package/src/components/DatePicker/DatePicker copy.tsx +0 -551
|
@@ -1,9 +1,44 @@
|
|
|
1
|
-
import { forwardRef, memo, useCallback, useEffect, useState } from 'react';
|
|
1
|
+
import { forwardRef, memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
2
2
|
import { useChart } from '../../lib/composables/useChart';
|
|
3
3
|
import { useChartToolbar } from '../../lib/composables/useChartToolbar';
|
|
4
4
|
import { CHART } from '../../lib/constants/components';
|
|
5
|
-
import { ChartProps } from '
|
|
5
|
+
import { ChartProps } from './types';
|
|
6
6
|
import ChartToolbar from './ChartToolbar';
|
|
7
|
+
import { AtomixGlass } from '../AtomixGlass/AtomixGlass';
|
|
8
|
+
import type { AtomixGlassProps } from '../../lib/types/components';
|
|
9
|
+
|
|
10
|
+
// Create a context to share chart state between Chart and its children
|
|
11
|
+
import { createContext, useContext } from 'react';
|
|
12
|
+
|
|
13
|
+
interface ChartContextValue {
|
|
14
|
+
zoomLevel: number;
|
|
15
|
+
panOffset: { x: number; y: number };
|
|
16
|
+
panEnabled: boolean;
|
|
17
|
+
onZoomIn: () => void;
|
|
18
|
+
onZoomOut: () => void;
|
|
19
|
+
onZoomReset: () => void;
|
|
20
|
+
onPanToggle: (enabled: boolean) => void;
|
|
21
|
+
onReset: () => void;
|
|
22
|
+
setZoomLevel: (level: number) => void;
|
|
23
|
+
setPanOffset: (offset: { x: number; y: number }) => void;
|
|
24
|
+
setPanEnabled: (enabled: boolean) => void;
|
|
25
|
+
toolbarState: {
|
|
26
|
+
showTooltips?: boolean;
|
|
27
|
+
showLegend?: boolean;
|
|
28
|
+
animationsEnabled?: boolean;
|
|
29
|
+
showGrid?: boolean;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const ChartContext = createContext<ChartContextValue | null>(null);
|
|
34
|
+
|
|
35
|
+
export const useChartContext = () => {
|
|
36
|
+
const context = useContext(ChartContext);
|
|
37
|
+
if (!context) {
|
|
38
|
+
throw new Error('useChartContext must be used within a Chart component');
|
|
39
|
+
}
|
|
40
|
+
return context;
|
|
41
|
+
};
|
|
7
42
|
|
|
8
43
|
const Chart = memo(
|
|
9
44
|
forwardRef<HTMLDivElement, ChartProps>(
|
|
@@ -29,12 +64,86 @@ const Chart = memo(
|
|
|
29
64
|
exportFormats = ['png', 'svg', 'csv'],
|
|
30
65
|
datasets,
|
|
31
66
|
config,
|
|
67
|
+
// Destructure non-DOM props to prevent passing to DOM element
|
|
68
|
+
toolbarConfig,
|
|
69
|
+
customToolbarActions,
|
|
70
|
+
customToolbarGroups,
|
|
71
|
+
data,
|
|
72
|
+
showLegend,
|
|
73
|
+
interactive,
|
|
74
|
+
fullscreen,
|
|
75
|
+
onDataPointClick,
|
|
76
|
+
onLegendItemClick,
|
|
77
|
+
glass,
|
|
32
78
|
...props
|
|
33
79
|
},
|
|
34
80
|
ref
|
|
35
81
|
) => {
|
|
36
82
|
const [isFullscreen, setIsFullscreen] = useState(false);
|
|
37
83
|
const [isExporting, setIsExporting] = useState(false);
|
|
84
|
+
const chartContainerRef = useRef<HTMLDivElement>(null);
|
|
85
|
+
|
|
86
|
+
// Internal zoom and pan state
|
|
87
|
+
const [zoomLevel, setZoomLevel] = useState(1);
|
|
88
|
+
const [panOffset, setPanOffset] = useState({ x: 0, y: 0 });
|
|
89
|
+
const [panEnabled, setPanEnabled] = useState(false);
|
|
90
|
+
|
|
91
|
+
// Memoize fullscreen handler
|
|
92
|
+
const handleFullscreenChange = useCallback(
|
|
93
|
+
(fullscreen: boolean) => {
|
|
94
|
+
setIsFullscreen(fullscreen);
|
|
95
|
+
onFullscreen?.(fullscreen);
|
|
96
|
+
},
|
|
97
|
+
[onFullscreen]
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
// Zoom and pan handlers
|
|
101
|
+
const handleZoomIn = useCallback(() => {
|
|
102
|
+
setZoomLevel(prev => Math.min(prev * 1.2, 5));
|
|
103
|
+
}, []);
|
|
104
|
+
|
|
105
|
+
const handleZoomOut = useCallback(() => {
|
|
106
|
+
setZoomLevel(prev => Math.max(prev / 1.2, 0.2));
|
|
107
|
+
}, []);
|
|
108
|
+
|
|
109
|
+
const handleZoomReset = useCallback(() => {
|
|
110
|
+
setZoomLevel(1);
|
|
111
|
+
setPanOffset({ x: 0, y: 0 });
|
|
112
|
+
}, []);
|
|
113
|
+
|
|
114
|
+
const handlePanToggle = useCallback((enabled: boolean) => {
|
|
115
|
+
setPanEnabled(enabled);
|
|
116
|
+
}, []);
|
|
117
|
+
|
|
118
|
+
const handleReset = useCallback(() => {
|
|
119
|
+
setZoomLevel(1);
|
|
120
|
+
setPanOffset({ x: 0, y: 0 });
|
|
121
|
+
setPanEnabled(false);
|
|
122
|
+
}, []);
|
|
123
|
+
|
|
124
|
+
// Memoize toolbar handlers object to prevent unnecessary re-renders
|
|
125
|
+
const toolbarHandlersConfig = useMemo(
|
|
126
|
+
() => ({
|
|
127
|
+
onRefresh,
|
|
128
|
+
onExport,
|
|
129
|
+
onFullscreen: handleFullscreenChange,
|
|
130
|
+
onZoomIn: handleZoomIn,
|
|
131
|
+
onZoomOut: handleZoomOut,
|
|
132
|
+
onZoomReset: handleZoomReset,
|
|
133
|
+
onPanToggle: handlePanToggle,
|
|
134
|
+
onReset: handleReset,
|
|
135
|
+
}),
|
|
136
|
+
[
|
|
137
|
+
onRefresh,
|
|
138
|
+
onExport,
|
|
139
|
+
handleFullscreenChange,
|
|
140
|
+
handleZoomIn,
|
|
141
|
+
handleZoomOut,
|
|
142
|
+
handleZoomReset,
|
|
143
|
+
handlePanToggle,
|
|
144
|
+
handleReset,
|
|
145
|
+
]
|
|
146
|
+
);
|
|
38
147
|
|
|
39
148
|
// Enhanced toolbar with dynamic configuration
|
|
40
149
|
const {
|
|
@@ -49,9 +158,7 @@ const Chart = memo(
|
|
|
49
158
|
refresh: enableRefresh,
|
|
50
159
|
export: enableExport,
|
|
51
160
|
fullscreen: enableFullscreen,
|
|
52
|
-
|
|
53
|
-
pan: true, // Enable pan by default
|
|
54
|
-
reset: true, // Enable reset by default
|
|
161
|
+
// Let useChartToolbar determine zoom/pan/reset based on chart type
|
|
55
162
|
grid: true, // Enable grid toggle by default
|
|
56
163
|
legend: true, // Enable legend toggle by default
|
|
57
164
|
tooltips: true, // Enable tooltips toggle by default
|
|
@@ -60,17 +167,10 @@ const Chart = memo(
|
|
|
60
167
|
},
|
|
61
168
|
exportFormats,
|
|
62
169
|
},
|
|
63
|
-
|
|
64
|
-
onRefresh,
|
|
65
|
-
onExport,
|
|
66
|
-
onFullscreen: fullscreen => {
|
|
67
|
-
setIsFullscreen(fullscreen);
|
|
68
|
-
onFullscreen?.(fullscreen);
|
|
69
|
-
},
|
|
70
|
-
}
|
|
170
|
+
toolbarHandlersConfig
|
|
71
171
|
);
|
|
72
172
|
|
|
73
|
-
const
|
|
173
|
+
const chartResult = useChart({
|
|
74
174
|
type,
|
|
75
175
|
size,
|
|
76
176
|
variant,
|
|
@@ -78,6 +178,22 @@ const Chart = memo(
|
|
|
78
178
|
error,
|
|
79
179
|
});
|
|
80
180
|
|
|
181
|
+
// Sync toolbar state with internal state
|
|
182
|
+
useEffect(() => {
|
|
183
|
+
setZoomLevel(toolbarState.zoomLevel);
|
|
184
|
+
}, [toolbarState.zoomLevel]);
|
|
185
|
+
|
|
186
|
+
useEffect(() => {
|
|
187
|
+
setPanEnabled(toolbarState.panEnabled);
|
|
188
|
+
}, [toolbarState.panEnabled]);
|
|
189
|
+
|
|
190
|
+
// Update toolbar state when internal state changes (for two-way binding)
|
|
191
|
+
useEffect(() => {
|
|
192
|
+
if (toolbarState.zoomLevel !== zoomLevel) {
|
|
193
|
+
// Toolbar state is already managed by useChartToolbar
|
|
194
|
+
}
|
|
195
|
+
}, [zoomLevel, toolbarState.zoomLevel]);
|
|
196
|
+
|
|
81
197
|
const chartClass = generateChartClass({
|
|
82
198
|
type,
|
|
83
199
|
size,
|
|
@@ -85,6 +201,8 @@ const Chart = memo(
|
|
|
85
201
|
loading,
|
|
86
202
|
error,
|
|
87
203
|
className,
|
|
204
|
+
interactive,
|
|
205
|
+
panEnabled,
|
|
88
206
|
});
|
|
89
207
|
|
|
90
208
|
// Legacy handlers for backward compatibility
|
|
@@ -113,106 +231,287 @@ const Chart = memo(
|
|
|
113
231
|
const renderToolbar = () => {
|
|
114
232
|
if (!showToolbar) return null;
|
|
115
233
|
|
|
234
|
+
// Only pass individual handlers if groups are not provided
|
|
235
|
+
const shouldPassIndividualHandlers = !toolbarGroups || toolbarGroups.length === 0;
|
|
236
|
+
|
|
116
237
|
return (
|
|
117
238
|
<ChartToolbar
|
|
118
239
|
chartType={type}
|
|
119
240
|
groups={toolbarGroups}
|
|
120
|
-
|
|
241
|
+
defaults={{
|
|
242
|
+
refresh: enableRefresh,
|
|
243
|
+
export: enableExport,
|
|
244
|
+
fullscreen: enableFullscreen,
|
|
245
|
+
zoom: toolbarState.zoomLevel !== undefined,
|
|
246
|
+
pan: toolbarState.panEnabled !== undefined,
|
|
247
|
+
reset: true,
|
|
248
|
+
grid: true,
|
|
249
|
+
legend: true,
|
|
250
|
+
tooltips: true,
|
|
251
|
+
animations: true,
|
|
252
|
+
settings: true,
|
|
253
|
+
}}
|
|
121
254
|
exportFormats={exportFormats}
|
|
122
255
|
state={{
|
|
123
256
|
isFullscreen: toolbarState.isFullscreen,
|
|
124
257
|
isExporting: toolbarState.isExporting,
|
|
125
258
|
isRefreshing: toolbarState.isRefreshing,
|
|
126
|
-
zoomLevel:
|
|
127
|
-
panEnabled:
|
|
259
|
+
zoomLevel: zoomLevel, // Use internal state for accurate display
|
|
260
|
+
panEnabled: panEnabled, // Use internal state for accurate display
|
|
128
261
|
showGrid: toolbarState.showGrid,
|
|
129
262
|
showLegend: toolbarState.showLegend,
|
|
130
263
|
showTooltips: toolbarState.showTooltips,
|
|
131
264
|
animationsEnabled: toolbarState.animationsEnabled,
|
|
132
265
|
}}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
266
|
+
{...(shouldPassIndividualHandlers
|
|
267
|
+
? {
|
|
268
|
+
onRefresh: toolbarHandlers.onRefresh,
|
|
269
|
+
onExport: toolbarHandlers.onExport,
|
|
270
|
+
onFullscreen: toolbarHandlers.onFullscreen,
|
|
271
|
+
onZoomIn: handleZoomIn,
|
|
272
|
+
onZoomOut: handleZoomOut,
|
|
273
|
+
onZoomReset: handleZoomReset,
|
|
274
|
+
onPanToggle: handlePanToggle,
|
|
275
|
+
onReset: handleReset,
|
|
276
|
+
onSettings: toolbarHandlers.onSettings,
|
|
277
|
+
onGridToggle: toolbarHandlers.onGridToggle,
|
|
278
|
+
onLegendToggle: toolbarHandlers.onLegendToggle,
|
|
279
|
+
onTooltipsToggle: toolbarHandlers.onTooltipsToggle,
|
|
280
|
+
onAnimationsToggle: toolbarHandlers.onAnimationsToggle,
|
|
281
|
+
}
|
|
282
|
+
: {})}
|
|
146
283
|
/>
|
|
147
284
|
);
|
|
148
285
|
};
|
|
149
286
|
|
|
150
|
-
const fullChartClass = `${chartClass}${isFullscreen ? ` ${CHART.CLASSES.FULLSCREEN}` : ''}`;
|
|
287
|
+
const fullChartClass = `${chartClass}${isFullscreen ? ` ${CHART.CLASSES.FULLSCREEN}` : ''}${glass ? ` c-chart--glass` : ''}`;
|
|
151
288
|
|
|
152
|
-
|
|
289
|
+
// Default glass settings optimized for charts
|
|
290
|
+
const defaultChartGlassProps: Partial<AtomixGlassProps> = useMemo(
|
|
291
|
+
() => ({
|
|
292
|
+
displacementScale: 25,
|
|
293
|
+
blurAmount: 0, // Charts need clarity, no blur
|
|
294
|
+
saturation: 180,
|
|
295
|
+
aberrationIntensity: 1.5,
|
|
296
|
+
elasticity: 0, // No elastic effect for charts
|
|
297
|
+
enableLiquidBlur: false, // Keep it simple
|
|
298
|
+
enableBorderEffect: true,
|
|
299
|
+
mode: 'standard' as const,
|
|
300
|
+
mouseContainer: chartContainerRef,
|
|
301
|
+
reducedMotion: false,
|
|
302
|
+
}),
|
|
303
|
+
[]
|
|
304
|
+
);
|
|
305
|
+
|
|
306
|
+
// Determine glass props
|
|
307
|
+
const glassProps = useMemo(() => {
|
|
308
|
+
if (!glass) return null;
|
|
309
|
+
if (glass === true) {
|
|
310
|
+
return defaultChartGlassProps;
|
|
311
|
+
}
|
|
312
|
+
return { ...defaultChartGlassProps, ...glass };
|
|
313
|
+
}, [glass, defaultChartGlassProps]);
|
|
314
|
+
|
|
315
|
+
// Extract border-radius from chart styles (use design token)
|
|
316
|
+
const chartBorderRadius = useMemo(() => {
|
|
317
|
+
// Use chart border-radius design token (typically 12px from $border-radius-lg)
|
|
318
|
+
// AtomixGlass will extract from children if not provided
|
|
319
|
+
return glassProps?.cornerRadius || undefined;
|
|
320
|
+
}, [glassProps?.cornerRadius]);
|
|
321
|
+
|
|
322
|
+
// Create context value
|
|
323
|
+
const chartContextValue = useMemo<ChartContextValue>(
|
|
324
|
+
() => ({
|
|
325
|
+
zoomLevel,
|
|
326
|
+
panOffset,
|
|
327
|
+
panEnabled,
|
|
328
|
+
onZoomIn: handleZoomIn,
|
|
329
|
+
onZoomOut: handleZoomOut,
|
|
330
|
+
onZoomReset: handleZoomReset,
|
|
331
|
+
onPanToggle: handlePanToggle,
|
|
332
|
+
onReset: handleReset,
|
|
333
|
+
setZoomLevel,
|
|
334
|
+
setPanOffset,
|
|
335
|
+
setPanEnabled,
|
|
336
|
+
toolbarState: {
|
|
337
|
+
showTooltips: toolbarState.showTooltips,
|
|
338
|
+
showLegend: toolbarState.showLegend,
|
|
339
|
+
animationsEnabled: toolbarState.animationsEnabled,
|
|
340
|
+
showGrid: toolbarState.showGrid,
|
|
341
|
+
},
|
|
342
|
+
}),
|
|
343
|
+
[
|
|
344
|
+
zoomLevel,
|
|
345
|
+
panOffset,
|
|
346
|
+
panEnabled,
|
|
347
|
+
handleZoomIn,
|
|
348
|
+
handleZoomOut,
|
|
349
|
+
handleZoomReset,
|
|
350
|
+
handlePanToggle,
|
|
351
|
+
handleReset,
|
|
352
|
+
setPanEnabled,
|
|
353
|
+
toolbarState.showTooltips,
|
|
354
|
+
toolbarState.showLegend,
|
|
355
|
+
toolbarState.animationsEnabled,
|
|
356
|
+
toolbarState.showGrid,
|
|
357
|
+
]
|
|
358
|
+
);
|
|
359
|
+
|
|
360
|
+
// Chart content component
|
|
361
|
+
const chartContent = (
|
|
153
362
|
<div
|
|
154
|
-
ref={
|
|
363
|
+
ref={chartContainerRef}
|
|
155
364
|
className={fullChartClass}
|
|
156
365
|
aria-label={ariaLabel || `${type} chart`}
|
|
157
366
|
role="img"
|
|
158
367
|
tabIndex={0}
|
|
159
|
-
{...chartAttributes}
|
|
160
368
|
{...props}
|
|
161
369
|
>
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
</div>
|
|
172
|
-
)}
|
|
173
|
-
|
|
174
|
-
<div className={CHART.CONTENT_CLASS}>
|
|
175
|
-
{loading && (
|
|
176
|
-
<div className={CHART.LOADING_CLASS}>
|
|
177
|
-
<div className={CHART.LOADING_SPINNER_CLASS}></div>
|
|
178
|
-
<span className={CHART.LOADING_TEXT_CLASS}>
|
|
179
|
-
{toolbarState.isExporting
|
|
180
|
-
? 'Exporting chart...'
|
|
181
|
-
: toolbarState.isRefreshing
|
|
182
|
-
? 'Refreshing chart...'
|
|
183
|
-
: 'Loading chart...'}
|
|
184
|
-
</span>
|
|
370
|
+
{(title || subtitle || showToolbar) && (
|
|
371
|
+
<div
|
|
372
|
+
className={`${CHART.HEADER_CLASS} u-d-flex u-justify-between u-align-items-start u-gap-4`}
|
|
373
|
+
>
|
|
374
|
+
<div className={`${CHART.HEADER_CONTENT_CLASS} u-flex-1`}>
|
|
375
|
+
{title && <h3 className={`${CHART.TITLE_CLASS} u-mb-1`}>{title}</h3>}
|
|
376
|
+
{subtitle && <p className={`${CHART.SUBTITLE_CLASS} u-mb-0`}>{subtitle}</p>}
|
|
377
|
+
</div>
|
|
378
|
+
{renderToolbar()}
|
|
185
379
|
</div>
|
|
186
380
|
)}
|
|
187
381
|
|
|
188
|
-
{
|
|
189
|
-
|
|
190
|
-
<div className={CHART.
|
|
191
|
-
|
|
192
|
-
<
|
|
193
|
-
|
|
382
|
+
<div className={CHART.CONTENT_CLASS}>
|
|
383
|
+
{loading && (
|
|
384
|
+
<div className={CHART.LOADING_CLASS}>
|
|
385
|
+
<div className={CHART.LOADING_SPINNER_CLASS}></div>
|
|
386
|
+
<span className={CHART.LOADING_TEXT_CLASS}>
|
|
387
|
+
{toolbarState.isExporting
|
|
388
|
+
? 'Exporting chart...'
|
|
389
|
+
: toolbarState.isRefreshing
|
|
390
|
+
? 'Refreshing chart...'
|
|
391
|
+
: 'Loading chart...'}
|
|
392
|
+
</span>
|
|
194
393
|
</div>
|
|
195
|
-
|
|
196
|
-
)}
|
|
394
|
+
)}
|
|
197
395
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
396
|
+
{error && (
|
|
397
|
+
<div className={CHART.ERROR_CLASS}>
|
|
398
|
+
<div className={CHART.ERROR_ICON_CLASS}>⚠</div>
|
|
399
|
+
<div className={CHART.ERROR_CONTENT_CLASS}>
|
|
400
|
+
<div className={CHART.ERROR_MESSAGE_CLASS}>Chart Error</div>
|
|
401
|
+
<div className={CHART.ERROR_DETAILS_CLASS}>{error}</div>
|
|
402
|
+
</div>
|
|
204
403
|
</div>
|
|
205
|
-
|
|
206
|
-
|
|
404
|
+
)}
|
|
405
|
+
|
|
406
|
+
{!loading && !error && !children && (
|
|
407
|
+
<div className={CHART.EMPTY_CLASS}>
|
|
408
|
+
<div className={CHART.EMPTY_ICON_CLASS}>📊</div>
|
|
409
|
+
<div className={CHART.EMPTY_MESSAGE_CLASS}>No data available</div>
|
|
410
|
+
<div className={CHART.EMPTY_DETAILS_CLASS}>
|
|
411
|
+
Add data to your chart to see visualizations
|
|
412
|
+
</div>
|
|
413
|
+
</div>
|
|
414
|
+
)}
|
|
207
415
|
|
|
208
|
-
|
|
416
|
+
{!loading && !error && children && (
|
|
417
|
+
<div className={CHART.CANVAS_CLASS}>{children}</div>
|
|
418
|
+
)}
|
|
419
|
+
</div>
|
|
420
|
+
</div>
|
|
421
|
+
);
|
|
422
|
+
|
|
423
|
+
// Wrap with AtomixGlass if glass is enabled
|
|
424
|
+
const wrappedChart = glassProps ? (
|
|
425
|
+
<AtomixGlass
|
|
426
|
+
{...glassProps}
|
|
427
|
+
cornerRadius={chartBorderRadius}
|
|
428
|
+
style={{
|
|
429
|
+
width: '100%',
|
|
430
|
+
height: '100%',
|
|
431
|
+
...glassProps.style,
|
|
432
|
+
}}
|
|
433
|
+
>
|
|
434
|
+
{chartContent}
|
|
435
|
+
</AtomixGlass>
|
|
436
|
+
) : (
|
|
437
|
+
chartContent
|
|
438
|
+
);
|
|
439
|
+
|
|
440
|
+
return (
|
|
441
|
+
<ChartContext.Provider value={chartContextValue}>
|
|
442
|
+
<div ref={ref} style={{ width: '100%', height: '100%' }}>
|
|
443
|
+
{wrappedChart}
|
|
209
444
|
</div>
|
|
210
|
-
</
|
|
445
|
+
</ChartContext.Provider>
|
|
211
446
|
);
|
|
212
447
|
}
|
|
213
448
|
)
|
|
214
449
|
);
|
|
215
450
|
|
|
451
|
+
// Helper function to generate chart class names
|
|
452
|
+
const generateChartClass = ({
|
|
453
|
+
type,
|
|
454
|
+
size,
|
|
455
|
+
variant,
|
|
456
|
+
loading,
|
|
457
|
+
error,
|
|
458
|
+
className,
|
|
459
|
+
interactive,
|
|
460
|
+
panEnabled,
|
|
461
|
+
}: {
|
|
462
|
+
type: ChartProps['type'];
|
|
463
|
+
size: ChartProps['size'];
|
|
464
|
+
variant: ChartProps['variant'];
|
|
465
|
+
loading: ChartProps['loading'];
|
|
466
|
+
error: ChartProps['error'];
|
|
467
|
+
className: string;
|
|
468
|
+
interactive?: boolean;
|
|
469
|
+
panEnabled?: boolean;
|
|
470
|
+
}) => {
|
|
471
|
+
const classes = [CHART.ROOT_CLASS];
|
|
472
|
+
|
|
473
|
+
// Add type class
|
|
474
|
+
if (type) {
|
|
475
|
+
const typeKey = type.toUpperCase() as keyof typeof CHART.CLASSES;
|
|
476
|
+
const typeClass = CHART.CLASSES[typeKey] || `${CHART.TYPE_PREFIX}${type}`;
|
|
477
|
+
classes.push(typeClass);
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
// Add size class
|
|
481
|
+
if (size) {
|
|
482
|
+
const sizeKey = size.toUpperCase() as keyof typeof CHART.CLASSES;
|
|
483
|
+
const sizeClass = CHART.CLASSES[sizeKey] || `${CHART.SIZE_PREFIX}${size}`;
|
|
484
|
+
classes.push(sizeClass);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// Add variant class
|
|
488
|
+
if (variant) {
|
|
489
|
+
const variantKey = variant.toUpperCase() as keyof typeof CHART.CLASSES;
|
|
490
|
+
const variantClass = CHART.CLASSES[variantKey] || `${CHART.VARIANT_PREFIX}${variant}`;
|
|
491
|
+
classes.push(variantClass);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
// Add interactive class
|
|
495
|
+
if (interactive || panEnabled) {
|
|
496
|
+
classes.push(CHART.CLASSES.INTERACTIVE);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// Add state classes
|
|
500
|
+
if (loading) {
|
|
501
|
+
classes.push(CHART.LOADING_STATE_CLASS);
|
|
502
|
+
}
|
|
503
|
+
if (error) {
|
|
504
|
+
classes.push(CHART.ERROR_STATE_CLASS);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
// Add custom className
|
|
508
|
+
if (className) {
|
|
509
|
+
classes.push(className);
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
return classes.join(' ');
|
|
513
|
+
};
|
|
514
|
+
|
|
216
515
|
Chart.displayName = 'Chart';
|
|
217
516
|
export default Chart;
|
|
218
517
|
export type { ChartProps };
|