@coinbase/cds-mobile-visualization 3.4.0-beta.1 → 3.4.0-beta.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/dts/chart/CartesianChart.d.ts +57 -33
  3. package/dts/chart/CartesianChart.d.ts.map +1 -1
  4. package/dts/chart/ChartContextBridge.d.ts +28 -0
  5. package/dts/chart/ChartContextBridge.d.ts.map +1 -0
  6. package/dts/chart/Path.d.ts +77 -34
  7. package/dts/chart/Path.d.ts.map +1 -1
  8. package/dts/chart/PeriodSelector.d.ts +2 -2
  9. package/dts/chart/PeriodSelector.d.ts.map +1 -1
  10. package/dts/chart/area/Area.d.ts +42 -27
  11. package/dts/chart/area/Area.d.ts.map +1 -1
  12. package/dts/chart/area/AreaChart.d.ts +51 -10
  13. package/dts/chart/area/AreaChart.d.ts.map +1 -1
  14. package/dts/chart/area/DottedArea.d.ts +21 -2
  15. package/dts/chart/area/DottedArea.d.ts.map +1 -1
  16. package/dts/chart/area/GradientArea.d.ts +19 -13
  17. package/dts/chart/area/GradientArea.d.ts.map +1 -1
  18. package/dts/chart/area/SolidArea.d.ts +17 -2
  19. package/dts/chart/area/SolidArea.d.ts.map +1 -1
  20. package/dts/chart/axis/Axis.d.ts +86 -118
  21. package/dts/chart/axis/Axis.d.ts.map +1 -1
  22. package/dts/chart/axis/DefaultAxisTickLabel.d.ts +8 -0
  23. package/dts/chart/axis/DefaultAxisTickLabel.d.ts.map +1 -0
  24. package/dts/chart/axis/XAxis.d.ts +1 -1
  25. package/dts/chart/axis/XAxis.d.ts.map +1 -1
  26. package/dts/chart/axis/YAxis.d.ts +2 -2
  27. package/dts/chart/axis/YAxis.d.ts.map +1 -1
  28. package/dts/chart/axis/index.d.ts +1 -0
  29. package/dts/chart/axis/index.d.ts.map +1 -1
  30. package/dts/chart/bar/Bar.d.ts +16 -13
  31. package/dts/chart/bar/Bar.d.ts.map +1 -1
  32. package/dts/chart/bar/BarChart.d.ts +36 -20
  33. package/dts/chart/bar/BarChart.d.ts.map +1 -1
  34. package/dts/chart/bar/BarPlot.d.ts +2 -1
  35. package/dts/chart/bar/BarPlot.d.ts.map +1 -1
  36. package/dts/chart/bar/BarStack.d.ts +39 -48
  37. package/dts/chart/bar/BarStack.d.ts.map +1 -1
  38. package/dts/chart/bar/BarStackGroup.d.ts +1 -0
  39. package/dts/chart/bar/BarStackGroup.d.ts.map +1 -1
  40. package/dts/chart/bar/DefaultBar.d.ts +1 -1
  41. package/dts/chart/bar/DefaultBar.d.ts.map +1 -1
  42. package/dts/chart/bar/DefaultBarStack.d.ts.map +1 -1
  43. package/dts/chart/gradient/Gradient.d.ts +25 -0
  44. package/dts/chart/gradient/Gradient.d.ts.map +1 -0
  45. package/dts/chart/gradient/index.d.ts +2 -0
  46. package/dts/chart/gradient/index.d.ts.map +1 -0
  47. package/dts/chart/index.d.ts +3 -1
  48. package/dts/chart/index.d.ts.map +1 -1
  49. package/dts/chart/line/DefaultReferenceLineLabel.d.ts +9 -0
  50. package/dts/chart/line/DefaultReferenceLineLabel.d.ts.map +1 -0
  51. package/dts/chart/line/DottedLine.d.ts +13 -5
  52. package/dts/chart/line/DottedLine.d.ts.map +1 -1
  53. package/dts/chart/line/Line.d.ts +64 -25
  54. package/dts/chart/line/Line.d.ts.map +1 -1
  55. package/dts/chart/line/LineChart.d.ts +43 -9
  56. package/dts/chart/line/LineChart.d.ts.map +1 -1
  57. package/dts/chart/line/ReferenceLine.d.ts +68 -20
  58. package/dts/chart/line/ReferenceLine.d.ts.map +1 -1
  59. package/dts/chart/line/SolidLine.d.ts +8 -5
  60. package/dts/chart/line/SolidLine.d.ts.map +1 -1
  61. package/dts/chart/line/index.d.ts +1 -1
  62. package/dts/chart/line/index.d.ts.map +1 -1
  63. package/dts/chart/point/DefaultPointLabel.d.ts +10 -0
  64. package/dts/chart/point/DefaultPointLabel.d.ts.map +1 -0
  65. package/dts/chart/point/Point.d.ts +120 -0
  66. package/dts/chart/point/Point.d.ts.map +1 -0
  67. package/dts/chart/point/index.d.ts +3 -0
  68. package/dts/chart/point/index.d.ts.map +1 -0
  69. package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts +8 -0
  70. package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts.map +1 -0
  71. package/dts/chart/scrubber/DefaultScrubberBeaconLabel.d.ts +12 -0
  72. package/dts/chart/scrubber/DefaultScrubberBeaconLabel.d.ts.map +1 -0
  73. package/dts/chart/scrubber/DefaultScrubberLabel.d.ts +11 -0
  74. package/dts/chart/scrubber/DefaultScrubberLabel.d.ts.map +1 -0
  75. package/dts/chart/scrubber/Scrubber.d.ts +172 -43
  76. package/dts/chart/scrubber/Scrubber.d.ts.map +1 -1
  77. package/dts/chart/scrubber/ScrubberBeaconGroup.d.ts +44 -0
  78. package/dts/chart/scrubber/ScrubberBeaconGroup.d.ts.map +1 -0
  79. package/dts/chart/scrubber/ScrubberBeaconLabelGroup.d.ts +31 -0
  80. package/dts/chart/scrubber/ScrubberBeaconLabelGroup.d.ts.map +1 -0
  81. package/dts/chart/scrubber/ScrubberProvider.d.ts +6 -3
  82. package/dts/chart/scrubber/ScrubberProvider.d.ts.map +1 -1
  83. package/dts/chart/scrubber/index.d.ts +3 -0
  84. package/dts/chart/scrubber/index.d.ts.map +1 -1
  85. package/dts/chart/text/ChartText.d.ts +151 -77
  86. package/dts/chart/text/ChartText.d.ts.map +1 -1
  87. package/dts/chart/text/{SmartChartTextGroup.d.ts → ChartTextGroup.d.ts} +9 -3
  88. package/dts/chart/text/ChartTextGroup.d.ts.map +1 -0
  89. package/dts/chart/text/index.d.ts +1 -1
  90. package/dts/chart/text/index.d.ts.map +1 -1
  91. package/dts/chart/utils/axis.d.ts +25 -1
  92. package/dts/chart/utils/axis.d.ts.map +1 -1
  93. package/dts/chart/utils/chart.d.ts +34 -7
  94. package/dts/chart/utils/chart.d.ts.map +1 -1
  95. package/dts/chart/utils/context.d.ts +28 -7
  96. package/dts/chart/utils/context.d.ts.map +1 -1
  97. package/dts/chart/utils/gradient.d.ts +117 -0
  98. package/dts/chart/utils/gradient.d.ts.map +1 -0
  99. package/dts/chart/utils/index.d.ts +3 -0
  100. package/dts/chart/utils/index.d.ts.map +1 -1
  101. package/dts/chart/utils/path.d.ts +53 -0
  102. package/dts/chart/utils/path.d.ts.map +1 -1
  103. package/dts/chart/utils/point.d.ts +71 -7
  104. package/dts/chart/utils/point.d.ts.map +1 -1
  105. package/dts/chart/utils/scale.d.ts +102 -0
  106. package/dts/chart/utils/scale.d.ts.map +1 -1
  107. package/dts/chart/utils/scrubber.d.ts +39 -0
  108. package/dts/chart/utils/scrubber.d.ts.map +1 -0
  109. package/dts/chart/utils/transition.d.ts +140 -0
  110. package/dts/chart/utils/transition.d.ts.map +1 -0
  111. package/esm/chart/CartesianChart.js +164 -70
  112. package/esm/chart/ChartContextBridge.js +148 -0
  113. package/esm/chart/Path.js +198 -113
  114. package/esm/chart/PeriodSelector.js +2 -2
  115. package/esm/chart/__stories__/CartesianChart.stories.js +378 -131
  116. package/esm/chart/__stories__/Chart.stories.js +2 -4
  117. package/esm/chart/__stories__/PeriodSelector.stories.js +103 -75
  118. package/esm/chart/area/Area.js +25 -35
  119. package/esm/chart/area/AreaChart.js +17 -12
  120. package/esm/chart/area/DottedArea.js +61 -109
  121. package/esm/chart/area/GradientArea.js +35 -91
  122. package/esm/chart/area/SolidArea.js +22 -8
  123. package/esm/chart/area/__stories__/AreaChart.stories.js +1 -1
  124. package/esm/chart/axis/Axis.js +5 -39
  125. package/esm/chart/axis/DefaultAxisTickLabel.js +11 -0
  126. package/esm/chart/axis/XAxis.js +148 -66
  127. package/esm/chart/axis/YAxis.js +149 -65
  128. package/esm/chart/axis/__stories__/Axis.stories.js +259 -1
  129. package/esm/chart/axis/index.js +1 -0
  130. package/esm/chart/bar/Bar.js +3 -1
  131. package/esm/chart/bar/BarChart.js +15 -37
  132. package/esm/chart/bar/BarPlot.js +41 -35
  133. package/esm/chart/bar/BarStack.js +75 -38
  134. package/esm/chart/bar/BarStackGroup.js +6 -16
  135. package/esm/chart/bar/DefaultBar.js +26 -48
  136. package/esm/chart/bar/DefaultBarStack.js +23 -58
  137. package/esm/chart/bar/__stories__/BarChart.stories.js +502 -77
  138. package/esm/chart/gradient/Gradient.js +53 -0
  139. package/esm/chart/gradient/index.js +1 -0
  140. package/esm/chart/index.js +3 -1
  141. package/esm/chart/line/DefaultReferenceLineLabel.js +66 -0
  142. package/esm/chart/line/DottedLine.js +29 -14
  143. package/esm/chart/line/Line.js +106 -67
  144. package/esm/chart/line/LineChart.js +20 -14
  145. package/esm/chart/line/ReferenceLine.js +80 -63
  146. package/esm/chart/line/SolidLine.js +25 -10
  147. package/esm/chart/line/__stories__/LineChart.stories.js +2101 -1977
  148. package/esm/chart/line/__stories__/ReferenceLine.stories.js +83 -28
  149. package/esm/chart/line/index.js +1 -1
  150. package/esm/chart/point/DefaultPointLabel.js +39 -0
  151. package/esm/chart/point/Point.js +188 -0
  152. package/esm/chart/point/index.js +2 -0
  153. package/esm/chart/scrubber/DefaultScrubberBeacon.js +179 -0
  154. package/esm/chart/scrubber/DefaultScrubberBeaconLabel.js +43 -0
  155. package/esm/chart/scrubber/DefaultScrubberLabel.js +28 -0
  156. package/esm/chart/scrubber/Scrubber.js +126 -146
  157. package/esm/chart/scrubber/ScrubberBeaconGroup.js +161 -0
  158. package/esm/chart/scrubber/ScrubberBeaconLabelGroup.js +185 -0
  159. package/esm/chart/scrubber/ScrubberProvider.js +46 -54
  160. package/esm/chart/scrubber/index.js +3 -1
  161. package/esm/chart/text/ChartText.js +242 -174
  162. package/esm/chart/text/{SmartChartTextGroup.js → ChartTextGroup.js} +6 -5
  163. package/esm/chart/text/index.js +1 -1
  164. package/esm/chart/utils/axis.js +45 -29
  165. package/esm/chart/utils/chart.js +44 -3
  166. package/esm/chart/utils/gradient.js +305 -0
  167. package/esm/chart/utils/index.js +3 -0
  168. package/esm/chart/utils/path.js +76 -8
  169. package/esm/chart/utils/point.js +171 -17
  170. package/esm/chart/utils/scale.js +242 -2
  171. package/esm/chart/utils/scrubber.js +139 -0
  172. package/esm/chart/utils/transition.js +185 -0
  173. package/esm/sparkline/__stories__/Sparkline.stories.js +11 -7
  174. package/esm/sparkline/__stories__/SparklineGradient.stories.js +7 -4
  175. package/esm/sparkline/sparkline-interactive/__stories__/SparklineInteractive.stories.js +51 -26
  176. package/esm/sparkline/sparkline-interactive-header/__stories__/SparklineInteractiveHeader.stories.js +17 -9
  177. package/package.json +15 -9
  178. package/dts/chart/Point.d.ts +0 -103
  179. package/dts/chart/Point.d.ts.map +0 -1
  180. package/dts/chart/line/GradientLine.d.ts +0 -45
  181. package/dts/chart/line/GradientLine.d.ts.map +0 -1
  182. package/dts/chart/scrubber/ScrubberBeacon.d.ts +0 -75
  183. package/dts/chart/scrubber/ScrubberBeacon.d.ts.map +0 -1
  184. package/dts/chart/text/SmartChartTextGroup.d.ts.map +0 -1
  185. package/esm/chart/Point.js +0 -111
  186. package/esm/chart/line/GradientLine.js +0 -62
  187. package/esm/chart/scrubber/ScrubberBeacon.js +0 -199
