@flikk/ui 1.0.0-beta.27 → 1.0.0-beta.29
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/dist/bg/1.webp +0 -0
- package/dist/bg/10.webp +0 -0
- package/dist/bg/11.webp +0 -0
- package/dist/bg/12.webp +0 -0
- package/dist/bg/13.webp +0 -0
- package/dist/bg/14.webp +0 -0
- package/dist/bg/15.webp +0 -0
- package/dist/bg/16.webp +0 -0
- package/dist/bg/17.webp +0 -0
- package/dist/bg/18.webp +0 -0
- package/dist/bg/19.webp +0 -0
- package/dist/bg/2.webp +0 -0
- package/dist/bg/20.webp +0 -0
- package/dist/bg/21.webp +0 -0
- package/dist/bg/22.webp +0 -0
- package/dist/bg/3.webp +0 -0
- package/dist/bg/4.webp +0 -0
- package/dist/bg/5.webp +0 -0
- package/dist/bg/6.webp +0 -0
- package/dist/bg/7.webp +0 -0
- package/dist/bg/8.webp +0 -0
- package/dist/bg/9.webp +0 -0
- package/dist/components/ai/CodeBlock/CodeBlock.theme.js +1 -1
- package/dist/components/ai/PromptInput/PromptInput.js +7 -143
- package/dist/components/ai/PromptInput/VoiceRecorder.js +0 -88
- package/dist/components/ai/TokenCounter/TokenCounter.theme.js +1 -1
- package/dist/components/canvas/Background.d.ts +19 -0
- package/dist/components/canvas/Background.js +23 -0
- package/dist/components/canvas/BaseNode.d.ts +15 -0
- package/dist/components/canvas/BaseNode.js +20 -0
- package/dist/components/canvas/CanvasToolbar.d.ts +34 -0
- package/dist/components/canvas/CanvasToolbar.js +34 -0
- package/dist/components/canvas/Edge.d.ts +35 -0
- package/dist/components/canvas/Edge.js +97 -0
- package/dist/components/canvas/EdgeLayer.d.ts +18 -0
- package/dist/components/canvas/EdgeLayer.js +111 -0
- package/dist/components/canvas/Handle.d.ts +11 -0
- package/dist/components/canvas/Handle.js +63 -0
- package/dist/components/canvas/MiniMap.d.ts +22 -0
- package/dist/components/canvas/MiniMap.js +105 -0
- package/dist/components/canvas/NodeCanvas.d.ts +10 -0
- package/dist/components/canvas/NodeCanvas.js +477 -0
- package/dist/components/canvas/NodeCanvas.theme.d.ts +7 -0
- package/dist/components/canvas/NodeCanvas.theme.js +9 -0
- package/dist/components/canvas/NodeCanvas.types.d.ts +187 -0
- package/dist/components/canvas/NodeControls.d.ts +25 -0
- package/dist/components/canvas/NodeControls.js +40 -0
- package/dist/components/canvas/NodeRenderer.d.ts +19 -0
- package/dist/components/canvas/NodeRenderer.js +117 -0
- package/dist/components/canvas/changes.d.ts +11 -0
- package/dist/components/canvas/changes.js +76 -0
- package/dist/components/canvas/context/CanvasContext.d.ts +32 -0
- package/dist/components/canvas/context/CanvasContext.js +14 -0
- package/dist/components/canvas/context/ConnectionContext.d.ts +33 -0
- package/dist/components/canvas/context/ConnectionContext.js +13 -0
- package/dist/components/canvas/context/HandleRegistry.d.ts +24 -0
- package/dist/components/canvas/context/HandleRegistry.js +15 -0
- package/dist/components/canvas/context/InteractionContext.d.ts +18 -0
- package/dist/components/canvas/context/InteractionContext.js +14 -0
- package/dist/components/canvas/context/NodeIdContext.d.ts +3 -0
- package/dist/components/canvas/context/NodeIdContext.js +15 -0
- package/dist/components/canvas/hooks/useConnection.d.ts +17 -0
- package/dist/components/canvas/hooks/useConnection.js +29 -0
- package/dist/components/canvas/hooks/useMarquee.d.ts +25 -0
- package/dist/components/canvas/hooks/useMarquee.js +91 -0
- package/dist/components/canvas/hooks/useNodeDrag.d.ts +23 -0
- package/dist/components/canvas/hooks/useNodeDrag.js +110 -0
- package/dist/components/canvas/hooks/usePanZoom.d.ts +30 -0
- package/dist/components/canvas/hooks/usePanZoom.js +189 -0
- package/dist/components/canvas/hooks/useViewport.d.ts +21 -0
- package/dist/components/canvas/hooks/useViewport.js +35 -0
- package/dist/components/canvas/index.d.ts +14 -0
- package/dist/components/canvas/index.js +12 -0
- package/dist/components/canvas/layout.d.ts +22 -0
- package/dist/components/canvas/layout.js +67 -0
- package/dist/components/canvas/utils.d.ts +4 -0
- package/dist/components/canvas/utils.js +16 -0
- package/dist/components/charts/AreaChart/AreaChart.js +136 -101
- package/dist/components/charts/AreaChart/AreaChart.types.d.ts +5 -5
- package/dist/components/charts/AreaChart/AreaChart.types.js +1 -0
- package/dist/components/charts/BarChart/BarChart.js +207 -143
- package/dist/components/charts/BarChart/BarChart.types.d.ts +4 -4
- package/dist/components/charts/BarChart/BarChart.types.js +1 -0
- package/dist/components/charts/ComboChart/ComboChart.types.d.ts +2 -2
- package/dist/components/charts/LineChart/LineChart.js +88 -72
- package/dist/components/charts/LineChart/LineChart.types.d.ts +3 -3
- package/dist/components/charts/RadarChart/RadarChart.js +1 -1
- package/dist/components/charts/RadarChart/RadarChart.theme.js +5 -2
- package/dist/components/charts/ScatterPlot/ScatterPlot.js +62 -72
- package/dist/components/charts/ScatterPlot/ScatterPlot.theme.js +10 -1
- package/dist/components/charts/ScatterPlot/ScatterPlot.types.d.ts +3 -9
- package/dist/components/charts/StackedBarChart/StackedBarChart.js +33 -33
- package/dist/components/charts/StackedBarChart/StackedBarChart.types.d.ts +2 -2
- package/dist/components/charts/hooks/index.d.ts +2 -0
- package/dist/components/charts/hooks/useChartDimensions.d.ts +29 -0
- package/dist/components/charts/hooks/useChartDimensions.js +42 -0
- package/dist/components/charts/shared/ChartTooltip/ChartTooltip.theme.js +1 -1
- package/dist/components/charts/types/chart.types.d.ts +11 -2
- package/dist/components/charts/types/chart.types.js +10 -3
- package/dist/components/core/Avatar/Avatar.js +5 -1
- package/dist/components/core/AvatarGroup/AvatarGroup.js +5 -1
- package/dist/components/core/AvatarGroup/AvatarGroup.theme.js +4 -2
- package/dist/components/core/Badge/Badge.js +1 -1
- package/dist/components/core/Badge/Badge.theme.js +16 -15
- package/dist/components/core/Button/Button.js +1 -1
- package/dist/components/core/Button/Button.theme.js +2 -2
- package/dist/components/core/Calendar/Calendar.theme.js +1 -1
- package/dist/components/core/Card/Card.js +7 -3
- package/dist/components/core/Card/Card.theme.js +3 -3
- package/dist/components/core/Card/Card.types.d.ts +27 -2
- package/dist/components/core/CommandPalette/CommandPalette.theme.js +2 -2
- package/dist/components/core/ContextMenu/ContextMenu.theme.js +2 -2
- package/dist/components/core/ContextMenu/ContextMenuItem.js +1 -1
- package/dist/components/core/ContextMenu/ContextMenuSubTrigger.js +1 -1
- package/dist/components/core/Dropdown/Dropdown.theme.js +3 -3
- package/dist/components/core/Dropdown/DropdownMenu.js +57 -29
- package/dist/components/core/HeroCard/HeroCard.d.ts +5 -0
- package/dist/components/core/HeroCard/HeroCard.js +99 -0
- package/dist/components/core/HeroCard/HeroCard.theme.d.ts +3 -0
- package/dist/components/core/HeroCard/HeroCard.theme.js +8 -0
- package/dist/components/core/HeroCard/HeroCard.types.d.ts +70 -0
- package/dist/components/core/HeroCard/index.d.ts +4 -0
- package/dist/components/core/Kbd/Kbd.theme.js +1 -1
- package/dist/components/core/Modal/Modal.d.ts +1 -1
- package/dist/components/core/Modal/Modal.js +2 -7
- package/dist/components/core/Modal/Modal.theme.js +4 -8
- package/dist/components/core/Modal/Modal.types.d.ts +0 -10
- package/dist/components/core/Modal/index.d.ts +1 -1
- package/dist/components/core/ModalStack/ModalStack.d.ts +1 -1
- package/dist/components/core/ModalStack/ModalStack.types.d.ts +1 -2
- package/dist/components/core/ModalStack/ModalStackModal.d.ts +1 -1
- package/dist/components/core/ModalStack/ModalStackModal.js +2 -7
- package/dist/components/core/PageHeading/PageHeading.theme.js +2 -2
- package/dist/components/core/Popover/Popover.theme.js +1 -1
- package/dist/components/core/ScrollArea/ScrollArea.js +242 -4
- package/dist/components/core/ScrollArea/ScrollArea.types.d.ts +12 -1
- package/dist/components/core/ScrollArea/smooth/SmoothScrollEngine.d.ts +4 -0
- package/dist/components/core/ScrollArea/smooth/SmoothScrollEngine.js +23 -0
- package/dist/components/core/ScrollArea/smooth/useSmoothScroll.js +4 -0
- package/dist/components/core/ScrollArea/smooth/useSmoothScroll.types.d.ts +5 -0
- package/dist/components/core/Segmented/Segmented.theme.js +2 -2
- package/dist/components/core/Tooltip/Tooltip.theme.js +1 -1
- package/dist/components/core/index.d.ts +1 -0
- package/dist/components/core/index.js +2 -0
- package/dist/components/data-display/DescriptionList/DescriptionList.js +23 -7
- package/dist/components/data-display/DescriptionList/DescriptionList.theme.js +10 -3
- package/dist/components/data-display/DescriptionList/DescriptionList.types.d.ts +49 -10
- package/dist/components/data-display/DescriptionList/index.d.ts +1 -1
- package/dist/components/data-display/Feed/Feed.js +28 -5
- package/dist/components/data-display/Feed/Feed.theme.js +1 -1
- package/dist/components/data-display/Feed/Feed.types.d.ts +32 -1
- package/dist/components/data-display/Feed/index.d.ts +1 -1
- package/dist/components/data-display/Metric/Metric.js +8 -8
- package/dist/components/data-display/Metric/Metric.theme.d.ts +3 -2
- package/dist/components/data-display/Metric/Metric.theme.js +50 -68
- package/dist/components/data-display/Metric/Metric.types.d.ts +19 -21
- package/dist/components/data-display/Table/Table.js +2 -2
- package/dist/components/data-display/Table/Table.theme.js +24 -4
- package/dist/components/data-display/Table/Table.types.d.ts +8 -0
- package/dist/components/data-display/Table/TableBody.js +2 -2
- package/dist/components/data-display/Table/TableCell.js +1 -1
- package/dist/components/data-display/Table/TableRow.d.ts +1 -1
- package/dist/components/data-display/Table/TableRow.js +9 -2
- package/dist/components/data-display/Timeline/Timeline.js +27 -5
- package/dist/components/data-display/Timeline/Timeline.theme.d.ts +10 -2
- package/dist/components/data-display/Timeline/Timeline.theme.js +14 -8
- package/dist/components/data-display/Timeline/Timeline.types.d.ts +48 -16
- package/dist/components/data-display/Timeline/Timeline.utils.d.ts +6 -0
- package/dist/components/data-display/Timeline/Timeline.utils.js +11 -0
- package/dist/components/data-display/Timeline/TimelineItem.js +13 -20
- package/dist/components/data-display/Timeline/TimelineMarker.js +10 -8
- package/dist/components/data-display/Timeline/index.d.ts +2 -2
- package/dist/components/effects/3d/index.d.ts +0 -2
- package/dist/components/effects/3d/index.js +0 -1
- package/dist/components/effects/DotPattern/DotPattern.js +1 -1
- package/dist/components/effects/Overlay/Overlay.theme.js +1 -2
- package/dist/components/effects/Preloader/Preloader.animations.d.ts +23 -0
- package/dist/components/effects/Preloader/Preloader.animations.js +150 -0
- package/dist/components/effects/Preloader/Preloader.d.ts +3 -0
- package/dist/components/effects/Preloader/Preloader.js +119 -0
- package/dist/components/effects/Preloader/Preloader.types.d.ts +63 -0
- package/dist/components/effects/Preloader/index.d.ts +2 -0
- package/dist/components/effects/ProgressiveBlur/ProgressiveBlur.js +25 -14
- package/dist/components/effects/ProgressiveBlur/ProgressiveBlur.types.d.ts +2 -0
- package/dist/components/effects/TiltCard/TiltCard.d.ts +12 -0
- package/dist/components/effects/TiltCard/TiltCard.glow.d.ts +28 -0
- package/dist/components/effects/TiltCard/TiltCard.glow.js +114 -0
- package/dist/components/effects/TiltCard/TiltCard.js +177 -0
- package/dist/components/effects/{SpotlightBorder/SpotlightBorder.shaders.d.ts → TiltCard/TiltCard.shaders.d.ts} +1 -1
- package/dist/components/effects/{SpotlightBorder/SpotlightBorder.shaders.js → TiltCard/TiltCard.shaders.js} +1 -1
- package/dist/components/effects/TiltCard/TiltCard.types.d.ts +88 -0
- package/dist/components/effects/TiltCard/index.d.ts +2 -0
- package/dist/components/effects/index.d.ts +4 -12
- package/dist/components/effects/index.js +2 -6
- package/dist/components/forms/Checkbox/Checkbox.js +7 -1
- package/dist/components/forms/DatePicker/DatePicker.theme.js +2 -2
- package/dist/components/forms/DateRangePicker/DateRangePicker.theme.js +1 -1
- package/dist/components/forms/FileUpload/FileUpload.js +1 -89
- package/dist/components/forms/FormLabel/FormLabel.theme.js +1 -1
- package/dist/components/forms/RichTextEditor/RichTextEditor.theme.js +2 -2
- package/dist/components/forms/Slider/Slider.theme.js +1 -1
- package/dist/components/forms/Switch/Switch.js +27 -15
- package/dist/components/forms/Switch/Switch.theme.d.ts +36 -6
- package/dist/components/forms/Switch/Switch.theme.js +33 -4
- package/dist/components/forms/Switch/Switch.types.d.ts +12 -2
- package/dist/components/forms/TimePicker/TimePicker.theme.js +1 -2
- package/dist/components/forms/TimePicker/TimePickerContent.js +1 -90
- package/dist/components/forms/forms.theme.js +1 -1
- package/dist/components/forms/index.d.ts +0 -4
- package/dist/components/forms/index.js +0 -92
- package/dist/components/generative/GenerativeView.d.ts +21 -0
- package/dist/components/generative/GenerativeView.js +116 -0
- package/dist/components/generative/actions.d.ts +26 -0
- package/dist/components/generative/actions.js +51 -0
- package/dist/components/generative/index.d.ts +11 -0
- package/dist/components/generative/index.js +9 -0
- package/dist/components/generative/registry.d.ts +43 -0
- package/dist/components/generative/registry.js +114 -0
- package/dist/components/generative/resolvers.d.ts +35 -0
- package/dist/components/generative/resolvers.js +93 -0
- package/dist/components/generative/schema.generated.d.ts +2 -0
- package/dist/components/generative/schema.generated.js +1639 -0
- package/dist/components/generative/schemaTypes.d.ts +30 -0
- package/dist/components/generative/streaming.d.ts +39 -0
- package/dist/components/generative/streaming.js +283 -0
- package/dist/components/generative/tools.d.ts +21 -0
- package/dist/components/generative/tools.js +54 -0
- package/dist/components/generative/types.d.ts +41 -0
- package/dist/components/generative/useGenerativeStream.d.ts +37 -0
- package/dist/components/generative/useGenerativeStream.js +36 -0
- package/dist/components/generative/validate.d.ts +24 -0
- package/dist/components/generative/validate.js +259 -0
- package/dist/components/layout/AppShell/AppShell.theme.js +2 -2
- package/dist/components/layout/FormLayout/FormLayout.js +1 -90
- package/dist/components/layout/Grid/Grid.d.ts +3 -0
- package/dist/components/layout/Grid/Grid.js +50 -0
- package/dist/components/layout/Grid/Grid.theme.d.ts +2 -0
- package/dist/components/layout/Grid/Grid.theme.js +35 -0
- package/dist/components/layout/Grid/Grid.types.d.ts +57 -0
- package/dist/components/layout/Grid/index.d.ts +3 -0
- package/dist/components/layout/Section/Section.d.ts +3 -0
- package/dist/components/layout/Section/Section.js +18 -0
- package/dist/components/layout/Section/Section.theme.d.ts +2 -0
- package/dist/components/layout/Section/Section.theme.js +10 -0
- package/dist/components/layout/Section/Section.types.d.ts +34 -0
- package/dist/components/layout/Section/index.d.ts +3 -0
- package/dist/components/layout/Stack/Stack.d.ts +3 -0
- package/dist/components/layout/Stack/Stack.js +19 -0
- package/dist/components/layout/Stack/Stack.theme.d.ts +2 -0
- package/dist/components/layout/Stack/Stack.theme.js +10 -0
- package/dist/components/layout/Stack/Stack.types.d.ts +39 -0
- package/dist/components/layout/Stack/index.d.ts +3 -0
- package/dist/components/layout/index.d.ts +3 -0
- package/dist/components/layout/index.js +6 -0
- package/dist/generative.schema.json +1637 -0
- package/dist/index.js +180 -180
- package/dist/registry.json +648 -464
- package/dist/styles.css +1 -1
- package/dist/tools.json +1731 -0
- package/package.json +17 -4
- package/src/global.scss +53 -101
- package/src/styles/theme.css +687 -493
- package/dist/bg/1.jpg +0 -0
- package/dist/bg/10.jpg +0 -0
- package/dist/bg/11.jpg +0 -0
- package/dist/bg/14.jpg +0 -0
- package/dist/bg/15.jpg +0 -0
- package/dist/bg/16.jpg +0 -0
- package/dist/bg/17.jpg +0 -0
- package/dist/bg/18.jpg +0 -0
- package/dist/bg/19.jpg +0 -0
- package/dist/bg/2.jpg +0 -0
- package/dist/bg/20.jpg +0 -0
- package/dist/bg/21.jpg +0 -0
- package/dist/bg/22.jpg +0 -0
- package/dist/bg/23.jpg +0 -0
- package/dist/bg/24.jpg +0 -0
- package/dist/bg/3.jpg +0 -0
- package/dist/bg/4.jpg +0 -0
- package/dist/bg/5.jpg +0 -0
- package/dist/bg/6.jpg +0 -0
- package/dist/bg/7.jpg +0 -0
- package/dist/bg/8.jpg +0 -0
- package/dist/bg/9.jpg +0 -0
- package/dist/components/effects/MorphingText/MorphingText.d.ts +0 -17
- package/dist/components/effects/MorphingText/MorphingText.js +0 -125
- package/dist/components/effects/MorphingText/MorphingText.types.d.ts +0 -18
- package/dist/components/effects/MorphingText/index.d.ts +0 -2
- package/dist/components/effects/PageTransition/PageTransition.animations.d.ts +0 -8
- package/dist/components/effects/PageTransition/PageTransition.animations.js +0 -53
- package/dist/components/effects/PageTransition/PageTransition.d.ts +0 -3
- package/dist/components/effects/PageTransition/PageTransition.js +0 -82
- package/dist/components/effects/PageTransition/PageTransition.types.d.ts +0 -15
- package/dist/components/effects/PageTransition/index.d.ts +0 -2
- package/dist/components/effects/ParallaxSection/ParallaxSection.d.ts +0 -26
- package/dist/components/effects/ParallaxSection/ParallaxSection.js +0 -71
- package/dist/components/effects/ParallaxSection/ParallaxSection.types.d.ts +0 -11
- package/dist/components/effects/ParallaxSection/index.d.ts +0 -2
- package/dist/components/effects/Spotlight/Spotlight.d.ts +0 -36
- package/dist/components/effects/Spotlight/Spotlight.js +0 -112
- package/dist/components/effects/Spotlight/Spotlight.types.d.ts +0 -29
- package/dist/components/effects/Spotlight/index.d.ts +0 -2
- package/dist/components/effects/SpotlightBorder/SpotlightBorder.d.ts +0 -18
- package/dist/components/effects/SpotlightBorder/SpotlightBorder.js +0 -213
- package/dist/components/effects/SpotlightBorder/SpotlightBorder.types.d.ts +0 -61
- package/dist/components/effects/SpotlightBorder/index.d.ts +0 -2
- package/dist/components/effects/StickyScroll/StickyScroll.d.ts +0 -30
- package/dist/components/effects/StickyScroll/StickyScroll.js +0 -128
- package/dist/components/effects/StickyScroll/StickyScroll.types.d.ts +0 -19
- package/dist/components/effects/StickyScroll/index.d.ts +0 -2
- package/dist/components/forms/CronInput/CronInput.d.ts +0 -3
- package/dist/components/forms/CronInput/CronInput.js +0 -113
- package/dist/components/forms/CronInput/CronInput.theme.d.ts +0 -6
- package/dist/components/forms/CronInput/CronInput.theme.js +0 -75
- package/dist/components/forms/CronInput/CronInput.types.d.ts +0 -109
- package/dist/components/forms/CronInput/CronInput.utils.d.ts +0 -67
- package/dist/components/forms/CronInput/CronInput.utils.js +0 -505
- package/dist/components/forms/CronInput/index.d.ts +0 -4
- /package/dist/components/effects/{SpotlightBorder/SpotlightBorder.types.js → TiltCard/TiltCard.types.js} +0 -0
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
-
import { useRef,
|
|
3
|
-
import { motion } from 'motion/react';
|
|
2
|
+
import { useRef, useId, useMemo, useState, useCallback, useEffect } from 'react';
|
|
3
|
+
import { useReducedMotion, motion } from 'motion/react';
|
|
4
4
|
import { cn } from '../../../utils/cn.js';
|
|
5
5
|
import { useTooltipPosition } from '../hooks/useTooltipPosition.js';
|
|
6
6
|
import { useChartAccessibility } from '../hooks/useChartAccessibility.js';
|
|
7
|
+
import { useChartDimensions } from '../hooks/useChartDimensions.js';
|
|
7
8
|
import { XAxis } from '../shared/ChartAxis/XAxis.js';
|
|
8
9
|
import { YAxis } from '../shared/ChartAxis/YAxis.js';
|
|
9
10
|
import { HorizontalGrid } from '../shared/ChartGrid/HorizontalGrid.js';
|
|
@@ -13,6 +14,7 @@ import { ChartCrosshair } from '../shared/ChartCrosshair/ChartCrosshair.js';
|
|
|
13
14
|
import { generateNiceTicks } from '../utils/chart-validation.js';
|
|
14
15
|
import { generateCurvePath } from '../utils/path-utils.js';
|
|
15
16
|
import { LINE_CHART_DEFAULTS } from './LineChart.types.js';
|
|
17
|
+
import { X_AXIS_MARGIN } from '../types/chart.types.js';
|
|
16
18
|
|
|
17
19
|
// Production-ready color system with CORRECT CSS variable syntax
|
|
18
20
|
const getSeriesColorClass = (index) => {
|
|
@@ -25,7 +27,19 @@ const getSeriesColorClass = (index) => {
|
|
|
25
27
|
return colors[index % colors.length];
|
|
26
28
|
};
|
|
27
29
|
// Get color value for SVG elements and tooltips
|
|
28
|
-
const getSeriesFillColor = (index) => {
|
|
30
|
+
const getSeriesFillColor = (index, key, config) => {
|
|
31
|
+
var _a;
|
|
32
|
+
if (key && config && ((_a = config[key]) === null || _a === void 0 ? void 0 : _a.color)) {
|
|
33
|
+
const customColor = config[key].color;
|
|
34
|
+
if (!customColor.startsWith("var(") &&
|
|
35
|
+
!customColor.startsWith("#") &&
|
|
36
|
+
!customColor.startsWith("rgb") &&
|
|
37
|
+
!customColor.startsWith("hsl") &&
|
|
38
|
+
customColor.includes("-")) {
|
|
39
|
+
return `var(--color-${customColor})`;
|
|
40
|
+
}
|
|
41
|
+
return customColor;
|
|
42
|
+
}
|
|
29
43
|
const colorVars = [
|
|
30
44
|
"var(--color-primary)",
|
|
31
45
|
"var(--color-warning)",
|
|
@@ -43,7 +57,7 @@ color = LINE_CHART_DEFAULTS.color,
|
|
|
43
57
|
dotRadius, radius, // @deprecated Use dotRadius instead
|
|
44
58
|
strokeWidth = LINE_CHART_DEFAULTS.strokeWidth, curved = LINE_CHART_DEFAULTS.curved, curveType = LINE_CHART_DEFAULTS.curveType, showDots = LINE_CHART_DEFAULTS.showDots,
|
|
45
59
|
// Base props
|
|
46
|
-
className, title, description, enableKeyboardNavigation = LINE_CHART_DEFAULTS.enableKeyboardNavigation, children, ...props }) => {
|
|
60
|
+
className, title, description, enableKeyboardNavigation = LINE_CHART_DEFAULTS.enableKeyboardNavigation, width, height, children, ...props }) => {
|
|
47
61
|
var _a;
|
|
48
62
|
// Resolve dotRadius with backward compatibility
|
|
49
63
|
const resolvedDotRadius = (_a = dotRadius !== null && dotRadius !== void 0 ? dotRadius : radius) !== null && _a !== void 0 ? _a : LINE_CHART_DEFAULTS.dotRadius;
|
|
@@ -54,12 +68,21 @@ className, title, description, enableKeyboardNavigation = LINE_CHART_DEFAULTS.en
|
|
|
54
68
|
}
|
|
55
69
|
// Simplified color system - no complex theme hook needed
|
|
56
70
|
const containerRef = useRef(null);
|
|
57
|
-
|
|
58
|
-
|
|
71
|
+
// `measured` gates the rise + dots so motion captures the baseline scaleY
|
|
72
|
+
// origin and dot positions at the real size, not the 600×400 fallback.
|
|
73
|
+
const { dimensions, measured } = useChartDimensions(containerRef);
|
|
59
74
|
const shadowFilterId = useId();
|
|
60
75
|
const verticalFadeId = useId();
|
|
61
76
|
const horizontalFadeId = useId();
|
|
62
77
|
const ANIMATION_DURATION = 1.5;
|
|
78
|
+
// Entrance: the line RISES from the x-axis (scaleY 0→1 about the baseline),
|
|
79
|
+
// mirroring how BarChart's bars grow up from the zero line. A single
|
|
80
|
+
// continuous path can't morph between datasets of different point counts, so
|
|
81
|
+
// it rises rather than draws. Keying the line group on the data signature
|
|
82
|
+
// replays the rise on every range switch; reduced-motion users get a stable
|
|
83
|
+
// key + scaleY:1 (no animation).
|
|
84
|
+
const shouldReduceMotion = useReducedMotion();
|
|
85
|
+
const dataSignature = useMemo(() => JSON.stringify(data), [data]);
|
|
63
86
|
const [hoveredPoint, setHoveredPoint] = useState(null);
|
|
64
87
|
// Detect if device is mobile/touch
|
|
65
88
|
const isMobile = typeof window !== "undefined" &&
|
|
@@ -78,26 +101,6 @@ className, title, description, enableKeyboardNavigation = LINE_CHART_DEFAULTS.en
|
|
|
78
101
|
description,
|
|
79
102
|
enableKeyboardNavigation,
|
|
80
103
|
});
|
|
81
|
-
// Measure container dimensions
|
|
82
|
-
useEffect(() => {
|
|
83
|
-
const updateDimensions = () => {
|
|
84
|
-
if (containerRef.current) {
|
|
85
|
-
const { width, height } = containerRef.current.getBoundingClientRect();
|
|
86
|
-
setDimensions({
|
|
87
|
-
width: width || 600,
|
|
88
|
-
height: height || 400,
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
updateDimensions();
|
|
93
|
-
const resizeObserver = new ResizeObserver(updateDimensions);
|
|
94
|
-
if (containerRef.current) {
|
|
95
|
-
resizeObserver.observe(containerRef.current);
|
|
96
|
-
}
|
|
97
|
-
return () => {
|
|
98
|
-
resizeObserver.disconnect();
|
|
99
|
-
};
|
|
100
|
-
}, []);
|
|
101
104
|
// Early return if no data
|
|
102
105
|
if (!data || data.length === 0) {
|
|
103
106
|
return (jsx("div", { className: cn("chart-container flex items-center justify-center text-[var(--color-text-placeholder)]", className), role: "img", "aria-label": "Empty line chart", ...props, children: jsx("span", { children: "No data available" }) }));
|
|
@@ -106,7 +109,7 @@ className, title, description, enableKeyboardNavigation = LINE_CHART_DEFAULTS.en
|
|
|
106
109
|
const margin = useMemo(() => ({
|
|
107
110
|
top: 0,
|
|
108
111
|
right: 0,
|
|
109
|
-
bottom: showXAxis ?
|
|
112
|
+
bottom: showXAxis ? X_AXIS_MARGIN : 0, // shared X-axis margin so baselines align across chart types
|
|
110
113
|
left: showYAxis ? 60 : 0, // Reduce left margin when Y-axis is hidden
|
|
111
114
|
}), [showXAxis, showYAxis]);
|
|
112
115
|
const innerWidth = dimensions.width - margin.left - margin.right;
|
|
@@ -189,7 +192,7 @@ className, title, description, enableKeyboardNavigation = LINE_CHART_DEFAULTS.en
|
|
|
189
192
|
key: seriesKey,
|
|
190
193
|
label: ((_a = config[seriesKey]) === null || _a === void 0 ? void 0 : _a.label) || seriesKey,
|
|
191
194
|
value: numValue,
|
|
192
|
-
color: ((_b = config[seriesKey]) === null || _b === void 0 ? void 0 : _b.color) || getSeriesFillColor(keyIndex),
|
|
195
|
+
color: ((_b = config[seriesKey]) === null || _b === void 0 ? void 0 : _b.color) || getSeriesFillColor(keyIndex, seriesKey, config),
|
|
193
196
|
};
|
|
194
197
|
});
|
|
195
198
|
const content = {
|
|
@@ -231,14 +234,15 @@ className, title, description, enableKeyboardNavigation = LINE_CHART_DEFAULTS.en
|
|
|
231
234
|
handleMouseEnter,
|
|
232
235
|
handleMouseLeave,
|
|
233
236
|
]);
|
|
234
|
-
return (jsxs("div", { ref: containerRef, className: cn("chart-container w-full h-full", className),
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
237
|
+
return (jsxs("div", { ref: containerRef, className: cn("chart-container w-full h-full", className), style: {
|
|
238
|
+
width: width !== undefined ? (typeof width === "number" ? `${width}px` : width) : undefined,
|
|
239
|
+
height: height !== undefined ? (typeof height === "number" ? `${height}px` : height) : undefined,
|
|
240
|
+
}, ...chartAccessibilityProps, onMouseEnter: handleMouseInteraction, onMouseMove: handleMouseInteraction, onMouseLeave: () => {
|
|
241
|
+
// Clear the crosshair + glow marker when the pointer leaves the chart.
|
|
242
|
+
// The per-point rects only hide the tooltip; nothing else resets this.
|
|
243
|
+
setHoveredPoint(null);
|
|
244
|
+
handleMouseLeave();
|
|
245
|
+
}, ...props, children: [descriptionProps && jsx("div", { ...descriptionProps }), jsxs("svg", { width: "100%", height: "100%", viewBox: `0 0 ${dimensions.width} ${dimensions.height}`, className: "overflow-visible", role: "presentation", children: [jsxs("defs", { children: [jsx("filter", { id: shadowFilterId, x: "-20%", y: "-20%", width: "140%", height: "140%", children: jsx("feDropShadow", { dx: "8", dy: "8", stdDeviation: "8", floodOpacity: "0.15", floodColor: "#000000" }) }), jsxs("linearGradient", { id: verticalFadeId, x1: "0%", y1: "0%", x2: "0%", y2: "100%", children: [jsx("stop", { offset: "0%", stopColor: "#6b7280", stopOpacity: "0" }), jsx("stop", { offset: "40%", stopColor: "#6b7280", stopOpacity: "0.3" }), jsx("stop", { offset: "50%", stopColor: "#6b7280", stopOpacity: "0.5" }), jsx("stop", { offset: "60%", stopColor: "#6b7280", stopOpacity: "0.3" }), jsx("stop", { offset: "100%", stopColor: "#6b7280", stopOpacity: "0" })] }), jsxs("linearGradient", { id: horizontalFadeId, x1: "0%", y1: "0%", x2: "100%", y2: "0%", children: [jsx("stop", { offset: "0%", stopColor: "#6b7280", stopOpacity: "0" }), jsx("stop", { offset: "40%", stopColor: "#6b7280", stopOpacity: "0.3" }), jsx("stop", { offset: "50%", stopColor: "#6b7280", stopOpacity: "0.5" }), jsx("stop", { offset: "60%", stopColor: "#6b7280", stopOpacity: "0.3" }), jsx("stop", { offset: "100%", stopColor: "#6b7280", stopOpacity: "0" })] })] }), jsx(HorizontalGrid, { show: showGrid, x: margin.left, y: margin.top, width: innerWidth, height: innerHeight, lineCount: 5 }), jsx(ChartCrosshair, { show: hoveredPoint !== null, x: hoveredPoint !== null
|
|
242
246
|
? data.length === 1
|
|
243
247
|
? margin.left + innerWidth / 2
|
|
244
248
|
: margin.left +
|
|
@@ -258,40 +262,52 @@ className, title, description, enableKeyboardNavigation = LINE_CHART_DEFAULTS.en
|
|
|
258
262
|
if (Math.abs(value) >= 1000)
|
|
259
263
|
return `${(value / 1000).toFixed(0)}k`;
|
|
260
264
|
return value.toString();
|
|
261
|
-
} }), minValue < 0 && maxValue > 0 && (jsx("line", { x1: margin.left, y1: margin.top + innerHeight - ((0 - minValue) / (maxValue - minValue)) * innerHeight, x2: margin.left + innerWidth, y2: margin.top + innerHeight - ((0 - minValue) / (maxValue - minValue)) * innerHeight, className: "stroke-[var(--color-text-secondary)]", strokeWidth: 1, opacity: 0.6 })), jsx("g", { className: "chart-lines", children:
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
265
|
+
} }), minValue < 0 && maxValue > 0 && (jsx("line", { x1: margin.left, y1: margin.top + innerHeight - ((0 - minValue) / (maxValue - minValue)) * innerHeight, x2: margin.left + innerWidth, y2: margin.top + innerHeight - ((0 - minValue) / (maxValue - minValue)) * innerHeight, className: "stroke-[var(--color-text-secondary)]", strokeWidth: 1, opacity: 0.6 })), jsx("g", { className: "chart-lines", children: measured &&
|
|
266
|
+
dataKeys.map((key, keyIndex) => {
|
|
267
|
+
var _a;
|
|
268
|
+
const targetPath = allPaths[key];
|
|
269
|
+
const colorClass = getSeriesColorClass(keyIndex);
|
|
270
|
+
return (jsxs("g", { children: [jsxs(motion.g, { initial: { scaleY: shouldReduceMotion ? 1 : 0 }, animate: { scaleY: 1 }, transition: { duration: ANIMATION_DURATION, ease: "easeOut" },
|
|
271
|
+
// Rise from the x-axis like the bars. Framer forces
|
|
272
|
+
// transform-box:fill-box for SVG, so `originY:1` anchors scaleY
|
|
273
|
+
// to the group's fill-box BOTTOM. The invisible rect pins that
|
|
274
|
+
// bottom to the plot baseline (a bare line's bbox stops at its
|
|
275
|
+
// lowest point), so the line grows UP from the x-axis.
|
|
276
|
+
style: { originY: 1, transformOrigin: "bottom" }, children: [jsx("rect", { x: margin.left, y: margin.top, width: innerWidth, height: innerHeight, fill: "none", stroke: "none", style: { pointerEvents: "none" } }), jsx("path", { d: targetPath, fill: "none", strokeWidth: strokeWidth, strokeLinecap: "round",
|
|
277
|
+
// Constant stroke width through the scaleY rise (no squash).
|
|
278
|
+
vectorEffect: "non-scaling-stroke", className: cn("transition-all duration-200", colorClass), style: { stroke: (_a = config[key]) === null || _a === void 0 ? void 0 : _a.color }, filter: `url(#${shadowFilterId})` })] }, shouldReduceMotion ? "line-static" : dataSignature), showDots &&
|
|
279
|
+
data.map((item, dataIndex) => {
|
|
280
|
+
var _a;
|
|
281
|
+
const rawValue = item[key];
|
|
282
|
+
const isNull = rawValue === null || rawValue === undefined;
|
|
283
|
+
const value = isNull
|
|
284
|
+
? 0
|
|
285
|
+
: typeof rawValue === "number"
|
|
286
|
+
? rawValue
|
|
287
|
+
: 0;
|
|
288
|
+
// Don't render dots for null values
|
|
289
|
+
if (isNull)
|
|
290
|
+
return null;
|
|
291
|
+
const { x, y } = getPointPosition(dataIndex, value);
|
|
292
|
+
const isFocused = isKeyboardMode && focusedElementIndex === dataIndex;
|
|
293
|
+
return (jsx(motion.g, { initial: { opacity: 0, scale: 0 }, animate: { opacity: 1, scale: 1 }, transition: {
|
|
294
|
+
// Markers pop in one-by-one (left-to-right) only AFTER the
|
|
295
|
+
// line has fully risen — start the stagger at the rise's end.
|
|
296
|
+
delay: shouldReduceMotion ? 0 : ANIMATION_DURATION + dataIndex * 0.06,
|
|
297
|
+
type: "spring",
|
|
298
|
+
stiffness: 260,
|
|
299
|
+
damping: 20,
|
|
300
|
+
}, style: {
|
|
301
|
+
originX: "50%",
|
|
302
|
+
originY: "50%",
|
|
303
|
+
transformBox: "fill-box",
|
|
304
|
+
}, children: jsx(ChartMarker, { cx: x, cy: y, radius: isFocused
|
|
305
|
+
? resolvedDotRadius + 2
|
|
306
|
+
: resolvedDotRadius, colorClass: cn(colorClass, isFocused &&
|
|
307
|
+
"stroke-[var(--color-primary-600)] stroke-2"), strokeColor: (_a = config[key]) === null || _a === void 0 ? void 0 : _a.color }) }, `${key}-${dataIndex}${shouldReduceMotion ? "" : `-${dataSignature}`}`));
|
|
308
|
+
})] }, key));
|
|
309
|
+
}) }), !showDots && hoveredPoint !== null && (jsx("g", { className: "chart-hover-markers", children: dataKeys.map((key, keyIndex) => {
|
|
310
|
+
var _a;
|
|
295
311
|
const item = data[hoveredPoint.index];
|
|
296
312
|
const rawValue = item[key];
|
|
297
313
|
const isNull = rawValue === null || rawValue === undefined;
|
|
@@ -305,7 +321,7 @@ className, title, description, enableKeyboardNavigation = LINE_CHART_DEFAULTS.en
|
|
|
305
321
|
return null;
|
|
306
322
|
const { x, y } = getPointPosition(hoveredPoint.index, value);
|
|
307
323
|
const colorClass = getSeriesColorClass(keyIndex);
|
|
308
|
-
return (jsx(ChartMarker, { cx: x, cy: y, radius: resolvedDotRadius, colorClass: colorClass }, `hover-${key}-${hoveredPoint.index}`));
|
|
324
|
+
return (jsx(ChartMarker, { cx: x, cy: y, radius: resolvedDotRadius, colorClass: colorClass, strokeColor: (_a = config[key]) === null || _a === void 0 ? void 0 : _a.color }, `hover-${key}-${hoveredPoint.index}`));
|
|
309
325
|
}) })), jsx("g", { className: "chart-hover-areas", children: data.map((item, dataIndex) => {
|
|
310
326
|
// Calculate hover area based on new point positioning
|
|
311
327
|
const pointX = data.length === 1
|
|
@@ -332,7 +348,7 @@ className, title, description, enableKeyboardNavigation = LINE_CHART_DEFAULTS.en
|
|
|
332
348
|
label: ((_a = config[seriesKey]) === null || _a === void 0 ? void 0 : _a.label) || seriesKey,
|
|
333
349
|
value: numValue,
|
|
334
350
|
color: ((_b = config[seriesKey]) === null || _b === void 0 ? void 0 : _b.color) ||
|
|
335
|
-
getSeriesFillColor(keyIndex),
|
|
351
|
+
getSeriesFillColor(keyIndex, seriesKey, config),
|
|
336
352
|
};
|
|
337
353
|
});
|
|
338
354
|
const content = {
|
|
@@ -11,12 +11,12 @@ export interface LineChartProps extends BaseChartProps, Omit<StandardChartDispla
|
|
|
11
11
|
}
|
|
12
12
|
export declare const LINE_CHART_DEFAULTS: {
|
|
13
13
|
readonly color: undefined;
|
|
14
|
-
readonly dotRadius:
|
|
15
|
-
readonly radius:
|
|
14
|
+
readonly dotRadius: 3;
|
|
15
|
+
readonly radius: 3;
|
|
16
16
|
readonly strokeWidth: 2;
|
|
17
17
|
readonly curved: true;
|
|
18
18
|
readonly curveType: import("..").CurveType;
|
|
19
|
-
readonly showDots:
|
|
19
|
+
readonly showDots: false;
|
|
20
20
|
readonly showGrid: true;
|
|
21
21
|
readonly showXAxis: true;
|
|
22
22
|
readonly showYAxis: true;
|
|
@@ -134,7 +134,7 @@ const RadarChart = ({ axes, series, size = 400, gridLevels = 5, maxValue: maxVal
|
|
|
134
134
|
}, [showTooltip, buildTooltipContent, handleMouseEnter]);
|
|
135
135
|
/* ----------------------------- Animation ----------------------------- */
|
|
136
136
|
const shouldAnimate = showAnimation && !shouldReduceMotion;
|
|
137
|
-
return (jsxs("div", { ref: containerRef, className: cn(theme.baseStyle, className), role: "img", "aria-label": `Radar chart comparing ${series.map((s) => s.label).join(", ")} across ${axes.join(", ")}`, ...props, children: [jsxs("svg", { viewBox: `0 0 ${size} ${size}`, width: size, height: size, className: "overflow-visible", children: [gridRings.map((points, idx) => (jsx("polygon", { points: points, fill: "none", stroke:
|
|
137
|
+
return (jsxs("div", { ref: containerRef, className: cn(theme.baseStyle, className), role: "img", "aria-label": `Radar chart comparing ${series.map((s) => s.label).join(", ")} across ${axes.join(", ")}`, ...props, children: [jsxs("svg", { viewBox: `0 0 ${size} ${size}`, width: size, height: size, className: "overflow-visible", children: [gridRings.map((points, idx) => (jsx("polygon", { points: points, fill: "none", stroke: themeOverrides === null || themeOverrides === void 0 ? void 0 : themeOverrides.gridColor, className: cn(!(themeOverrides === null || themeOverrides === void 0 ? void 0 : themeOverrides.gridColor) && "stroke-[var(--color-border)]"), strokeWidth: 1 }, `grid-${idx}`))), spokes.map((spoke, idx) => (jsx("line", { x1: spoke.x1, y1: spoke.y1, x2: spoke.x2, y2: spoke.y2, stroke: themeOverrides === null || themeOverrides === void 0 ? void 0 : themeOverrides.axisColor, className: cn(!(themeOverrides === null || themeOverrides === void 0 ? void 0 : themeOverrides.axisColor) && "stroke-[var(--color-border-secondary)]"), strokeWidth: 1 }, `spoke-${idx}`))), polygons.map((poly, idx) => shouldAnimate ? (jsx(motion.polygon, { points: poly.points, fill: poly.color, fillOpacity: fillOpacity, stroke: poly.color, strokeWidth: strokeWidth, strokeLinejoin: "round", initial: { opacity: 0, scale: 0 }, animate: { opacity: 1, scale: 1 }, transition: getSpringAnimation(RADAR_CHART_ANIMATIONS.preset, shouldReduceMotion, RADAR_CHART_ANIMATIONS.initialDelay +
|
|
138
138
|
getStaggerDelay(idx, RADAR_CHART_ANIMATIONS.seriesStagger)), style: { transformOrigin: `${cx}px ${cy}px` } }, `series-${idx}`)) : (jsx("polygon", { points: poly.points, fill: poly.color, fillOpacity: fillOpacity, stroke: poly.color, strokeWidth: strokeWidth, strokeLinejoin: "round" }, `series-${idx}`))), series.map((s, sIdx) => s.data.map((v, dIdx) => {
|
|
139
139
|
const ratio = maxValue > 0 ? Math.min(v, maxValue) / maxValue : 0;
|
|
140
140
|
const r = ratio * chartRadius;
|
|
@@ -8,9 +8,12 @@
|
|
|
8
8
|
const radarChartTheme = {
|
|
9
9
|
// Outer wrapper
|
|
10
10
|
baseStyle: "flex flex-col items-center gap-4",
|
|
11
|
-
// Grid ring
|
|
11
|
+
// Grid ring / axis spoke colors are drawn from the dark-mode-aware
|
|
12
|
+
// `--color-border` / `--color-border-secondary` tokens in the component
|
|
13
|
+
// (applied via className so the CSS variable resolves). These hex values are
|
|
14
|
+
// only the fallback used when a consumer overrides `theme.gridColor` /
|
|
15
|
+
// `theme.axisColor` — they are NOT the rendered default.
|
|
12
16
|
gridColor: "#e5e7eb",
|
|
13
|
-
// Axis spoke stroke color (gray-300 equivalent)
|
|
14
17
|
axisColor: "#d1d5db",
|
|
15
18
|
// Axis label classes (applied to <text> elements via className)
|
|
16
19
|
labelStyle: "text-xs fill-[#6b7280] select-none",
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
-
import { useRef,
|
|
2
|
+
import { useRef, useMemo, useCallback } from 'react';
|
|
3
3
|
import { motion } from 'motion/react';
|
|
4
4
|
import { cn } from '../../../utils/cn.js';
|
|
5
5
|
import { useTooltipPosition } from '../hooks/useTooltipPosition.js';
|
|
6
6
|
import { useChartAccessibility } from '../hooks/useChartAccessibility.js';
|
|
7
|
+
import { useChartDimensions } from '../hooks/useChartDimensions.js';
|
|
7
8
|
import { XAxis } from '../shared/ChartAxis/XAxis.js';
|
|
8
9
|
import { YAxis } from '../shared/ChartAxis/YAxis.js';
|
|
9
10
|
import { ChartTooltip } from '../shared/ChartTooltip/ChartTooltip.js';
|
|
@@ -17,37 +18,17 @@ import { getCategoryColor, scatterPlotTheme } from './ScatterPlot.theme.js';
|
|
|
17
18
|
* Now uses shared axis components with tick marks and value labels like other charts.
|
|
18
19
|
*/
|
|
19
20
|
const ScatterPlot = ({ data, xLabel, yLabel, dotRadius: propDotRadius, pointSize, // @deprecated
|
|
20
|
-
showGrid = SCATTER_PLOT_DEFAULTS.showGrid, showXAxis = SCATTER_PLOT_DEFAULTS.showXAxis, showYAxis = SCATTER_PLOT_DEFAULTS.showYAxis, showTooltip = SCATTER_PLOT_DEFAULTS.showTooltip, colors, minValue: propMinValue, maxValue: propMaxValue, theme: themeOverrides, className, svgClassName, dotClassName, gridClassName, axisClassName, title, description, enableKeyboardNavigation = SCATTER_PLOT_DEFAULTS.enableKeyboardNavigation, ...props }) => {
|
|
21
|
+
showGrid = SCATTER_PLOT_DEFAULTS.showGrid, showXAxis = SCATTER_PLOT_DEFAULTS.showXAxis, showYAxis = SCATTER_PLOT_DEFAULTS.showYAxis, showTooltip = SCATTER_PLOT_DEFAULTS.showTooltip, colors, minValue: propMinValue, maxValue: propMaxValue, theme: themeOverrides, className, svgClassName, dotClassName, gridClassName, axisClassName, title, description, enableKeyboardNavigation = SCATTER_PLOT_DEFAULTS.enableKeyboardNavigation, width, height, ...props }) => {
|
|
21
22
|
var _a;
|
|
22
23
|
const theme = { ...scatterPlotTheme, ...(themeOverrides || {}) };
|
|
23
24
|
const chartColors = colors || theme.colors || scatterPlotTheme.colors;
|
|
24
25
|
// Use dotRadius, fallback to pointSize for backward compatibility
|
|
25
26
|
const dotRadiusValue = (_a = propDotRadius !== null && propDotRadius !== void 0 ? propDotRadius : pointSize) !== null && _a !== void 0 ? _a : SCATTER_PLOT_DEFAULTS.dotRadius;
|
|
26
|
-
// Responsive container dimensions
|
|
27
|
+
// Responsive container dimensions. `measured` gates dot mount so motion
|
|
28
|
+
// captures scale-in geometry at real cx/cy, not the 600×400 fallback (dots
|
|
29
|
+
// would otherwise fly in from the wrong positions on cold load).
|
|
27
30
|
const containerRef = useRef(null);
|
|
28
|
-
const
|
|
29
|
-
// Update dimensions on mount and resize
|
|
30
|
-
useEffect(() => {
|
|
31
|
-
if (!containerRef.current)
|
|
32
|
-
return;
|
|
33
|
-
const updateDimensions = () => {
|
|
34
|
-
if (containerRef.current) {
|
|
35
|
-
const rect = containerRef.current.getBoundingClientRect();
|
|
36
|
-
setDimensions({
|
|
37
|
-
width: rect.width || 600,
|
|
38
|
-
height: rect.height || 400,
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
// Initial measurement
|
|
43
|
-
updateDimensions();
|
|
44
|
-
// Setup ResizeObserver
|
|
45
|
-
const resizeObserver = new ResizeObserver(updateDimensions);
|
|
46
|
-
resizeObserver.observe(containerRef.current);
|
|
47
|
-
return () => {
|
|
48
|
-
resizeObserver.disconnect();
|
|
49
|
-
};
|
|
50
|
-
}, []);
|
|
31
|
+
const { dimensions, measured } = useChartDimensions(containerRef);
|
|
51
32
|
// Calculate ranges and categories
|
|
52
33
|
const { xMin, xMax, yMin, yMax, categories, validData } = useMemo(() => {
|
|
53
34
|
// Filter out invalid data points
|
|
@@ -155,53 +136,62 @@ showGrid = SCATTER_PLOT_DEFAULTS.showGrid, showXAxis = SCATTER_PLOT_DEFAULTS.sho
|
|
|
155
136
|
}, [xMin, xMax]);
|
|
156
137
|
// Return empty state if no data
|
|
157
138
|
if (validData.length === 0) {
|
|
158
|
-
return (jsx("div", { ref: containerRef, className: cn(theme.containerStyle, className), style: {
|
|
139
|
+
return (jsx("div", { ref: containerRef, className: cn(theme.containerStyle, className), style: {
|
|
140
|
+
minHeight: height === undefined ? '400px' : undefined,
|
|
141
|
+
width: width !== undefined ? (typeof width === "number" ? `${width}px` : width) : undefined,
|
|
142
|
+
height: height !== undefined ? (typeof height === "number" ? `${height}px` : height) : undefined,
|
|
143
|
+
}, ...props, children: jsx("div", { className: theme.emptyStateStyle, children: data.length === 0 ? 'No data available' : 'No valid data points' }) }));
|
|
159
144
|
}
|
|
160
|
-
return (jsxs("div", { ref: containerRef, className: cn(theme.containerStyle, className), style: {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
145
|
+
return (jsxs("div", { ref: containerRef, className: cn(theme.containerStyle, className), style: {
|
|
146
|
+
minHeight: height === undefined ? '400px' : undefined,
|
|
147
|
+
width: width !== undefined ? (typeof width === "number" ? `${width}px` : width) : undefined,
|
|
148
|
+
height: height !== undefined ? (typeof height === "number" ? `${height}px` : height) : undefined,
|
|
149
|
+
}, ...chartAccessibilityProps, ...props, children: [jsxs("svg", { width: dimensions.width, height: dimensions.height, className: cn(theme.svgStyle, svgClassName), ...descriptionProps, children: [jsx(YAxis, { show: showYAxis, min: yMin, max: yMax, x: margin.left, y: margin.top, height: innerHeight, showGrid: showGrid, gridWidth: innerWidth, tickCount: 5, className: cn(axisClassName) }), measured &&
|
|
150
|
+
validData.map((point, index) => {
|
|
151
|
+
const cx = scaleX(point.x);
|
|
152
|
+
const cy = scaleY(point.y);
|
|
153
|
+
const size = point.size ? Math.sqrt(point.size) / 2 : dotRadiusValue;
|
|
154
|
+
const pointColor = getColor(point.category);
|
|
155
|
+
return (jsx(motion.circle, { cx: cx, cy: cy, r: size, fill: pointColor, className: cn(theme.dotStyle, dotClassName), strokeWidth: "0.5", initial: { scale: 0, opacity: 0 }, animate: { scale: 1, opacity: 1 }, transition: { delay: index * 0.01, duration: 0.3 }, whileHover: { scale: 1.5, opacity: 1 }, onMouseEnter: (e) => {
|
|
156
|
+
if (showTooltip) {
|
|
157
|
+
const content = {
|
|
158
|
+
category: point.label || point.category || `Point ${index + 1}`,
|
|
159
|
+
series: [
|
|
160
|
+
{
|
|
161
|
+
key: 'x',
|
|
162
|
+
label: xLabel || 'X',
|
|
163
|
+
value: point.x.toFixed(2),
|
|
164
|
+
color: pointColor,
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
key: 'y',
|
|
168
|
+
label: yLabel || 'Y',
|
|
169
|
+
value: point.y.toFixed(2),
|
|
170
|
+
color: pointColor,
|
|
171
|
+
},
|
|
172
|
+
...(point.size
|
|
173
|
+
? [
|
|
174
|
+
{
|
|
175
|
+
key: 'size',
|
|
176
|
+
label: 'Size',
|
|
177
|
+
value: point.size.toFixed(2),
|
|
178
|
+
color: pointColor,
|
|
179
|
+
},
|
|
180
|
+
]
|
|
181
|
+
: []),
|
|
182
|
+
],
|
|
183
|
+
};
|
|
184
|
+
// Pass SVG coordinates for proper positioning (especially in mobile/constrained containers)
|
|
185
|
+
const svgCoordinates = isMobile ? {
|
|
186
|
+
x: cx,
|
|
187
|
+
y: cy,
|
|
188
|
+
dimensions
|
|
189
|
+
} : undefined;
|
|
190
|
+
handleMouseEnter(e, content, svgCoordinates);
|
|
191
|
+
}
|
|
192
|
+
handleMouseInteraction();
|
|
193
|
+
}, onMouseMove: handleMouseMove, onMouseLeave: handleMouseLeave }, index));
|
|
194
|
+
}), jsx(XAxis, { show: showXAxis, data: xAxisData, x: margin.left, y: margin.top + innerHeight, width: innerWidth, categoryWidth: innerWidth / (xAxisData.length - 1), categoryGap: 0, alignWithEdge: true, className: cn(axisClassName) }), xLabel && showXAxis && (jsx("text", { x: margin.left + innerWidth / 2, y: dimensions.height - 5, textAnchor: "middle", className: "text-sm fill-[var(--color-text-secondary)]", children: xLabel })), yLabel && showYAxis && (jsx("text", { x: 15, y: margin.top + innerHeight / 2, textAnchor: "middle", className: "text-sm fill-[var(--color-text-secondary)]", transform: `rotate(-90 15 ${margin.top + innerHeight / 2})`, children: yLabel }))] }), categories.length > 0 && (jsx("div", { className: theme.legendContainerStyle, children: categories.map((cat, index) => (jsxs("div", { className: theme.legendItemStyle, children: [jsx("div", { className: theme.legendDotStyle, style: { backgroundColor: getCategoryColor(chartColors, index) } }), jsx("span", { className: theme.legendLabelStyle, children: cat })] }, cat))) })), showTooltip && (jsx(ChartTooltip, { active: !!tooltipData, position: tooltipData ? { x: tooltipData.x, y: tooltipData.y } : { x: 0, y: 0 }, tooltipRef: tooltipRef, content: tooltipData === null || tooltipData === void 0 ? void 0 : tooltipData.content, chartType: "scatter" }))] }));
|
|
205
195
|
};
|
|
206
196
|
ScatterPlot.displayName = 'ScatterPlot';
|
|
207
197
|
|
|
@@ -32,7 +32,16 @@ const scatterPlotTheme = {
|
|
|
32
32
|
* Get fill color for category (supports both CSS variables and direct colors)
|
|
33
33
|
*/
|
|
34
34
|
function getCategoryColor(colors, categoryIndex) {
|
|
35
|
-
|
|
35
|
+
const color = colors[categoryIndex % colors.length];
|
|
36
|
+
if (color &&
|
|
37
|
+
!color.startsWith("var(") &&
|
|
38
|
+
!color.startsWith("#") &&
|
|
39
|
+
!color.startsWith("rgb") &&
|
|
40
|
+
!color.startsWith("hsl") &&
|
|
41
|
+
color.includes("-")) {
|
|
42
|
+
return `var(--color-${color})`;
|
|
43
|
+
}
|
|
44
|
+
return color;
|
|
36
45
|
}
|
|
37
46
|
|
|
38
47
|
export { getCategoryColor, scatterPlotTheme };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StandardChartDisplayProps } from '../types/chart.types';
|
|
1
|
+
import { StandardChartDisplayProps, BaseChartProps } from '../types/chart.types';
|
|
2
2
|
/**
|
|
3
3
|
* Data point for ScatterPlot
|
|
4
4
|
*/
|
|
@@ -17,7 +17,7 @@ export interface ScatterPlotDataPoint {
|
|
|
17
17
|
/**
|
|
18
18
|
* ScatterPlot props - extends standardized chart props
|
|
19
19
|
*/
|
|
20
|
-
export interface ScatterPlotProps extends StandardChartDisplayProps {
|
|
20
|
+
export interface ScatterPlotProps extends StandardChartDisplayProps, Omit<BaseChartProps, 'data' | 'config'> {
|
|
21
21
|
/** Data points */
|
|
22
22
|
data: ScatterPlotDataPoint[];
|
|
23
23
|
/** X-axis label */
|
|
@@ -31,12 +31,6 @@ export interface ScatterPlotProps extends StandardChartDisplayProps {
|
|
|
31
31
|
colors?: string[];
|
|
32
32
|
/** Enable tooltip on hover */
|
|
33
33
|
showTooltip?: boolean;
|
|
34
|
-
/** Accessibility props */
|
|
35
|
-
title?: string;
|
|
36
|
-
description?: string;
|
|
37
|
-
enableKeyboardNavigation?: boolean;
|
|
38
|
-
/** Additional className */
|
|
39
|
-
className?: string;
|
|
40
34
|
/** className overrides for chart elements (shadcn approach) */
|
|
41
35
|
svgClassName?: string;
|
|
42
36
|
dotClassName?: string;
|
|
@@ -63,7 +57,7 @@ export declare const SCATTER_PLOT_DEFAULTS: {
|
|
|
63
57
|
readonly curveType: import("..").CurveType;
|
|
64
58
|
readonly fillOpacity: 0.3;
|
|
65
59
|
readonly showStroke: true;
|
|
66
|
-
readonly showDots:
|
|
60
|
+
readonly showDots: false;
|
|
67
61
|
readonly orientation: "vertical" | "horizontal";
|
|
68
62
|
readonly stacked: false;
|
|
69
63
|
readonly variant: import("..").ChartVariant;
|