@coinbase/cds-mobile-visualization 3.4.0-beta.18 → 3.4.0-beta.19

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 (68) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dts/chart/Path.d.ts +35 -13
  3. package/dts/chart/Path.d.ts.map +1 -1
  4. package/dts/chart/area/Area.d.ts +7 -11
  5. package/dts/chart/area/Area.d.ts.map +1 -1
  6. package/dts/chart/area/AreaChart.d.ts +1 -1
  7. package/dts/chart/area/DottedArea.d.ts.map +1 -1
  8. package/dts/chart/area/GradientArea.d.ts.map +1 -1
  9. package/dts/chart/area/SolidArea.d.ts.map +1 -1
  10. package/dts/chart/bar/Bar.d.ts +32 -2
  11. package/dts/chart/bar/Bar.d.ts.map +1 -1
  12. package/dts/chart/bar/BarChart.d.ts +2 -0
  13. package/dts/chart/bar/BarChart.d.ts.map +1 -1
  14. package/dts/chart/bar/BarPlot.d.ts +2 -1
  15. package/dts/chart/bar/BarPlot.d.ts.map +1 -1
  16. package/dts/chart/bar/BarStack.d.ts +5 -10
  17. package/dts/chart/bar/BarStack.d.ts.map +1 -1
  18. package/dts/chart/bar/BarStackGroup.d.ts +1 -0
  19. package/dts/chart/bar/BarStackGroup.d.ts.map +1 -1
  20. package/dts/chart/bar/DefaultBar.d.ts.map +1 -1
  21. package/dts/chart/bar/DefaultBarStack.d.ts.map +1 -1
  22. package/dts/chart/line/DottedLine.d.ts.map +1 -1
  23. package/dts/chart/line/Line.d.ts +4 -9
  24. package/dts/chart/line/Line.d.ts.map +1 -1
  25. package/dts/chart/line/LineChart.d.ts +1 -1
  26. package/dts/chart/line/SolidLine.d.ts.map +1 -1
  27. package/dts/chart/point/Point.d.ts +18 -2
  28. package/dts/chart/point/Point.d.ts.map +1 -1
  29. package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts +9 -1
  30. package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts.map +1 -1
  31. package/dts/chart/scrubber/Scrubber.d.ts +45 -24
  32. package/dts/chart/scrubber/Scrubber.d.ts.map +1 -1
  33. package/dts/chart/scrubber/ScrubberBeaconLabelGroup.d.ts +9 -1
  34. package/dts/chart/scrubber/ScrubberBeaconLabelGroup.d.ts.map +1 -1
  35. package/dts/chart/utils/bar.d.ts +34 -0
  36. package/dts/chart/utils/bar.d.ts.map +1 -1
  37. package/dts/chart/utils/path.d.ts +6 -0
  38. package/dts/chart/utils/path.d.ts.map +1 -1
  39. package/dts/chart/utils/transition.d.ts +59 -21
  40. package/dts/chart/utils/transition.d.ts.map +1 -1
  41. package/esm/chart/Path.js +16 -14
  42. package/esm/chart/__stories__/CartesianChart.stories.js +3 -77
  43. package/esm/chart/__stories__/ChartTransitions.stories.js +629 -0
  44. package/esm/chart/area/Area.js +2 -0
  45. package/esm/chart/area/DottedArea.js +7 -3
  46. package/esm/chart/area/GradientArea.js +4 -2
  47. package/esm/chart/area/SolidArea.js +4 -2
  48. package/esm/chart/bar/Bar.js +2 -0
  49. package/esm/chart/bar/BarChart.js +4 -2
  50. package/esm/chart/bar/BarPlot.js +2 -0
  51. package/esm/chart/bar/BarStack.js +3 -0
  52. package/esm/chart/bar/DefaultBar.js +15 -15
  53. package/esm/chart/bar/DefaultBarStack.js +14 -3
  54. package/esm/chart/bar/__stories__/BarChart.stories.js +448 -52
  55. package/esm/chart/line/DottedLine.js +4 -2
  56. package/esm/chart/line/Line.js +6 -18
  57. package/esm/chart/line/SolidLine.js +4 -2
  58. package/esm/chart/line/__stories__/LineChart.stories.js +17 -226
  59. package/esm/chart/line/__stories__/ReferenceLine.stories.js +95 -1
  60. package/esm/chart/point/Point.js +33 -35
  61. package/esm/chart/scrubber/DefaultScrubberBeacon.js +2 -5
  62. package/esm/chart/scrubber/Scrubber.js +10 -8
  63. package/esm/chart/scrubber/ScrubberBeaconLabelGroup.js +29 -7
  64. package/esm/chart/utils/bar.js +43 -0
  65. package/esm/chart/utils/path.js +8 -0
  66. package/esm/chart/utils/transition.js +96 -61
  67. package/package.json +5 -5
  68. package/esm/chart/__stories__/Chart.stories.js +0 -77