@@ -0,0 +1,53 @@
1
+ import { memo, useMemo } from 'react';
2
+ import { LinearGradient, vec } from '@shopify/react-native-skia';
3
+ import { useCartesianChartContext } from '../ChartProvider';
4
+ import { getColorWithOpacity, getGradientConfig } from '../utils/gradient';
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ /**
7
+ * Renders a Skia LinearGradient element based on a GradientDefinition.
8
+ * The gradient should be used as a child of a Path component.
9
+ *
10
+ * @example
11
+ * <Path d={pathString} stroke="red">
12
+ * {gradient && <Gradient gradient={gradient} yAxisId={yAxisId} />}
13
+ * </Path>
14
+ */
15
+ export const Gradient = /*#__PURE__*/memo(_ref => {
16
+ var _gradient$axis;
17
+ let {
18
+ gradient,
19
+ yAxisId
20
+ } = _ref;
21
+ const context = useCartesianChartContext();
22
+ const xScale = context.getXScale();
23
+ const yScale = context.getYScale(yAxisId);
24
+ const axis = (_gradient$axis = gradient.axis) != null ? _gradient$axis : 'y';
25
+ const scale = axis === 'x' ? xScale : yScale;
26
+
27
+ // Process gradient definition into stops
28
+ const stops = useMemo(() => {
29
+ if (!xScale || !yScale) return;
30
+ return getGradientConfig(gradient, xScale, yScale);
31
+ }, [gradient, xScale, yScale]);
32
+ if (!stops || !scale) return;
33
+ const range = scale.range();
34
+
35
+ // Determine gradient direction based on axis
36
+ // For y-axis, we need to flip the gradient direction because y-scales are inverted
37
+ // (higher data values have smaller pixel values, appearing at the top)
38
+ const start = axis === 'x' ? vec(range[0], 0) : vec(0, range[0]);
39
+ const end = axis === 'x' ? vec(range[1], 0) : vec(0, range[1]);
40
+
41
+ // Extract colors and positions for LinearGradient
42
+ const colors = stops.map(s => {
43
+ var _s$opacity;
44
+ return getColorWithOpacity(s.color, (_s$opacity = s.opacity) != null ? _s$opacity : 1);
45
+ });
46
+ const positions = stops.map(s => s.offset);
47
+ return /*#__PURE__*/_jsx(LinearGradient, {
48
+ colors: colors,
49
+ end: end,
50
+ positions: positions,
51
+ start: start
52
+ });
53
+ });
@@ -0,0 +1 @@
1
+ export * from './Gradient';
@@ -3,11 +3,13 @@ export * from './area';
3
3
  export * from './axis';
