@coinbase/cds-mobile-visualization 3.4.0-beta.9 → 3.4.0

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 (167) hide show
  1. package/CHANGELOG.md +132 -0
  2. package/dts/chart/CartesianChart.d.ts +92 -7
  3. package/dts/chart/CartesianChart.d.ts.map +1 -1
  4. package/dts/chart/ChartContextBridge.d.ts.map +1 -1
  5. package/dts/chart/ChartProvider.d.ts +3 -0
  6. package/dts/chart/ChartProvider.d.ts.map +1 -1
  7. package/dts/chart/Path.d.ts +36 -13
  8. package/dts/chart/Path.d.ts.map +1 -1
  9. package/dts/chart/PeriodSelector.d.ts +20 -5
  10. package/dts/chart/PeriodSelector.d.ts.map +1 -1
  11. package/dts/chart/area/Area.d.ts +14 -11
  12. package/dts/chart/area/Area.d.ts.map +1 -1
  13. package/dts/chart/area/AreaChart.d.ts +33 -9
  14. package/dts/chart/area/AreaChart.d.ts.map +1 -1
  15. package/dts/chart/area/DottedArea.d.ts.map +1 -1
  16. package/dts/chart/area/GradientArea.d.ts.map +1 -1
  17. package/dts/chart/area/SolidArea.d.ts.map +1 -1
  18. package/dts/chart/axis/Axis.d.ts +22 -42
  19. package/dts/chart/axis/Axis.d.ts.map +1 -1
  20. package/dts/chart/axis/XAxis.d.ts +6 -0
  21. package/dts/chart/axis/XAxis.d.ts.map +1 -1
  22. package/dts/chart/axis/YAxis.d.ts +1 -0
  23. package/dts/chart/axis/YAxis.d.ts.map +1 -1
  24. package/dts/chart/bar/Bar.d.ts +51 -51
  25. package/dts/chart/bar/Bar.d.ts.map +1 -1
  26. package/dts/chart/bar/BarChart.d.ts +56 -11
  27. package/dts/chart/bar/BarChart.d.ts.map +1 -1
  28. package/dts/chart/bar/BarPlot.d.ts +2 -1
  29. package/dts/chart/bar/BarPlot.d.ts.map +1 -1
  30. package/dts/chart/bar/BarStack.d.ts +45 -20
  31. package/dts/chart/bar/BarStack.d.ts.map +1 -1
  32. package/dts/chart/bar/BarStackGroup.d.ts +2 -1
  33. package/dts/chart/bar/BarStackGroup.d.ts.map +1 -1
  34. package/dts/chart/bar/DefaultBar.d.ts.map +1 -1
  35. package/dts/chart/bar/DefaultBarStack.d.ts.map +1 -1
  36. package/dts/chart/gradient/Gradient.d.ts +5 -0
  37. package/dts/chart/gradient/Gradient.d.ts.map +1 -1
  38. package/dts/chart/index.d.ts +1 -0
  39. package/dts/chart/index.d.ts.map +1 -1
  40. package/dts/chart/legend/DefaultLegendEntry.d.ts +5 -0
  41. package/dts/chart/legend/DefaultLegendEntry.d.ts.map +1 -0
  42. package/dts/chart/legend/DefaultLegendShape.d.ts +5 -0
  43. package/dts/chart/legend/DefaultLegendShape.d.ts.map +1 -0
  44. package/dts/chart/legend/Legend.d.ts +168 -0
  45. package/dts/chart/legend/Legend.d.ts.map +1 -0
  46. package/dts/chart/legend/index.d.ts +4 -0
  47. package/dts/chart/legend/index.d.ts.map +1 -0
  48. package/dts/chart/line/DottedLine.d.ts.map +1 -1
  49. package/dts/chart/line/Line.d.ts +23 -19
  50. package/dts/chart/line/Line.d.ts.map +1 -1
  51. package/dts/chart/line/LineChart.d.ts +26 -9
  52. package/dts/chart/line/LineChart.d.ts.map +1 -1
  53. package/dts/chart/line/ReferenceLine.d.ts +1 -0
  54. package/dts/chart/line/ReferenceLine.d.ts.map +1 -1
  55. package/dts/chart/line/SolidLine.d.ts.map +1 -1
  56. package/dts/chart/point/Point.d.ts +26 -2
  57. package/dts/chart/point/Point.d.ts.map +1 -1
  58. package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts +32 -2
  59. package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts.map +1 -1
  60. package/dts/chart/scrubber/DefaultScrubberLabel.d.ts +2 -1
  61. package/dts/chart/scrubber/DefaultScrubberLabel.d.ts.map +1 -1
  62. package/dts/chart/scrubber/Scrubber.d.ts +86 -17
  63. package/dts/chart/scrubber/Scrubber.d.ts.map +1 -1
  64. package/dts/chart/scrubber/ScrubberAccessibilityView.d.ts +12 -0
  65. package/dts/chart/scrubber/ScrubberAccessibilityView.d.ts.map +1 -0
  66. package/dts/chart/scrubber/ScrubberBeaconGroup.d.ts +10 -0
  67. package/dts/chart/scrubber/ScrubberBeaconGroup.d.ts.map +1 -1
  68. package/dts/chart/scrubber/ScrubberBeaconLabelGroup.d.ts +16 -1
  69. package/dts/chart/scrubber/ScrubberBeaconLabelGroup.d.ts.map +1 -1
  70. package/dts/chart/scrubber/ScrubberProvider.d.ts.map +1 -1
  71. package/dts/chart/utils/axis.d.ts +45 -10
  72. package/dts/chart/utils/axis.d.ts.map +1 -1
  73. package/dts/chart/utils/bar.d.ts +190 -0
  74. package/dts/chart/utils/bar.d.ts.map +1 -1
  75. package/dts/chart/utils/chart.d.ts +32 -0
  76. package/dts/chart/utils/chart.d.ts.map +1 -1
  77. package/dts/chart/utils/context.d.ts +21 -6
  78. package/dts/chart/utils/context.d.ts.map +1 -1
  79. package/dts/chart/utils/gradient.d.ts +3 -1
  80. package/dts/chart/utils/gradient.d.ts.map +1 -1
  81. package/dts/chart/utils/path.d.ts +26 -0
  82. package/dts/chart/utils/path.d.ts.map +1 -1
  83. package/dts/chart/utils/point.d.ts +24 -12
  84. package/dts/chart/utils/point.d.ts.map +1 -1
  85. package/dts/chart/utils/scale.d.ts +11 -0
  86. package/dts/chart/utils/scale.d.ts.map +1 -1
  87. package/dts/chart/utils/scrubber.d.ts +2 -1
  88. package/dts/chart/utils/scrubber.d.ts.map +1 -1
  89. package/dts/chart/utils/transition.d.ts +63 -22
  90. package/dts/chart/utils/transition.d.ts.map +1 -1
  91. package/dts/sparkline/Sparkline.d.ts +2 -1
  92. package/dts/sparkline/Sparkline.d.ts.map +1 -1
  93. package/dts/sparkline/SparklineArea.d.ts +2 -1
  94. package/dts/sparkline/SparklineArea.d.ts.map +1 -1
  95. package/dts/sparkline/SparklineGradient.d.ts +2 -1
  96. package/dts/sparkline/SparklineGradient.d.ts.map +1 -1
  97. package/dts/sparkline/sparkline-interactive/SparklineInteractive.d.ts +2 -1
  98. package/dts/sparkline/sparkline-interactive/SparklineInteractive.d.ts.map +1 -1
  99. package/esm/chart/CartesianChart.js +176 -82
  100. package/esm/chart/ChartContextBridge.js +14 -3
  101. package/esm/chart/ChartProvider.js +2 -2
  102. package/esm/chart/Path.js +34 -29
  103. package/esm/chart/PeriodSelector.js +5 -1
  104. package/esm/chart/__stories__/CartesianChart.stories.js +16 -80
  105. package/esm/chart/__stories__/ChartAccessibility.stories.js +721 -0
  106. package/esm/chart/__stories__/ChartTransitions.stories.js +625 -0
  107. package/esm/chart/__stories__/PeriodSelector.stories.js +99 -1
  108. package/esm/chart/area/Area.js +21 -9
  109. package/esm/chart/area/AreaChart.js +18 -13
  110. package/esm/chart/area/DottedArea.js +28 -18
  111. package/esm/chart/area/GradientArea.js +14 -7
  112. package/esm/chart/area/SolidArea.js +6 -2
  113. package/esm/chart/area/__stories__/AreaChart.stories.js +47 -5
  114. package/esm/chart/axis/Axis.js +5 -41
  115. package/esm/chart/axis/XAxis.js +116 -47
  116. package/esm/chart/axis/YAxis.js +105 -26
  117. package/esm/chart/axis/__stories__/Axis.stories.js +324 -48
  118. package/esm/chart/bar/Bar.js +17 -15
  119. package/esm/chart/bar/BarChart.js +38 -33
  120. package/esm/chart/bar/BarPlot.js +40 -45
  121. package/esm/chart/bar/BarStack.js +92 -475
  122. package/esm/chart/bar/BarStackGroup.js +37 -27
  123. package/esm/chart/bar/DefaultBar.js +27 -18
  124. package/esm/chart/bar/DefaultBarStack.js +25 -9
  125. package/esm/chart/bar/__stories__/BarChart.stories.js +728 -54
  126. package/esm/chart/gradient/Gradient.js +2 -1
  127. package/esm/chart/index.js +1 -0
  128. package/esm/chart/legend/DefaultLegendEntry.js +42 -0
  129. package/esm/chart/legend/DefaultLegendShape.js +64 -0
  130. package/esm/chart/legend/Legend.js +59 -0
  131. package/esm/chart/legend/__stories__/Legend.stories.js +574 -0
  132. package/esm/chart/legend/index.js +3 -0
  133. package/esm/chart/line/DottedLine.js +6 -2
  134. package/esm/chart/line/Line.js +42 -38
  135. package/esm/chart/line/LineChart.js +36 -12
  136. package/esm/chart/line/SolidLine.js +6 -2
  137. package/esm/chart/line/__stories__/LineChart.stories.js +236 -590
  138. package/esm/chart/line/__stories__/ReferenceLine.stories.js +95 -1
  139. package/esm/chart/point/Point.js +35 -36
  140. package/esm/chart/scrubber/DefaultScrubberBeacon.js +41 -38
  141. package/esm/chart/scrubber/DefaultScrubberLabel.js +26 -10
  142. package/esm/chart/scrubber/Scrubber.js +67 -35
  143. package/esm/chart/scrubber/ScrubberAccessibilityView.js +177 -0
  144. package/esm/chart/scrubber/ScrubberBeaconGroup.js +30 -22
  145. package/esm/chart/scrubber/ScrubberBeaconLabelGroup.js +35 -8
  146. package/esm/chart/scrubber/ScrubberProvider.js +29 -24
  147. package/esm/chart/scrubber/__stories__/Scrubber.stories.js +946 -0
  148. package/esm/chart/utils/axis.js +88 -44
  149. package/esm/chart/utils/bar.js +820 -0
  150. package/esm/chart/utils/chart.js +34 -7
  151. package/esm/chart/utils/context.js +7 -0
  152. package/esm/chart/utils/gradient.js +8 -4
  153. package/esm/chart/utils/path.js +91 -61
  154. package/esm/chart/utils/point.js +92 -39
  155. package/esm/chart/utils/scale.js +13 -2
  156. package/esm/chart/utils/scrubber.js +12 -5
  157. package/esm/chart/utils/transition.js +108 -60
  158. package/esm/sparkline/Sparkline.js +2 -1
  159. package/esm/sparkline/SparklineArea.js +2 -1
  160. package/esm/sparkline/SparklineGradient.js +2 -1
  161. package/esm/sparkline/__figma__/Sparkline.figma.js +1 -1
  162. package/esm/sparkline/sparkline-interactive/SparklineInteractive.js +2 -1
  163. package/esm/sparkline/sparkline-interactive/__figma__/SparklineInteractive.figma.js +1 -1
  164. package/esm/sparkline/sparkline-interactive-header/__figma__/SparklineInteractiveHeader.figma.js +1 -1
  165. package/esm/sparkline/sparkline-interactive-header/__stories__/SparklineInteractiveHeader.stories.js +2 -0
  166. package/package.json +5 -6
  167. package/esm/chart/__stories__/Chart.stories.js +0 -77