@@ -1,9 +1,10 @@
1
1
  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); }
2
2
  import { memo, useCallback, useMemo, useState } from 'react';
3
- import { useDerivedValue } from 'react-native-reanimated';
3
+ import { useAnimatedReaction, useDerivedValue, useSharedValue } from 'react-native-reanimated';
4
4
  import { useCartesianChartContext } from '../ChartProvider';
5
- import { applySerializableScale, useScrubberContext } from '../utils';
5
+ import { applySerializableScale, unwrapAnimatedValue, useScrubberContext } from '../utils';
6
6
  import { calculateLabelYPositions, getLabelPosition } from '../utils/scrubber';
7
+ import { buildTransition, defaultTransition, getTransition } from '../utils/transition';
7
8
  import { DefaultScrubberBeaconLabel } from './DefaultScrubberBeaconLabel';
8
9
  import { jsx as _jsx } from "react/jsx-runtime";
9
10
  const PositionedLabel = /*#__PURE__*/memo(_ref => {
@@ -11,6 +12,8 @@ const PositionedLabel = /*#__PURE__*/memo(_ref => {
11
12
  index,
12
13
  positions,
13
14
  position,
15
+ isIdle,
16
+ updateTransition,
14
17
  label,
15
18
  color,
16
19
  seriesId,
@@ -24,10 +27,21 @@ const PositionedLabel = /*#__PURE__*/memo(_ref => {
24
27
  var _positions$value$inde, _positions$value$inde2;
25
28
  return (_positions$value$inde = (_positions$value$inde2 = positions.value[index]) == null ? void 0 : _positions$value$inde2.x) != null ? _positions$value$inde : 0;
26
29
  }, [positions, index]);
27
- const y = useDerivedValue(() => {
30
+ const targetY = useDerivedValue(() => {
28
31
  var _positions$value$inde3, _positions$value$inde4;
29
32
  return (_positions$value$inde3 = (_positions$value$inde4 = positions.value[index]) == null ? void 0 : _positions$value$inde4.y) != null ? _positions$value$inde3 : 0;
30
33
  }, [positions, index]);
34
+ const animatedY = useSharedValue(0);
35
+ useAnimatedReaction(() => ({
36
+ y: targetY.value,
37
+ idle: unwrapAnimatedValue(isIdle)
38
+ }), (current, previous) => {
39
+ if (previous === null || !previous.idle || !current.idle) {
40
+ animatedY.value = current.y;
41
+ } else {
42
+ animatedY.value = buildTransition(current.y, updateTransition);
43
+ }
44
+ }, [updateTransition]);
31
45
  const dx = useDerivedValue(() => {
32
46
  return position.value === 'right' ? labelHorizontalOffset : -labelHorizontalOffset;
33
47
  }, [position, labelHorizontalOffset]);
@@ -42,7 +56,7 @@ const PositionedLabel = /*#__PURE__*/memo(_ref => {
42
56
  opacity: opacity,
43
57
  seriesId: seriesId,
44
58
  x: x,
45
- y: y
59
+ y: animatedY
46
60
  });
47
61
  });
48
62
  export const ScrubberBeaconLabelGroup = /*#__PURE__*/memo(_ref2 => {
@@ -52,7 +66,8 @@ export const ScrubberBeaconLabelGroup = /*#__PURE__*/memo(_ref2 => {
52
66
  labelHorizontalOffset = 16,
53
67
  labelFont,
54
68
  labelPreferredSide = 'right',
55
- BeaconLabelComponent = DefaultScrubberBeaconLabel
69
+ BeaconLabelComponent = DefaultScrubberBeaconLabel,
70
+ transitions
56
71
  } = _ref2;
57
72
  const {
58
73
  getSeries,
@@ -61,11 +76,16 @@ export const ScrubberBeaconLabelGroup = /*#__PURE__*/memo(_ref2 => {
61
76
  getYSerializableScale,
62
77
  getXAxis,
63
78
  drawingArea,
64
- dataLength
79
+ dataLength,
80
+ animate
65
81
  } = useCartesianChartContext();
66
82
  const {
67
83
  scrubberPosition
68
84
  } = useScrubberContext();
85
+ const isIdle = useDerivedValue(() => {
86
+ return scrubberPosition.value === undefined;
87
+ }, [scrubberPosition]);
88
+ const updateTransition = useMemo(() => getTransition(transitions == null ? void 0 : transitions.update, animate, defaultTransition), [transitions == null ? void 0 : transitions.update, animate]);
69
89
  const [labelDimensions, setLabelDimensions] = useState({});
70
90
  const handleDimensionsChange = useCallback((id, dimensions) => {
71
91
  setLabelDimensions(prev => {
@@ -174,13 +194,15 @@ export const ScrubberBeaconLabelGroup = /*#__PURE__*/memo(_ref2 => {
174
194
  BeaconLabelComponent: BeaconLabelComponent,
175
195
  color: labelInfo.color,
176
196
  index: index,
197
+ isIdle: isIdle,
177
198
  label: labelInfo.label,
178
199
  labelFont: labelFont,
179
200
  labelHorizontalOffset: labelHorizontalOffset,
180
201
  onDimensionsChange: handleDimensionsChange,
181
202
  position: currentPosition,
182
203
  positions: allLabelPositions,
183
- seriesId: info.seriesId
204
+ seriesId: info.seriesId,
205
+ updateTransition: updateTransition
184
206
  }, info.seriesId);
185
207
  });
186
208
  });
@@ -1,3 +1,46 @@
1
+ const _excluded = ["staggerDelay"];
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 { defaultTransition } from './transition';
5
+
6
+ /**
7
+ * A bar-specific transition that extends Transition with stagger support.
8
+ * When `staggerDelay` is provided, bars will animate with increasing delays
9
+ * based on their horizontal position (leftmost starts first, rightmost last).
10
+ *
11
+ * @example
12
+ * // Bars stagger in from left to right over 250ms, each animating for 750ms
13
+ * { type: 'timing', duration: 750, staggerDelay: 250 }
14
+ */
15
+
16
+ /**
17
+ * Strips `staggerDelay` from a transition and computes a positional delay.
18
+ *
19
+ * @param transition - The transition config (may include staggerDelay)
20
+ * @param normalizedX - The bar's normalized x position (0 = left edge, 1 = right edge)
21
+ * @returns A standard Transition with computed delay
22
+ */
23
+ export const withStaggerDelayTransition = (transition, normalizedX) => {
24
+ var _baseTransition$delay;
25
+ const {
26
+ staggerDelay
27
+ } = transition,
28
+ baseTransition = _objectWithoutPropertiesLoose(transition, _excluded);
29
+ if (!staggerDelay) return transition;
30
+ return _extends({}, baseTransition, {
31
+ delay: ((_baseTransition$delay = baseTransition == null ? void 0 : baseTransition.delay) != null ? _baseTransition$delay : 0) + normalizedX * staggerDelay
32
+ });
33
+ };
34
+
35
+ /**
36
+ * Default bar enter transition. Uses the default spring with a stagger delay
37
+ * so bars spring into place from left to right.
38
+ * `{ type: 'spring', stiffness: 900, damping: 120, staggerDelay: 250 }`
39
+ */
40
+ export const defaultBarEnterTransition = _extends({}, defaultTransition, {
41
+ staggerDelay: 250
42
+ });
43
+
1
44
  /**
2
45
  * Calculates the size adjustment needed for bars when accounting for gaps between them.
3
46
  * This function helps determine how much to reduce each bar's width to accommodate
@@ -1,6 +1,14 @@
1
1
  import { area as d3Area, curveBumpX, curveCatmullRom, curveLinear, curveLinearClosed, curveMonotoneX, curveNatural, curveStep, curveStepAfter, curveStepBefore, line as d3Line } from 'd3-shape';
2
2
  import { projectPoint, projectPoints } from './point';
3
3
  import { isCategoricalScale } from './scale';
4
+ /**
5
+ * Default enter transition for path-based components (Line, Area).
6
+ * `{ type: 'timing', duration: 500 }`
7
+ */
8
+ export const defaultPathEnterTransition = {
9
+ type: 'timing',
10
+ duration: 500
11
+ };
4
12
  /**
5
13
  * Get the d3 curve function for a path.
6
14
  * See https://d3js.org/d3-shape/curve
@@ -1,5 +1,7 @@
1
+ const _excluded = ["delay"];
2
+ 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; }
1
3
  import { useEffect, useMemo, useRef } from 'react';
2
- import { useAnimatedReaction, useSharedValue, withSpring, withTiming } from 'react-native-reanimated';
4
+ import { useAnimatedReaction, useSharedValue, withDelay, withSpring, withTiming } from 'react-native-reanimated';
3
5
  import { notifyChange, Skia } from '@shopify/react-native-skia';
4
6
  import { interpolatePath } from 'd3-interpolate-path';
5
7
 
@@ -18,7 +20,8 @@ import { interpolatePath } from 'd3-interpolate-path';
18
20
  */
19
21
 
20
22
  /**
21
- * Default transition configuration used across all chart components.
23
+ * Default update transition used across all chart components.
24
+ * `{ type: 'spring', stiffness: 900, damping: 120 }`
22
25
  */
23
26
  export const defaultTransition = {
24
27
  type: 'spring',
@@ -26,6 +29,15 @@ export const defaultTransition = {
26
29
  damping: 120
27
30
  };
28
31
 
32
+ /**
33
+ * Instant transition that completes immediately with no animation.
34
+ * Used when a transition is set to `null`.
35
+ */
36
+ export const instantTransition = {
37
+ type: 'timing',
38
+ duration: 0
39
+ };
40
+
29
41
  /**
30
42
  * Duration in milliseconds for accessory elements to fade in.
31
43
  */
@@ -37,41 +49,23 @@ export const accessoryFadeTransitionDuration = 150;
37
49
  export const accessoryFadeTransitionDelay = 350;
38
50
 
39
51
  /**
40
- * Custom hook that uses d3-interpolate-path for more robust path interpolation.
41
- * then use Skia's native interpolation in the worklet.
42
- *
43
- * @param progress - Shared value between 0 and 1
44
- * @param fromPath - Starting path as SVG string
45
- * @param toPath - Ending path as SVG string
46
- * @returns Interpolated SkPath as a shared value
52
+ * Default enter transition for accessory elements (Point, Scrubber beacons).
53
+ * `{ type: 'timing', duration: 150, delay: 350 }`
47
54
  */
48
- export const useD3PathInterpolation = (progress, fromPath, toPath) => {
49
- // Pre-compute intermediate paths on JS thread using d3-interpolate-path
50
- const {
51
- fromSkiaPath,
52
- i0,
53
- i1,
54
- toSkiaPath
55
- } = useMemo(() => {
56
- var _Skia$Path$MakeFromSV, _Skia$Path$MakeFromSV2, _Skia$Path$MakeFromSV3, _Skia$Path$MakeFromSV4;
57
- const pathInterpolator = interpolatePath(fromPath, toPath);
58
- const d = 1e-3;
59
- return {
60
- fromSkiaPath: (_Skia$Path$MakeFromSV = Skia.Path.MakeFromSVGString(fromPath)) != null ? _Skia$Path$MakeFromSV : Skia.Path.Make(),
61
- i0: (_Skia$Path$MakeFromSV2 = Skia.Path.MakeFromSVGString(pathInterpolator(d))) != null ? _Skia$Path$MakeFromSV2 : Skia.Path.Make(),
62
- i1: (_Skia$Path$MakeFromSV3 = Skia.Path.MakeFromSVGString(pathInterpolator(1 - d))) != null ? _Skia$Path$MakeFromSV3 : Skia.Path.Make(),
63
- toSkiaPath: (_Skia$Path$MakeFromSV4 = Skia.Path.MakeFromSVGString(toPath)) != null ? _Skia$Path$MakeFromSV4 : Skia.Path.Make()
64
- };
65
- }, [fromPath, toPath]);
66
- const result = useSharedValue(fromSkiaPath);
67
- useAnimatedReaction(() => progress.value, t => {
68
- 'worklet';
55
+ export const defaultAccessoryEnterTransition = {
56
+ type: 'timing',
57
+ duration: accessoryFadeTransitionDuration,
58
+ delay: accessoryFadeTransitionDelay
59
+ };
69
60
 
70
- var _i1$interpolate;
71
- result.value = (_i1$interpolate = i1.interpolate(i0, t)) != null ? _i1$interpolate : toSkiaPath;
72
- notifyChange(result);
73
- }, [fromSkiaPath, i0, i1, toSkiaPath]);
74
- return result;
61
+ /**
62
+ * Resolves a transition value based on the animation state and a default.
63
+ * @note Passing in null will disable an animation.
64
+ * @note Passing in undefined will use the provided default.
65
+ */
66
+ export const getTransition = (value, animate, defaultValue) => {
67
+ if (!animate || value === null) return instantTransition;
68
+ return value != null ? value : defaultValue;
75
69
  };
76
70
 
77
71
  // Interpolator and useInterpolator are brought over from non exported code in @shopify/react-native-skia
@@ -114,21 +108,32 @@ export const useInterpolator = (factory, value, interpolator, input, output, opt
114
108
  export const buildTransition = (targetValue, transition) => {
115
109
  'worklet';
116
110
 
117
- switch (transition.type) {
111
+ const {
112
+ delay: delayMs
113
+ } = transition,
114
+ config = _objectWithoutPropertiesLoose(transition, _excluded);
115
+ let animation;
116
+ switch (config.type) {
118
117
  case 'timing':
119
118
  {
120
- return withTiming(targetValue, transition);
119
+ animation = withTiming(targetValue, config);
120
+ break;
121
121
  }
122
122
  case 'spring':
123
123
  {
124
- return withSpring(targetValue, transition);
124
+ animation = withSpring(targetValue, config);
125
+ break;
125
126
  }
126
127
  default:
127
128
  {
128
- // Fallback to default transition config
129
- return withSpring(targetValue, defaultTransition);
129
+ animation = withSpring(targetValue, defaultTransition);
130
+ break;
130
131
  }
131
132
  }
133
+ if (delayMs && delayMs > 0) {
134
+ return withDelay(delayMs, animation);
135
+ }
136
+ return animation;
132
137
  };
133
138
 
134
139
  /**
@@ -136,15 +141,16 @@ export const buildTransition = (targetValue, transition) => {
136
141
  *
137
142
  * @param currentPath - Current target path to animate to
138
143
  * @param initialPath - Initial path for enter animation. When provided, the first animation will go from initialPath to currentPath.
139
- * @param transition - Transition configuration
144
+ * @param transitions - Transition configuration for enter and update animations
140
145
  * @returns Animated SkPath as a shared value
141
146
  *
142
147
  * @example
143
148
  * // Simple path transition
144
149
  * const path = usePathTransition({
145
150
  * currentPath: d ?? '',
146
- * animate: shouldAnimate,
147
- * transition: { type: 'timing', duration: 3000 }
151
+ * transitions: {
152
+ * update: { type: 'timing', duration: 3000 },
153
+ * },
148
154
  * });
149
155
  *
150
156
  * @example
@@ -152,34 +158,63 @@ export const buildTransition = (targetValue, transition) => {
152
158
  * const path = usePathTransition({
153
159
  * currentPath: targetPath,
154
160
  * initialPath: baselinePath,
155
- * animate: true,
156
- * transition: { type: 'timing', duration: 300 }
161
+ * transitions: {
162
+ * enter: { type: 'tween', duration: 500 },
163
+ * update: { type: 'spring', stiffness: 900, damping: 120 },
164
+ * },
157
165
  * });
158
166
  */
159
167
  export const usePathTransition = _ref => {
168
+ var _transitions$update, _Skia$Path$MakeFromSV;
160
169
  let {
161
170
  currentPath,
162
171
  initialPath,
172
+ transitions,
163
173
  transition = defaultTransition
164
174
  } = _ref;
165
- // Track the previous path - updated in useEffect AFTER render,
166
- // so during render it naturally holds the "from" path value
167
- const previousPathRef = useRef(initialPath != null ? initialPath : currentPath);
175
+ const updateTransition = (_transitions$update = transitions == null ? void 0 : transitions.update) != null ? _transitions$update : transition;
176
+ const enterTransition = transitions == null ? void 0 : transitions.enter;
177
+ const targetPathRef = useRef(initialPath != null ? initialPath : currentPath);
178
+ const isFirstAnimation = useRef(!!initialPath);
179
+ const interpolatorRef = useRef(null);
168
180
  const progress = useSharedValue(0);
169
-
170
- // During render: previousPathRef still has old value, currentPath is new
171
- const fromPath = previousPathRef.current;
172
- const toPath = currentPath;
181
+ const initialSkiaPath = (_Skia$Path$MakeFromSV = Skia.Path.MakeFromSVGString(initialPath != null ? initialPath : currentPath)) != null ? _Skia$Path$MakeFromSV : Skia.Path.Make();
182
+ const normalizedStartShared = useSharedValue(initialSkiaPath);
183
+ const normalizedEndShared = useSharedValue(initialSkiaPath);
184
+ const fallbackPathShared = useSharedValue(initialSkiaPath);
185
+ const result = useSharedValue(initialSkiaPath);
173
186
  useEffect(() => {
174
- const shouldAnimate = previousPathRef.current !== currentPath;
175
- if (shouldAnimate) {
176
- // Update ref for next path change (happens after this render)
177
- previousPathRef.current = currentPath;
178
-
179
- // Animate from old path to new path
187
+ if (targetPathRef.current !== currentPath) {
188
+ var _Skia$Path$MakeFromSV2, _Skia$Path$MakeFromSV3, _Skia$Path$MakeFromSV4;
189
+ let fromPath = targetPathRef.current;
190
+ if (interpolatorRef.current) {
191
+ const p = Math.min(Math.max(progress.value, 0), 1);
192
+ fromPath = interpolatorRef.current(p);
193
+ }
194
+ targetPathRef.current = currentPath;
195
+ const pathInterpolator = interpolatePath(fromPath, currentPath);
196
+ interpolatorRef.current = pathInterpolator;
197
+ normalizedStartShared.value = (_Skia$Path$MakeFromSV2 = Skia.Path.MakeFromSVGString(pathInterpolator(0))) != null ? _Skia$Path$MakeFromSV2 : Skia.Path.Make();
198
+ normalizedEndShared.value = (_Skia$Path$MakeFromSV3 = Skia.Path.MakeFromSVGString(pathInterpolator(1))) != null ? _Skia$Path$MakeFromSV3 : Skia.Path.Make();
199
+ fallbackPathShared.value = (_Skia$Path$MakeFromSV4 = Skia.Path.MakeFromSVGString(currentPath)) != null ? _Skia$Path$MakeFromSV4 : Skia.Path.Make();
200
+ const activeTransition = isFirstAnimation.current && enterTransition !== undefined ? enterTransition : updateTransition;
201
+ isFirstAnimation.current = false;
180
202
  progress.value = 0;
181
- progress.value = buildTransition(1, transition);
203
+ progress.value = buildTransition(1, activeTransition);
182
204
  }
183
- }, [currentPath, transition, progress]);
184
- return useD3PathInterpolation(progress, fromPath, toPath);
205
+ }, [currentPath, updateTransition, enterTransition, progress, normalizedStartShared, normalizedEndShared, fallbackPathShared]);
206
+ useAnimatedReaction(() => ({
207
+ p: progress.value,
208
+ to: fallbackPathShared.value
209
+ }), _ref2 => {
210
+ 'worklet';
211
+
212
+ var _normalizedEndShared$;
213
+ let {
214
+ p
215
+ } = _ref2;
216
+ result.value = (_normalizedEndShared$ = normalizedEndShared.value.interpolate(normalizedStartShared.value, p)) != null ? _normalizedEndShared$ : fallbackPathShared.value;
217
+ notifyChange(result);
218
+ }, []);
219
+ return result;
185
220
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coinbase/cds-mobile-visualization",
3
- "version": "3.4.0-beta.18",
3
+ "version": "3.4.0-beta.19",
4
4
  "description": "Coinbase Design System - Mobile Visualization Native",
5
5
  "repository": {
6
6
  "type": "git",
@@ -36,9 +36,9 @@
36
36
  "CHANGELOG"
37
37
  ],
38
38
  "peerDependencies": {
39
- "@coinbase/cds-common": "^8.43.0",
39
+ "@coinbase/cds-common": "^8.48.0",
40
40
  "@coinbase/cds-lottie-files": "^3.3.4",
41
- "@coinbase/cds-mobile": "^8.43.0",
41
+ "@coinbase/cds-mobile": "^8.48.0",
42
42
  "@coinbase/cds-utils": "^2.3.5",
43
43
  "@shopify/react-native-skia": "^1.12.4 || ^2.0.0",
44
44
  "react": "^18.3.1",
@@ -57,9 +57,9 @@
57
57
  "@babel/preset-env": "^7.28.0",
58
58
  "@babel/preset-react": "^7.27.1",
59
59
  "@babel/preset-typescript": "^7.27.1",
60
- "@coinbase/cds-common": "^8.43.0",
60
+ "@coinbase/cds-common": "^8.48.0",
61
61
  "@coinbase/cds-lottie-files": "^3.3.4",
62
- "@coinbase/cds-mobile": "^8.43.0",
62
+ "@coinbase/cds-mobile": "^8.48.0",
63
63
  "@coinbase/cds-utils": "^2.3.5",
64
64
  "@shopify/react-native-skia": "1.12.4",
65
65
  "@types/react": "^18.3.12",
@@ -1,77 +0,0 @@
1
- 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); }
2
- import { Example, ExampleScreen } from '@coinbase/cds-mobile/examples/ExampleScreen';
3
- import { CartesianChart, DottedArea, Line, LineChart, SolidLine } from '../';
4
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
5
- const defaultChartHeight = 250;
6
- const BasicLineChart = () => {
7
- const chartData = [65, 78, 45, 88, 92, 73, 69];
8
- return /*#__PURE__*/_jsx(LineChart, {
9
- showYAxis: true,
10
- height: defaultChartHeight,
11
- series: [{
12
- id: 'monthly-growth',
13
- data: chartData,
14
- label: 'Monthly Growth',
15
- color: '#2ca02c'
16
- }],
17
- yAxis: {
18
- requestedTickCount: 2,
19
- tickLabelFormatter: value => "$" + value,
20
- showGrid: true
21
- }
22
- });
23
- };
24
- const LineStyles = () => {
25
- const topChartData = [15, 28, 32, 44, 46, 36, 40, 45, 48, 38];
26
- const upperMiddleChartData = [12, 23, 21, 29, 34, 28, 31, 38, 42, 35];
27
- const lowerMiddleChartData = [8, 15, 14, 25, 20, 18, 22, 28, 24, 30];
28
- const bottomChartData = [4, 8, 11, 15, 16, 14, 16, 10, 12, 14];
29
- return /*#__PURE__*/_jsxs(CartesianChart, {
30
- height: defaultChartHeight,
31
- series: [{
32
- id: 'top',
33
- data: topChartData
34
- }, {
35
- id: 'upperMiddle',
36
- data: upperMiddleChartData,
37
- color: '#ef4444'
38
- }, {
39
- id: 'lowerMiddle',
40
- data: lowerMiddleChartData,
41
- color: '#f59e0b'
42
- }, {
43
- id: 'bottom',
44
- data: bottomChartData,
45
- color: '#800080'
46
- }],
47
- children: [/*#__PURE__*/_jsx(Line, {
48
- seriesId: "top"
49
- }), /*#__PURE__*/_jsx(Line, {
50
- seriesId: "upperMiddle",
51
- type: "dotted"
52
- }), /*#__PURE__*/_jsx(Line, {
53
- LineComponent: props => /*#__PURE__*/_jsx(SolidLine, _extends({}, props, {
54
- strokeWidth: 4
55
- })),
56
- curve: "natural",
57
- seriesId: "lowerMiddle"
58
- }), /*#__PURE__*/_jsx(Line, {
59
- showArea: true,
60
- AreaComponent: DottedArea,
61
- curve: "step",
62
- seriesId: "bottom"
63
- })]
64
- });
65
- };
66
- const ChartStories = () => {
67
- return /*#__PURE__*/_jsxs(ExampleScreen, {
68
- children: [/*#__PURE__*/_jsx(Example, {
69
- title: "Basic Line Chart",
70
- children: /*#__PURE__*/_jsx(BasicLineChart, {})
71
- }), /*#__PURE__*/_jsx(Example, {
72
- title: "Line Styles",
73
- children: /*#__PURE__*/_jsx(LineStyles, {})
74
- })]
75
- });
76
- };
77
- export default ChartStories;