4
4
  export * from './bar';
5
5
  export * from './CartesianChart';
6
+ export * from './ChartContextBridge';
6
7
  export * from './ChartProvider';
8
+ export * from './gradient';
7
9
  export * from './line';
8
10
  export * from './Path';
9
11
  export * from './PeriodSelector';
10
- export * from './Point';
12
+ export * from './point';
11
13
  export * from './scrubber';
12
14
  export * from './text';
13
15
  export * from './utils';
@@ -0,0 +1,66 @@
1
+ const _excluded = ["color", "elevated", "borderRadius", "inset", "boundsInset"];
2
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
3
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
4
+ import { memo, useMemo } from 'react';
5
+ import { useTheme } from '@coinbase/cds-mobile';
6
+ import { useCartesianChartContext } from '../ChartProvider';
7
+ import { ChartText } from '../text';
8
+ import { getChartInset } from '../utils';
9
+ import { jsx as _jsx } from "react/jsx-runtime";
10
+ const elevatedInset = {
11
+ top: 8,
12
+ bottom: 8,
13
+ left: 12,
14
+ right: 12
15
+ };
16
+ const elevatedBorderRadius = 4;
17
+ // Default bounds inset when elevated to prevent shadow clipping
18
+ const elevatedBoundsInset = {
19
+ top: 4,
20
+ bottom: 20,
21
+ left: 12,
22
+ right: 12
23
+ };
24
+ const nonElevatedBoundsInset = {
25
+ top: 0,
26
+ bottom: 0,
27
+ left: 0,
28
+ right: 0
29
+ };
30
+
31
+ /**
32
+ * DefaultReferenceLineLabel is the default label component for ReferenceLine.
33
+ * Provides standard styling with elevation, inset, and color defaults.
34
+ * When elevated, automatically adds bounds to prevent shadow cutoff at chart edges.
35
+ */
36
+ export const DefaultReferenceLineLabel = /*#__PURE__*/memo(_ref => {
37
+ let {
38
+ color,
39
+ elevated,
40
+ borderRadius = elevated ? elevatedBorderRadius : undefined,
41
+ inset = elevated ? elevatedInset : undefined,
42
+ boundsInset: boundsInsetProp
43
+ } = _ref,
44
+ props = _objectWithoutPropertiesLoose(_ref, _excluded);
45
+ const theme = useTheme();
46
+ const {
47
+ width: chartWidth,
48
+ height: chartHeight
49
+ } = useCartesianChartContext();
50
+ const bounds = useMemo(() => {
51
+ const boundsInset = getChartInset(boundsInsetProp, elevated ? elevatedBoundsInset : nonElevatedBoundsInset);
52
+ return {
53
+ x: boundsInset.left,
54
+ y: boundsInset.top,
55
+ width: chartWidth - boundsInset.left - boundsInset.right,
56
+ height: chartHeight - boundsInset.top - boundsInset.bottom
57
+ };
58
+ }, [elevated, boundsInsetProp, chartWidth, chartHeight]);
59
+ return /*#__PURE__*/_jsx(ChartText, _extends({
60
+ borderRadius: borderRadius,
61
+ bounds: bounds,
62
+ color: color != null ? color : theme.color.fgMuted,
63
+ elevated: elevated,
64
+ inset: inset
65
+ }, props));
66
+ });
@@ -1,35 +1,50 @@
1
- const _excluded = ["fill", "stroke", "strokeDasharray", "strokeLinecap", "strokeLinejoin", "strokeOpacity", "strokeWidth", "vectorEffect"];
1
+ const _excluded = ["fill", "stroke", "dashIntervals", "strokeCap", "strokeJoin", "strokeOpacity", "strokeWidth", "gradient", "yAxisId", "d", "animate", "transition"];
2
2
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
3
3
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
4
4
  import { memo } from 'react';
