@shohojdhara/atomix 0.3.15 → 0.4.1
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/build-tools/index.d.ts +31 -30
- package/build-tools/package.json +4 -21
- package/dist/atomix.css +20234 -2027
- package/dist/atomix.css.map +1 -1
- package/dist/atomix.min.css +76 -2
- package/dist/atomix.min.css.map +1 -1
- package/dist/build-tools/index.d.ts +31 -30
- package/dist/build-tools/package.json +4 -21
- package/dist/charts.js +4 -5
- package/dist/charts.js.map +1 -1
- package/dist/core.d.ts +87 -10
- package/dist/core.js +673 -480
- package/dist/core.js.map +1 -1
- package/dist/forms.d.ts +15 -3
- package/dist/forms.js +530 -97
- package/dist/forms.js.map +1 -1
- package/dist/heavy.js +5 -6
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +644 -277
- package/dist/index.esm.js +1948 -1347
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +3333 -2728
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/layout.js.map +1 -1
- package/dist/theme.d.ts +9 -9
- package/dist/theme.js.map +1 -1
- package/package.json +2 -2
- package/scripts/atomix-cli.js +10 -1
- package/scripts/cli/__tests__/utils.test.js +6 -2
- package/scripts/cli/migration-tools.js +2 -2
- package/scripts/cli/theme-bridge.js +7 -9
- package/scripts/cli/utils.js +2 -1
- package/src/components/Accordion/Accordion.stories.tsx +72 -23
- package/src/components/Accordion/Accordion.test.tsx +70 -50
- package/src/components/Accordion/Accordion.tsx +219 -96
- package/src/components/Accordion/AccordionCompound.test.tsx +70 -0
- package/src/components/AtomixGlass/AtomixGlass.test.tsx +1 -1
- package/src/components/AtomixGlass/GlassFilter.tsx +9 -16
- package/src/components/AtomixGlass/glass-utils.ts +4 -3
- package/src/components/AtomixGlass/shader-utils.ts +128 -52
- package/src/components/AtomixGlass/stories/Playground.stories.tsx +1 -1
- package/src/components/AtomixGlass/stories/Shaders.stories.tsx +1 -1
- package/src/components/Avatar/Avatar.stories.tsx +45 -62
- package/src/components/Avatar/Avatar.tsx +58 -56
- package/src/components/Badge/Badge.stories.tsx +20 -9
- package/src/components/Badge/Badge.test.tsx +41 -41
- package/src/components/Badge/Badge.tsx +64 -62
- package/src/components/Block/Block.stories.tsx +14 -4
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +9 -8
- package/src/components/Breadcrumb/Breadcrumb.tsx +173 -65
- package/src/components/Breadcrumb/BreadcrumbCompound.test.tsx +84 -0
- package/src/components/Button/Button.stories.tsx +13 -22
- package/src/components/Button/Button.test.tsx +97 -81
- package/src/components/Button/Button.tsx +46 -14
- package/src/components/Button/ButtonGroup.stories.tsx +37 -32
- package/src/components/Button/ButtonGroup.tsx +4 -15
- package/src/components/Callout/Callout.stories.tsx +166 -918
- package/src/components/Callout/Callout.tsx +196 -84
- package/src/components/Callout/CalloutCompound.test.tsx +72 -0
- package/src/components/Card/Card.stories.tsx +67 -36
- package/src/components/Card/Card.tsx +30 -14
- package/src/components/Chart/AreaChart.tsx +1 -1
- package/src/components/Chart/CandlestickChart.tsx +23 -16
- package/src/components/Chart/Chart.stories.tsx +4 -9
- package/src/components/Chart/Chart.tsx +40 -44
- package/src/components/Chart/ChartRenderer.tsx +39 -12
- package/src/components/Chart/ChartToolbar.tsx +21 -5
- package/src/components/Chart/DonutChart.tsx +1 -1
- package/src/components/Chart/FunnelChart.tsx +4 -1
- package/src/components/Chart/GaugeChart.tsx +3 -1
- package/src/components/Chart/HeatmapChart.tsx +50 -37
- package/src/components/Chart/LineChart.tsx +3 -2
- package/src/components/Chart/MultiAxisChart.tsx +24 -16
- package/src/components/Chart/RadarChart.tsx +19 -17
- package/src/components/Chart/ScatterChart.tsx +29 -21
- package/src/components/ColorModeToggle/ColorModeToggle.stories.tsx +6 -2
- package/src/components/ColorModeToggle/ColorModeToggle.tsx +15 -3
- package/src/components/Countdown/Countdown.stories.tsx +7 -7
- package/src/components/DataTable/DataTable.stories.tsx +43 -38
- package/src/components/DataTable/DataTable.test.tsx +26 -148
- package/src/components/DataTable/DataTable.tsx +485 -456
- package/src/components/DatePicker/DatePicker.stories.tsx +32 -47
- package/src/components/DatePicker/DatePicker.tsx +31 -26
- package/src/components/Dropdown/Dropdown.stories.tsx +2 -5
- package/src/components/Dropdown/Dropdown.tsx +425 -298
- package/src/components/Dropdown/DropdownCompound.test.tsx +64 -0
- package/src/components/EdgePanel/EdgePanel.stories.tsx +6 -19
- package/src/components/EdgePanel/EdgePanel.tsx +163 -113
- package/src/components/EdgePanel/EdgePanelCompound.test.tsx +53 -0
- package/src/components/Footer/Footer.stories.tsx +21 -16
- package/src/components/Footer/Footer.tsx +130 -128
- package/src/components/Footer/FooterLink.tsx +2 -2
- package/src/components/Form/Checkbox.test.tsx +49 -49
- package/src/components/Form/Checkbox.tsx +108 -100
- package/src/components/Form/Form.stories.tsx +2 -10
- package/src/components/Form/Input.stories.tsx +22 -39
- package/src/components/Form/Input.test.tsx +38 -44
- package/src/components/Form/Radio.stories.tsx +6 -12
- package/src/components/Form/Radio.tsx +68 -66
- package/src/components/Form/Select.stories.tsx +23 -0
- package/src/components/Form/Select.test.tsx +99 -0
- package/src/components/Form/Select.tsx +239 -186
- package/src/components/Form/SelectOption.tsx +88 -0
- package/src/components/Form/Textarea.test.tsx +27 -32
- package/src/components/Hero/Hero.stories.tsx +93 -23
- package/src/components/Hero/Hero.test.tsx +142 -0
- package/src/components/Hero/Hero.tsx +343 -58
- package/src/components/Icon/index.ts +7 -1
- package/src/components/List/List.test.tsx +62 -0
- package/src/components/List/List.tsx +32 -25
- package/src/components/List/ListItem.tsx +20 -0
- package/src/components/Modal/Modal.stories.tsx +67 -2
- package/src/components/Modal/Modal.tsx +208 -125
- package/src/components/Modal/ModalCompound.test.tsx +94 -0
- package/src/components/Navigation/Menu/MegaMenu.tsx +70 -70
- package/src/components/Navigation/Nav/NavDropdown.tsx +1 -5
- package/src/components/Navigation/SideMenu/SideMenu.stories.tsx +128 -28
- package/src/components/Navigation/SideMenu/SideMenu.tsx +5 -7
- package/src/components/Navigation/SideMenu/SideMenuItem.tsx +4 -5
- package/src/components/Pagination/Pagination.stories.tsx +7 -4
- package/src/components/Pagination/Pagination.tsx +199 -202
- package/src/components/PhotoViewer/PhotoViewer.tsx +4 -1
- package/src/components/Popover/Popover.stories.tsx +99 -192
- package/src/components/Popover/Popover.tsx +41 -37
- package/src/components/Progress/Progress.stories.tsx +35 -44
- package/src/components/River/River.stories.tsx +2 -1
- package/src/components/SectionIntro/SectionIntro.stories.tsx +71 -71
- package/src/components/Slider/Slider.stories.tsx +12 -4
- package/src/components/Spinner/Spinner.stories.tsx +3 -1
- package/src/components/Spinner/Spinner.test.tsx +23 -23
- package/src/components/Spinner/Spinner.tsx +43 -46
- package/src/components/Steps/Steps.stories.tsx +8 -6
- package/src/components/Steps/Steps.tsx +124 -21
- package/src/components/Steps/StepsCompound.test.tsx +81 -0
- package/src/components/Tabs/Tabs.stories.tsx +12 -9
- package/src/components/Tabs/Tabs.tsx +230 -75
- package/src/components/Tabs/TabsCompound.test.tsx +64 -0
- package/src/components/Toggle/Toggle.stories.tsx +27 -13
- package/src/components/Toggle/Toggle.test.tsx +65 -70
- package/src/components/Toggle/Toggle.tsx +4 -1
- package/src/components/Tooltip/Tooltip.stories.tsx +24 -20
- package/src/components/Tooltip/Tooltip.tsx +104 -106
- package/src/components/Upload/Upload.stories.tsx +129 -127
- package/src/components/Upload/Upload.tsx +287 -283
- package/src/components/VideoPlayer/VideoPlayer.tsx +6 -1
- package/src/components/index.ts +13 -2
- package/src/layouts/Grid/Grid.stories.tsx +9 -3
- package/src/layouts/MasonryGrid/MasonryGrid.tsx +5 -1
- package/src/lib/__tests__/theme-tools.test.ts +32 -6
- package/src/lib/composables/index.ts +0 -4
- package/src/lib/composables/shared-mouse-tracker.ts +13 -14
- package/src/lib/composables/useAtomixGlass.ts +102 -60
- package/src/lib/composables/useChartExport.ts +1 -1
- package/src/lib/composables/useDataTable.ts +29 -17
- package/src/lib/composables/useHero.ts +58 -14
- package/src/lib/composables/useHeroBackgroundSlider.ts +2 -9
- package/src/lib/composables/useInput.ts +10 -8
- package/src/lib/composables/useSideMenu.ts +6 -5
- package/src/lib/composables/useTooltip.ts +1 -2
- package/src/lib/composables/useVideoPlayer.ts +44 -35
- package/src/lib/config/index.ts +154 -154
- package/src/lib/constants/cssVariables.ts +29 -29
- package/src/lib/hooks/__tests__/useComponentCustomization.test.ts +2 -6
- package/src/lib/hooks/index.ts +1 -1
- package/src/lib/hooks/useComponentCustomization.ts +11 -17
- package/src/lib/hooks/usePerformanceMonitor.ts +6 -7
- package/src/lib/patterns/__tests__/slots.test.ts +1 -1
- package/src/lib/patterns/index.ts +1 -1
- package/src/lib/patterns/slots.tsx +8 -13
- package/src/lib/storybook/InteractiveDemo.tsx +13 -18
- package/src/lib/storybook/PreviewContainer.tsx +1 -1
- package/src/lib/storybook/VariantsGrid.tsx +3 -7
- package/src/lib/storybook/index.ts +1 -1
- package/src/lib/theme/adapters/cssVariableMapper.ts +47 -74
- package/src/lib/theme/adapters/index.ts +3 -9
- package/src/lib/theme/adapters/themeAdapter.ts +41 -26
- package/src/lib/theme/config/index.ts +1 -1
- package/src/lib/theme/config/types.ts +2 -2
- package/src/lib/theme/config/validator.ts +10 -5
- package/src/lib/theme/constants/constants.ts +2 -2
- package/src/lib/theme/constants/index.ts +1 -2
- package/src/lib/theme/core/__tests__/createTheme.test.ts +20 -22
- package/src/lib/theme/core/composeTheme.ts +32 -26
- package/src/lib/theme/core/createTheme.ts +1 -1
- package/src/lib/theme/core/createThemeObject.ts +308 -301
- package/src/lib/theme/core/index.ts +3 -3
- package/src/lib/theme/devtools/CLI.ts +105 -111
- package/src/lib/theme/devtools/Comparator.tsx +50 -32
- package/src/lib/theme/devtools/DesignTokensCustomizer.stories.tsx +50 -48
- package/src/lib/theme/devtools/DesignTokensCustomizer.tsx +257 -63
- package/src/lib/theme/devtools/Inspector.tsx +75 -60
- package/src/lib/theme/devtools/LiveEditor.tsx +97 -76
- package/src/lib/theme/devtools/Preview.tsx +150 -106
- package/src/lib/theme/devtools/ThemeValidator.ts +29 -21
- package/src/lib/theme/devtools/index.ts +3 -9
- package/src/lib/theme/devtools/useHistory.ts +23 -21
- package/src/lib/theme/errors/errors.ts +12 -11
- package/src/lib/theme/errors/index.ts +2 -7
- package/src/lib/theme/generators/generateCSS.ts +9 -13
- package/src/lib/theme/generators/generateCSSNested.ts +1 -6
- package/src/lib/theme/generators/generateCSSVariables.ts +673 -630
- package/src/lib/theme/generators/index.ts +1 -4
- package/src/lib/theme/i18n/index.ts +1 -1
- package/src/lib/theme/i18n/rtl.ts +13 -13
- package/src/lib/theme/index.ts +7 -16
- package/src/lib/theme/runtime/ThemeApplicator.ts +4 -4
- package/src/lib/theme/runtime/ThemeContext.tsx +1 -1
- package/src/lib/theme/runtime/ThemeErrorBoundary.tsx +19 -23
- package/src/lib/theme/runtime/ThemeProvider.tsx +230 -239
- package/src/lib/theme/runtime/__tests__/ThemeProvider.integration.test.tsx +1 -1
- package/src/lib/theme/runtime/__tests__/ThemeProvider.test.tsx +24 -29
- package/src/lib/theme/runtime/index.ts +2 -5
- package/src/lib/theme/runtime/useTheme.ts +18 -18
- package/src/lib/theme/runtime/useThemeTokens.ts +22 -22
- package/src/lib/theme/test/testTheme.ts +15 -16
- package/src/lib/theme/tokens/index.ts +2 -7
- package/src/lib/theme/tokens/tokens.ts +25 -24
- package/src/lib/theme/types.ts +428 -411
- package/src/lib/theme/utils/__tests__/themeValidation.test.ts +3 -3
- package/src/lib/theme/utils/componentTheming.ts +18 -18
- package/src/lib/theme/utils/domUtils.ts +277 -289
- package/src/lib/theme/utils/index.ts +1 -2
- package/src/lib/theme/utils/injectCSS.ts +10 -14
- package/src/lib/theme/utils/naming.ts +20 -16
- package/src/lib/theme/utils/themeHelpers.ts +10 -12
- package/src/lib/theme/utils/themeUtils.ts +85 -86
- package/src/lib/theme/utils/themeValidation.ts +82 -33
- package/src/lib/theme-tools.ts +8 -6
- package/src/lib/types/components.ts +180 -73
- package/src/lib/types/partProps.ts +1 -1
- package/src/lib/utils/__tests__/componentUtils.test.ts +57 -2
- package/src/lib/utils/__tests__/csv.test.ts +1 -1
- package/src/lib/utils/__tests__/themeNaming.test.ts +117 -0
- package/src/lib/utils/componentUtils.ts +8 -12
- package/src/lib/utils/csv.ts +3 -1
- package/src/lib/utils/dataTableExport.ts +1 -5
- package/src/lib/utils/fontPreloader.ts +10 -19
- package/src/lib/utils/icons.ts +4 -1
- package/src/lib/utils/index.ts +2 -6
- package/src/lib/utils/memoryMonitor.ts +10 -8
- package/src/lib/utils/themeNaming.ts +3 -3
- package/src/styles/01-settings/_index.scss +0 -1
- package/src/styles/01-settings/_settings.colors.scss +8 -8
- package/src/styles/01-settings/_settings.design-tokens.scss +61 -50
- package/src/styles/01-settings/_settings.navbar.scss +1 -1
- package/src/styles/01-settings/_settings.spacing.scss +3 -4
- package/src/styles/01-settings/_settings.tooltip.scss +1 -1
- package/src/styles/01-settings/_settings.typography.scss +1 -1
- package/src/styles/02-tools/_tools.breakpoints.scss +1 -1
- package/src/styles/02-tools/_tools.button.scss +51 -21
- package/src/styles/02-tools/_tools.utility-api.scss +36 -24
- package/src/styles/03-generic/_generic.root.scss +4 -3
- package/src/styles/06-components/_components.atomix-glass.scss +13 -9
- package/src/styles/06-components/_components.button.scss +16 -4
- package/src/styles/06-components/_components.callout.scss +27 -21
- package/src/styles/06-components/_components.card.scss +5 -14
- package/src/styles/06-components/_components.chart.scss +22 -19
- package/src/styles/06-components/_components.checkbox.scss +3 -1
- package/src/styles/06-components/_components.color-mode-toggle.scss +3 -1
- package/src/styles/06-components/_components.edge-panel.scss +9 -2
- package/src/styles/06-components/_components.footer.scss +1 -1
- package/src/styles/06-components/_components.side-menu.scss +5 -5
- package/src/styles/06-components/_components.toggle.scss +18 -0
- package/src/styles/06-components/_index.scss +1 -1
- package/src/styles/06-components/old.chart.styles.scss +0 -2
- package/src/styles/99-utilities/_utilities.border.scss +69 -27
- package/src/styles/99-utilities/_utilities.display.scss +1 -1
- package/src/styles/99-utilities/_utilities.opacity.scss +10 -0
- package/src/styles/99-utilities/_utilities.position.scss +16 -9
- package/src/styles/99-utilities/_utilities.scss +1 -1
- package/src/styles/99-utilities/_utilities.sizes.scss +47 -18
- package/src/styles/99-utilities/_utilities.spacing.scss +118 -66
- package/src/styles/99-utilities/_utilities.text-gradient.scss +30 -30
- package/src/styles/99-utilities/_utilities.text.scss +67 -47
|
@@ -49,7 +49,7 @@ const AreaChart = memo(
|
|
|
49
49
|
y: scales.yScale(point.value),
|
|
50
50
|
}));
|
|
51
51
|
|
|
52
|
-
const areaPath = `M ${areaPoints.map(
|
|
52
|
+
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`;
|
|
53
53
|
|
|
54
54
|
return (
|
|
55
55
|
<g key={`dataset-${datasetIndex}`}>
|
|
@@ -125,7 +125,10 @@ const CandlestickChart = memo(
|
|
|
125
125
|
borderColor = 'var(--atomix-primary-border-subtle)',
|
|
126
126
|
showMovingAverages = false,
|
|
127
127
|
movingAveragePeriods = [7, 21],
|
|
128
|
-
movingAverageColors = [
|
|
128
|
+
movingAverageColors = [
|
|
129
|
+
'var(--atomix-warning-bg-subtle)',
|
|
130
|
+
'var(--atomix-warning-border-subtle)',
|
|
131
|
+
],
|
|
129
132
|
dateFormat = 'short',
|
|
130
133
|
dateFormatter,
|
|
131
134
|
showGrid = true,
|
|
@@ -189,7 +192,11 @@ const CandlestickChart = memo(
|
|
|
189
192
|
}: ChartRenderContentParams) => {
|
|
190
193
|
if (!candlestickData.length) return null;
|
|
191
194
|
|
|
192
|
-
const showTooltips =
|
|
195
|
+
const showTooltips =
|
|
196
|
+
toolbarState?.showTooltips ??
|
|
197
|
+
renderConfig?.showTooltips ??
|
|
198
|
+
candlestickOptions.showTooltips ??
|
|
199
|
+
true;
|
|
193
200
|
|
|
194
201
|
const padding = 40;
|
|
195
202
|
const chartWidth = scales.width - padding * 2;
|
|
@@ -298,7 +305,9 @@ const CandlestickChart = memo(
|
|
|
298
305
|
);
|
|
299
306
|
}}
|
|
300
307
|
onMouseLeave={handlers.onPointLeave}
|
|
301
|
-
onClick={() =>
|
|
308
|
+
onClick={() =>
|
|
309
|
+
handlers.onDataPointClick?.(candle as unknown as ChartDataPoint, 0, index)
|
|
310
|
+
}
|
|
302
311
|
/>
|
|
303
312
|
</g>
|
|
304
313
|
);
|
|
@@ -372,19 +381,17 @@ const CandlestickChart = memo(
|
|
|
372
381
|
{candles}
|
|
373
382
|
{volumeBars}
|
|
374
383
|
{movingAverages}
|
|
375
|
-
{showTooltips &&
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
/>
|
|
387
|
-
)}
|
|
384
|
+
{showTooltips && hoveredPoint && candlestickData[hoveredPoint.pointIndex] && (
|
|
385
|
+
<ChartTooltip
|
|
386
|
+
dataPoint={candlestickData[hoveredPoint.pointIndex] as unknown as ChartDataPoint}
|
|
387
|
+
datasetLabel="Candlestick"
|
|
388
|
+
position={{
|
|
389
|
+
x: hoveredPoint.clientX,
|
|
390
|
+
y: hoveredPoint.clientY,
|
|
391
|
+
}}
|
|
392
|
+
visible={true}
|
|
393
|
+
/>
|
|
394
|
+
)}
|
|
388
395
|
</>
|
|
389
396
|
);
|
|
390
397
|
};
|
|
@@ -179,7 +179,7 @@ type Story = StoryObj<typeof meta>;
|
|
|
179
179
|
|
|
180
180
|
// Glass Variant Story
|
|
181
181
|
export const GlassVariant: Story = {
|
|
182
|
-
render:
|
|
182
|
+
render: args => {
|
|
183
183
|
const sampleData = [
|
|
184
184
|
{ label: 'Jan', value: 65 },
|
|
185
185
|
{ label: 'Feb', value: 78 },
|
|
@@ -240,12 +240,7 @@ export const GlassVariant: Story = {
|
|
|
240
240
|
/>
|
|
241
241
|
</GridCol>
|
|
242
242
|
<GridCol col={12} md={6}>
|
|
243
|
-
<PieChart
|
|
244
|
-
title="Market Share"
|
|
245
|
-
data={sampleData}
|
|
246
|
-
glass={true}
|
|
247
|
-
showToolbar={true}
|
|
248
|
-
/>
|
|
243
|
+
<PieChart title="Market Share" data={sampleData} glass={true} showToolbar={true} />
|
|
249
244
|
</GridCol>
|
|
250
245
|
<GridCol col={12} md={6}>
|
|
251
246
|
<AreaChart
|
|
@@ -356,7 +351,7 @@ const generateTreemapData = (count = 12) => {
|
|
|
356
351
|
'Agriculture',
|
|
357
352
|
'Construction',
|
|
358
353
|
];
|
|
359
|
-
|
|
354
|
+
|
|
360
355
|
return Array.from({ length: count }, (_, i) => ({
|
|
361
356
|
id: `category-${i}`,
|
|
362
357
|
label: categories[i % categories.length] || `Category ${i + 1}`,
|
|
@@ -377,7 +372,7 @@ const generateFunnelData = () => {
|
|
|
377
372
|
{ label: 'Evaluation', value: 600 },
|
|
378
373
|
{ label: 'Purchase', value: 300 },
|
|
379
374
|
];
|
|
380
|
-
|
|
375
|
+
|
|
381
376
|
return stages.map(stage => ({
|
|
382
377
|
...stage,
|
|
383
378
|
percentage: ((stage.value / stages[0].value) * 100).toFixed(1),
|
|
@@ -351,57 +351,53 @@ const Chart = memo(
|
|
|
351
351
|
tabIndex={0}
|
|
352
352
|
{...props}
|
|
353
353
|
>
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
<
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
354
|
+
{(title || subtitle || showToolbar) && (
|
|
355
|
+
<div className={`${CHART.HEADER_CLASS} u-flex u-justify-between u-items-start u-gap-4`}>
|
|
356
|
+
<div className={`${CHART.HEADER_CONTENT_CLASS} u-flex-1`}>
|
|
357
|
+
{title && <h3 className={`${CHART.TITLE_CLASS} u-mb-1`}>{title}</h3>}
|
|
358
|
+
{subtitle && <p className={`${CHART.SUBTITLE_CLASS} u-mb-0`}>{subtitle}</p>}
|
|
359
|
+
</div>
|
|
360
|
+
{renderToolbar()}
|
|
361
|
+
</div>
|
|
362
|
+
)}
|
|
363
|
+
|
|
364
|
+
<div className={CHART.CONTENT_CLASS}>
|
|
365
|
+
{loading && (
|
|
366
|
+
<div className={CHART.LOADING_CLASS}>
|
|
367
|
+
<div className={CHART.LOADING_SPINNER_CLASS}></div>
|
|
368
|
+
<span className={CHART.LOADING_TEXT_CLASS}>
|
|
369
|
+
{toolbarState.isExporting
|
|
370
|
+
? 'Exporting chart...'
|
|
371
|
+
: toolbarState.isRefreshing
|
|
372
|
+
? 'Refreshing chart...'
|
|
373
|
+
: 'Loading chart...'}
|
|
374
|
+
</span>
|
|
363
375
|
</div>
|
|
364
376
|
)}
|
|
365
377
|
|
|
366
|
-
|
|
367
|
-
{
|
|
368
|
-
<div className={CHART.
|
|
369
|
-
|
|
370
|
-
<
|
|
371
|
-
|
|
372
|
-
? 'Exporting chart...'
|
|
373
|
-
: toolbarState.isRefreshing
|
|
374
|
-
? 'Refreshing chart...'
|
|
375
|
-
: 'Loading chart...'}
|
|
376
|
-
</span>
|
|
378
|
+
{error && (
|
|
379
|
+
<div className={CHART.ERROR_CLASS}>
|
|
380
|
+
<div className={CHART.ERROR_ICON_CLASS}>⚠</div>
|
|
381
|
+
<div className={CHART.ERROR_CONTENT_CLASS}>
|
|
382
|
+
<div className={CHART.ERROR_MESSAGE_CLASS}>Chart Error</div>
|
|
383
|
+
<div className={CHART.ERROR_DETAILS_CLASS}>{error}</div>
|
|
377
384
|
</div>
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
</div>
|
|
388
|
-
)}
|
|
389
|
-
|
|
390
|
-
{!loading && !error && !children && (
|
|
391
|
-
<div className={CHART.EMPTY_CLASS}>
|
|
392
|
-
<div className={CHART.EMPTY_ICON_CLASS}>📊</div>
|
|
393
|
-
<div className={CHART.EMPTY_MESSAGE_CLASS}>No data available</div>
|
|
394
|
-
<div className={CHART.EMPTY_DETAILS_CLASS}>
|
|
395
|
-
Add data to your chart to see visualizations
|
|
396
|
-
</div>
|
|
385
|
+
</div>
|
|
386
|
+
)}
|
|
387
|
+
|
|
388
|
+
{!loading && !error && !children && (
|
|
389
|
+
<div className={CHART.EMPTY_CLASS}>
|
|
390
|
+
<div className={CHART.EMPTY_ICON_CLASS}>📊</div>
|
|
391
|
+
<div className={CHART.EMPTY_MESSAGE_CLASS}>No data available</div>
|
|
392
|
+
<div className={CHART.EMPTY_DETAILS_CLASS}>
|
|
393
|
+
Add data to your chart to see visualizations
|
|
397
394
|
</div>
|
|
398
|
-
|
|
395
|
+
</div>
|
|
396
|
+
)}
|
|
399
397
|
|
|
400
|
-
|
|
401
|
-
<div className={CHART.CANVAS_CLASS}>{children}</div>
|
|
402
|
-
)}
|
|
403
|
-
</div>
|
|
398
|
+
{!loading && !error && children && <div className={CHART.CANVAS_CLASS}>{children}</div>}
|
|
404
399
|
</div>
|
|
400
|
+
</div>
|
|
405
401
|
);
|
|
406
402
|
|
|
407
403
|
// Wrap with AtomixGlass if glass is enabled
|
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
forwardRef,
|
|
3
|
+
memo,
|
|
4
|
+
useCallback,
|
|
5
|
+
useContext,
|
|
6
|
+
useEffect,
|
|
7
|
+
useMemo,
|
|
8
|
+
useRef,
|
|
9
|
+
useState,
|
|
10
|
+
} from 'react';
|
|
2
11
|
import {
|
|
3
12
|
useChart,
|
|
4
13
|
useChartAccessibility,
|
|
@@ -88,7 +97,7 @@ const ChartRenderer = memo(
|
|
|
88
97
|
const svgRef = useRef<SVGSVGElement>(null);
|
|
89
98
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
90
99
|
const [isInitialized, setIsInitialized] = useState(false);
|
|
91
|
-
|
|
100
|
+
|
|
92
101
|
// Responsive dimensions state - initialize with 0 to prevent layout shifts
|
|
93
102
|
const [dimensions, setDimensions] = useState({
|
|
94
103
|
width: 0,
|
|
@@ -121,7 +130,7 @@ const ChartRenderer = memo(
|
|
|
121
130
|
});
|
|
122
131
|
|
|
123
132
|
// Use ResizeObserver to track container size changes
|
|
124
|
-
const resizeObserver = new ResizeObserver(
|
|
133
|
+
const resizeObserver = new ResizeObserver(entries => {
|
|
125
134
|
for (const entry of entries) {
|
|
126
135
|
const { width: containerWidth, height: containerHeight } = entry.contentRect;
|
|
127
136
|
if (containerWidth > 0 && containerHeight > 0) {
|
|
@@ -274,7 +283,13 @@ const ChartRenderer = memo(
|
|
|
274
283
|
return null;
|
|
275
284
|
}
|
|
276
285
|
|
|
277
|
-
const scales = calculateScales(
|
|
286
|
+
const scales = calculateScales(
|
|
287
|
+
processedData,
|
|
288
|
+
dimensions.width,
|
|
289
|
+
dimensions.height,
|
|
290
|
+
undefined,
|
|
291
|
+
config
|
|
292
|
+
);
|
|
278
293
|
if (!scales) return null;
|
|
279
294
|
|
|
280
295
|
const colors = getChartColors(processedData.length).filter(
|
|
@@ -289,7 +304,15 @@ const ChartRenderer = memo(
|
|
|
289
304
|
color: dataset.color || colors[i],
|
|
290
305
|
})),
|
|
291
306
|
};
|
|
292
|
-
}, [
|
|
307
|
+
}, [
|
|
308
|
+
processedData,
|
|
309
|
+
config,
|
|
310
|
+
dimensions.width,
|
|
311
|
+
dimensions.height,
|
|
312
|
+
isInitialized,
|
|
313
|
+
calculateScales,
|
|
314
|
+
getChartColors,
|
|
315
|
+
]);
|
|
293
316
|
|
|
294
317
|
useEffect(() => {
|
|
295
318
|
return () => {
|
|
@@ -335,12 +358,12 @@ const ChartRenderer = memo(
|
|
|
335
358
|
// Don't render until dimensions are initialized to prevent layout shifts
|
|
336
359
|
if (!isInitialized || dimensions.width === 0 || dimensions.height === 0) {
|
|
337
360
|
return (
|
|
338
|
-
<div
|
|
339
|
-
ref={containerRef}
|
|
340
|
-
className={CHART.CANVAS_CLASS}
|
|
341
|
-
style={{
|
|
342
|
-
width: '100%',
|
|
343
|
-
height: '100%',
|
|
361
|
+
<div
|
|
362
|
+
ref={containerRef}
|
|
363
|
+
className={CHART.CANVAS_CLASS}
|
|
364
|
+
style={{
|
|
365
|
+
width: '100%',
|
|
366
|
+
height: '100%',
|
|
344
367
|
minHeight: '200px',
|
|
345
368
|
display: 'flex',
|
|
346
369
|
alignItems: 'center',
|
|
@@ -359,7 +382,11 @@ const ChartRenderer = memo(
|
|
|
359
382
|
|
|
360
383
|
return (
|
|
361
384
|
<>
|
|
362
|
-
<div
|
|
385
|
+
<div
|
|
386
|
+
ref={containerRef}
|
|
387
|
+
className={CHART.CANVAS_CLASS}
|
|
388
|
+
style={{ width: '100%', height: '100%' }}
|
|
389
|
+
>
|
|
363
390
|
<svg
|
|
364
391
|
ref={svgRef}
|
|
365
392
|
width={svgWidth}
|
|
@@ -569,14 +569,20 @@ const ChartToolbar = memo(
|
|
|
569
569
|
onRefresh?.();
|
|
570
570
|
break;
|
|
571
571
|
default:
|
|
572
|
-
console.warn(
|
|
572
|
+
console.warn(
|
|
573
|
+
`No handler found for action: ${String(action.id).replace(/[\r\n\t]/g, '')}`
|
|
574
|
+
);
|
|
573
575
|
}
|
|
574
576
|
}
|
|
575
577
|
}
|
|
576
578
|
};
|
|
577
579
|
|
|
578
580
|
const buttonRef =
|
|
579
|
-
action.id === 'export'
|
|
581
|
+
action.id === 'export'
|
|
582
|
+
? exportButtonRef
|
|
583
|
+
: action.id === 'settings'
|
|
584
|
+
? settingsButtonRef
|
|
585
|
+
: null;
|
|
580
586
|
|
|
581
587
|
return (
|
|
582
588
|
<button
|
|
@@ -589,7 +595,13 @@ const ChartToolbar = memo(
|
|
|
589
595
|
type="button"
|
|
590
596
|
aria-label={action.label}
|
|
591
597
|
aria-pressed={action.active ? 'true' : 'false'}
|
|
592
|
-
aria-expanded={
|
|
598
|
+
aria-expanded={
|
|
599
|
+
action.id === 'export'
|
|
600
|
+
? showExportMenu
|
|
601
|
+
: action.id === 'settings'
|
|
602
|
+
? showSettingsMenu
|
|
603
|
+
: undefined
|
|
604
|
+
}
|
|
593
605
|
>
|
|
594
606
|
<Icon name={action.icon} size="sm" />
|
|
595
607
|
{size === 'lg' && <span className={`${CHART.ACTION_CLASS}-label`}>{action.label}</span>}
|
|
@@ -698,14 +710,18 @@ const ChartToolbar = memo(
|
|
|
698
710
|
|
|
699
711
|
{/* Info items */}
|
|
700
712
|
{state.zoomLevel !== undefined && (
|
|
701
|
-
<div
|
|
713
|
+
<div
|
|
714
|
+
className={`${CHART.SETTINGS_MENU_CLASS}-item ${CHART.SETTINGS_MENU_CLASS}-item--info`}
|
|
715
|
+
>
|
|
702
716
|
<span className={`${CHART.SETTINGS_MENU_CLASS}-label`}>Zoom Level</span>
|
|
703
717
|
<span className={`${CHART.SETTINGS_MENU_CLASS}-value`}>
|
|
704
718
|
{Math.round((state.zoomLevel || 1) * 100)}%
|
|
705
719
|
</span>
|
|
706
720
|
</div>
|
|
707
721
|
)}
|
|
708
|
-
<div
|
|
722
|
+
<div
|
|
723
|
+
className={`${CHART.SETTINGS_MENU_CLASS}-item ${CHART.SETTINGS_MENU_CLASS}-item--info`}
|
|
724
|
+
>
|
|
709
725
|
<span className={`${CHART.SETTINGS_MENU_CLASS}-label`}>Chart Type</span>
|
|
710
726
|
<span className={`${CHART.SETTINGS_MENU_CLASS}-value`}>{chartType}</span>
|
|
711
727
|
</div>
|
|
@@ -125,7 +125,7 @@ const DonutChart = memo(
|
|
|
125
125
|
// Calculate angles for each slice
|
|
126
126
|
const padAngleRad = ((pieOptions.padAngle || 1) * Math.PI) / 180;
|
|
127
127
|
let currentAngle = ((pieOptions.startAngle || 0) * Math.PI) / 180;
|
|
128
|
-
|
|
128
|
+
|
|
129
129
|
const slices = chartData.validDataPoints.map((point, index) => {
|
|
130
130
|
const percentage = point.value / total;
|
|
131
131
|
const sliceAngle = percentage * (2 * Math.PI) - padAngleRad;
|
|
@@ -282,7 +282,10 @@ const FunnelChart = memo(
|
|
|
282
282
|
<ChartTooltip
|
|
283
283
|
dataPoint={funnelData[hoveredPoint.pointIndex]!}
|
|
284
284
|
datasetLabel="Funnel Data"
|
|
285
|
-
datasetColor={
|
|
285
|
+
datasetColor={
|
|
286
|
+
funnelData[hoveredPoint.pointIndex]?.color ||
|
|
287
|
+
colors[hoveredPoint.pointIndex % colors.length]
|
|
288
|
+
}
|
|
286
289
|
position={{
|
|
287
290
|
x: hoveredPoint.clientX,
|
|
288
291
|
y: hoveredPoint.clientY,
|
|
@@ -335,7 +335,9 @@ const GaugeChart = memo(
|
|
|
335
335
|
d={createArcPath(centerX, centerY, radius, startAngleRad, valueAngle, thickness)}
|
|
336
336
|
fill="var(--atomix-brand-bg-subtle)"
|
|
337
337
|
style={{
|
|
338
|
-
transition: shouldAnimate
|
|
338
|
+
transition: shouldAnimate
|
|
339
|
+
? `all ${animationDuration}ms ${animationEasing}`
|
|
340
|
+
: 'none',
|
|
339
341
|
}}
|
|
340
342
|
/>
|
|
341
343
|
|
|
@@ -288,21 +288,28 @@ const HeatmapChart = memo(
|
|
|
288
288
|
<g>
|
|
289
289
|
{/* Gradient definitions */}
|
|
290
290
|
<defs>
|
|
291
|
-
{showColorLegend &&
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
291
|
+
{showColorLegend &&
|
|
292
|
+
(() => {
|
|
293
|
+
const schemeColors = colorSchemes[colorScale.scheme] || colorSchemes.viridis;
|
|
294
|
+
if (!schemeColors || schemeColors.length === 0) return null;
|
|
295
|
+
return (
|
|
296
|
+
<linearGradient
|
|
297
|
+
id="heatmap-legend-gradient"
|
|
298
|
+
x1="0%"
|
|
299
|
+
y1="100%"
|
|
300
|
+
x2="0%"
|
|
301
|
+
y2="0%"
|
|
302
|
+
>
|
|
303
|
+
{schemeColors.map((color, i) => (
|
|
304
|
+
<stop
|
|
305
|
+
key={i}
|
|
306
|
+
offset={`${(i / (schemeColors.length - 1)) * 100}%`}
|
|
307
|
+
stopColor={color}
|
|
308
|
+
/>
|
|
309
|
+
))}
|
|
310
|
+
</linearGradient>
|
|
311
|
+
);
|
|
312
|
+
})()}
|
|
306
313
|
</defs>
|
|
307
314
|
|
|
308
315
|
{/* Grid cells */}
|
|
@@ -333,11 +340,15 @@ const HeatmapChart = memo(
|
|
|
333
340
|
}}
|
|
334
341
|
onClick={() => {
|
|
335
342
|
if (cell) {
|
|
336
|
-
handlers.onDataPointClick?.(
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
343
|
+
handlers.onDataPointClick?.(
|
|
344
|
+
{
|
|
345
|
+
...cell,
|
|
346
|
+
label: cell.label || `${cell.x}, ${cell.y}`,
|
|
347
|
+
value: cell.value,
|
|
348
|
+
} as any,
|
|
349
|
+
rowIndex,
|
|
350
|
+
colIndex
|
|
351
|
+
);
|
|
341
352
|
}
|
|
342
353
|
}}
|
|
343
354
|
onMouseEnter={e => {
|
|
@@ -422,23 +433,25 @@ const HeatmapChart = memo(
|
|
|
422
433
|
</g>
|
|
423
434
|
)}
|
|
424
435
|
</g>
|
|
425
|
-
{showTooltips &&
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
renderedDatasets[hoveredPoint.datasetIndex]?.
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
436
|
+
{showTooltips &&
|
|
437
|
+
hoveredPoint &&
|
|
438
|
+
renderedDatasets[hoveredPoint.datasetIndex]?.data?.[hoveredPoint.pointIndex] && (
|
|
439
|
+
<ChartTooltip
|
|
440
|
+
dataPoint={
|
|
441
|
+
renderedDatasets[hoveredPoint.datasetIndex]!.data![hoveredPoint.pointIndex]!
|
|
442
|
+
}
|
|
443
|
+
datasetLabel={renderedDatasets[hoveredPoint.datasetIndex]?.label}
|
|
444
|
+
datasetColor={
|
|
445
|
+
renderedDatasets[hoveredPoint.datasetIndex]?.color ||
|
|
446
|
+
colors[hoveredPoint.datasetIndex % colors.length]
|
|
447
|
+
}
|
|
448
|
+
position={{
|
|
449
|
+
x: hoveredPoint.clientX,
|
|
450
|
+
y: hoveredPoint.clientY,
|
|
451
|
+
}}
|
|
452
|
+
visible={true}
|
|
453
|
+
/>
|
|
454
|
+
)}
|
|
442
455
|
</>
|
|
443
456
|
);
|
|
444
457
|
};
|
|
@@ -81,7 +81,8 @@ const LineChart = memo(
|
|
|
81
81
|
if (!renderedDatasets.length) return null;
|
|
82
82
|
|
|
83
83
|
const showTooltips = toolbarState?.showTooltips ?? renderConfig?.showTooltips ?? true;
|
|
84
|
-
const shouldAnimate =
|
|
84
|
+
const shouldAnimate =
|
|
85
|
+
toolbarState?.animationsEnabled ?? renderConfig?.animate ?? mergedLineOptions.smooth;
|
|
85
86
|
|
|
86
87
|
return (
|
|
87
88
|
<>
|
|
@@ -101,7 +102,7 @@ const LineChart = memo(
|
|
|
101
102
|
// Generate line path - ensure proper SVG path format
|
|
102
103
|
const path = mergedLineOptions.smooth
|
|
103
104
|
? generateSmoothPath(points)
|
|
104
|
-
: `M ${points.map(
|
|
105
|
+
: `M ${points.map(p => `${p.x},${p.y}`).join(' L ')}`;
|
|
105
106
|
|
|
106
107
|
return (
|
|
107
108
|
<g key={`dataset-${datasetIndex}`}>
|
|
@@ -164,7 +164,8 @@ const MultiAxisChart = memo(
|
|
|
164
164
|
}: ChartRenderContentParams) => {
|
|
165
165
|
if (!datasets.length) return null;
|
|
166
166
|
|
|
167
|
-
const effectiveShowTooltips =
|
|
167
|
+
const effectiveShowTooltips =
|
|
168
|
+
toolbarState?.showTooltips ?? renderConfig?.showTooltips ?? showTooltips ?? true;
|
|
168
169
|
const effectiveShowGrid = toolbarState?.showGrid ?? true; // Grid visibility from toolbar
|
|
169
170
|
|
|
170
171
|
const padding = 60;
|
|
@@ -221,19 +222,19 @@ const MultiAxisChart = memo(
|
|
|
221
222
|
|
|
222
223
|
// Draw grid lines
|
|
223
224
|
if (effectiveShowGrid) {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
225
|
+
for (let i = 0; i <= 5; i++) {
|
|
226
|
+
const y = padding + (i / 5) * chartHeight;
|
|
227
|
+
elements.push(
|
|
228
|
+
<line
|
|
229
|
+
key={`grid-${i}`}
|
|
230
|
+
x1={padding}
|
|
231
|
+
y1={y}
|
|
232
|
+
x2={padding + chartWidth}
|
|
233
|
+
y2={y}
|
|
234
|
+
className="c-chart__grid"
|
|
235
|
+
/>
|
|
236
|
+
);
|
|
237
|
+
}
|
|
237
238
|
}
|
|
238
239
|
|
|
239
240
|
// Draw datasets
|
|
@@ -253,7 +254,7 @@ const MultiAxisChart = memo(
|
|
|
253
254
|
// Generate line path
|
|
254
255
|
let linePath = '';
|
|
255
256
|
if (points.length > 0) {
|
|
256
|
-
linePath = `M ${points.map(
|
|
257
|
+
linePath = `M ${points.map(p => `${p.x},${p.y}`).join(' L ')}`;
|
|
257
258
|
}
|
|
258
259
|
|
|
259
260
|
// Draw area under line
|
|
@@ -338,7 +339,14 @@ const MultiAxisChart = memo(
|
|
|
338
339
|
|
|
339
340
|
elements.push(
|
|
340
341
|
<g key={`legend-${index}`}>
|
|
341
|
-
<rect
|
|
342
|
+
<rect
|
|
343
|
+
x={legendX}
|
|
344
|
+
y={legendY}
|
|
345
|
+
width="12"
|
|
346
|
+
height="12"
|
|
347
|
+
fill={color}
|
|
348
|
+
className="c-chart__legend-item-color"
|
|
349
|
+
/>
|
|
342
350
|
<text x={legendX + 16} y={legendY + 10} className="c-chart__legend-item-text">
|
|
343
351
|
{dataset.label}
|
|
344
352
|
</text>
|
|
@@ -282,23 +282,25 @@ const RadarChart = memo(
|
|
|
282
282
|
{dataPaths}
|
|
283
283
|
{axisLabels}
|
|
284
284
|
</g>
|
|
285
|
-
{showTooltips &&
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
renderedDatasets[hoveredPoint.datasetIndex]?.
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
285
|
+
{showTooltips &&
|
|
286
|
+
hoveredPoint &&
|
|
287
|
+
renderedDatasets[hoveredPoint.datasetIndex]?.data?.[hoveredPoint.pointIndex] && (
|
|
288
|
+
<ChartTooltip
|
|
289
|
+
dataPoint={
|
|
290
|
+
renderedDatasets[hoveredPoint.datasetIndex]!.data![hoveredPoint.pointIndex]!
|
|
291
|
+
}
|
|
292
|
+
datasetLabel={renderedDatasets[hoveredPoint.datasetIndex]?.label}
|
|
293
|
+
datasetColor={
|
|
294
|
+
renderedDatasets[hoveredPoint.datasetIndex]?.color ||
|
|
295
|
+
colors[hoveredPoint.datasetIndex]
|
|
296
|
+
}
|
|
297
|
+
position={{
|
|
298
|
+
x: hoveredPoint.clientX,
|
|
299
|
+
y: hoveredPoint.clientY,
|
|
300
|
+
}}
|
|
301
|
+
visible={true}
|
|
302
|
+
/>
|
|
303
|
+
)}
|
|
302
304
|
</>
|
|
303
305
|
);
|
|
304
306
|
};
|