@@ -178,7 +178,8 @@ declare function SparklineInteractiveWithGeneric<Period extends string>({
178
178
  ...props
179
179
  }: SparklineInteractiveProps<Period>): import('react/jsx-runtime').JSX.Element;
180
180
  /**
181
- * @deprecated Use LineChart instead.
181
+ * @deprecated Use LineChart instead. This will be removed in a future major release.
182
+ * @deprecationExpectedRemoval v4
182
183
  */
183
184
  export declare const SparklineInteractive: typeof SparklineInteractiveWithGeneric;
184
185
  //# sourceMappingURL=SparklineInteractive.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SparklineInteractive.d.ts","sourceRoot":"","sources":["../../../src/sparkline/sparkline-interactive/SparklineInteractive.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SparklineInteractive.d.ts","sourceRoot":"","sources":["../../../src/sparkline/sparkline-interactive/SparklineInteractive.tsx"],"names":[],"mappings":"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"}
@@ -1,23 +1,32 @@
1
- const _excluded = ["series", "children", "animate", "enableScrubbing", "xAxis", "yAxis", "inset", "onScrubberPositionChange", "width", "height", "style", "styles", "allowOverflowGestures", "fontFamilies", "fontProvider", "collapsable"];
1
+ const _excluded = ["series", "children", "layout", "animate", "enableScrubbing", "getScrubberAccessibilityLabel", "scrubberAccessibilityLabelStep", "xAxis", "yAxis", "inset", "onScrubberPositionChange", "legend", "legendPosition", "legendAccessibilityLabel", "width", "height", "style", "styles", "allowOverflowGestures", "fontFamilies", "fontProvider", "collapsable", "accessible", "accessibilityLabel", "accessibilityLiveRegion"];
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 React, { forwardRef, memo, useCallback, useMemo } from 'react';
5
5
  import { useLayout } from '@coinbase/cds-mobile/hooks/useLayout';