5
5
  import { useTheme } from '@coinbase/cds-mobile/hooks/useTheme';
6
+ import { DashPathEffect } from '@shopify/react-native-skia';
7
+ import { Gradient } from '../gradient';
6
8
  import { Path } from '../Path';
7
- import { jsx as _jsx } from "react/jsx-runtime";
9
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
10
  /**
9
- * A customizable dotted line component which uses path element.
11
+ * A customizable dotted line component.
12
+ * Supports gradient for gradient effects on the dots and smooth data transitions via AnimatedPath.
10
13
  */
11
14
  export const DottedLine = /*#__PURE__*/memo(_ref => {
12
15
  let {
13
16
  fill = 'none',
14
17
  stroke,
15
- strokeDasharray = '0 4',
16
- strokeLinecap = 'round',
17
- strokeLinejoin = 'round',
18
+ dashIntervals = [0, 4],
19
+ strokeCap = 'round',
20
+ strokeJoin = 'round',
18
21
  strokeOpacity = 1,
19
22
  strokeWidth = 2,
20
- vectorEffect = 'non-scaling-stroke'
23
+ gradient,
24
+ yAxisId,
25
+ d,
26
+ animate,
27
+ transition
21
28
  } = _ref,
22
29
  props = _objectWithoutPropertiesLoose(_ref, _excluded);
23
30
  const theme = useTheme();
24
- return /*#__PURE__*/_jsx(Path, _extends({
31
+ return /*#__PURE__*/_jsxs(Path, _extends({
32
+ animate: animate,
25
33
  clipOffset: strokeWidth,
34
+ d: d,
26
35
  fill: fill,
27
- stroke: stroke != null ? stroke : theme.color.bgLine,
28
- strokeDasharray: strokeDasharray,
29
- strokeLinecap: strokeLinecap,
30
- strokeLinejoin: strokeLinejoin,
36
+ stroke: stroke != null ? stroke : theme.color.fgPrimary,
37
+ strokeCap: strokeCap,
38
+ strokeJoin: strokeJoin,
31
39
  strokeOpacity: strokeOpacity,
32
40
  strokeWidth: strokeWidth,
33
- vectorEffect: vectorEffect
34
- }, props));
41
+ transition: transition
42
+ }, props, {
43
+ children: [/*#__PURE__*/_jsx(DashPathEffect, {
44
+ intervals: dashIntervals
45
+ }), gradient && /*#__PURE__*/_jsx(Gradient, {
46
+ gradient: gradient,
47
+ yAxisId: yAxisId
48
+ })]
49
+ }));
35
50
  });
