@coinbase/cds-mobile-visualization 3.4.0-beta.12 → 3.4.0-beta.14

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 (48) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dts/chart/CartesianChart.d.ts +35 -1
  3. package/dts/chart/CartesianChart.d.ts.map +1 -1
  4. package/dts/chart/bar/Bar.d.ts +4 -0
  5. package/dts/chart/bar/Bar.d.ts.map +1 -1
  6. package/dts/chart/bar/BarChart.d.ts +6 -3
  7. package/dts/chart/bar/BarChart.d.ts.map +1 -1
  8. package/dts/chart/bar/BarStack.d.ts +11 -2
  9. package/dts/chart/bar/BarStack.d.ts.map +1 -1
  10. package/dts/chart/index.d.ts +1 -0
  11. package/dts/chart/index.d.ts.map +1 -1
  12. package/dts/chart/legend/DefaultLegendEntry.d.ts +5 -0
  13. package/dts/chart/legend/DefaultLegendEntry.d.ts.map +1 -0
  14. package/dts/chart/legend/DefaultLegendShape.d.ts +5 -0
  15. package/dts/chart/legend/DefaultLegendShape.d.ts.map +1 -0
  16. package/dts/chart/legend/Legend.d.ts +168 -0
  17. package/dts/chart/legend/Legend.d.ts.map +1 -0
  18. package/dts/chart/legend/index.d.ts +4 -0
  19. package/dts/chart/legend/index.d.ts.map +1 -0
  20. package/dts/chart/line/LineChart.d.ts.map +1 -1
  21. package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts +24 -2
  22. package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts.map +1 -1
  23. package/dts/chart/scrubber/Scrubber.d.ts +28 -2
  24. package/dts/chart/scrubber/Scrubber.d.ts.map +1 -1
  25. package/dts/chart/scrubber/ScrubberBeaconGroup.d.ts +10 -0
  26. package/dts/chart/scrubber/ScrubberBeaconGroup.d.ts.map +1 -1
  27. package/dts/chart/utils/chart.d.ts +18 -0
  28. package/dts/chart/utils/chart.d.ts.map +1 -1
  29. package/esm/chart/CartesianChart.js +40 -10
  30. package/esm/chart/__stories__/CartesianChart.stories.js +3 -3
  31. package/esm/chart/bar/Bar.js +2 -0
  32. package/esm/chart/bar/BarStack.js +8 -1
  33. package/esm/chart/index.js +1 -0
  34. package/esm/chart/legend/DefaultLegendEntry.js +42 -0
  35. package/esm/chart/legend/DefaultLegendShape.js +64 -0
  36. package/esm/chart/legend/Legend.js +59 -0
  37. package/esm/chart/legend/__stories__/Legend.stories.js +574 -0
  38. package/esm/chart/legend/index.js +3 -0
  39. package/esm/chart/line/LineChart.js +2 -1
  40. package/esm/chart/line/__stories__/LineChart.stories.js +161 -6
  41. package/esm/chart/scrubber/DefaultScrubberBeacon.js +14 -10
  42. package/esm/chart/scrubber/Scrubber.js +5 -2
  43. package/esm/chart/scrubber/ScrubberBeaconGroup.js +6 -2
  44. package/esm/chart/utils/chart.js +13 -0
  45. package/esm/sparkline/__figma__/Sparkline.figma.js +1 -1
  46. package/esm/sparkline/sparkline-interactive/__figma__/SparklineInteractive.figma.js +1 -1
  47. package/esm/sparkline/sparkline-interactive-header/__figma__/SparklineInteractiveHeader.figma.js +1 -1
  48. package/package.json +5 -6
@@ -717,6 +717,36 @@ function StylingScrubber() {
717
717
  })
718
718
  });
719
719
  }
720
+ function HideBeaconLabels() {
721
+ const theme = useTheme();
722
+ const pageViews = [2400, 1398, 9800, 3908, 4800, 3800, 4300];
723
+ const uniqueVisitors = [4000, 3000, 2000, 2780, 1890, 2390, 3490];
724
+ return /*#__PURE__*/_jsx(LineChart, {
725
+ enableScrubbing: true,
726
+ legend: true,
727
+ showArea: true,
728
+ height: 200,
729
+ inset: {
730
+ top: 60
731
+ },
732
+ series: [{
733
+ id: 'pageViews',
734
+ data: pageViews,
735
+ color: theme.color.accentBoldGreen,
736
+ label: 'Page Views'
737
+ }, {
738
+ id: 'uniqueVisitors',
739
+ data: uniqueVisitors,
740
+ color: theme.color.accentBoldPurple,
741
+ label: 'Unique Visitors'
742
+ }],
743
+ children: /*#__PURE__*/_jsx(Scrubber, {
744
+ hideBeaconLabels: true,
745
+ labelElevated: true,
746
+ label: dataIndex => "Day " + (dataIndex + 1)
747
+ })
748
+ });
749
+ }
720
750
  function Compact() {
721
751
  const theme = useTheme();
722
752
  const dimensions = {
@@ -992,7 +1022,7 @@ const LegendDot = /*#__PURE__*/memo(props => {
992
1022
  width: 10
993
1023
  }, props));
994
1024
  });
