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

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/CHANGELOG.md CHANGED
@@ -8,6 +8,24 @@ All notable changes to this project will be documented in this file.
8
8
 
9
9
  <!-- template-start -->
10
10
 
11
+ ## 3.4.0-beta.13 (1/20/2026 PST)
12
+
13
+ #### 🚀 Updates
14
+
15
+ - Feat: support styling default scrubber beacon. [[#315](https://github.com/coinbase/cds/pull/315)]
16
+ - Fix: idlePulse works on mobile even when Chart animation is off, matching web. [[#315](https://github.com/coinbase/cds/pull/315)]
17
+
18
+ #### 📘 Misc
19
+
20
+ - Internal: code connect file lint fixes. [[#311](https://github.com/coinbase/cds/pull/311)]
21
+ - Internal: update figma code connect config and some mapping files. [[#304](https://github.com/coinbase/cds/pull/304)]
22
+
23
+ ## 3.4.0-beta.12 (1/8/2026 PST)
24
+
25
+ #### 🐞 Fixes
26
+
27
+ - Fix pulse with spread operator broken on new react-native architecture. [[#296](https://github.com/coinbase/cds/pull/296)]
28
+
11
29
  ## 3.4.0-beta.11 (1/7/2026 PST)
12
30
 
13
31
  #### 🐞 Fixes
@@ -1,8 +1,30 @@
1
1
  import type { ScrubberBeaconProps, ScrubberBeaconRef } from './Scrubber';
2
- export type DefaultScrubberBeaconProps = ScrubberBeaconProps;
2
+ export type DefaultScrubberBeaconProps = ScrubberBeaconProps & {
3
+ /**
4
+ * Radius of the beacon circle.
5
+ * @default 5
6
+ */
7
+ radius?: number;
8
+ /**
9
+ * Stroke width of the beacon circle.
10
+ * @default 2
11
+ */
12
+ strokeWidth?: number;
13
+ };
3
14
  export declare const DefaultScrubberBeacon: import('react').MemoExoticComponent<
4
15
  import('react').ForwardRefExoticComponent<
5
- ScrubberBeaconProps & import('react').RefAttributes<ScrubberBeaconRef>
16
+ ScrubberBeaconProps & {
17
+ /**
18
+ * Radius of the beacon circle.
19
+ * @default 5
20
+ */
21
+ radius?: number;
22
+ /**
23
+ * Stroke width of the beacon circle.
24
+ * @default 2
25
+ */
26
+ strokeWidth?: number;
27
+ } & import('react').RefAttributes<ScrubberBeaconRef>
6
28
  >
7
29
  >;
8
30
  //# sourceMappingURL=DefaultScrubberBeacon.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultScrubberBeacon.d.ts","sourceRoot":"","sources":["../../../src/chart/scrubber/DefaultScrubberBeacon.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAkBzE,MAAM,MAAM,0BAA0B,GAAG,mBAAmB,CAAC;AAE7D,eAAO,MAAM,qBAAqB,wJAgLjC,CAAC"}
1
+ {"version":3,"file":"DefaultScrubberBeacon.d.ts","sourceRoot":"","sources":["../../../src/chart/scrubber/DefaultScrubberBeacon.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAkBzE,MAAM,MAAM,0BAA0B,GAAG,mBAAmB,GAAG;IAC7D;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,eAAO,MAAM,qBAAqB;IAZhC;;;OAGG;aACM,MAAM;IACf;;;OAGG;kBACW,MAAM;sDAiMrB,CAAC"}
@@ -43,11 +43,14 @@ export type ScrubberBeaconProps = {
43
43
  isIdle: AnimatedProp<boolean>;
44
44
  /**
45
45
  * Pulse the beacon while it is at rest.
46
+ *
47
+ * @note Only has an effect when `isIdle` is `true`. Pulse animations work
48
+ * regardless of the chart's `animate` prop.
46
49
  */
47
50
  idlePulse?: boolean;
48
51
  /**
49
- * Whether animations are enabled.
50
- * @default true
52
+ * Whether position animations are enabled.
53
+ * @default to ChartContext's animate value
51
54
  */
52
55
  animate?: boolean;
53
56
  /**
@@ -76,6 +79,11 @@ export type ScrubberBeaconProps = {
76
79
  * @default 1
77
80
  */
78
81
  opacity?: AnimatedProp<number>;
82
+ /**
83
+ * Stroke color of the beacon circle.
84
+ * @default theme.color.bg
85
+ */
86
+ stroke?: string;
79
87
  };
80
88
  export type ScrubberBeaconComponent = React.FC<
81
89
  ScrubberBeaconProps & {
@@ -159,6 +167,11 @@ export type ScrubberBaseProps = Pick<ScrubberBeaconGroupBaseProps, 'idlePulse'>
159
167
  * Transition configuration for the scrubber beacon.
160
168
  */
161
169
  beaconTransitions?: ScrubberBeaconProps['transitions'];
170
+ /**
171
+ * Stroke color of the scrubber beacon circle.
172
+ * @default theme.color.bg
173
+ */
174
+ beaconStroke?: string;
162
175
  };
163
176
  export type ScrubberProps = ScrubberBaseProps;
164
177
  export type ScrubberRef = ScrubberBeaconGroupRef;
@@ -227,6 +240,11 @@ export declare const Scrubber: React.MemoExoticComponent<
227
240
  * Transition configuration for the scrubber beacon.
228
241
  */
229
242
  beaconTransitions?: ScrubberBeaconProps['transitions'];
243
+ /**
244
+ * Stroke color of the scrubber beacon circle.
245
+ * @default theme.color.bg
246
+ */
247
+ beaconStroke?: string;
230
248
  } & React.RefAttributes<ScrubberBeaconGroupRef>
231
249
  >
232
250
  >;
@@ -1 +1 @@
1
- {"version":3,"file":"Scrubber.d.ts","sourceRoot":"","sources":["../../../src/chart/scrubber/Scrubber.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Scrubber.d.ts","sourceRoot":"","sources":["../../../src/chart/scrubber/Scrubber.tsx"],"names":[],"mappings":"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"}
@@ -25,6 +25,11 @@ export type ScrubberBeaconGroupProps = ScrubberBeaconGroupBaseProps & {
25
25
  * @default DefaultScrubberBeacon
26
26
  */
27
27
  BeaconComponent?: ScrubberBeaconComponent;
28
+ /**
29
+ * Stroke color of the beacon circle.
30
+ * @default theme.color.bg
31
+ */
32
+ stroke?: string;
28
33
  };
29
34
  export declare const ScrubberBeaconGroup: import('react').MemoExoticComponent<
30
35
  import('react').ForwardRefExoticComponent<
@@ -38,6 +43,11 @@ export declare const ScrubberBeaconGroup: import('react').MemoExoticComponent<
38
43
  * @default DefaultScrubberBeacon
39
44
  */
40
45
  BeaconComponent?: ScrubberBeaconComponent;
46
+ /**
47
+ * Stroke color of the beacon circle.
48
+ * @default theme.color.bg
49
+ */
50
+ stroke?: string;
41
51
  } & import('react').RefAttributes<ScrubberBeaconGroupRef>
42
52
  >
43
53
  >;
@@ -1 +1 @@
1
- {"version":3,"file":"ScrubberBeaconGroup.d.ts","sourceRoot":"","sources":["../../../src/chart/scrubber/ScrubberBeaconGroup.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,uBAAuB,EAAE,mBAAmB,EAAqB,MAAM,YAAY,CAAC;AAgHlG,MAAM,MAAM,sBAAsB,GAAG;IACnC;;OAEG;IACH,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG;IACzC;;OAEG;IACH,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,4BAA4B,GAAG;IACpE;;OAEG;IACH,WAAW,CAAC,EAAE,mBAAmB,CAAC,aAAa,CAAC,CAAC;IACjD;;;OAGG;IACH,eAAe,CAAC,EAAE,uBAAuB,CAAC;CAC3C,CAAC;AAEF,eAAO,MAAM,mBAAmB;IAX9B;;OAEG;kBACW,mBAAmB,CAAC,aAAa,CAAC;IAChD;;;OAGG;sBACe,uBAAuB;2DAqE1C,CAAC"}
1
+ {"version":3,"file":"ScrubberBeaconGroup.d.ts","sourceRoot":"","sources":["../../../src/chart/scrubber/ScrubberBeaconGroup.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,uBAAuB,EAAE,mBAAmB,EAAqB,MAAM,YAAY,CAAC;AAmHlG,MAAM,MAAM,sBAAsB,GAAG;IACnC;;OAEG;IACH,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG;IACzC;;OAEG;IACH,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,4BAA4B,GAAG;IACpE;;OAEG;IACH,WAAW,CAAC,EAAE,mBAAmB,CAAC,aAAa,CAAC,CAAC;IACjD;;;OAGG;IACH,eAAe,CAAC,EAAE,uBAAuB,CAAC;IAC1C;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,mBAAmB;IAhB9B;;OAEG;kBACW,mBAAmB,CAAC,aAAa,CAAC;IAChD;;;OAGG;sBACe,uBAAuB;IACzC;;;OAGG;aACM,MAAM;2DAyEhB,CAAC"}
@@ -2014,6 +2014,122 @@ function HiddenScrubberWhenIdle() {
2014
2014
  })
2015
2015
  });
2016
2016
  }
2017
+ function CustomBeaconStroke() {
2018
+ const theme = useTheme();
2019
+ const backgroundColor = "rgb(" + theme.spectrum.red40 + ")";
2020
+ const foregroundColor = "rgb(" + theme.spectrum.gray0 + ")";
2021
+ return /*#__PURE__*/_jsx(Box, {
2022
+ borderRadius: 300,
2023
+ padding: 2,
2024
+ style: {
2025
+ backgroundColor
2026
+ },
2027
+ children: /*#__PURE__*/_jsx(LineChart, {
2028
+ enableScrubbing: true,
2029
+ showArea: true,
2030
+ height: 150,
2031
+ series: [{
2032
+ id: 'prices',
2033
+ data: [10, 22, 29, 45, 98, 45, 22, 52, 21, 4, 68, 20, 21, 58],
2034
+ color: foregroundColor
2035
+ }],
2036
+ children: /*#__PURE__*/_jsx(Scrubber, {
2037
+ hideOverlay: true,
2038
+ idlePulse: true,
2039
+ beaconStroke: backgroundColor,
2040
+ lineStroke: foregroundColor
2041
+ })
2042
+ })
2043
+ });
2044
+ }
2045
+ function CustomBeaconSize() {
2046
+ const theme = useTheme();
2047
+ const dataCount = 14;
2048
+ const minDataValue = 0;
2049
+ const maxDataValue = 100;
2050
+ const minStepOffset = 5;
2051
+ const maxStepOffset = 20;
2052
+ const updateInterval = 2000;
2053
+ function generateNextValue(previousValue) {
2054
+ const range = maxStepOffset - minStepOffset;
2055
+ const offset = Math.random() * range + minStepOffset;
2056
+ let direction;
2057
+ if (previousValue >= maxDataValue) {
2058
+ direction = -1;
2059
+ } else if (previousValue <= minDataValue) {
2060
+ direction = 1;
2061
+ } else {
2062
+ direction = Math.random() < 0.5 ? -1 : 1;
2063
+ }
2064
+ const newValue = previousValue + offset * direction;
2065
+ return Math.max(minDataValue, Math.min(maxDataValue, newValue));
2066
+ }
2067
+ function generateInitialData() {
2068
+ const data = [];
2069
+ let previousValue = Math.random() * (maxDataValue - minDataValue) + minDataValue;
2070
+ data.push(previousValue);
2071
+ for (let i = 1; i < dataCount; i++) {
2072
+ const newValue = generateNextValue(previousValue);
2073
+ data.push(newValue);
2074
+ previousValue = newValue;
2075
+ }
2076
+ return data;
2077
+ }
2078
+ const InvertedBeacon = useMemo(() => props => /*#__PURE__*/_jsx(DefaultScrubberBeacon, _extends({}, props, {
2079
+ color: theme.color.bg,
2080
+ radius: 5,
2081
+ stroke: theme.color.fg,
2082
+ strokeWidth: 3
2083
+ })), [theme.color.fg, theme.color.bg]);
2084
+ const CustomBeaconSizeChart = /*#__PURE__*/memo(() => {
2085
+ const [data, setData] = useState(generateInitialData);
2086
+ useEffect(() => {
2087
+ const intervalId = setInterval(() => {
2088
+ setData(currentData => {
2089
+ var _currentData2;
2090
+ const lastValue = (_currentData2 = currentData[currentData.length - 1]) != null ? _currentData2 : 50;
2091
+ const newValue = generateNextValue(lastValue);
2092
+ return [...currentData.slice(1), newValue];
2093
+ });
2094
+ }, updateInterval);
2095
+ return () => clearInterval(intervalId);
2096
+ }, []);
2097
+ return /*#__PURE__*/_jsx(LineChart, {
2098
+ enableScrubbing: true,
2099
+ showArea: true,
2100
+ showYAxis: true,
2101
+ height: 150,
2102
+ series: [{
2103
+ id: 'prices',
2104
+ data,
2105
+ color: theme.color.fg
2106
+ }],
2107
+ xAxis: {
2108
+ range: _ref23 => {
2109
+ let {
2110
+ min,
2111
+ max
2112
+ } = _ref23;
2113
+ return {
2114
+ min,
2115
+ max: max - 16
2116
+ };
2117
+ }
2118
+ },
2119
+ yAxis: {
2120
+ showGrid: true,
2121
+ domain: {
2122
+ min: 0,
2123
+ max: 100
2124
+ }
2125
+ },
2126
+ children: /*#__PURE__*/_jsx(Scrubber, {
2127
+ BeaconComponent: InvertedBeacon
2128
+ })
2129
+ });
2130
+ });
2131
+ return /*#__PURE__*/_jsx(CustomBeaconSizeChart, {});
2132
+ }
2017
2133
  function TwoLineScrubberLabel() {
2018
2134
  const theme = useTheme();
2019
2135
  const data = useMemo(() => [10, 22, 29, 45, 98, 45, 22, 52, 21, 4, 68, 20, 21, 58], []);
@@ -2260,11 +2376,11 @@ function ExampleNavigator() {
2260
2376
  }],
2261
2377
  xAxis: {
2262
2378
  // Give space before the end of the chart for the scrubber
2263
- range: _ref23 => {
2379
+ range: _ref24 => {
2264
2380
  let {
2265
2381
  min,
2266
2382
  max
2267
- } = _ref23;
2383
+ } = _ref24;
2268
2384
  return {
2269
2385
  min,
2270
2386
  max: max - 24
@@ -2319,6 +2435,12 @@ function ExampleNavigator() {
2319
2435
  }, {
2320
2436
  title: 'Two-Line Scrubber Label',
2321
2437
  component: /*#__PURE__*/_jsx(TwoLineScrubberLabel, {})
2438
+ }, {
2439
+ title: 'Custom Beacon Stroke',
2440
+ component: /*#__PURE__*/_jsx(CustomBeaconStroke, {})
2441
+ }, {
2442
+ title: 'Custom Beacon Size',
2443
+ component: /*#__PURE__*/_jsx(CustomBeaconSize, {})
2322
2444
  }], [theme.color.fg, theme.color.fgPositive, theme.spectrum.gray50]);
2323
2445
  const currentExample = examples[currentIndex];
2324
2446
  const isFirstExample = currentIndex === 0;
@@ -1,6 +1,5 @@
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 { forwardRef, memo, useImperativeHandle, useMemo } from 'react';
3
- import { cancelAnimation, Easing, useAnimatedReaction, useDerivedValue, useSharedValue, withRepeat, withSequence } from 'react-native-reanimated';
1
+ import { forwardRef, memo, useEffect, useImperativeHandle, useMemo } from 'react';
2
+ import { cancelAnimation, Easing, useAnimatedReaction, useDerivedValue, useSharedValue, withDelay, withRepeat, withSequence, withTiming } from 'react-native-reanimated';
4
3
  import { useTheme } from '@coinbase/cds-mobile';
5
4
  import { Circle, Group } from '@shopify/react-native-skia';
6
5
  import { useCartesianChartContext } from '../ChartProvider';
@@ -8,12 +7,12 @@ import { unwrapAnimatedValue } from '../utils';
8
7
  import { projectPointWithSerializableScale } from '../utils/point';
9
8
  import { buildTransition, defaultTransition } from '../utils/transition';
10
9
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
11
- const radius = 5;
12
- const strokeWidth = 2;
10
+ const defaultRadius = 5;
11
+ const defaultStrokeWidth = 2;
13
12
  const pulseOpacityStart = 0.5;
14
13
  const pulseOpacityEnd = 0;
15
- const pulseRadiusStart = 10;
16
- const pulseRadiusEnd = 15;
14
+ const pulseRadiusStartMultiplier = 2;
15
+ const pulseRadiusEndMultiplier = 3;
17
16
  const defaultPulseTransition = {
18
17
  type: 'timing',
19
18
  duration: 1600,
@@ -30,7 +29,10 @@ export const DefaultScrubberBeacon = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((
30
29
  idlePulse,
31
30
  animate = true,
32
31
  transitions,
33
- opacity: opacityProp = 1
32
+ opacity: opacityProp = 1,
33
+ radius = defaultRadius,
34
+ stroke,
35
+ strokeWidth = defaultStrokeWidth
34
36
  } = _ref;
35
37
  const theme = useTheme();
36
38
  const {
@@ -58,8 +60,18 @@ export const DefaultScrubberBeacon = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((
58
60
  var _transitions$pulseRep;
59
61
  return (_transitions$pulseRep = transitions == null ? void 0 : transitions.pulseRepeatDelay) != null ? _transitions$pulseRep : defaultPulseRepeatDelay;
60
62
  }, [transitions == null ? void 0 : transitions.pulseRepeatDelay]);
63
+ const pulseRadiusStart = radius * pulseRadiusStartMultiplier;
64
+ const pulseRadiusEnd = radius * pulseRadiusEndMultiplier;
61
65
  const pulseOpacity = useSharedValue(0);
62
66
  const pulseRadius = useSharedValue(pulseRadiusStart);
67
+
68
+ // Convert idlePulse prop to SharedValue so useAnimatedReaction can detect changes.
69
+ // In the new React Native architecture, regular JS props are captured by value in worklets
70
+ // and won't update when the prop changes.
71
+ const idlePulseShared = useSharedValue(idlePulse != null ? idlePulse : false);
72
+ useEffect(() => {
73
+ idlePulseShared.value = idlePulse != null ? idlePulse : false;
74
+ }, [idlePulse, idlePulseShared]);
63
75
  const animatedX = useSharedValue(0);
64
76
  const animatedY = useSharedValue(0);
65
77
 
@@ -103,41 +115,33 @@ export const DefaultScrubberBeacon = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((
103
115
  useImperativeHandle(ref, () => ({
104
116
  pulse: () => {
105
117
  // Only trigger manual pulse when idlePulse is not enabled
106
- if (!idlePulse) {
118
+ if (!idlePulseShared.value) {
107
119
  cancelAnimation(pulseOpacity);
108
120
  cancelAnimation(pulseRadius);
109
121
 
110
122
  // Manual pulse without delay
111
- const immediatePulseTransition = _extends({}, pulseTransition, {
112
- delay: 0
113
- });
114
123
  pulseOpacity.value = pulseOpacityStart;
115
124
  pulseRadius.value = pulseRadiusStart;
116
- pulseOpacity.value = buildTransition(pulseOpacityEnd, immediatePulseTransition);
117
- pulseRadius.value = buildTransition(pulseRadiusEnd, immediatePulseTransition);
125
+ pulseOpacity.value = buildTransition(pulseOpacityEnd, pulseTransition);
126
+ pulseRadius.value = buildTransition(pulseRadiusEnd, pulseTransition);
118
127
  }
119
128
  }
120
- }), [idlePulse, pulseOpacity, pulseRadius, pulseTransition]);
129
+ }), [idlePulseShared, pulseOpacity, pulseRadius, pulseTransition, pulseRadiusStart, pulseRadiusEnd]);
121
130
 
122
131
  // Watch idlePulse changes and control continuous pulse
123
- useAnimatedReaction(() => idlePulse, (current, previous) => {
124
- if (!animate) return;
132
+ useAnimatedReaction(() => idlePulseShared.value, current => {
125
133
  if (current) {
126
134
  // Start continuous pulse when idlePulse is enabled
127
- // Create instant transition to reset pulse after delay
128
- const instantTransition = {
129
- type: 'timing',
130
- duration: 0
131
- };
132
- const resetWithDelay = _extends({}, instantTransition, {
133
- delay: pulseRepeatDelay
134
- });
135
135
  pulseOpacity.value = pulseOpacityStart;
136
136
  pulseRadius.value = pulseRadiusStart;
137
- pulseOpacity.value = withRepeat(withSequence(buildTransition(pulseOpacityEnd, pulseTransition), buildTransition(pulseOpacityStart, resetWithDelay)), -1,
137
+ pulseOpacity.value = withRepeat(withSequence(buildTransition(pulseOpacityEnd, pulseTransition), withDelay(pulseRepeatDelay, withTiming(pulseOpacityStart, {
138
+ duration: 0
139
+ }))), -1,
138
140
  // infinite loop
139
141
  false);
140
- pulseRadius.value = withRepeat(withSequence(buildTransition(pulseRadiusEnd, pulseTransition), buildTransition(pulseRadiusStart, resetWithDelay)), -1,
142
+ pulseRadius.value = withRepeat(withSequence(buildTransition(pulseRadiusEnd, pulseTransition), withDelay(pulseRepeatDelay, withTiming(pulseRadiusStart, {
143
+ duration: 0
144
+ }))), -1,
141
145
  // infinite loop
142
146
  false);
143
147
  } else {
@@ -147,7 +151,7 @@ export const DefaultScrubberBeacon = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((
147
151
  pulseOpacity.value = pulseOpacityEnd;
148
152
  pulseRadius.value = pulseRadiusStart;
149
153
  }
150
- }, [animate, pulseTransition, pulseRepeatDelay]);
154
+ }, [pulseTransition, pulseRepeatDelay, pulseRadiusStart, pulseRadiusEnd]);
151
155
  const pulseVisibility = useDerivedValue(() => {
152
156
  // Never pulse when scrubbing
153
157
  if (!unwrapAnimatedValue(isIdle)) return 0;
@@ -168,7 +172,7 @@ export const DefaultScrubberBeacon = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((
168
172
  r: pulseRadius
169
173
  }), /*#__PURE__*/_jsx(Circle, {
170
174
  c: animatedPoint,
171
- color: theme.color.bg,
175
+ color: stroke != null ? stroke : theme.color.bg,
172
176
  r: radius + strokeWidth / 2
173
177
  }), /*#__PURE__*/_jsx(Circle, {
174
178
  c: animatedPoint,
@@ -32,7 +32,8 @@ export const Scrubber = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =>
32
32
  labelBoundsInset,
33
33
  beaconLabelFont,
34
34
  idlePulse,
35
- beaconTransitions
35
+ beaconTransitions,
36
+ beaconStroke
36
37
  } = _ref;
37
38
  const theme = useTheme();
38
39
  const beaconGroupRef = React.useRef(null);
@@ -154,6 +155,7 @@ export const Scrubber = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =>
154
155
  BeaconComponent: BeaconComponent,
155
156
  idlePulse: idlePulse,
156
157
  seriesIds: filteredSeriesIds,
158
+ stroke: beaconStroke,
157
159
  transitions: beaconTransitions
158
160
  }), beaconLabels.length > 0 && /*#__PURE__*/_jsx(ScrubberBeaconLabelGroup, {
159
161
  BeaconLabelComponent: BeaconLabelComponent,
@@ -18,7 +18,8 @@ const BeaconWithData = /*#__PURE__*/memo(_ref => {
18
18
  idlePulse,
19
19
  animate,
20
20
  transitions,
21
- beaconRef
21
+ beaconRef,
22
+ stroke
22
23
  } = _ref;
23
24
  const {
24
25
  getSeries,
@@ -91,6 +92,7 @@ const BeaconWithData = /*#__PURE__*/memo(_ref => {
91
92
  idlePulse: idlePulse,
92
93
  isIdle: isIdle,
93
94
  seriesId: seriesId,
95
+ stroke: stroke,
94
96
  transitions: transitions
95
97
  });
96
98
  });
@@ -99,7 +101,8 @@ export const ScrubberBeaconGroup = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_r
99
101
  seriesIds,
100
102
  idlePulse,
101
103
  transitions,
102
- BeaconComponent = DefaultScrubberBeacon
104
+ BeaconComponent = DefaultScrubberBeacon,
105
+ stroke
103
106
  } = _ref2;
104
107
  const ScrubberBeaconRefs = useRefMap();
105
108
  const {
@@ -156,6 +159,7 @@ export const ScrubberBeaconGroup = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_r
156
159
  idlePulse: idlePulse,
157
160
  isIdle: isIdle,
158
161
  seriesId: s.id,
162
+ stroke: stroke,
159
163
  transitions: transitions
160
164
  }, s.id));
161
165
  }));
@@ -4,7 +4,7 @@ import { figma } from '@figma/code-connect';
4
4
  import { Sparkline } from '../Sparkline';
5
5
  import { jsx as _jsx } from "react/jsx-runtime";
6
6
  figma.connect(Sparkline, 'https://www.figma.com/design/k5CtyJccNQUGMI5bI4lJ2g/%E2%9C%A8-CDS-Components?node-id=320%3A15040', {
7
- imports: ["import { Sparkline } from '@coinbase/cds-mobile-visualization';", "import { useSparklinePath } from '@coinbase/cds-common/visualizations/useSparklinePath';"],
7
+ imports: ["import { Sparkline } from '@coinbase/cds-mobile-visualization'", "import { useSparklinePath } from '@coinbase/cds-common/visualizations/useSparklinePath'"],
8
8
  example: function Example() {
9
9
  const data = [20, 30, 5, 45, 0];
10
10
  const path = useSparklinePath({
@@ -4,7 +4,7 @@ import { figma } from '@figma/code-connect';
4
4
  import { SparklineInteractive } from '../SparklineInteractive';
5
5
  import { jsx as _jsx } from "react/jsx-runtime";
6
6
  figma.connect(SparklineInteractive, 'https://www.figma.com/design/k5CtyJccNQUGMI5bI4lJ2g/%E2%9C%A8-CDS-Components?node-id=320-14858&m=dev', {
7
- imports: ["import { SparklineInteractive } from '@coinbase/cds-web-visualization';"],
7
+ imports: ["import { SparklineInteractive } from '@coinbase/cds-mobile-visualization'"],
8
8
  props: {
9
9
  compact: figma.boolean('compact'),
10
10
  disableScrubbing: figma.boolean('scrubbing', {
@@ -5,7 +5,7 @@ import { SparklineInteractive } from '../../sparkline-interactive/SparklineInter
5
5
  import { SparklineInteractiveHeader } from '../SparklineInteractiveHeader';
6
6
  import { jsx as _jsx } from "react/jsx-runtime";
7
7
  figma.connect(SparklineInteractiveHeader, 'https://www.figma.com/design/k5CtyJccNQUGMI5bI4lJ2g/✨-CDS-Components?node-id=320-14931&m=dev', {
8
- imports: ["import { SparklineInteractiveHeader } from '@coinbase/cds-web-visualization';", "import { SparklineInteractive } from '@coinbase/cds-web-visualization';"],
8
+ imports: ["import { SparklineInteractiveHeader } from '@coinbase/cds-mobile-visualization'", "import { SparklineInteractive } from '@coinbase/cds-mobile-visualization'"],
9
9
  props: {
10
10
  compact: figma.boolean('compact'),
11
11
  disableScrubbing: figma.boolean('scrubbing', {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coinbase/cds-mobile-visualization",
3
- "version": "3.4.0-beta.11",
3
+ "version": "3.4.0-beta.13",
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.36.2",
39
+ "@coinbase/cds-common": "^8.38.1",
40
40
  "@coinbase/cds-lottie-files": "^3.3.4",
41
- "@coinbase/cds-mobile": "^8.36.2",
41
+ "@coinbase/cds-mobile": "^8.38.1",
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,11 +57,10 @@
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.36.2",
60
+ "@coinbase/cds-common": "^8.38.1",
61
61
  "@coinbase/cds-lottie-files": "^3.3.4",
62
- "@coinbase/cds-mobile": "^8.36.2",
62
+ "@coinbase/cds-mobile": "^8.38.1",
63
63
  "@coinbase/cds-utils": "^2.3.5",
64
- "@figma/code-connect": "^1.3.4",
65
64
  "@shopify/react-native-skia": "1.12.4",
66
65
  "@types/react": "^18.3.12",
67
66
  "react-native-gesture-handler": "2.16.2",