@@ -1,70 +1,69 @@
1
- const _excluded = ["seriesId", "curve", "type", "areaType", "areaBaseline", "stroke", "showArea", "LineComponent", "AreaComponent", "opacity", "renderPoints"];
1
+ const _excluded = ["seriesId", "curve", "type", "areaType", "areaBaseline", "stroke", "strokeOpacity", "showArea", "LineComponent", "AreaComponent", "opacity", "points", "connectNulls", "transition", "gradient"];
2
2
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
3
3
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
4
- import React, { memo, useMemo } from 'react';
5
- import { useTheme } from '@coinbase/cds-mobile/hooks/useTheme';
4
+ import React, { memo, useEffect, useMemo } from 'react';
5
+ import { useSharedValue, withDelay, withTiming } from 'react-native-reanimated';
6
+ import { useTheme } from '@coinbase/cds-mobile';
7
+ import { Group } from '@shopify/react-native-skia';
6
8
  import { Area } from '../area/Area';
7
9
  import { useCartesianChartContext } from '../ChartProvider';
8
- import { Point } from '../Point';
9
- import { getLinePath } from '../utils';
10
+ import { Point } from '../point';
11
+ import { accessoryFadeTransitionDelay, accessoryFadeTransitionDuration, getLineData, getLinePath } from '../utils';
12
+ import { evaluateGradientAtValue, getGradientStops } from '../utils/gradient';
13
+ import { convertToSerializableScale } from '../utils/scale';
10
14
  import { DottedLine } from './DottedLine';