995
- const LegendItem = /*#__PURE__*/memo(_ref0 => {
1025
+ const LegendEntry = /*#__PURE__*/memo(_ref0 => {
996
1026
  let {
997
1027
  color = assets.btc.color,
998
1028
  label,
@@ -1037,15 +1067,15 @@ const PerformanceHeader = /*#__PURE__*/memo(_ref1 => {
1037
1067
  return /*#__PURE__*/_jsxs(HStack, {
1038
1068
  gap: 1,
1039
1069
  paddingX: 1,
1040
- children: [/*#__PURE__*/_jsx(LegendItem, {
1070
+ children: [/*#__PURE__*/_jsx(LegendEntry, {
1041
1071
  color: theme.color.fgPositive,
1042
1072
  label: "High Price",
1043
1073
  value: formatPriceThousands(sparklineTimePeriodDataValues[shownPosition] * 1.2)
1044
- }), /*#__PURE__*/_jsx(LegendItem, {
1074
+ }), /*#__PURE__*/_jsx(LegendEntry, {
1045
1075
  color: assets.btc.color,
1046
1076
  label: "Actual Price",
1047
1077
  value: formatPriceThousands(sparklineTimePeriodDataValues[shownPosition])
1048
- }), /*#__PURE__*/_jsx(LegendItem, {
1078
+ }), /*#__PURE__*/_jsx(LegendEntry, {
1049
1079
  color: theme.color.fgNegative,
1050
1080
  label: "Low Price",
1051
1081
  value: formatPriceThousands(sparklineTimePeriodDataValues[shownPosition] * 0.8)
@@ -2014,6 +2044,122 @@ function HiddenScrubberWhenIdle() {
2014
2044
  })
2015
2045
  });
2016
2046
  }
2047
+ function CustomBeaconStroke() {
2048
+ const theme = useTheme();
2049
+ const backgroundColor = "rgb(" + theme.spectrum.red40 + ")";
2050
+ const foregroundColor = "rgb(" + theme.spectrum.gray0 + ")";
2051
+ return /*#__PURE__*/_jsx(Box, {
2052
+ borderRadius: 300,
2053
+ padding: 2,
2054
+ style: {
2055
+ backgroundColor
2056
+ },
2057
+ children: /*#__PURE__*/_jsx(LineChart, {
2058
+ enableScrubbing: true,
2059
+ showArea: true,
2060
+ height: 150,
2061
+ series: [{
2062
+ id: 'prices',
2063
+ data: [10, 22, 29, 45, 98, 45, 22, 52, 21, 4, 68, 20, 21, 58],
2064
+ color: foregroundColor
2065
+ }],
2066
+ children: /*#__PURE__*/_jsx(Scrubber, {
2067
+ hideOverlay: true,
2068
+ idlePulse: true,
2069
+ beaconStroke: backgroundColor,
2070
+ lineStroke: foregroundColor
2071
+ })
2072
+ })
2073
+ });
2074
+ }
2075
+ function CustomBeaconSize() {
2076
+ const theme = useTheme();
2077
+ const dataCount = 14;
2078
+ const minDataValue = 0;
2079
+ const maxDataValue = 100;
2080
+ const minStepOffset = 5;
2081
+ const maxStepOffset = 20;
2082
+ const updateInterval = 2000;
2083
+ function generateNextValue(previousValue) {
2084
+ const range = maxStepOffset - minStepOffset;
2085
+ const offset = Math.random() * range + minStepOffset;
2086
+ let direction;
2087
+ if (previousValue >= maxDataValue) {
2088
+ direction = -1;
2089
+ } else if (previousValue <= minDataValue) {
2090
+ direction = 1;
2091
+ } else {
2092
+ direction = Math.random() < 0.5 ? -1 : 1;
2093
+ }
2094
+ const newValue = previousValue + offset * direction;
2095
+ return Math.max(minDataValue, Math.min(maxDataValue, newValue));
2096
+ }
2097
+ function generateInitialData() {
2098
+ const data = [];
2099
+ let previousValue = Math.random() * (maxDataValue - minDataValue) + minDataValue;
2100
+ data.push(previousValue);
2101
+ for (let i = 1; i < dataCount; i++) {
2102
+ const newValue = generateNextValue(previousValue);
2103
+ data.push(newValue);
2104
+ previousValue = newValue;
2105
+ }
2106
+ return data;
2107
+ }
2108
+ const InvertedBeacon = useMemo(() => props => /*#__PURE__*/_jsx(DefaultScrubberBeacon, _extends({}, props, {
2109
+ color: theme.color.bg,
2110
+ radius: 5,
2111
+ stroke: theme.color.fg,
2112
+ strokeWidth: 3
2113
+ })), [theme.color.fg, theme.color.bg]);
2114
+ const CustomBeaconSizeChart = /*#__PURE__*/memo(() => {
2115
+ const [data, setData] = useState(generateInitialData);
2116
+ useEffect(() => {
2117
+ const intervalId = setInterval(() => {
2118
+ setData(currentData => {
2119
+ var _currentData2;
2120
+ const lastValue = (_currentData2 = currentData[currentData.length - 1]) != null ? _currentData2 : 50;
2121
+ const newValue = generateNextValue(lastValue);
2122
+ return [...currentData.slice(1), newValue];
2123
+ });
2124
+ }, updateInterval);
2125
+ return () => clearInterval(intervalId);
2126
+ }, []);
2127
+ return /*#__PURE__*/_jsx(LineChart, {
2128
+ enableScrubbing: true,
2129
+ showArea: true,
2130
+ showYAxis: true,
2131
+ height: 150,
2132
+ series: [{
2133
+ id: 'prices',
2134
+ data,
2135
+ color: theme.color.fg
2136
+ }],
2137
+ xAxis: {
2138
+ range: _ref23 => {
2139
+ let {
2140
+ min,
2141
+ max
2142
+ } = _ref23;
2143
+ return {
2144
+ min,
2145
+ max: max - 16
2146
+ };
2147
+ }
2148
+ },
2149
+ yAxis: {
2150
+ showGrid: true,
2151
+ domain: {
2152
+ min: 0,
2153
+ max: 100
2154
+ }
2155
+ },
2156
+ children: /*#__PURE__*/_jsx(Scrubber, {
2157
+ BeaconComponent: InvertedBeacon
2158
+ })
2159
+ });
2160
+ });
2161
+ return /*#__PURE__*/_jsx(CustomBeaconSizeChart, {});
2162
+ }
2017
2163
  function TwoLineScrubberLabel() {
2018
2164
  const theme = useTheme();
2019
2165
  const data = useMemo(() => [10, 22, 29, 45, 98, 45, 22, 52, 21, 4, 68, 20, 21, 58], []);
@@ -2260,11 +2406,11 @@ function ExampleNavigator() {
2260
2406
  }],
2261
2407
  xAxis: {
2262
2408
  // Give space before the end of the chart for the scrubber
2263
- range: _ref23 => {
2409
+ range: _ref24 => {
2264
2410
  let {
2265
2411
  min,
2266
2412
  max
2267
- } = _ref23;
2413
+ } = _ref24;
2268
2414
  return {
2269
2415
  min,
2270
2416
  max: max - 24
@@ -2319,6 +2465,15 @@ function ExampleNavigator() {
2319
2465
  }, {
2320
2466
  title: 'Two-Line Scrubber Label',
2321
2467
  component: /*#__PURE__*/_jsx(TwoLineScrubberLabel, {})
2468
+ }, {
2469
+ title: 'Hide Beacon Labels',
2470
+ component: /*#__PURE__*/_jsx(HideBeaconLabels, {})
2471
+ }, {
2472
+ title: 'Custom Beacon Stroke',
2473
+ component: /*#__PURE__*/_jsx(CustomBeaconStroke, {})
2474
+ }, {
2475
+ title: 'Custom Beacon Size',
2476
+ component: /*#__PURE__*/_jsx(CustomBeaconSize, {})
2322
2477
  }], [theme.color.fg, theme.color.fgPositive, theme.spectrum.gray50]);
2323
2478
  const currentExample = examples[currentIndex];
2324
2479
  const isFirstExample = currentIndex === 0;
@@ -7,12 +7,12 @@ import { unwrapAnimatedValue } from '../utils';
7
7
  import { projectPointWithSerializableScale } from '../utils/point';
8
8
  import { buildTransition, defaultTransition } from '../utils/transition';
9
9
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
- const radius = 5;
11
- const strokeWidth = 2;
10
+ const defaultRadius = 5;
11
+ const defaultStrokeWidth = 2;
12
12
  const pulseOpacityStart = 0.5;
13
13
  const pulseOpacityEnd = 0;
14
- const pulseRadiusStart = 10;
15
- const pulseRadiusEnd = 15;
14
+ const pulseRadiusStartMultiplier = 2;
15
+ const pulseRadiusEndMultiplier = 3;
16
16
  const defaultPulseTransition = {
17
17
  type: 'timing',
18
18
  duration: 1600,
@@ -29,7 +29,10 @@ export const DefaultScrubberBeacon = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((
29
29
  idlePulse,
30
30
  animate = true,
31
31
  transitions,
32
- opacity: opacityProp = 1
32
+ opacity: opacityProp = 1,
33
+ radius = defaultRadius,
34
+ stroke,
35
+ strokeWidth = defaultStrokeWidth
33
36
  } = _ref;
34
37
  const theme = useTheme();
35
38
  const {
@@ -57,6 +60,8 @@ export const DefaultScrubberBeacon = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((
57
60
  var _transitions$pulseRep;
58
61
  return (_transitions$pulseRep = transitions == null ? void 0 : transitions.pulseRepeatDelay) != null ? _transitions$pulseRep : defaultPulseRepeatDelay;
59
62
  }, [transitions == null ? void 0 : transitions.pulseRepeatDelay]);
63
+ const pulseRadiusStart = radius * pulseRadiusStartMultiplier;
64
+ const pulseRadiusEnd = radius * pulseRadiusEndMultiplier;
60
65
  const pulseOpacity = useSharedValue(0);
61
66
  const pulseRadius = useSharedValue(pulseRadiusStart);
62
67
 
@@ -121,11 +126,10 @@ export const DefaultScrubberBeacon = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((
121
126
  pulseRadius.value = buildTransition(pulseRadiusEnd, pulseTransition);
122
127
  }
123
128
  }
124
- }), [idlePulseShared, pulseOpacity, pulseRadius, pulseTransition]);
129
+ }), [idlePulseShared, pulseOpacity, pulseRadius, pulseTransition, pulseRadiusStart, pulseRadiusEnd]);
125
130
 
126
131
  // Watch idlePulse changes and control continuous pulse
127
- useAnimatedReaction(() => idlePulseShared.value, (current, previous) => {
128
- if (!animate) return;
132
+ useAnimatedReaction(() => idlePulseShared.value, current => {
129
133
  if (current) {
130
134
  // Start continuous pulse when idlePulse is enabled
131
135
  pulseOpacity.value = pulseOpacityStart;
@@ -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,
@@ -16,6 +16,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
16
16
  export const Scrubber = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) => {
17
17
  let {
18
18
  seriesIds,
19
+ hideBeaconLabels,
19
20
  hideLine,
20
21
  label,
21
22
  lineStroke,
@@ -32,7 +33,8 @@ export const Scrubber = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =>
32
33
  labelBoundsInset,
33
34
  beaconLabelFont,
34
35
  idlePulse,
35
- beaconTransitions
36
+ beaconTransitions,
37
+ beaconStroke
36
38
  } = _ref;
37
39
  const theme = useTheme();
38
40
  const beaconGroupRef = React.useRef(null);
@@ -154,8 +156,9 @@ export const Scrubber = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =>
154
156
  BeaconComponent: BeaconComponent,
155
157
  idlePulse: idlePulse,
156
158
  seriesIds: filteredSeriesIds,
159
+ stroke: beaconStroke,
157
160
  transitions: beaconTransitions
158
- }), beaconLabels.length > 0 && /*#__PURE__*/_jsx(ScrubberBeaconLabelGroup, {
161
+ }), !hideBeaconLabels && beaconLabels.length > 0 && /*#__PURE__*/_jsx(ScrubberBeaconLabelGroup, {
159
162
  BeaconLabelComponent: BeaconLabelComponent,
160
163
  labelFont: beaconLabelFont,
161
164
  labelHorizontalOffset: beaconLabelHorizontalOffset,
@@ -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
  }));
@@ -1,6 +1,19 @@
1
1
  import { isSharedValue } from 'react-native-reanimated';
2
2
  import { stack as d3Stack, stackOffsetDiverging, stackOrderNone } from 'd3-shape';
3
3
  export const defaultStackId = 'DEFAULT_STACK_ID';
4
+
5
+ /**
6
+ * Shape variants available for legend items.
7
+ */
8
+
9
+ /**
10
+ * Shape for legend items. Can be a preset variant or a custom ReactNode.
11
+ */
12
+
13
+ /**
14
+ * Position of the legend relative to the chart.
15
+ */
16
+
4
17
  /**
5
18
  * Type guard to check if bounds are complete with both min and max values.
6
19
  * @param bounds - The bounds to validate
@@ -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.12",
3
+ "version": "3.4.0-beta.14",
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.6",
40
40
  "@coinbase/cds-lottie-files": "^3.3.4",
41
- "@coinbase/cds-mobile": "^8.36.2",
41
+ "@coinbase/cds-mobile": "^8.38.6",
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.6",
61
61
  "@coinbase/cds-lottie-files": "^3.3.4",
62
- "@coinbase/cds-mobile": "^8.36.2",
62
+ "@coinbase/cds-mobile": "^8.38.6",
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",