@coinbase/cds-mobile-visualization 3.4.0-beta.2 → 3.4.0-beta.21
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 +128 -0
- package/dts/chart/CartesianChart.d.ts +92 -34
- package/dts/chart/CartesianChart.d.ts.map +1 -1
- package/dts/chart/ChartContextBridge.d.ts +28 -0
- package/dts/chart/ChartContextBridge.d.ts.map +1 -0
- package/dts/chart/ChartProvider.d.ts +3 -0
- package/dts/chart/ChartProvider.d.ts.map +1 -1
- package/dts/chart/Path.d.ts +97 -32
- package/dts/chart/Path.d.ts.map +1 -1
- package/dts/chart/PeriodSelector.d.ts +6 -13
- package/dts/chart/PeriodSelector.d.ts.map +1 -1
- package/dts/chart/area/Area.d.ts +39 -28
- package/dts/chart/area/Area.d.ts.map +1 -1
- package/dts/chart/area/AreaChart.d.ts +51 -10
- package/dts/chart/area/AreaChart.d.ts.map +1 -1
- package/dts/chart/area/DottedArea.d.ts +21 -2
- package/dts/chart/area/DottedArea.d.ts.map +1 -1
- package/dts/chart/area/GradientArea.d.ts +19 -13
- package/dts/chart/area/GradientArea.d.ts.map +1 -1
- package/dts/chart/area/SolidArea.d.ts +17 -2
- package/dts/chart/area/SolidArea.d.ts.map +1 -1
- package/dts/chart/axis/Axis.d.ts +86 -118
- package/dts/chart/axis/Axis.d.ts.map +1 -1
- package/dts/chart/axis/DefaultAxisTickLabel.d.ts +8 -0
- package/dts/chart/axis/DefaultAxisTickLabel.d.ts.map +1 -0
- package/dts/chart/axis/XAxis.d.ts +1 -1
- package/dts/chart/axis/XAxis.d.ts.map +1 -1
- package/dts/chart/axis/YAxis.d.ts +2 -2
- package/dts/chart/axis/YAxis.d.ts.map +1 -1
- package/dts/chart/axis/index.d.ts +1 -0
- package/dts/chart/axis/index.d.ts.map +1 -1
- package/dts/chart/bar/Bar.d.ts +49 -12
- package/dts/chart/bar/Bar.d.ts.map +1 -1
- package/dts/chart/bar/BarChart.d.ts +40 -19
- package/dts/chart/bar/BarChart.d.ts.map +1 -1
- package/dts/chart/bar/BarPlot.d.ts +3 -1
- package/dts/chart/bar/BarPlot.d.ts.map +1 -1
- package/dts/chart/bar/BarStack.d.ts +41 -46
- package/dts/chart/bar/BarStack.d.ts.map +1 -1
- package/dts/chart/bar/BarStackGroup.d.ts +2 -0
- package/dts/chart/bar/BarStackGroup.d.ts.map +1 -1
- package/dts/chart/bar/DefaultBar.d.ts +1 -1
- package/dts/chart/bar/DefaultBar.d.ts.map +1 -1
- package/dts/chart/bar/DefaultBarStack.d.ts.map +1 -1
- package/dts/chart/gradient/Gradient.d.ts +25 -0
- package/dts/chart/gradient/Gradient.d.ts.map +1 -0
- package/dts/chart/gradient/index.d.ts +2 -0
- package/dts/chart/gradient/index.d.ts.map +1 -0
- package/dts/chart/index.d.ts +4 -1
- package/dts/chart/index.d.ts.map +1 -1
- package/dts/chart/legend/DefaultLegendEntry.d.ts +5 -0
- package/dts/chart/legend/DefaultLegendEntry.d.ts.map +1 -0
- package/dts/chart/legend/DefaultLegendShape.d.ts +5 -0
- package/dts/chart/legend/DefaultLegendShape.d.ts.map +1 -0
- package/dts/chart/legend/Legend.d.ts +168 -0
- package/dts/chart/legend/Legend.d.ts.map +1 -0
- package/dts/chart/legend/index.d.ts +4 -0
- package/dts/chart/legend/index.d.ts.map +1 -0
- package/dts/chart/line/DefaultReferenceLineLabel.d.ts +9 -0
- package/dts/chart/line/DefaultReferenceLineLabel.d.ts.map +1 -0
- package/dts/chart/line/DottedLine.d.ts +13 -5
- package/dts/chart/line/DottedLine.d.ts.map +1 -1
- package/dts/chart/line/Line.d.ts +61 -27
- package/dts/chart/line/Line.d.ts.map +1 -1
- package/dts/chart/line/LineChart.d.ts +43 -9
- package/dts/chart/line/LineChart.d.ts.map +1 -1
- package/dts/chart/line/ReferenceLine.d.ts +68 -20
- package/dts/chart/line/ReferenceLine.d.ts.map +1 -1
- package/dts/chart/line/SolidLine.d.ts +8 -5
- package/dts/chart/line/SolidLine.d.ts.map +1 -1
- package/dts/chart/line/index.d.ts +1 -1
- package/dts/chart/line/index.d.ts.map +1 -1
- package/dts/chart/point/DefaultPointLabel.d.ts +10 -0
- package/dts/chart/point/DefaultPointLabel.d.ts.map +1 -0
- package/dts/chart/point/Point.d.ts +136 -0
- package/dts/chart/point/Point.d.ts.map +1 -0
- package/dts/chart/point/index.d.ts +3 -0
- package/dts/chart/point/index.d.ts.map +1 -0
- package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts +38 -0
- package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts.map +1 -0
- package/dts/chart/scrubber/DefaultScrubberBeaconLabel.d.ts +12 -0
- package/dts/chart/scrubber/DefaultScrubberBeaconLabel.d.ts.map +1 -0
- package/dts/chart/scrubber/DefaultScrubberLabel.d.ts +11 -0
- package/dts/chart/scrubber/DefaultScrubberLabel.d.ts.map +1 -0
- package/dts/chart/scrubber/Scrubber.d.ts +230 -42
- package/dts/chart/scrubber/Scrubber.d.ts.map +1 -1
- package/dts/chart/scrubber/ScrubberBeaconGroup.d.ts +54 -0
- package/dts/chart/scrubber/ScrubberBeaconGroup.d.ts.map +1 -0
- package/dts/chart/scrubber/ScrubberBeaconLabelGroup.d.ts +46 -0
- package/dts/chart/scrubber/ScrubberBeaconLabelGroup.d.ts.map +1 -0
- package/dts/chart/scrubber/ScrubberProvider.d.ts +6 -3
- package/dts/chart/scrubber/ScrubberProvider.d.ts.map +1 -1
- package/dts/chart/scrubber/index.d.ts +3 -0
- package/dts/chart/scrubber/index.d.ts.map +1 -1
- package/dts/chart/text/ChartText.d.ts +151 -77
- package/dts/chart/text/ChartText.d.ts.map +1 -1
- package/dts/chart/text/{SmartChartTextGroup.d.ts → ChartTextGroup.d.ts} +9 -3
- package/dts/chart/text/ChartTextGroup.d.ts.map +1 -0
- package/dts/chart/text/index.d.ts +1 -1
- package/dts/chart/text/index.d.ts.map +1 -1
- package/dts/chart/utils/axis.d.ts +25 -1
- package/dts/chart/utils/axis.d.ts.map +1 -1
- package/dts/chart/utils/bar.d.ts +34 -0
- package/dts/chart/utils/bar.d.ts.map +1 -1
- package/dts/chart/utils/chart.d.ts +52 -7
- package/dts/chart/utils/chart.d.ts.map +1 -1
- package/dts/chart/utils/context.d.ts +28 -7
- package/dts/chart/utils/context.d.ts.map +1 -1
- package/dts/chart/utils/gradient.d.ts +117 -0
- package/dts/chart/utils/gradient.d.ts.map +1 -0
- package/dts/chart/utils/index.d.ts +3 -0
- package/dts/chart/utils/index.d.ts.map +1 -1
- package/dts/chart/utils/path.d.ts +59 -0
- package/dts/chart/utils/path.d.ts.map +1 -1
- package/dts/chart/utils/point.d.ts +71 -7
- package/dts/chart/utils/point.d.ts.map +1 -1
- package/dts/chart/utils/scale.d.ts +102 -0
- package/dts/chart/utils/scale.d.ts.map +1 -1
- package/dts/chart/utils/scrubber.d.ts +40 -0
- package/dts/chart/utils/scrubber.d.ts.map +1 -0
- package/dts/chart/utils/transition.d.ts +178 -0
- package/dts/chart/utils/transition.d.ts.map +1 -0
- package/esm/chart/CartesianChart.js +199 -75
- package/esm/chart/ChartContextBridge.js +159 -0
- package/esm/chart/ChartProvider.js +2 -2
- package/esm/chart/Path.js +200 -114
- package/esm/chart/PeriodSelector.js +7 -3
- package/esm/chart/__stories__/CartesianChart.stories.js +307 -134
- package/esm/chart/__stories__/ChartTransitions.stories.js +629 -0
- package/esm/chart/__stories__/PeriodSelector.stories.js +201 -75
- package/esm/chart/area/Area.js +27 -35
- package/esm/chart/area/AreaChart.js +17 -12
- package/esm/chart/area/DottedArea.js +64 -108
- package/esm/chart/area/GradientArea.js +37 -91
- package/esm/chart/area/SolidArea.js +24 -8
- package/esm/chart/area/__stories__/AreaChart.stories.js +1 -1
- package/esm/chart/axis/Axis.js +5 -39
- package/esm/chart/axis/DefaultAxisTickLabel.js +11 -0
- package/esm/chart/axis/XAxis.js +148 -66
- package/esm/chart/axis/YAxis.js +149 -65
- package/esm/chart/axis/__stories__/Axis.stories.js +259 -1
- package/esm/chart/axis/index.js +1 -0
- package/esm/chart/bar/Bar.js +7 -1
- package/esm/chart/bar/BarChart.js +17 -37
- package/esm/chart/bar/BarPlot.js +43 -35
- package/esm/chart/bar/BarStack.js +84 -37
- package/esm/chart/bar/BarStackGroup.js +7 -17
- package/esm/chart/bar/DefaultBar.js +29 -51
- package/esm/chart/bar/DefaultBarStack.js +34 -58
- package/esm/chart/bar/__stories__/BarChart.stories.js +948 -88
- package/esm/chart/gradient/Gradient.js +53 -0
- package/esm/chart/gradient/index.js +1 -0
- package/esm/chart/index.js +4 -1
- package/esm/chart/legend/DefaultLegendEntry.js +42 -0
- package/esm/chart/legend/DefaultLegendShape.js +64 -0
- package/esm/chart/legend/Legend.js +59 -0
- package/esm/chart/legend/__stories__/Legend.stories.js +574 -0
- package/esm/chart/legend/index.js +3 -0
- package/esm/chart/line/DefaultReferenceLineLabel.js +66 -0
- package/esm/chart/line/DottedLine.js +31 -14
- package/esm/chart/line/Line.js +96 -68
- package/esm/chart/line/LineChart.js +21 -14
- package/esm/chart/line/ReferenceLine.js +80 -63
- package/esm/chart/line/SolidLine.js +27 -10
- package/esm/chart/line/__stories__/LineChart.stories.js +1748 -2048
- package/esm/chart/line/__stories__/ReferenceLine.stories.js +177 -28
- package/esm/chart/line/index.js +1 -1
- package/esm/chart/point/DefaultPointLabel.js +39 -0
- package/esm/chart/point/Point.js +186 -0
- package/esm/chart/point/index.js +2 -0
- package/esm/chart/scrubber/DefaultScrubberBeacon.js +180 -0
- package/esm/chart/scrubber/DefaultScrubberBeaconLabel.js +43 -0
- package/esm/chart/scrubber/DefaultScrubberLabel.js +28 -0
- package/esm/chart/scrubber/Scrubber.js +130 -144
- package/esm/chart/scrubber/ScrubberBeaconGroup.js +165 -0
- package/esm/chart/scrubber/ScrubberBeaconLabelGroup.js +208 -0
- package/esm/chart/scrubber/ScrubberProvider.js +46 -54
- package/esm/chart/scrubber/__stories__/Scrubber.stories.js +760 -0
- package/esm/chart/scrubber/index.js +3 -1
- package/esm/chart/text/ChartText.js +242 -174
- package/esm/chart/text/{SmartChartTextGroup.js → ChartTextGroup.js} +6 -5
- package/esm/chart/text/index.js +1 -1
- package/esm/chart/utils/axis.js +47 -31
- package/esm/chart/utils/bar.js +43 -0
- package/esm/chart/utils/chart.js +57 -3
- package/esm/chart/utils/gradient.js +305 -0
- package/esm/chart/utils/index.js +3 -0
- package/esm/chart/utils/path.js +84 -8
- package/esm/chart/utils/point.js +171 -17
- package/esm/chart/utils/scale.js +242 -2
- package/esm/chart/utils/scrubber.js +146 -0
- package/esm/chart/utils/transition.js +215 -0
- package/esm/sparkline/__figma__/Sparkline.figma.js +1 -1
- package/esm/sparkline/__stories__/Sparkline.stories.js +11 -7
- package/esm/sparkline/__stories__/SparklineGradient.stories.js +7 -4
- package/esm/sparkline/sparkline-interactive/__figma__/SparklineInteractive.figma.js +1 -1
- package/esm/sparkline/sparkline-interactive/__stories__/SparklineInteractive.stories.js +51 -26
- package/esm/sparkline/sparkline-interactive-header/__figma__/SparklineInteractiveHeader.figma.js +1 -1
- package/esm/sparkline/sparkline-interactive-header/__stories__/SparklineInteractiveHeader.stories.js +17 -9
- package/package.json +15 -10
- package/dts/chart/Point.d.ts +0 -103
- package/dts/chart/Point.d.ts.map +0 -1
- package/dts/chart/line/GradientLine.d.ts +0 -45
- package/dts/chart/line/GradientLine.d.ts.map +0 -1
- package/dts/chart/scrubber/ScrubberBeacon.d.ts +0 -75
- package/dts/chart/scrubber/ScrubberBeacon.d.ts.map +0 -1
- package/dts/chart/text/SmartChartTextGroup.d.ts.map +0 -1
- package/esm/chart/Point.js +0 -111
- package/esm/chart/__stories__/Chart.stories.js +0 -79
- package/esm/chart/line/GradientLine.js +0 -62
- package/esm/chart/scrubber/ScrubberBeacon.js +0 -199
|
@@ -0,0 +1,159 @@
|
|
|
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
|
+
/**
|
|
3
|
+
* Simplified context bridge utilities for React Native.
|
|
4
|
+
* Adapted from its-fine to enable context sharing across React renderers
|
|
5
|
+
* https://github.com/pmndrs/its-fine/blob/598b81f02778c22ed21121c2b1a786bdefb14e23/src/index.tsx
|
|
6
|
+
*/
|
|
7
|
+
|
|
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];
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Represents a react-internal tree node.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Represents a tree node selector for traversal.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Traverses up or down a React tree, return `true` to stop and select a node.
|
|
31
|
+
*/
|
|
32
|
+
function traverseTreeNode(node, ascending, selector) {
|
|
33
|
+
if (!node) return;
|
|
34
|
+
if (selector(node) === true) return node;
|
|
35
|
+
let child = ascending ? node.return : node.child;
|
|
36
|
+
while (child) {
|
|
37
|
+
const match = traverseTreeNode(child, ascending, selector);
|
|
38
|
+
if (match) return match;
|
|
39
|
+
child = ascending ? null : child.sibling;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Wraps context to hide React development warnings about using contexts between renderers.
|
|
45
|
+
*/
|
|
46
|
+
function wrapContext(context) {
|
|
47
|
+
try {
|
|
48
|
+
return Object.defineProperties(context, {
|
|
49
|
+
_currentRenderer: {
|
|
50
|
+
get() {
|
|
51
|
+
return null;
|
|
52
|
+
},
|
|
53
|
+
set() {}
|
|
54
|
+
},
|
|
55
|
+
_currentRenderer2: {
|
|
56
|
+
get() {
|
|
57
|
+
return null;
|
|
58
|
+
},
|
|
59
|
+
set() {}
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
} catch (_) {
|
|
63
|
+
return context;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// In development, React will warn about using contexts between renderers.
|
|
68
|
+
// Suppress the warning because our context bridge fixes this issue
|
|
69
|
+
const error = console.error;
|
|
70
|
+
console.error = function () {
|
|
71
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
72
|
+
args[_key] = arguments[_key];
|
|
73
|
+
}
|
|
74
|
+
const message = args.join('');
|
|
75
|
+
if (message != null && message.startsWith('Warning:') && message.includes('useContext')) {
|
|
76
|
+
console.error = error;
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
return error.apply(this, args);
|
|
80
|
+
};
|
|
81
|
+
const TreeNodeContext = wrapContext(/*#__PURE__*/React.createContext(null));
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* A react-internal tree node provider that binds React children to the React tree for chart context bridging.
|
|
85
|
+
*/
|
|
86
|
+
export class ChartBridgeProvider extends React.Component {
|
|
87
|
+
render() {
|
|
88
|
+
return /*#__PURE__*/_jsx(TreeNodeContext.Provider, {
|
|
89
|
+
value: this._reactInternals,
|
|
90
|
+
children: this.props.children
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Returns the current react-internal tree node.
|
|
97
|
+
*/
|
|
98
|
+
function useTreeNode() {
|
|
99
|
+
const root = React.useContext(TreeNodeContext);
|
|
100
|
+
if (root === null) throw new Error('useTreeNode must be called within a <ChartBridgeProvider />!');
|
|
101
|
+
const id = React.useId();
|
|
102
|
+
const treeNode = React.useMemo(() => {
|
|
103
|
+
for (const maybeNode of [root, root == null ? void 0 : root.alternate]) {
|
|
104
|
+
if (!maybeNode) continue;
|
|
105
|
+
const node = traverseTreeNode(maybeNode, false, node => {
|
|
106
|
+
let state = node.memoizedState;
|
|
107
|
+
while (state) {
|
|
108
|
+
if (state.memoizedState === id) return true;
|
|
109
|
+
state = state.next;
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
if (node) return node;
|
|
113
|
+
}
|
|
114
|
+
}, [root, id]);
|
|
115
|
+
return treeNode;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Returns a map of whitelisted contexts and their values.
|
|
119
|
+
*/
|
|
120
|
+
function useContextMap() {
|
|
121
|
+
const treeNode = useTreeNode();
|
|
122
|
+
const [contextMap] = React.useState(() => new Map());
|
|
123
|
+
|
|
124
|
+
// Collect live context
|
|
125
|
+
contextMap.clear();
|
|
126
|
+
let node = treeNode;
|
|
127
|
+
while (node) {
|
|
128
|
+
if (node.type && typeof node.type === 'object') {
|
|
129
|
+
// https://github.com/facebook/react/pull/28226
|
|
130
|
+
const enableRenderableContext = node.type._context === undefined && node.type.Provider === node.type;
|
|
131
|
+
const context = enableRenderableContext ? node.type : node.type._context;
|
|
132
|
+
if (context && context !== TreeNodeContext && BRIDGED_CONTEXTS.includes(context) && !contextMap.has(context)) {
|
|
133
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
134
|
+
contextMap.set(context, React.useContext(wrapContext(context)));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
node = node.return;
|
|
138
|
+
}
|
|
139
|
+
return contextMap;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Represents a chart context bridge provider component.
|
|
144
|
+
*/
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Returns a ChartContextBridge of live context providers to pierce Context across renderers.
|
|
148
|
+
* Pass ChartContextBridge as a component to a secondary renderer (e.g., Skia Canvas) to enable context-sharing in charts.
|
|
149
|
+
*/
|
|
150
|
+
export function useChartContextBridge() {
|
|
151
|
+
const contextMap = useContextMap();
|
|
152
|
+
|
|
153
|
+
// Flatten context and their memoized values into a `ChartContextBridge` provider
|
|
154
|
+
return React.useMemo(() => Array.from(contextMap.keys()).reduce((Prev, context) => props => /*#__PURE__*/_jsx(Prev, {
|
|
155
|
+
children: /*#__PURE__*/_jsx(context.Provider, _extends({}, props, {
|
|
156
|
+
value: contextMap.get(context)
|
|
157
|
+
}))
|
|
158
|
+
}), props => /*#__PURE__*/_jsx(ChartBridgeProvider, _extends({}, props))), [contextMap]);
|
|
159
|
+
}
|
|
@@ -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
|
|
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,133 +1,219 @@
|
|
|
1
|
-
const _excluded = ["
|
|
2
|
-
|
|
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
|
-
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
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
|
+
import { memo, useEffect, useMemo } from 'react';
|
|
6
|
+
import { useDerivedValue, useSharedValue } from 'react-native-reanimated';
|
|
7
|
+
import { Group, Path as SkiaPath, Skia, usePathInterpolation } from '@shopify/react-native-skia';
|
|
8
|
+
import { defaultPathEnterTransition } from './utils/path';
|
|
9
|
+
import { buildTransition, defaultTransition, getTransition, usePathTransition } from './utils/transition';
|
|
9
10
|
import { useCartesianChartContext } from './ChartProvider';
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
import { unwrapAnimatedValue } from './utils';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Duration in milliseconds for path enter transition.
|
|
15
|
+
*/
|
|
16
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
17
|
+
export const pathEnterTransitionDuration = 500;
|
|
18
|
+
const AnimatedPath = /*#__PURE__*/memo(_ref => {
|
|
13
19
|
let {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
d = '',
|
|
21
|
+
initialPath,
|
|
22
|
+
fill,
|
|
23
|
+
fillOpacity,
|
|
24
|
+
stroke,
|
|
25
|
+
strokeOpacity,
|
|
26
|
+
strokeWidth,
|
|
27
|
+
strokeCap,
|
|
28
|
+
strokeJoin,
|
|
29
|
+
children,
|
|
30
|
+
transitions
|
|
31
|
+
} = _ref,
|
|
32
|
+
pathProps = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
33
|
+
const isDAnimated = typeof d !== 'string';
|
|
34
|
+
const animatedPath = usePathTransition({
|
|
35
|
+
currentPath: isDAnimated ? '' : d,
|
|
36
|
+
initialPath,
|
|
37
|
+
transitions
|
|
38
|
+
});
|
|
39
|
+
const isFilled = fill !== undefined && fill !== 'none';
|
|
40
|
+
const isStroked = stroke !== undefined && stroke !== 'none';
|
|
41
|
+
const activePath = useDerivedValue(() => {
|
|
42
|
+
if (isDAnimated) {
|
|
43
|
+
var _d$value;
|
|
44
|
+
return (_d$value = d.value) != null ? _d$value : Skia.Path.Make();
|
|
45
|
+
}
|
|
46
|
+
return animatedPath.value;
|
|
47
|
+
});
|
|
48
|
+
return /*#__PURE__*/_jsxs(_Fragment, {
|
|
49
|
+
children: [isFilled && /*#__PURE__*/_jsx(SkiaPath, _extends({
|
|
50
|
+
color: fill,
|
|
51
|
+
opacity: fillOpacity,
|
|
52
|
+
path: activePath,
|
|
53
|
+
style: "fill"
|
|
54
|
+
}, pathProps, {
|
|
55
|
+
children: children
|
|
56
|
+
})), isStroked && /*#__PURE__*/_jsx(SkiaPath, _extends({
|
|
57
|
+
color: stroke,
|
|
58
|
+
opacity: strokeOpacity,
|
|
59
|
+
path: activePath,
|
|
60
|
+
strokeCap: strokeCap,
|
|
61
|
+
strokeJoin: strokeJoin,
|
|
62
|
+
strokeWidth: strokeWidth,
|
|
63
|
+
style: "stroke"
|
|
64
|
+
}, pathProps, {
|
|
65
|
+
children: children
|
|
66
|
+
}))]
|
|
23
67
|
});
|
|
24
|
-
useEffect(() => {
|
|
25
|
-
animatedWidth.value = withTiming(width + totalOffset, {
|
|
26
|
-
duration: 1000
|
|
27
|
-
});
|
|
28
|
-
}, [animatedWidth, width, totalOffset]);
|
|
29
|
-
return /*#__PURE__*/_jsx(AnimatedRect, _extends({
|
|
30
|
-
animatedProps: animatedProps
|
|
31
|
-
}, rectProps));
|
|
32
68
|
});
|
|
33
|
-
export const Path = /*#__PURE__*/memo(
|
|
34
|
-
|
|
69
|
+
export const Path = /*#__PURE__*/memo(props => {
|
|
70
|
+
const {
|
|
71
|
+
animate: animateProp,
|
|
35
72
|
clipRect,
|
|
36
|
-
|
|
73
|
+
clipPath: clipPathProp,
|
|
74
|
+
clipOffset = 0,
|
|
37
75
|
d = '',
|
|
76
|
+
initialPath,
|
|
38
77
|
fill,
|
|
78
|
+
fillOpacity,
|
|
39
79
|
stroke,
|
|
40
|
-
strokeWidth,
|
|
41
80
|
strokeOpacity,
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
const
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const
|
|
60
|
-
if (!animate) return targetPath;
|
|
61
|
-
return previousPath != null ? previousPath : targetPath;
|
|
62
|
-
}, [animate, previousPath, targetPath]);
|
|
63
|
-
const pathInterpolator = useMemo(() => interpolate.interpolatePath(fromPath, targetPath), [fromPath, targetPath]);
|
|
64
|
-
const updatePath = useCallback(progress => {
|
|
65
|
-
var _pathRef$current;
|
|
66
|
-
if (!pathInterpolator) return;
|
|
67
|
-
const val = Number(progress.toFixed(4));
|
|
68
|
-
(_pathRef$current = pathRef.current) == null || _pathRef$current.setNativeProps({
|
|
69
|
-
d: pathInterpolator(val)
|
|
70
|
-
});
|
|
71
|
-
}, [pathInterpolator]);
|
|
72
|
-
useAnimatedReaction(() => animationProgress.value, progress => {
|
|
73
|
-
'worklet';
|
|
81
|
+
strokeWidth,
|
|
82
|
+
strokeCap,
|
|
83
|
+
strokeJoin,
|
|
84
|
+
children,
|
|
85
|
+
transitions,
|
|
86
|
+
transition
|
|
87
|
+
} = props,
|
|
88
|
+
pathProps = _objectWithoutPropertiesLoose(props, _excluded2);
|
|
89
|
+
const context = useCartesianChartContext();
|
|
90
|
+
const rect = clipRect != null ? clipRect : context.drawingArea;
|
|
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
|
+
|
|
96
|
+
// The clip offset provides extra padding to prevent path from being cut off
|
|
97
|
+
// Area charts typically use offset=0 for exact clipping, while lines use offset=2 for breathing room
|
|
98
|
+
const totalOffset = clipOffset * 2; // Applied on both sides
|
|
74
99
|
|
|
75
|
-
|
|
76
|
-
|
|
100
|
+
// Animation progress for clip path reveal
|
|
101
|
+
const clipProgress = useSharedValue(animate ? 0 : 1);
|
|
77
102
|
useEffect(() => {
|
|
78
|
-
if (
|
|
79
|
-
|
|
80
|
-
pathRef.current.setNativeProps({
|
|
81
|
-
d: targetPath
|
|
82
|
-
});
|
|
83
|
-
animationProgress.value = 1;
|
|
84
|
-
return;
|
|
103
|
+
if (animate && isReady) {
|
|
104
|
+
clipProgress.value = buildTransition(1, enterTransition);
|
|
85
105
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
106
|
+
}, [animate, isReady, clipProgress, enterTransition]);
|
|
107
|
+
|
|
108
|
+
// Create initial and target clip paths for animation
|
|
109
|
+
const {
|
|
110
|
+
initialClipPath,
|
|
111
|
+
targetClipPath
|
|
112
|
+
} = useMemo(() => {
|
|
113
|
+
if (!rect) return {
|
|
114
|
+
initialClipPath: null,
|
|
115
|
+
targetClipPath: null
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
// Initial clip path (width = 0)
|
|
119
|
+
const initial = Skia.Path.Make();
|
|
120
|
+
initial.addRect({
|
|
121
|
+
x: rect.x - clipOffset,
|
|
122
|
+
y: rect.y - clipOffset,
|
|
123
|
+
width: 0,
|
|
124
|
+
height: rect.height + totalOffset
|
|
89
125
|
});
|
|
90
|
-
}, [animate, animationProgress, targetPath, pathInterpolator]);
|
|
91
|
-
if (!d || !rect) return;
|
|
92
126
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
127
|
+
// Target clip path (full width)
|
|
128
|
+
const target = Skia.Path.Make();
|
|
129
|
+
target.addRect({
|
|
130
|
+
x: rect.x - clipOffset,
|
|
131
|
+
y: rect.y - clipOffset,
|
|
132
|
+
width: rect.width + totalOffset,
|
|
133
|
+
height: rect.height + totalOffset
|
|
134
|
+
});
|
|
135
|
+
return {
|
|
136
|
+
initialClipPath: initial,
|
|
137
|
+
targetClipPath: target
|
|
138
|
+
};
|
|
139
|
+
}, [rect, clipOffset, totalOffset]);
|
|
140
|
+
|
|
141
|
+
// Use usePathInterpolation for animated clip path
|
|
142
|
+
const animatedClipPath = usePathInterpolation(clipProgress, [0, 1], animate && initialClipPath && targetClipPath ? [initialClipPath, targetClipPath] : targetClipPath ? [targetClipPath, targetClipPath] : [Skia.Path.Make(), Skia.Path.Make()]);
|
|
96
143
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
144
|
+
// Resolve the final clip path:
|
|
145
|
+
// 1. If clipPath prop was explicitly provided, use it (even if null = no clipping)
|
|
146
|
+
// 2. If animating, use the interpolated clip path
|
|
147
|
+
// 3. Otherwise, use static target clip path
|
|
148
|
+
const resolvedClipPath = useMemo(() => {
|
|
149
|
+
// If clipPath was explicitly provided (null or string), use it directly
|
|
150
|
+
if (clipPathProp !== undefined) {
|
|
151
|
+
return clipPathProp;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// If not animating or paths are null, return target clip path
|
|
155
|
+
if (!animate || !targetClipPath) {
|
|
156
|
+
return targetClipPath;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Return undefined here since we'll use animatedClipPath directly
|
|
160
|
+
return undefined;
|
|
161
|
+
}, [clipPathProp, animate, targetClipPath]);
|
|
162
|
+
|
|
163
|
+
// Convert SVG path string to SkPath for static rendering
|
|
164
|
+
const staticPath = useDerivedValue(() => {
|
|
165
|
+
var _Skia$Path$MakeFromSV;
|
|
166
|
+
const dValue = unwrapAnimatedValue(d);
|
|
167
|
+
if (!dValue) return Skia.Path.Make();
|
|
168
|
+
return (_Skia$Path$MakeFromSV = Skia.Path.MakeFromSVGString(dValue)) != null ? _Skia$Path$MakeFromSV : Skia.Path.Make();
|
|
169
|
+
}, [d]);
|
|
170
|
+
const isFilled = fill !== undefined && fill !== 'none';
|
|
171
|
+
const isStroked = stroke !== undefined && stroke !== 'none';
|
|
172
|
+
const content = !animate ? /*#__PURE__*/_jsxs(_Fragment, {
|
|
173
|
+
children: [isFilled && /*#__PURE__*/_jsx(SkiaPath, _extends({
|
|
174
|
+
color: fill,
|
|
175
|
+
opacity: fillOpacity,
|
|
176
|
+
path: staticPath,
|
|
177
|
+
style: "fill"
|
|
178
|
+
}, pathProps, {
|
|
179
|
+
children: children
|
|
180
|
+
})), isStroked && /*#__PURE__*/_jsx(SkiaPath, _extends({
|
|
181
|
+
color: stroke,
|
|
182
|
+
opacity: strokeOpacity,
|
|
183
|
+
path: staticPath,
|
|
184
|
+
strokeCap: strokeCap,
|
|
185
|
+
strokeJoin: strokeJoin,
|
|
129
186
|
strokeWidth: strokeWidth,
|
|
130
|
-
|
|
131
|
-
}, pathProps
|
|
187
|
+
style: "stroke"
|
|
188
|
+
}, pathProps, {
|
|
189
|
+
children: children
|
|
190
|
+
}))]
|
|
191
|
+
}) : /*#__PURE__*/_jsx(AnimatedPath, {
|
|
192
|
+
d: d,
|
|
193
|
+
fill: fill,
|
|
194
|
+
fillOpacity: fillOpacity,
|
|
195
|
+
initialPath: initialPath,
|
|
196
|
+
stroke: stroke,
|
|
197
|
+
strokeCap: strokeCap,
|
|
198
|
+
strokeJoin: strokeJoin,
|
|
199
|
+
strokeOpacity: strokeOpacity,
|
|
200
|
+
strokeWidth: strokeWidth,
|
|
201
|
+
transitions: {
|
|
202
|
+
enter: enterTransition,
|
|
203
|
+
update: updateTransition
|
|
204
|
+
},
|
|
205
|
+
children: children
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
// Determine which clip path to use
|
|
209
|
+
const finalClipPath = animate && resolvedClipPath === undefined ? animatedClipPath : resolvedClipPath;
|
|
210
|
+
|
|
211
|
+
// If finalClipPath is null, render without clipping
|
|
212
|
+
if (finalClipPath === null) {
|
|
213
|
+
return content;
|
|
214
|
+
}
|
|
215
|
+
return /*#__PURE__*/_jsx(Group, {
|
|
216
|
+
clip: finalClipPath,
|
|
217
|
+
children: content
|
|
132
218
|
});
|
|
133
219
|
});
|
|
@@ -9,7 +9,7 @@ import { useTheme } from '@coinbase/cds-mobile/hooks/useTheme';
|
|
|
9
9
|
import { SegmentedTabs } from '@coinbase/cds-mobile/tabs';
|
|
10
10
|
import { SegmentedTab } from '@coinbase/cds-mobile/tabs/SegmentedTab';
|
|
11
11
|
import { tabsSpringConfig } from '@coinbase/cds-mobile/tabs/Tabs';
|
|
12
|
-
import { Text } from '@coinbase/cds-mobile/typography
|
|
12
|
+
import { Text } from '@coinbase/cds-mobile/typography';
|
|
13
13
|
|
|
14
14
|
// Animated active indicator to support smooth transition of background color
|
|
15
15
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
@@ -24,7 +24,8 @@ export const PeriodSelectorActiveIndicator = _ref => {
|
|
|
24
24
|
const {
|
|
25
25
|
width,
|
|
26
26
|
height,
|
|
27
|
-
x
|
|
27
|
+
x,
|
|
28
|
+
y
|
|
28
29
|
} = activeTabRect;
|
|
29
30
|
|
|
30
31
|
// Get the target background color
|
|
@@ -38,6 +39,7 @@ export const PeriodSelectorActiveIndicator = _ref => {
|
|
|
38
39
|
// Combined animated value for position, size, and color
|
|
39
40
|
const newAnimatedValues = {
|
|
40
41
|
x,
|
|
42
|
+
y,
|
|
41
43
|
width,
|
|
42
44
|
backgroundColor: targetColor
|
|
43
45
|
};
|
|
@@ -51,11 +53,13 @@ export const PeriodSelectorActiveIndicator = _ref => {
|
|
|
51
53
|
const animatedStyles = useAnimatedStyle(() => ({
|
|
52
54
|
transform: [{
|
|
53
55
|
translateX: animatedValues.value.x
|
|
56
|
+
}, {
|
|
57
|
+
translateY: animatedValues.value.y
|
|
54
58
|
}],
|
|
55
59
|
width: animatedValues.value.width,
|
|
56
60
|
backgroundColor: animatedValues.value.backgroundColor
|
|
57
61
|
}), [animatedValues]);
|
|
58
|
-
if (!width) return
|
|
62
|
+
if (!width) return;
|
|
59
63
|
return /*#__PURE__*/_jsx(Animated.View, {
|
|
60
64
|
style: [{
|
|
61
65
|
position: position,
|