11
- import { GradientLine } from './GradientLine';
12
15
  import { SolidLine } from './SolidLine';
13
16
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
14
17
  export const Line = /*#__PURE__*/memo(_ref => {
15
18
  var _ref2;
16
19
  let {
17
20
  seriesId,
18
- curve = 'linear',
21
+ curve = 'bump',
19
22
  type = 'solid',
20
23
  areaType = 'gradient',
21
24
  areaBaseline,
22
- stroke: specifiedStroke,
23
- showArea = false,
25
+ stroke: strokeProp,
26
+ strokeOpacity,
27
+ showArea,
24
28
  LineComponent: SelectedLineComponent,
25
29
  AreaComponent,
26
30
  opacity = 1,
27
- renderPoints
31
+ points,
32
+ connectNulls,
33
+ transition,
34
+ gradient: gradientProp
28
35
  } = _ref,
29
36
  props = _objectWithoutPropertiesLoose(_ref, _excluded);
30
37
  const theme = useTheme();
31
38
  const {
39
+ animate,
32
40
  getSeries,
33
41
  getSeriesData,
34
42
  getXScale,
35
43
  getYScale,
36
44
  getXAxis
37
45
  } = useCartesianChartContext();
38
- const matchedSeries = getSeries(seriesId);
39
- const sourceData = useMemo(() => {
40
- return getSeriesData(seriesId) || null;
41
- }, [seriesId, getSeriesData]);
42
- const xAxis = getXAxis();
43
- const xScale = getXScale();
44
- const yScale = getYScale(matchedSeries == null ? void 0 : matchedSeries.yAxisId);
45
46
 
46
- // Convert sourceData to number array (line only supports numbers, not tuples)
47
- // If data is stacked (tuples), extract the actual values from [baseline, actualValue] format
48
- const chartData = useMemo(() => {
49
- if (!sourceData) return [];
47
+ // Animation state for delayed point rendering (matches web timing)
48
+ const pointsOpacity = useSharedValue(animate ? 0 : 1);
50
49
 
51
- // Check if this is stacked data (array of tuples)
52
- const firstNonNull = sourceData.find(d => d !== null);
53
- if (Array.isArray(firstNonNull)) {
54
- // Extract actual values from [baseline, value] tuples
55
- return sourceData.map(d => {
56
- if (d === null) return null;
57
- if (Array.isArray(d)) return d[1];
58
- return d;
59
- });
50
+ // Delay point appearance until after path enter animation completes
51
+ useEffect(() => {
52
+ if (animate) {
53
+ pointsOpacity.value = withDelay(accessoryFadeTransitionDelay, withTiming(1, {
54
+ duration: accessoryFadeTransitionDuration
55
+ }));
60
56
  }
57
+ }, [animate, pointsOpacity]);
58
+ const matchedSeries = useMemo(() => getSeries(seriesId), [getSeries, seriesId]);
59
+ const gradient = useMemo(() => gradientProp != null ? gradientProp : matchedSeries == null ? void 0 : matchedSeries.gradient, [gradientProp, matchedSeries == null ? void 0 : matchedSeries.gradient]);
60
+ const sourceData = useMemo(() => getSeriesData(seriesId), [getSeriesData, seriesId]);
61
+ const xAxis = useMemo(() => getXAxis(), [getXAxis]);
62
+ const xScale = useMemo(() => getXScale(), [getXScale]);
63
+ const yScale = useMemo(() => getYScale(matchedSeries == null ? void 0 : matchedSeries.yAxisId), [getYScale, matchedSeries == null ? void 0 : matchedSeries.yAxisId]);
61
64
 
62
- // Regular number array
63
- if (sourceData.every(d => typeof d === 'number' || d === null)) {
64
- return sourceData;
65
- }
66
- return [];
67
- }, [sourceData]);
65
+ // Convert sourceData to number array (line only supports numbers, not tuples)
66
+ const chartData = useMemo(() => getLineData(sourceData), [sourceData]);
68
67
  const path = useMemo(() => {
69
68
  if (!xScale || !yScale || chartData.length === 0) return '';
70
69
 
@@ -75,9 +74,10 @@ export const Line = /*#__PURE__*/memo(_ref => {
75
74
  xScale,
76
75
  yScale,
77
76
  curve,
78
- xData
77
+ xData,
78
+ connectNulls
79
79
  });
80
- }, [chartData, xScale, yScale, curve, xAxis == null ? void 0 : xAxis.data]);
80
+ }, [chartData, xScale, yScale, curve, xAxis == null ? void 0 : xAxis.data, connectNulls]);
81
81
  const LineComponent = useMemo(() => {
82
82
  if (SelectedLineComponent) {
83
83
  return SelectedLineComponent;
@@ -85,55 +85,94 @@ export const Line = /*#__PURE__*/memo(_ref => {
85
85
  switch (type) {
86
86
  case 'dotted':
87
87
  return DottedLine;
88
- case 'gradient':
89
- return GradientLine;
90
- case 'solid':
91
88
  default:
92
89
  return SolidLine;
93
90
  }
94
91
  }, [SelectedLineComponent, type]);
95
- const stroke = (_ref2 = specifiedStroke != null ? specifiedStroke : matchedSeries == null ? void 0 : matchedSeries.color) != null ? _ref2 : theme.color.fgPrimary;
92
+
93
+ // Get series color for stroke
94
+ const stroke = (_ref2 = strokeProp != null ? strokeProp : matchedSeries == null ? void 0 : matchedSeries.color) != null ? _ref2 : theme.color.fgPrimary;
96
95
  const xData = useMemo(() => {
97
96
  const data = xAxis == null ? void 0 : xAxis.data;
98
97
  return data && Array.isArray(data) && data.length > 0 && typeof data[0] === 'number' ? data : null;
99
98
  }, [xAxis == null ? void 0 : xAxis.data]);
100
- if (!xScale || !yScale) return;
99
+ const gradientConfig = useMemo(() => {
100
+ if (!gradient || !xScale || !yScale) return;
101
+ const gradientScale = gradient.axis === 'x' ? xScale : yScale;
102
+ const serializableScale = convertToSerializableScale(gradientScale);
103
+ if (!serializableScale) return;
104
+ const domain = {
105
+ min: serializableScale.domain[0],
106
+ max: serializableScale.domain[1]
107
+ };
108
+ const stops = getGradientStops(gradient.stops, domain);
109
+ return {
110
+ scale: serializableScale,
111
+ stops
112
+ };
113
+ }, [gradient, xScale, yScale]);
114
+ if (!xScale || !yScale || !path) return;
101
115
  return /*#__PURE__*/_jsxs(_Fragment, {
102
116
  children: [showArea && /*#__PURE__*/_jsx(Area, {
103
117
  AreaComponent: AreaComponent,
104
118
  baseline: areaBaseline,
119
+ connectNulls: connectNulls,
105
120
  curve: curve,
106
121
  fill: stroke,
107
122
  fillOpacity: opacity,
123
+ gradient: gradient,
108
124
  seriesId: seriesId,
125
+ transition: transition,
109
126
  type: areaType
110
127
  }), /*#__PURE__*/_jsx(LineComponent, _extends({
111
128
  d: path,
129
+ gradient: gradient,
112
130
  stroke: stroke,
113
- strokeOpacity: opacity
114
- }, props)), renderPoints && chartData.map((value, index) => {
115
- var _xScale, _yScale, _pointConfig$fill, _pointConfig$opacity;
116
- if (value === null) {
117
- return null;
118
- }
119
- const xValue = xData && xData[index] !== undefined ? xData[index] : index;
120
- const pointResult = renderPoints({
121
- dataY: value,
122
- dataX: xValue,
123
- x: (_xScale = xScale == null ? void 0 : xScale(xValue)) != null ? _xScale : 0,
124
- y: (_yScale = yScale == null ? void 0 : yScale(value)) != null ? _yScale : 0
125
- });
126
- if (pointResult === false || pointResult === null || pointResult === undefined) {
127
- return null;
128
- }
129
- const pointConfig = pointResult === true ? {} : pointResult;
130
- return /*#__PURE__*/_jsx(Point, _extends({
131
- dataX: xValue,
132
- dataY: value
133
- }, pointConfig, {
134
- fill: (_pointConfig$fill = pointConfig.fill) != null ? _pointConfig$fill : stroke,
135
- opacity: (_pointConfig$opacity = pointConfig.opacity) != null ? _pointConfig$opacity : opacity
136
- }), seriesId + "-renderpoint-" + index);
131
+ strokeOpacity: strokeOpacity != null ? strokeOpacity : opacity,
132
+ transition: transition,
133
+ yAxisId: matchedSeries == null ? void 0 : matchedSeries.yAxisId
134
+ }, props)), points && /*#__PURE__*/_jsx(Group, {
135
+ opacity: pointsOpacity,
136
+ children: chartData.map((value, index) => {
137
+ if (value === null) return;
138
+ const xValue = xData && xData[index] !== undefined ? xData[index] : index;
139
+ let pointFill = stroke;
140
+ if (gradientConfig && gradient) {
141
+ var _gradient$axis;
142
+ // Use the appropriate data value based on gradient axis
143
+ const axis = (_gradient$axis = gradient.axis) != null ? _gradient$axis : 'y';
144
+ const dataValue = axis === 'x' ? xValue : value;
145
+ const evaluatedColor = evaluateGradientAtValue(gradientConfig.stops, dataValue, gradientConfig.scale);
146
+ if (evaluatedColor) {
147
+ // Apply gradient color to fill if not explicitly set
148
+ pointFill = evaluatedColor;
149
+ }
150
+ }
151
+
152
+ // Build defaults that would be passed to Point
153
+ const defaults = {
154
+ dataX: xValue,
155
+ dataY: value,
156
+ fill: pointFill,
157
+ yAxisId: matchedSeries == null ? void 0 : matchedSeries.yAxisId,
158
+ opacity
159
+ };
160
+
161
+ // If points is true, render with defaults
162
+ if (points === true) {
163
+ return /*#__PURE__*/_jsx(Point, _extends({
164
+ transition: transition
165
+ }, defaults), seriesId + "-" + xValue);
166
+ }
167
+
168
+ // Call the function with defaults
169
+ const result = points(defaults);
170
+ if (!result) return;
171
+ const pointConfig = result === true ? {} : result;
172
+ return /*#__PURE__*/_jsx(Point, _extends({
173
+ transition: transition
174
+ }, defaults, pointConfig), seriesId + "-" + xValue);
175
+ })
137
176
  })]
138
177
  });
139
178
  });
@@ -1,4 +1,4 @@
1
- const _excluded = ["series", "showArea", "areaType", "type", "LineComponent", "AreaComponent", "curve", "renderPoints", "strokeWidth", "showXAxis", "showYAxis", "xAxis", "yAxis", "inset", "children"],
1
+ const _excluded = ["series", "showArea", "areaType", "type", "LineComponent", "AreaComponent", "curve", "points", "strokeWidth", "strokeOpacity", "connectNulls", "transition", "opacity", "showXAxis", "showYAxis", "xAxis", "yAxis", "inset", "children"],
2
2
  _excluded2 = ["scaleType", "data", "categoryPadding", "domain", "domainLimit", "range"],
3
3
  _excluded3 = ["scaleType", "data", "categoryPadding", "domain", "domainLimit", "range", "id"],
4
4
  _excluded4 = ["id", "data", "label", "color", "yAxisId"];
@@ -20,23 +20,21 @@ export const LineChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =
20
20
  LineComponent,
21
21
  AreaComponent,
22
22
  curve,
23
- renderPoints,
23
+ points,
24
24
  strokeWidth,
25
+ strokeOpacity,
26
+ connectNulls,
27
+ transition,
28
+ opacity,
25
29
  showXAxis,
26
30
  showYAxis,
27
31
  xAxis,
28
32
  yAxis,
29
- inset: userInset,
33
+ inset,
30
34
  children
31
35
  } = _ref,