6
6
  import { Box } from '@coinbase/cds-mobile/layout';
7
7
  import { Canvas, Skia } from '@shopify/react-native-skia';
8
+ import { ScrubberAccessibilityView } from './scrubber/ScrubberAccessibilityView';
8
9
  import { ScrubberProvider } from './scrubber/ScrubberProvider';
9
10
  import { convertToSerializableScale } from './utils/scale';
10
11
  import { useChartContextBridge } from './ChartContextBridge';
11
12
  import { CartesianChartProvider } from './ChartProvider';
12
- import { defaultAxisId, defaultChartInset, getAxisConfig, getAxisDomain, getAxisRange, getAxisScale, getChartInset, getStackedSeriesData as calculateStackedSeriesData, useTotalAxisPadding } from './utils';
13
- import { jsx as _jsx } from "react/jsx-runtime";
13
+ import { Legend } from './legend';
14
+ import { defaultAxisId, defaultHorizontalLayoutChartInset, defaultVerticalLayoutChartInset, getAxisConfig, getAxisRange, getCartesianAxisDomain, getCartesianAxisScale, getChartInset, getStackedSeriesData as calculateStackedSeriesData, useTotalAxisPadding } from './utils';
15
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
14
16
  const ChartCanvas = /*#__PURE__*/memo(_ref => {
15
17
  let {
16
18
  children,
17
- style
19
+ style,
20
+ accessible = true,
21
+ accessibilityLabel,
22
+ accessibilityLiveRegion = 'polite'
18
23
  } = _ref;
19
24
  const ContextBridge = useChartContextBridge();
25
+ const isAccessible = accessible && accessibilityLabel !== null;
20
26
  return /*#__PURE__*/_jsx(Canvas, {
27
+ accessibilityLabel: isAccessible ? accessibilityLabel : undefined,
28
+ accessibilityLiveRegion: isAccessible ? accessibilityLiveRegion : undefined,
29
+ accessible: isAccessible,
21
30
  style: [{
22
31
  width: '100%',
23
32
  height: '100%'
@@ -31,12 +40,18 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref2,
31
40
  let {
32
41
  series,
33
42
  children,
43
+ layout = 'vertical',
34
44
  animate = true,
35
45
  enableScrubbing,
46
+ getScrubberAccessibilityLabel,
47
+ scrubberAccessibilityLabelStep,
36
48
  xAxis: xAxisConfigProp,
37
49
  yAxis: yAxisConfigProp,
38
50
  inset,
39
51
  onScrubberPositionChange,
52
+ legend,
53
+ legendPosition = 'bottom',
54
+ legendAccessibilityLabel,
40
55
  width = '100%',
41
56
  height = '100%',
42
57
  style,
@@ -47,17 +62,27 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref2,
47
62
  // React Native will collapse views by default when only used
48
63
  // to group children, which interferes with gesture-handler
49
64
  // https://docs.swmansion.com/react-native-gesture-handler/docs/gestures/gesture-detector/#:~:text=%7B%0A%20%20return%20%3C-,View,-collapsable%3D%7B
50
- collapsable = false
65
+ collapsable = false,
66
+ accessible = true,
67
+ accessibilityLabel,
68
+ accessibilityLiveRegion = 'polite'
51
69
  } = _ref2,
52
70
  props = _objectWithoutPropertiesLoose(_ref2, _excluded);
53
71
  const [containerLayout, onContainerLayout] = useLayout();
54
72
  const chartWidth = containerLayout.width;
55
73
  const chartHeight = containerLayout.height;
56
- const calculatedInset = useMemo(() => getChartInset(inset, defaultChartInset), [inset]);
57
-
58
- // there can only be one x axis but the helper function always returns an array
59
- const xAxisConfig = useMemo(() => getAxisConfig('x', xAxisConfigProp)[0], [xAxisConfigProp]);
74
+ const calculatedInset = useMemo(() => getChartInset(inset, layout === 'horizontal' ? defaultHorizontalLayoutChartInset : defaultVerticalLayoutChartInset), [inset, layout]);
75
+ const xAxisConfig = useMemo(() => getAxisConfig('x', xAxisConfigProp), [xAxisConfigProp]);
60
76
  const yAxisConfig = useMemo(() => getAxisConfig('y', yAxisConfigProp), [yAxisConfigProp]);
77
+
78
+ // Horizontal layout supports multiple value axes on x, but only a single category axis on y.
79
+ // Vertical layout keeps a single x-axis to preserve existing behavior.
80
+ if (layout === 'horizontal' && yAxisConfig.length > 1) {
81
+ throw new Error('When layout="horizontal", only one y-axis is supported. See https://cds.coinbase.com/components/charts/CartesianChart.');
82
+ }
83
+ if (layout !== 'horizontal' && xAxisConfig.length > 1) {
84
+ throw new Error('Multiple x-axes are only supported when layout="horizontal". See https://cds.coinbase.com/components/charts/CartesianChart.');
85
+ }
61
86
  const {
62
87
  renderedAxes,
63
88
  registerAxis,
@@ -87,54 +112,76 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref2,
87
112
  };
88
113
  }, [chartHeight, chartWidth, totalInset]);
89
114
  const {
90
- xAxis,
91
- xScale
115
+ xAxes,
116
+ xScales
92
117
  } = useMemo(() => {
118
+ const axes = new Map();
119
+ const scales = new Map();
93
120
  if (!chartRect || chartRect.width <= 0 || chartRect.height <= 0) return {
94
- xAxis: undefined,
95
- xScale: undefined
96
- };
97
- const domain = getAxisDomain(xAxisConfig, series != null ? series : [], 'x');
98
- const range = getAxisRange(xAxisConfig, chartRect, 'x');
99
- const axisConfig = {
100
- scaleType: xAxisConfig.scaleType,
101
- domain,
102
- range,
103
- data: xAxisConfig.data,
104
- categoryPadding: xAxisConfig.categoryPadding,
105
- domainLimit: xAxisConfig.domainLimit
121
+ xAxes: axes,
122
+ xScales: scales
106
123
  };
124
+ xAxisConfig.forEach(axisParam => {
125
+ var _axisParam$id, _series$filter, _axisParam$domainLimi;
126
+ const axisId = (_axisParam$id = axisParam.id) != null ? _axisParam$id : defaultAxisId;
107
127
 
108
- // Create the scale
109
- const scale = getAxisScale({
110
- config: axisConfig,
111
- type: 'x',
112
- range: axisConfig.range,
113
- dataDomain: axisConfig.domain
114
- });
115
- if (!scale) return {
116
- xAxis: undefined,
117
- xScale: undefined
118
- };
128
+ // Get relevant series data.
129
+ const relevantSeries = xAxisConfig.length > 1 ? (_series$filter = series == null ? void 0 : series.filter(s => {
130
+ var _s$xAxisId;
131
+ return ((_s$xAxisId = s.xAxisId) != null ? _s$xAxisId : defaultAxisId) === axisId;
132
+ })) != null ? _series$filter : [] : series != null ? series : [];
133
+
134
+ // Calculate domain and range.
135
+ const dataDomain = getCartesianAxisDomain(axisParam, relevantSeries, 'x', layout);
136
+ const range = getAxisRange(axisParam, chartRect, 'x');
137
+ const axisConfig = {
138
+ scaleType: axisParam.scaleType,
139
+ domain: dataDomain,
140
+ range,
141
+ data: axisParam.data,
142
+ categoryPadding: axisParam.categoryPadding,
143
+ domainLimit: (_axisParam$domainLimi = axisParam.domainLimit) != null ? _axisParam$domainLimi : layout === 'horizontal' ? 'nice' : 'strict'
144
+ };
145
+
146
+ // Create the scale.
147
+ const scale = getCartesianAxisScale({
148
+ config: axisConfig,
149
+ type: 'x',
150
+ range: axisConfig.range,
151
+ dataDomain: axisConfig.domain,
152
+ layout
153
+ });
154
+ if (scale) {
155
+ scales.set(axisId, scale);
119
156
 
120
- // Update axis config with actual scale domain (after .nice() or other adjustments)
121
- const scaleDomain = scale.domain();
122
- const actualDomain = Array.isArray(scaleDomain) && scaleDomain.length === 2 ? {
123
- min: scaleDomain[0],
124
- max: scaleDomain[1]
125
- } : axisConfig.domain;
126
- const finalAxisConfig = _extends({}, axisConfig, {
127
- domain: actualDomain
157
+ // Update axis config with actual scale domain (after .nice() or other adjustments).
158
+ const scaleDomain = scale.domain();
159
+ const actualDomain = Array.isArray(scaleDomain) && scaleDomain.length === 2 ? {
160
+ min: scaleDomain[0],
161
+ max: scaleDomain[1]
162
+ } : axisConfig.domain;
163
+ axes.set(axisId, _extends({}, axisConfig, {
164
+ domain: actualDomain
165
+ }));
166
+ }
128
167
  });
129
168
  return {
130
- xAxis: finalAxisConfig,
131
- xScale: scale
169
+ xAxes: axes,
170
+ xScales: scales
132
171
  };
133
- }, [xAxisConfig, series, chartRect]);
134
- const xSerializableScale = useMemo(() => {
135
- if (!xScale) return;
136
- return convertToSerializableScale(xScale);
137
- }, [xScale]);
172
+ }, [xAxisConfig, series, chartRect, layout]);
173
+
174
+ // We need a set of serialized scales usable in UI thread.
175
+ const xSerializableScales = useMemo(() => {
176
+ const serializableScales = new Map();
177
+ xScales.forEach((scale, id) => {
178
+ const serializableScale = convertToSerializableScale(scale);
179
+ if (serializableScale) {
180
+ serializableScales.set(id, serializableScale);
181
+ }
182
+ });
183
+ return serializableScales;
184
+ }, [xScales]);
138
185
  const {
139
186
  yAxes,
140
187
  yScales
@@ -146,17 +193,17 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref2,
146
193
  yScales: scales
147
194
  };
148
195
  yAxisConfig.forEach(axisParam => {
149
- var _axisParam$id, _series$filter, _axisParam$domainLimi;
150
- const axisId = (_axisParam$id = axisParam.id) != null ? _axisParam$id : defaultAxisId;
196
+ var _axisParam$id2, _series$filter2, _axisParam$domainLimi2;
197
+ const axisId = (_axisParam$id2 = axisParam.id) != null ? _axisParam$id2 : defaultAxisId;
151
198
 
152
- // Get relevant series data
153
- const relevantSeries = (_series$filter = series == null ? void 0 : series.filter(s => {
199
+ // Get relevant series data.
200
+ const relevantSeries = yAxisConfig.length > 1 ? (_series$filter2 = series == null ? void 0 : series.filter(s => {
154
201
  var _s$yAxisId;
155
202
  return ((_s$yAxisId = s.yAxisId) != null ? _s$yAxisId : defaultAxisId) === axisId;
156
- })) != null ? _series$filter : [];
203
+ })) != null ? _series$filter2 : [] : series != null ? series : [];
157
204
 
158
- // Calculate domain and range
159
- const dataDomain = getAxisDomain(axisParam, relevantSeries, 'y');
205
+ // Calculate domain and range.
206
+ const dataDomain = getCartesianAxisDomain(axisParam, relevantSeries, 'y', layout);
160
207
  const range = getAxisRange(axisParam, chartRect, 'y');
161
208
  const axisConfig = {
162
209
  scaleType: axisParam.scaleType,
@@ -164,20 +211,21 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref2,
164
211
  range,
165
212
  data: axisParam.data,
166
213
  categoryPadding: axisParam.categoryPadding,
167
- domainLimit: (_axisParam$domainLimi = axisParam.domainLimit) != null ? _axisParam$domainLimi : 'nice'
214
+ domainLimit: (_axisParam$domainLimi2 = axisParam.domainLimit) != null ? _axisParam$domainLimi2 : layout === 'horizontal' ? 'strict' : 'nice'
168
215
  };
169
216
 
170
- // Create the scale
171
- const scale = getAxisScale({
217
+ // Create the scale.
218
+ const scale = getCartesianAxisScale({
172
219
  config: axisConfig,
173
220
  type: 'y',
174
221
  range: axisConfig.range,
175
- dataDomain: axisConfig.domain
222
+ dataDomain: axisConfig.domain,
223
+ layout
176
224
  });
177
225
  if (scale) {
178
226
  scales.set(axisId, scale);
179
227
 
180
- // Update axis config with actual scale domain (after .nice() or other adjustments)
228
+ // Update axis config with actual scale domain (after .nice() or other adjustments).
181
229
  const scaleDomain = scale.domain();
182
230
  const actualDomain = Array.isArray(scaleDomain) && scaleDomain.length === 2 ? {
183
231
  min: scaleDomain[0],
@@ -192,7 +240,7 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref2,
192
240
  yAxes: axes,
193
241
  yScales: scales
194
242
  };
195
- }, [yAxisConfig, series, chartRect]);
243
+ }, [yAxisConfig, series, chartRect, layout]);
196
244
 
197
245
  // We need a set of serialized scales usable in UI thread
198
246
  const ySerializableScales = useMemo(() => {
@@ -205,11 +253,11 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref2,
205
253
  });
206
254
  return serializableScales;
207
255
  }, [yScales]);
208
- const getXAxis = useCallback(() => xAxis, [xAxis]);
256
+ const getXAxis = useCallback(id => xAxes.get(id != null ? id : defaultAxisId), [xAxes]);
209
257
  const getYAxis = useCallback(id => yAxes.get(id != null ? id : defaultAxisId), [yAxes]);
210
- const getXScale = useCallback(() => xScale, [xScale]);
258
+ const getXScale = useCallback(id => xScales.get(id != null ? id : defaultAxisId), [xScales]);
211
259
  const getYScale = useCallback(id => yScales.get(id != null ? id : defaultAxisId), [yScales]);
212
- const getXSerializableScale = useCallback(() => xSerializableScale, [xSerializableScale]);
260
+ const getXSerializableScale = useCallback(id => xSerializableScales.get(id != null ? id : defaultAxisId), [xSerializableScales]);
213
261
  const getYSerializableScale = useCallback(id => ySerializableScales.get(id != null ? id : defaultAxisId), [ySerializableScales]);
214
262
  const getSeries = useCallback(seriesId => series == null ? void 0 : series.find(s => s.id === seriesId), [series]);
215
263
  const stackedDataMap = useMemo(() => {
@@ -220,20 +268,27 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref2,
220
268
  if (!seriesId) return undefined;
221
269
  return stackedDataMap.get(seriesId);
222
270
  }, [stackedDataMap]);
271
+ const categoryAxisIsX = useMemo(() => {
272
+ return layout !== 'horizontal';
273
+ }, [layout]);
274
+ const categoryAxisConfig = useMemo(() => {
275
+ var _xAxisConfig$, _yAxisConfig$;
276
+ return categoryAxisIsX ? (_xAxisConfig$ = xAxisConfig[0]) != null ? _xAxisConfig$ : yAxisConfig[0] : (_yAxisConfig$ = yAxisConfig[0]) != null ? _yAxisConfig$ : xAxisConfig[0];
277
+ }, [categoryAxisIsX, xAxisConfig, yAxisConfig]);
223
278
  const dataLength = useMemo(() => {
224
- // If xAxis has categorical data, use that length
225
- if (xAxisConfig.data && xAxisConfig.data.length > 0) {
226
- return xAxisConfig.data.length;
279
+ // If category axis has categorical data, use that length.
280
+ if (categoryAxisConfig.data && categoryAxisConfig.data.length > 0) {
281
+ return categoryAxisConfig.data.length;
227
282
  }
228
283
 
229
- // Otherwise, find the longest series
284
+ // Otherwise, find the longest series.
230
285
  if (!series || series.length === 0) return 0;
231
286
  return series.reduce((max, s) => {
232
287
  var _seriesData$length;
233
288
  const seriesData = getStackedSeriesData(s.id);
234
289
  return Math.max(max, (_seriesData$length = seriesData == null ? void 0 : seriesData.length) != null ? _seriesData$length : 0);
235
290
  }, 0);
236
- }, [xAxisConfig.data, series, getStackedSeriesData]);
291
+ }, [categoryAxisConfig, series, getStackedSeriesData]);
237
292
  const getAxisBounds = useCallback(axisId => {
238
293
  const axis = renderedAxes.get(axisId);
239
294
  if (!axis || !chartRect) return;
@@ -286,6 +341,7 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref2,
286
341
  return Skia.TypefaceFontProvider.Make();
287
342
  }, [fontProviderProp]);
288
343
  const contextValue = useMemo(() => ({
344
+ layout,
289
345
  series: series != null ? series : [],
290
346
  getSeries,
291
347
  getSeriesData: getStackedSeriesData,
@@ -305,30 +361,68 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref2,
305
361
  registerAxis,
306
362
  unregisterAxis,
307
363
  getAxisBounds
308
- }), [series, getSeries, getStackedSeriesData, animate, chartWidth, chartHeight, fontFamilies, fontProvider, getXAxis, getYAxis, getXScale, getYScale, getXSerializableScale, getYSerializableScale, chartRect, dataLength, registerAxis, unregisterAxis, getAxisBounds]);
364
+ }), [layout, series, getSeries, getStackedSeriesData, animate, chartWidth, chartHeight, fontFamilies, fontProvider, getXAxis, getYAxis, getXScale, getYScale, getXSerializableScale, getYSerializableScale, chartRect, dataLength, registerAxis, unregisterAxis, getAxisBounds]);
309
365
  const rootStyles = useMemo(() => {
310
366
  return [style, styles == null ? void 0 : styles.root];
311
367
  }, [style, styles == null ? void 0 : styles.root]);
368
+ const legendElement = useMemo(() => {
369
+ if (!legend) return;
370
+ if (legend === true) {
371
+ const isHorizontal = legendPosition === 'top' || legendPosition === 'bottom';
372
+ const flexDirection = isHorizontal ? 'row' : 'column';
373
+ return /*#__PURE__*/_jsx(Legend, {
374
+ accessibilityLabel: legendAccessibilityLabel,
375
+ flexDirection: flexDirection
376
+ });
377
+ }
378
+ return legend;
379
+ }, [legend, legendAccessibilityLabel, legendPosition]);
380
+ const rootBoxProps = useMemo(() => _extends({
381
+ ref,
382
+ height,
383
+ style: rootStyles,
384
+ width
385
+ }, props), [ref, height, rootStyles, width, props]);
312
386
  return /*#__PURE__*/_jsx(CartesianChartProvider, {
313
387
  value: contextValue,
314
388
  children: /*#__PURE__*/_jsx(ScrubberProvider, {
315
389
  allowOverflowGestures: allowOverflowGestures,
316
390
  enableScrubbing: enableScrubbing,
317
391
  onScrubberPositionChange: onScrubberPositionChange,
318
- children: /*#__PURE__*/_jsx(Box, _extends({
319
- ref: ref,
320
- accessibilityLiveRegion: "polite",
321
- accessibilityRole: "image",
392
+ children: legend ? /*#__PURE__*/_jsxs(Box, _extends({
393
+ flexDirection: legendPosition === 'top' || legendPosition === 'bottom' ? 'column' : 'row'
394
+ }, rootBoxProps, {
395
+ children: [(legendPosition === 'top' || legendPosition === 'left') && legendElement, /*#__PURE__*/_jsxs(Box, {
396
+ collapsable: collapsable,
397
+ onLayout: onContainerLayout,
398
+ style: {
399
+ flex: 1
400
+ },
401
+ children: [/*#__PURE__*/_jsx(ChartCanvas, {
402
+ accessibilityLabel: accessibilityLabel,
403
+ accessibilityLiveRegion: accessibilityLiveRegion,
404
+ accessible: accessible,
405
+ style: styles == null ? void 0 : styles.chart,
406
+ children: children
407
+ }), /*#__PURE__*/_jsx(ScrubberAccessibilityView, {
408
+ accessibilityLabel: getScrubberAccessibilityLabel,
409
+ accessibilityStep: scrubberAccessibilityLabelStep
410
+ })]
411
+ }), (legendPosition === 'bottom' || legendPosition === 'right') && legendElement]
412
+ })) : /*#__PURE__*/_jsxs(Box, _extends({
322
413
  collapsable: collapsable,
323
- height: height,
324
- onLayout: onContainerLayout,
325
- style: rootStyles,
326
- width: width
327
- }, props, {
328
- children: /*#__PURE__*/_jsx(ChartCanvas, {
414
+ onLayout: onContainerLayout
415
+ }, rootBoxProps, {
416
+ children: [/*#__PURE__*/_jsx(ChartCanvas, {
417
+ accessibilityLabel: accessibilityLabel,
418
+ accessibilityLiveRegion: accessibilityLiveRegion,
419
+ accessible: accessible,
329
420
  style: styles == null ? void 0 : styles.chart,
330
421
  children: children
331
- })
422
+ }), /*#__PURE__*/_jsx(ScrubberAccessibilityView, {
423
+ accessibilityLabel: getScrubberAccessibilityLabel,
424
+ accessibilityStep: scrubberAccessibilityLabelStep
425
+ })]
332
426
  }))
333
427
  })
334
428
  });
@@ -6,6 +6,17 @@ function _extends() { return _extends = Object.assign ? Object.assign.bind() : f
6
6
  */
7
7
 
8
8
  import * as React from 'react';
9
+ import { ThemeContext } from '@coinbase/cds-mobile/system/ThemeProvider';
10
+ import { ScrubberContext } from './utils/context';
11
+ import { CartesianChartContext } from './ChartProvider';
12
+
13
+ /**
14
+ * Whitelist of contexts that should be bridged to the Skia canvas.
15
+ * Only these contexts will be made available inside the chart's Skia tree.
16
+ * This improves performance by avoiding the overhead of rendering every bridged context.
17
+ */
18
+ import { jsx as _jsx } from "react/jsx-runtime";
19
+ const BRIDGED_CONTEXTS = [ThemeContext, CartesianChartContext, ScrubberContext];
9
20
 
10
21
  /**
11
22
  * Represents a react-internal tree node.
@@ -14,7 +25,7 @@ import * as React from 'react';
14
25
  /**
15
26
  * Represents a tree node selector for traversal.
16
27
  */
17
- import { jsx as _jsx } from "react/jsx-runtime";
28
+
18
29
  /**
19
30
  * Traverses up or down a React tree, return `true` to stop and select a node.
20
31
  */
@@ -104,7 +115,7 @@ function useTreeNode() {
104
115
  return treeNode;
105
116
  }
106
117
  /**
107
- * Returns a map of all contexts and their values.
118
+ * Returns a map of whitelisted contexts and their values.
108
119
  */
109
120
  function useContextMap() {
110
121
  const treeNode = useTreeNode();
@@ -118,7 +129,7 @@ function useContextMap() {
118
129
  // https://github.com/facebook/react/pull/28226
119
130
  const enableRenderableContext = node.type._context === undefined && node.type.Provider === node.type;
120
131
  const context = enableRenderableContext ? node.type : node.type._context;
121
- if (context && context !== TreeNodeContext && !contextMap.has(context)) {
132
+ if (context && context !== TreeNodeContext && BRIDGED_CONTEXTS.includes(context) && !contextMap.has(context)) {
122
133
  // eslint-disable-next-line react-hooks/rules-of-hooks
123
134
  contextMap.set(context, React.useContext(wrapContext(context)));
124
135
  }
@@ -1,9 +1,9 @@
1
1
  import { createContext, useContext } from 'react';
2
- const CartesianChartContext = /*#__PURE__*/createContext(undefined);
2
+ export const CartesianChartContext = /*#__PURE__*/createContext(undefined);
3
3
  export const useCartesianChartContext = () => {
4
4
  const context = useContext(CartesianChartContext);
5
5
  if (!context) {
6
- throw new Error('useCartesianChartContext must be used within a CartesianChart component. See http://cds.coinbase.com/components/graphs/CartesianChart.');
6
+ throw new Error('useCartesianChartContext must be used within a CartesianChart component. See https://cds.coinbase.com/components/charts/CartesianChart.');
7
7
  }
8
8
  return context;
9
9
  };
package/esm/chart/Path.js CHANGED
@@ -1,11 +1,12 @@
1
- const _excluded = ["d", "initialPath", "fill", "fillOpacity", "stroke", "strokeOpacity", "strokeWidth", "strokeCap", "strokeJoin", "children", "transition"],
2
- _excluded2 = ["animate", "clipRect", "clipPath", "clipOffset", "d", "initialPath", "fill", "fillOpacity", "stroke", "strokeOpacity", "strokeWidth", "strokeCap", "strokeJoin", "children", "transition"];
1
+ const _excluded = ["d", "initialPath", "fill", "fillOpacity", "stroke", "strokeOpacity", "strokeWidth", "strokeCap", "strokeJoin", "children", "transitions"],
2
+ _excluded2 = ["animate", "clipRect", "clipPath", "clipOffset", "d", "initialPath", "fill", "fillOpacity", "stroke", "strokeOpacity", "strokeWidth", "strokeCap", "strokeJoin", "children", "transitions", "transition"];
3
3
  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); }
4
4
  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; }
5
5
  import { memo, useEffect, useMemo } from 'react';
6
- import { useDerivedValue, useSharedValue, withTiming } from 'react-native-reanimated';
6
+ import { useDerivedValue, useSharedValue } from 'react-native-reanimated';
7
7
  import { Group, Path as SkiaPath, Skia, usePathInterpolation } from '@shopify/react-native-skia';
8
- import { usePathTransition } from './utils/transition';
8
+ import { defaultPathEnterTransition } from './utils/path';
9
+ import { buildTransition, defaultTransition, getTransition, usePathTransition } from './utils/transition';
9
10
  import { useCartesianChartContext } from './ChartProvider';
10
11
  import { unwrapAnimatedValue } from './utils';
11
12
 
@@ -26,17 +27,14 @@ const AnimatedPath = /*#__PURE__*/memo(_ref => {
26
27
  strokeCap,
27
28
  strokeJoin,
28
29
  children,
29
- transition
30
+ transitions
30
31
  } = _ref,
31
32
  pathProps = _objectWithoutPropertiesLoose(_ref, _excluded);
32
33
  const isDAnimated = typeof d !== 'string';
33
-
34
- // When d is animated, usePathTransition handles static path transitions.
35
- // For animated d values, we skip usePathTransition and use useDerivedValue directly.
36
34
  const animatedPath = usePathTransition({
37
35
  currentPath: isDAnimated ? '' : d,
38
36
  initialPath,
39
- transition
37
+ transitions
40
38
  });
41
39
  const isFilled = fill !== undefined && fill !== 'none';
42
40
  const isStroked = stroke !== undefined && stroke !== 'none';
@@ -84,28 +82,29 @@ export const Path = /*#__PURE__*/memo(props => {
84
82
  strokeCap,
85
83
  strokeJoin,
86
84
  children,
85
+ transitions,
87
86
  transition
88
87
  } = props,
89
88
  pathProps = _objectWithoutPropertiesLoose(props, _excluded2);
90
89
  const context = useCartesianChartContext();
91
90
  const rect = clipRect != null ? clipRect : context.drawingArea;
92
91
  const animate = animateProp != null ? animateProp : context.animate;
92
+ const isReady = !!context.getXScale();
93
+ const enterTransition = useMemo(() => getTransition(transitions == null ? void 0 : transitions.enter, animate, defaultPathEnterTransition), [animate, transitions == null ? void 0 : transitions.enter]);
94
+ const updateTransition = useMemo(() => getTransition((transitions == null ? void 0 : transitions.update) !== undefined ? transitions.update : transition, animate, defaultTransition), [animate, transitions == null ? void 0 : transitions.update, transition]);
95
+ const shouldAnimateClip = animate && enterTransition !== null;
93
96
 
94
97
  // The clip offset provides extra padding to prevent path from being cut off
95
98
  // Area charts typically use offset=0 for exact clipping, while lines use offset=2 for breathing room
96
99
  const totalOffset = clipOffset * 2; // Applied on both sides
97
100
 
98
101
  // Animation progress for clip path reveal
99
- const clipProgress = useSharedValue(animate ? 0 : 1);
100
-
101
- // Trigger clip path animation when component mounts and animate is true
102
+ const clipProgress = useSharedValue(shouldAnimateClip ? 0 : 1);
102
103
  useEffect(() => {
103
- if (animate) {
104
- clipProgress.value = withTiming(1, {
105
- duration: pathEnterTransitionDuration
106
- });
104
+ if (shouldAnimateClip && isReady) {
105
+ clipProgress.value = buildTransition(1, enterTransition);
107
106
  }
108
- }, [animate, clipProgress]);
107
+ }, [shouldAnimateClip, isReady, clipProgress, enterTransition]);
109
108
 
110
109
  // Create initial and target clip paths for animation
111
110
  const {
@@ -116,32 +115,35 @@ export const Path = /*#__PURE__*/memo(props => {
116
115
  initialClipPath: null,
117
116
  targetClipPath: null
118
117
  };
118
+ const categoryAxisIsX = context.layout !== 'horizontal';
119
+ const fullWidth = rect.width + totalOffset;
120
+ const fullHeight = rect.height + totalOffset;
119
121
 
120
- // Initial clip path (width = 0)
122
+ // Initial clip path starts collapsed on the category axis.
121
123
  const initial = Skia.Path.Make();
122
124
  initial.addRect({
123
125
  x: rect.x - clipOffset,
124
126
  y: rect.y - clipOffset,
125
- width: 0,
126
- height: rect.height + totalOffset
127
+ width: categoryAxisIsX ? 0 : fullWidth,
128
+ height: categoryAxisIsX ? fullHeight : 0
127
129
  });
128
130
 
129
- // Target clip path (full width)
131
+ // Target clip path is fully expanded.
130
132
  const target = Skia.Path.Make();
131
133
  target.addRect({
132
134
  x: rect.x - clipOffset,
133
135
  y: rect.y - clipOffset,
134
- width: rect.width + totalOffset,
135
- height: rect.height + totalOffset
136
+ width: fullWidth,
137
+ height: fullHeight
136
138
  });
137
139
  return {
138
140
  initialClipPath: initial,
139
141
  targetClipPath: target
140
142
  };
141
- }, [rect, clipOffset, totalOffset]);
143
+ }, [rect, clipOffset, totalOffset, context.layout]);
142
144
 
143
145
  // Use usePathInterpolation for animated clip path
144
- const animatedClipPath = usePathInterpolation(clipProgress, [0, 1], animate && initialClipPath && targetClipPath ? [initialClipPath, targetClipPath] : targetClipPath ? [targetClipPath, targetClipPath] : [Skia.Path.Make(), Skia.Path.Make()]);
146
+ const animatedClipPath = usePathInterpolation(clipProgress, [0, 1], shouldAnimateClip && initialClipPath && targetClipPath ? [initialClipPath, targetClipPath] : targetClipPath ? [targetClipPath, targetClipPath] : [Skia.Path.Make(), Skia.Path.Make()]);
145
147
 
146
148
  // Resolve the final clip path:
147
149
  // 1. If clipPath prop was explicitly provided, use it (even if null = no clipping)
@@ -154,13 +156,13 @@ export const Path = /*#__PURE__*/memo(props => {
154
156
  }
155
157
 
156
158
  // If not animating or paths are null, return target clip path
157
- if (!animate || !targetClipPath) {
159
+ if (!shouldAnimateClip || !targetClipPath) {
158
160
  return targetClipPath;
159
161
  }
160
162
 
161
163
  // Return undefined here since we'll use animatedClipPath directly
162
164
  return undefined;
163
- }, [clipPathProp, animate, targetClipPath]);
165
+ }, [clipPathProp, shouldAnimateClip, targetClipPath]);
164
166
 
165
167
  // Convert SVG path string to SkPath for static rendering
166
168
  const staticPath = useDerivedValue(() => {
@@ -200,12 +202,15 @@ export const Path = /*#__PURE__*/memo(props => {
200
202
  strokeJoin: strokeJoin,
201
203
  strokeOpacity: strokeOpacity,
202
204
  strokeWidth: strokeWidth,
203
- transition: transition,
205
+ transitions: {
206
+ enter: enterTransition,
207
+ update: updateTransition
208
+ },
204
209
  children: children
205
210
  });
206
211
 
207
212
  // Determine which clip path to use
208
- const finalClipPath = animate && resolvedClipPath === undefined ? animatedClipPath : resolvedClipPath;
213
+ const finalClipPath = shouldAnimateClip && resolvedClipPath === undefined ? animatedClipPath : resolvedClipPath;
209
214
 
210
215
  // If finalClipPath is null, render without clipping
211
216
  if (finalClipPath === null) {