32
36
  chartProps = _objectWithoutPropertiesLoose(_ref, _excluded);
33
- const calculatedInset = useMemo(() => getChartInset(userInset, defaultChartInset), [userInset]);
34
-
35
- // Check if we have valid data across all series
36
- const hasData = useMemo(() => {
37
- if (!series || series.length === 0) return false;
38
- return series.some(s => s.data && s.data.length > 0);
39
- }, [series]);
37
+ const calculatedInset = useMemo(() => getChartInset(inset, defaultChartInset), [inset]);
40
38
 
41
39
  // Convert LineSeries to Series for Chart context
42
40
  const chartSeries = useMemo(() => {
@@ -44,7 +42,10 @@ export const LineChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =
44
42
  id: s.id,
45
43
  data: s.data,
46
44
  label: s.label,
47
- color: s.color
45
+ color: s.color,
46
+ yAxisId: s.yAxisId,
47
+ stackId: s.stackId,
48
+ gradient: s.gradient
48
49
  }));
49
50
  }, [series]);
50
51
 
@@ -94,7 +95,8 @@ export const LineChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =
94
95
  yAxis: yAxisConfig,
95
96
  children: [showXAxis && /*#__PURE__*/_jsx(XAxis, _extends({}, xAxisVisualProps)), showYAxis && /*#__PURE__*/_jsx(YAxis, _extends({
96
97
  axisId: yAxisId
97
- }, yAxisVisualProps)), hasData && (series == null ? void 0 : series.map(_ref4 => {
98
+ }, yAxisVisualProps)), series == null ? void 0 : series.map(_ref4 => {
99
+ var _linePropsFromSeries$;
98
100
  let {
99
101
  id
100
102
  } = _ref4,
@@ -103,13 +105,17 @@ export const LineChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =
103
105
  AreaComponent: AreaComponent,
104
106
  LineComponent: LineComponent,
105
107
  areaType: areaType,
108
+ connectNulls: connectNulls,
106
109
  curve: curve,
107
- renderPoints: renderPoints,
110
+ opacity: opacity,
111
+ points: points,
108
112
  seriesId: id,
109
113
  showArea: showArea,
114
+ strokeOpacity: strokeOpacity,
110
115
  strokeWidth: strokeWidth,
116
+ transition: (_linePropsFromSeries$ = linePropsFromSeries.transition) != null ? _linePropsFromSeries$ : transition,
111
117
  type: type
112
118
  }, linePropsFromSeries), id);
113
- })), children]
119
+ }), children]
114
120
  }));
115
121
  }));