@coinbase/cds-web-visualization 0.0.0 → 3.3.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 (104) hide show
  1. package/README.md +3 -0
  2. package/dts/index.d.ts +2 -0
  3. package/dts/index.d.ts.map +1 -0
  4. package/dts/sparkline/Counter.d.ts +3 -0
  5. package/dts/sparkline/Counter.d.ts.map +1 -0
  6. package/dts/sparkline/Sparkline.d.ts +22 -0
  7. package/dts/sparkline/Sparkline.d.ts.map +1 -0
  8. package/dts/sparkline/SparklineArea.d.ts +7 -0
  9. package/dts/sparkline/SparklineArea.d.ts.map +1 -0
  10. package/dts/sparkline/SparklineAreaPattern.d.ts +6 -0
  11. package/dts/sparkline/SparklineAreaPattern.d.ts.map +1 -0
  12. package/dts/sparkline/SparklineGradient.d.ts +12 -0
  13. package/dts/sparkline/SparklineGradient.d.ts.map +1 -0
  14. package/dts/sparkline/SparklinePath.d.ts +10 -0
  15. package/dts/sparkline/SparklinePath.d.ts.map +1 -0
  16. package/dts/sparkline/__figma__/Sparkline.figma.d.ts +2 -0
  17. package/dts/sparkline/__figma__/Sparkline.figma.d.ts.map +1 -0
  18. package/dts/sparkline/generateSparklineWithId.d.ts +5 -0
  19. package/dts/sparkline/generateSparklineWithId.d.ts.map +1 -0
  20. package/dts/sparkline/index.d.ts +6 -0
  21. package/dts/sparkline/index.d.ts.map +1 -0
  22. package/dts/sparkline/sparkline-interactive/InnerSparklineInteractiveProvider.d.ts +9 -0
  23. package/dts/sparkline/sparkline-interactive/InnerSparklineInteractiveProvider.d.ts.map +1 -0
  24. package/dts/sparkline/sparkline-interactive/SparklineInteractive.d.ts +149 -0
  25. package/dts/sparkline/sparkline-interactive/SparklineInteractive.d.ts.map +1 -0
  26. package/dts/sparkline/sparkline-interactive/SparklineInteractiveAnimatedPath.d.ts +13 -0
  27. package/dts/sparkline/sparkline-interactive/SparklineInteractiveAnimatedPath.d.ts.map +1 -0
  28. package/dts/sparkline/sparkline-interactive/SparklineInteractiveHoverDate.d.ts +3 -0
  29. package/dts/sparkline/sparkline-interactive/SparklineInteractiveHoverDate.d.ts.map +1 -0
  30. package/dts/sparkline/sparkline-interactive/SparklineInteractiveHoverPrice.d.ts +3 -0
  31. package/dts/sparkline/sparkline-interactive/SparklineInteractiveHoverPrice.d.ts.map +1 -0
  32. package/dts/sparkline/sparkline-interactive/SparklineInteractiveLineVertical.d.ts +6 -0
  33. package/dts/sparkline/sparkline-interactive/SparklineInteractiveLineVertical.d.ts.map +1 -0
  34. package/dts/sparkline/sparkline-interactive/SparklineInteractiveMarkerDates.d.ts +12 -0
  35. package/dts/sparkline/sparkline-interactive/SparklineInteractiveMarkerDates.d.ts.map +1 -0
  36. package/dts/sparkline/sparkline-interactive/SparklineInteractivePaths.d.ts +11 -0
  37. package/dts/sparkline/sparkline-interactive/SparklineInteractivePaths.d.ts.map +1 -0
  38. package/dts/sparkline/sparkline-interactive/SparklineInteractivePeriodSelector.d.ts +20 -0
  39. package/dts/sparkline/sparkline-interactive/SparklineInteractivePeriodSelector.d.ts.map +1 -0
  40. package/dts/sparkline/sparkline-interactive/SparklineInteractiveProvider.d.ts +20 -0
  41. package/dts/sparkline/sparkline-interactive/SparklineInteractiveProvider.d.ts.map +1 -0
  42. package/dts/sparkline/sparkline-interactive/SparklineInteractiveScrubHandler.d.ts +17 -0
  43. package/dts/sparkline/sparkline-interactive/SparklineInteractiveScrubHandler.d.ts.map +1 -0
  44. package/dts/sparkline/sparkline-interactive/SparklineInteractiveScrubProvider.d.ts +18 -0
  45. package/dts/sparkline/sparkline-interactive/SparklineInteractiveScrubProvider.d.ts.map +1 -0
  46. package/dts/sparkline/sparkline-interactive/SparklineInteractiveTimeseriesPaths.d.ts +23 -0
  47. package/dts/sparkline/sparkline-interactive/SparklineInteractiveTimeseriesPaths.d.ts.map +1 -0
  48. package/dts/sparkline/sparkline-interactive/__figma__/SparklineInteractive.figma.d.ts +2 -0
  49. package/dts/sparkline/sparkline-interactive/__figma__/SparklineInteractive.figma.d.ts.map +1 -0
  50. package/dts/sparkline/sparkline-interactive/__stories__/SparklineInteractive.stories.d.ts +374 -0
  51. package/dts/sparkline/sparkline-interactive/__stories__/SparklineInteractive.stories.d.ts.map +1 -0
  52. package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractive.test.d.ts +2 -0
  53. package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractive.test.d.ts.map +1 -0
  54. package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractivePeriodSelector.test.d.ts +2 -0
  55. package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractivePeriodSelector.test.d.ts.map +1 -0
  56. package/dts/sparkline/sparkline-interactive/fade.d.ts +3 -0
  57. package/dts/sparkline/sparkline-interactive/fade.d.ts.map +1 -0
  58. package/dts/sparkline/sparkline-interactive/useSparklineInteractiveConstants.d.ts +13 -0
  59. package/dts/sparkline/sparkline-interactive/useSparklineInteractiveConstants.d.ts.map +1 -0
  60. package/dts/sparkline/sparkline-interactive-header/SparklineInteractiveHeader.d.ts +104 -0
  61. package/dts/sparkline/sparkline-interactive-header/SparklineInteractiveHeader.d.ts.map +1 -0
  62. package/dts/sparkline/sparkline-interactive-header/__figma__/SparklineInteractiveHeader.figma.d.ts +2 -0
  63. package/dts/sparkline/sparkline-interactive-header/__figma__/SparklineInteractiveHeader.figma.d.ts.map +1 -0
  64. package/dts/sparkline/sparkline-interactive-header/__stories__/SparklineInteractiveHeader.stories.d.ts +87 -0
  65. package/dts/sparkline/sparkline-interactive-header/__stories__/SparklineInteractiveHeader.stories.d.ts.map +1 -0
  66. package/dts/sparkline/sparkline-interactive-header/__tests__/SparklineInteractiveHeader.test.d.ts +2 -0
  67. package/dts/sparkline/sparkline-interactive-header/__tests__/SparklineInteractiveHeader.test.d.ts.map +1 -0
  68. package/esm/index.js +1 -0
  69. package/esm/sparkline/Counter.css +3 -0
  70. package/esm/sparkline/Counter.js +35 -0
  71. package/esm/sparkline/Sparkline.js +50 -0
  72. package/esm/sparkline/SparklineArea.js +13 -0
  73. package/esm/sparkline/SparklineAreaPattern.js +35 -0
  74. package/esm/sparkline/SparklineGradient.js +72 -0
  75. package/esm/sparkline/SparklinePath.js +19 -0
  76. package/esm/sparkline/__figma__/Sparkline.figma.js +24 -0
  77. package/esm/sparkline/generateSparklineWithId.js +6 -0
  78. package/esm/sparkline/index.js +5 -0
  79. package/esm/sparkline/sparkline-interactive/InnerSparklineInteractiveProvider.js +21 -0
  80. package/esm/sparkline/sparkline-interactive/SparklineInteractive.js +313 -0
  81. package/esm/sparkline/sparkline-interactive/SparklineInteractiveAnimatedPath.js +105 -0
  82. package/esm/sparkline/sparkline-interactive/SparklineInteractiveHoverDate.css +2 -0
  83. package/esm/sparkline/sparkline-interactive/SparklineInteractiveHoverDate.js +26 -0
  84. package/esm/sparkline/sparkline-interactive/SparklineInteractiveHoverPrice.css +2 -0
  85. package/esm/sparkline/sparkline-interactive/SparklineInteractiveHoverPrice.js +24 -0
  86. package/esm/sparkline/sparkline-interactive/SparklineInteractiveLineVertical.css +4 -0
  87. package/esm/sparkline/sparkline-interactive/SparklineInteractiveLineVertical.js +65 -0
  88. package/esm/sparkline/sparkline-interactive/SparklineInteractiveMarkerDates.css +1 -0
  89. package/esm/sparkline/sparkline-interactive/SparklineInteractiveMarkerDates.js +80 -0
  90. package/esm/sparkline/sparkline-interactive/SparklineInteractivePaths.js +52 -0
  91. package/esm/sparkline/sparkline-interactive/SparklineInteractivePeriodSelector.js +70 -0
  92. package/esm/sparkline/sparkline-interactive/SparklineInteractiveProvider.js +45 -0
  93. package/esm/sparkline/sparkline-interactive/SparklineInteractiveScrubHandler.css +5 -0
  94. package/esm/sparkline/sparkline-interactive/SparklineInteractiveScrubHandler.js +199 -0
  95. package/esm/sparkline/sparkline-interactive/SparklineInteractiveScrubProvider.js +39 -0
  96. package/esm/sparkline/sparkline-interactive/SparklineInteractiveTimeseriesPaths.js +92 -0
  97. package/esm/sparkline/sparkline-interactive/__figma__/SparklineInteractive.figma.js +89 -0
  98. package/esm/sparkline/sparkline-interactive/fade.css +2 -0
  99. package/esm/sparkline/sparkline-interactive/fade.js +14 -0
  100. package/esm/sparkline/sparkline-interactive/useSparklineInteractiveConstants.js +28 -0
  101. package/esm/sparkline/sparkline-interactive-header/SparklineInteractiveHeader.js +225 -0
  102. package/esm/sparkline/sparkline-interactive-header/__figma__/SparklineInteractiveHeader.figma.js +108 -0
  103. package/package.json +63 -5
  104. package/index.js +0 -1
@@ -0,0 +1,50 @@
1
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
2
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
3
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
4
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
5
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
6
+ import React, { memo, useRef } from 'react';
7
+ import { getAccessibleColor } from '@coinbase/cds-common/utils/getAccessibleColor';
8
+ import { getSparklineTransform } from '@coinbase/cds-common/visualizations/getSparklineTransform';
9
+ import { generateRandomId } from '@coinbase/cds-utils';
10
+ import { useTheme } from '@coinbase/cds-web/hooks/useTheme';
11
+ import { generateSparklineAreaWithId } from './generateSparklineWithId';
12
+ import { SparklineAreaPattern } from './SparklineAreaPattern';
13
+ import { SparklinePath } from './SparklinePath';
14
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
15
+ export const Sparkline = /*#__PURE__*/memo(_ref => {
16
+ let {
17
+ background,
18
+ color,
19
+ height,
20
+ path,
21
+ width,
22
+ yAxisScalingFactor,
23
+ children
24
+ } = _ref;
25
+ const theme = useTheme();
26
+ const patternId = useRef(generateRandomId());
27
+ const stroke = color !== 'auto' ? color : getAccessibleColor({
28
+ background: background !== null && background !== void 0 ? background : theme.color.bg,
29
+ foreground: 'auto',
30
+ usage: 'graphic'
31
+ });
32
+ const translateProps = getSparklineTransform(width, height, yAxisScalingFactor);
33
+ const defs = children ? /*#__PURE__*/_jsx("defs", {
34
+ children: /*#__PURE__*/_jsx(SparklineAreaPattern, {
35
+ color: stroke,
36
+ id: patternId.current
37
+ })
38
+ }) : null;
39
+ return /*#__PURE__*/_jsxs("svg", {
40
+ height: height,
41
+ width: width,
42
+ children: [defs, /*#__PURE__*/_jsxs("g", _objectSpread(_objectSpread({}, translateProps), {}, {
43
+ children: [/*#__PURE__*/_jsx(SparklinePath, {
44
+ path: path,
45
+ stroke: stroke
46
+ }), generateSparklineAreaWithId(patternId.current, children)]
47
+ }))]
48
+ });
49
+ });
50
+ Sparkline.displayName = 'Sparkline';
@@ -0,0 +1,13 @@
1
+ import React, { forwardRef, memo } from 'react';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ export const SparklineArea = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) => {
4
+ let {
5
+ area,
6
+ patternId
7
+ } = _ref;
8
+ return /*#__PURE__*/_jsx("path", {
9
+ ref: ref,
10
+ d: area,
11
+ fill: "url(#".concat(patternId, ")")
12
+ });
13
+ }));
@@ -0,0 +1,35 @@
1
+ import React from 'react';
2
+ import { useSparklineAreaOpacity } from '@coinbase/cds-common/visualizations/useSparklineAreaOpacity';
3
+ import { useTheme } from '@coinbase/cds-web/hooks/useTheme';
4
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
5
+ export const SparklineAreaPattern = _ref => {
6
+ let {
7
+ color,
8
+ id
9
+ } = _ref;
10
+ const {
11
+ activeColorScheme
12
+ } = useTheme();
13
+ const fillOpacity = useSparklineAreaOpacity(activeColorScheme);
14
+ return /*#__PURE__*/_jsx("pattern", {
15
+ height: "4",
16
+ id: id,
17
+ patternUnits: "userSpaceOnUse",
18
+ width: "4",
19
+ x: "0",
20
+ y: "0",
21
+ children: /*#__PURE__*/_jsxs("g", {
22
+ children: [/*#__PURE__*/_jsx("rect", {
23
+ fill: "transparent",
24
+ height: "4",
25
+ width: "4"
26
+ }), /*#__PURE__*/_jsx("circle", {
27
+ cx: "1",
28
+ cy: "1",
29
+ fill: color,
30
+ fillOpacity: fillOpacity,
31
+ r: "1"
32
+ })]
33
+ })
34
+ });
35
+ };
@@ -0,0 +1,72 @@
1
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
2
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
3
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
4
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
5
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
6
+ import React, { forwardRef, memo, useId, useMemo, useRef } from 'react';
7
+ import { getAccessibleForegroundGradient } from '@coinbase/cds-common/color/getAccessibleForegroundGradient';
8
+ import { getAccessibleColor } from '@coinbase/cds-common/utils/getAccessibleColor';
9
+ import { getSparklineTransform } from '@coinbase/cds-common/visualizations/getSparklineTransform';
10
+ import { generateRandomId } from '@coinbase/cds-utils';
11
+ import { useTheme } from '@coinbase/cds-web/hooks/useTheme';
12
+ import { generateSparklineAreaWithId } from './generateSparklineWithId';
13
+ import { SparklineAreaPattern } from './SparklineAreaPattern';
14
+ import { SparklinePath } from './SparklinePath';
15
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
16
+ export const SparklineGradient = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, forwardedRef) => {
17
+ let {
18
+ background,
19
+ color,
20
+ path,
21
+ height,
22
+ width,
23
+ yAxisScalingFactor,
24
+ children
25
+ } = _ref;
26
+ const theme = useTheme();
27
+ const patternId = useRef(generateRandomId());
28
+ const gradient = getAccessibleForegroundGradient({
29
+ background: background !== null && background !== void 0 ? background : theme.color.bg,
30
+ color,
31
+ colorScheme: theme.activeColorScheme,
32
+ usage: 'graphic'
33
+ });
34
+ const areaColor = color !== 'auto' ? color : getAccessibleColor({
35
+ background: background !== null && background !== void 0 ? background : theme.color.bg,
36
+ foreground: 'auto',
37
+ usage: 'graphic'
38
+ });
39
+ const gradientId = useId();
40
+ const translateProps = getSparklineTransform(width, height, yAxisScalingFactor);
41
+ const hasChildren = !!children;
42
+ const linearGradient = useMemo(() => {
43
+ return /*#__PURE__*/_jsxs("defs", {
44
+ children: [/*#__PURE__*/_jsx("linearGradient", {
45
+ id: gradientId,
46
+ x1: "0%",
47
+ x2: "100%",
48
+ y1: "0%",
49
+ y2: "0%",
50
+ children: gradient.map((item, i) => /*#__PURE__*/_jsx("stop", {
51
+ offset: item.offset,
52
+ stopColor: item.color
53
+ }, "".concat(i, "_").concat(item)))
54
+ }), hasChildren && /*#__PURE__*/_jsx(SparklineAreaPattern, {
55
+ color: areaColor,
56
+ id: patternId.current
57
+ })]
58
+ });
59
+ }, [gradientId, gradient, hasChildren, areaColor]);
60
+ return /*#__PURE__*/_jsxs("svg", {
61
+ height: height,
62
+ width: width,
63
+ children: [linearGradient, /*#__PURE__*/_jsxs("g", _objectSpread(_objectSpread({}, translateProps), {}, {
64
+ children: [/*#__PURE__*/_jsx(SparklinePath, {
65
+ ref: forwardedRef,
66
+ path: path,
67
+ stroke: "url(#".concat(gradientId, ")")
68
+ }), generateSparklineAreaWithId(patternId.current, children)]
69
+ }))]
70
+ });
71
+ }));
72
+ SparklineGradient.displayName = 'SparklineGradient';
@@ -0,0 +1,19 @@
1
+ import React, { forwardRef, memo } from 'react';
2
+ import { borderWidth } from '@coinbase/cds-common/tokens/sparkline';
3
+ import { jsx as _jsx } from "react/jsx-runtime";
4
+ export const SparklinePath = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, forwardedRef) => {
5
+ let {
6
+ path,
7
+ stroke
8
+ } = _ref;
9
+ return /*#__PURE__*/_jsx("path", {
10
+ ref: forwardedRef,
11
+ d: path,
12
+ fill: "transparent",
13
+ stroke: stroke,
14
+ strokeLinecap: "round",
15
+ strokeLinejoin: "round",
16
+ strokeWidth: borderWidth
17
+ });
18
+ }));
19
+ SparklinePath.displayName = 'SparklinePath';
@@ -0,0 +1,24 @@
1
+ /* eslint-disable react-hooks/rules-of-hooks */
2
+
3
+ import React from 'react';
4
+ import { figma } from '@figma/code-connect';
5
+ import { Sparkline } from '../Sparkline';
6
+ import { jsx as _jsx } from "react/jsx-runtime";
7
+ figma.connect(Sparkline, 'https://www.figma.com/design/k5CtyJccNQUGMI5bI4lJ2g/✨-CDS-Components?node-id=320-15040&m=dev', {
8
+ imports: ["import { Sparkline } from '@coinbase/cds-web-visualization';", "import { useSparklinePath } from '@coinbase/cds-common/visualizations/useSparklinePath';"],
9
+ example: () => {
10
+ const data = [20, 30, 5, 45, 0];
11
+ // @ts-expect-error: useSparklinePath is not typed correctly
12
+ const path = useSparklinePath({
13
+ height: 200,
14
+ width: 200,
15
+ data
16
+ });
17
+ return /*#__PURE__*/_jsx(Sparkline, {
18
+ color: "auto",
19
+ height: 200,
20
+ path: path,
21
+ width: 400
22
+ });
23
+ }
24
+ });
@@ -0,0 +1,6 @@
1
+ import { cloneElement } from 'react';
2
+ export function generateSparklineAreaWithId(id, children) {
3
+ return children ? /*#__PURE__*/cloneElement(children, {
4
+ patternId: id
5
+ }) : undefined;
6
+ }
@@ -0,0 +1,5 @@
1
+ export * from './Sparkline';
2
+ export * from './sparkline-interactive/SparklineInteractive';
3
+ export * from './sparkline-interactive-header/SparklineInteractiveHeader';
4
+ export * from './SparklineArea';
5
+ export * from './SparklineGradient';
@@ -0,0 +1,21 @@
1
+ import React, { useEffect } from 'react';
2
+ import { useSparklineInteractiveContext } from './SparklineInteractiveProvider';
3
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
4
+ export const InnerSparklineInteractiveProvider = _ref => {
5
+ let {
6
+ width,
7
+ height,
8
+ children
9
+ } = _ref;
10
+ const {
11
+ setWidth,
12
+ setHeight
13
+ } = useSparklineInteractiveContext();
14
+ useEffect(() => {
15
+ setWidth(width);
16
+ setHeight(height);
17
+ }, [width, height, setWidth, setHeight]);
18
+ return /*#__PURE__*/_jsx(_Fragment, {
19
+ children: children
20
+ });
21
+ };
@@ -0,0 +1,313 @@
1
+ const _excluded = ["compact"];
2
+ function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
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
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
5
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
6
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
7
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
8
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
9
+ import React, { memo, useCallback, useEffect, useMemo, useState } from 'react';
10
+ import { gutter } from '@coinbase/cds-common/tokens/sizing';
11
+ import { chartCompactHeight, chartHeight } from '@coinbase/cds-common/tokens/sparkline';
12
+ import { debounce } from '@coinbase/cds-common/utils/debounce';
13
+ import { getAccessibleColor } from '@coinbase/cds-common/utils/getAccessibleColor';
14
+ import { useSparklineCoordinates } from '@coinbase/cds-common/visualizations/useSparklineCoordinates';
15
+ import { chartFallbackNegative, chartFallbackPositive } from '@coinbase/cds-lottie-files';
16
+ import { emptyArray, isStorybook, noop } from '@coinbase/cds-utils';
17
+ import { cx, useTheme } from '@coinbase/cds-web';
18
+ import { Lottie } from '@coinbase/cds-web/animation';
19
+ import { useDimensions } from '@coinbase/cds-web/hooks/useDimensions';
20
+ import { HStack, VStack } from '@coinbase/cds-web/layout';
21
+ import { Box } from '@coinbase/cds-web/layout/Box';
22
+ import { getBrowserGlobals } from '@coinbase/cds-web/utils/browser';
23
+ import { VisualizationContainer } from '@coinbase/cds-web/visualizations/VisualizationContainer';
24
+ import isEqual from 'lodash/isEqual';
25
+ import isObject from 'lodash/isObject';
26
+ import { InnerSparklineInteractiveProvider } from './InnerSparklineInteractiveProvider';
27
+ import { SparklineInteractiveHoverDate } from './SparklineInteractiveHoverDate';
28
+ import { SparklineInteractiveHoverPrice } from './SparklineInteractiveHoverPrice';
29
+ import { SparklineInteractiveLineVertical } from './SparklineInteractiveLineVertical';
30
+ import { SparklineInteractiveMarkerDates } from './SparklineInteractiveMarkerDates';
31
+ import { SparklineInteractivePaths } from './SparklineInteractivePaths';
32
+ import { SparklineInteractivePeriodSelector } from './SparklineInteractivePeriodSelector';
33
+ import { SparklineInteractiveProvider, useSparklineInteractiveContext } from './SparklineInteractiveProvider';
34
+ import { SparklineInteractiveScrubHandler } from './SparklineInteractiveScrubHandler';
35
+ import { SparklineInteractiveScrubProvider } from './SparklineInteractiveScrubProvider';
36
+ import { useSparklineInteractiveConstants } from './useSparklineInteractiveConstants';
37
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
38
+ export * from '@coinbase/cds-common/types/Chart';
39
+ const DefaultFallback = /*#__PURE__*/memo(_ref => {
40
+ let {
41
+ fallbackType
42
+ } = _ref;
43
+ // don't show lottie animation in story book
44
+ const skipLottie = isStorybook();
45
+ const source = fallbackType === 'negative' ? chartFallbackNegative : chartFallbackPositive;
46
+ return !skipLottie && /*#__PURE__*/_jsx(Lottie, {
47
+ autoplay: true,
48
+ loop: true,
49
+ height: "100%",
50
+ source: source,
51
+ width: "100%"
52
+ });
53
+ });
54
+ const mobileLayoutBreakpoint = 650;
55
+ function SparklineInteractiveContentWithGeneric(_ref2) {
56
+ let {
57
+ data,
58
+ periods,
59
+ defaultPeriod,
60
+ onPeriodChanged,
61
+ strokeColor,
62
+ onScrub = noop,
63
+ onScrubStart = noop,
64
+ onScrubEnd = noop,
65
+ formatDate,
66
+ fallback = null,
67
+ hidePeriodSelector = false,
68
+ disableScrubbing = false,
69
+ fill = true,
70
+ yAxisScalingFactor = 1.0,
71
+ compact,
72
+ formatHoverDate,
73
+ formatHoverPrice,
74
+ headerNode,
75
+ fallbackType = 'positive',
76
+ timePeriodGutter,
77
+ hoverData,
78
+ periodSelectorPlacement = 'above',
79
+ className,
80
+ classNames,
81
+ style,
82
+ styles,
83
+ headerTestID
84
+ } = _ref2;
85
+ const [isScrubbing, setIsScrubbing] = useState(false);
86
+ const [isMarkerDateVisible, setIsMarkerDateVisible] = useState(false);
87
+ const innerSparklineInteractiveHeight = compact ? chartCompactHeight : chartHeight;
88
+ const {
89
+ isFallbackVisible,
90
+ showFallback
91
+ } = useSparklineInteractiveContext();
92
+ const {
93
+ observe: containerRef,
94
+ width: containerWidth
95
+ } = useDimensions();
96
+ const isMobileLayout = containerWidth > 0 && containerWidth < mobileLayoutBreakpoint;
97
+ const showHeaderPeriodSelector = periodSelectorPlacement === 'above' && !hidePeriodSelector;
98
+ const showBottomMarkerDates = useMemo(() => periodSelectorPlacement === 'above' || periodSelectorPlacement === 'below' && hidePeriodSelector || isMarkerDateVisible, [isMarkerDateVisible, periodSelectorPlacement, hidePeriodSelector]);
99
+ const color = strokeColor;
100
+ const [selectedPeriod, setSelectedPeriod] = useState(defaultPeriod);
101
+ const theme = useTheme();
102
+ const lineVerticalColor = useMemo(() => {
103
+ const lineColor = color !== 'auto' ? color : getAccessibleColor({
104
+ background: theme.color.bg,
105
+ foreground: 'auto',
106
+ usage: 'graphic'
107
+ });
108
+ return hoverData ? 'var(--color-bgLineHeavy)' : lineColor;
109
+ }, [hoverData, color, theme.color.bg]);
110
+ const dataForPeriod = useMemo(() => {
111
+ var _data$selectedPeriod;
112
+ if (!data) {
113
+ return emptyArray;
114
+ }
115
+ return (_data$selectedPeriod = data[selectedPeriod]) !== null && _data$selectedPeriod !== void 0 ? _data$selectedPeriod : emptyArray;
116
+ }, [data, selectedPeriod]);
117
+ const handleScrubStart = useCallback(() => {
118
+ if (hoverData) {
119
+ setIsScrubbing(true);
120
+ }
121
+ setIsMarkerDateVisible(true);
122
+ onScrubStart === null || onScrubStart === void 0 || onScrubStart();
123
+ }, [hoverData, onScrubStart]);
124
+ const handleScrubEnd = useCallback(() => {
125
+ if (hoverData) {
126
+ setIsScrubbing(false);
127
+ }
128
+ setIsMarkerDateVisible(false);
129
+ onScrubEnd === null || onScrubEnd === void 0 || onScrubEnd();
130
+ }, [hoverData, onScrubEnd]);
131
+
132
+ // If dataForPeriod is empty we know that we are either loading
133
+ // or backend returned bad data and we should show fallback UI.
134
+ const hasData = dataForPeriod.length > 0;
135
+ useEffect(() => {
136
+ var _data$selectedPeriod2;
137
+ // If there is no data for selected period show fallback loader
138
+ if (isObject(data) && !((_data$selectedPeriod2 = data[selectedPeriod]) !== null && _data$selectedPeriod2 !== void 0 && _data$selectedPeriod2.length) && !isFallbackVisible) {
139
+ showFallback();
140
+ }
141
+ }, [data, isFallbackVisible, selectedPeriod, showFallback]);
142
+ const updatePeriod = useCallback(period => {
143
+ if (isObject(data) && period !== selectedPeriod) {
144
+ // This can sometimes happen for newer assets which
145
+ // will have their 'all' chart data be the same as
146
+ // their 'year' chart data. In those cases we don't
147
+ // want to animate out the min/max since we rely on
148
+ // AnimatedSparklineInteractivePath to animate those components back in -
149
+ // and AnimatedSparklineInteractivePath will not trigger an animation
150
+ // if it's chartData is the same between re-renders
151
+ if (!isEqual(data[period], data[selectedPeriod])) {
152
+ // minMaxOpacity.setValue(0);
153
+ }
154
+ setSelectedPeriod(period);
155
+ onPeriodChanged === null || onPeriodChanged === void 0 || onPeriodChanged(period);
156
+ }
157
+ }, [data, selectedPeriod, onPeriodChanged /* , minMaxOpacity */]);
158
+ const {
159
+ chartWidth
160
+ } = useSparklineInteractiveConstants();
161
+ const {
162
+ path,
163
+ area,
164
+ getMarker
165
+ } = useSparklineCoordinates({
166
+ data: dataForPeriod,
167
+ width: chartWidth,
168
+ height: innerSparklineInteractiveHeight,
169
+ yAxisScalingFactor
170
+ });
171
+ let header;
172
+ if (headerNode) {
173
+ header = /*#__PURE__*/_jsx(Box, {
174
+ className: classNames === null || classNames === void 0 ? void 0 : classNames.header,
175
+ flexGrow: 1,
176
+ paddingX: !isMobileLayout ? gutter : 0,
177
+ style: styles === null || styles === void 0 ? void 0 : styles.header,
178
+ testID: headerTestID,
179
+ children: headerNode
180
+ });
181
+ }
182
+ const periodSelector = /*#__PURE__*/_jsx(SparklineInteractivePeriodSelector, {
183
+ color: color,
184
+ periods: periods,
185
+ selectedPeriod: selectedPeriod,
186
+ setSelectedPeriod: updatePeriod
187
+ });
188
+ const rootStyles = useMemo(() => _objectSpread(_objectSpread({
189
+ width: '100%'
190
+ }, style), styles === null || styles === void 0 ? void 0 : styles.root), [style, styles === null || styles === void 0 ? void 0 : styles.root]);
191
+ return /*#__PURE__*/_jsxs("div", {
192
+ ref: containerRef,
193
+ className: cx(className, classNames === null || classNames === void 0 ? void 0 : classNames.root),
194
+ style: rootStyles,
195
+ children: [isMobileLayout && showHeaderPeriodSelector && /*#__PURE__*/_jsx(Box, {
196
+ paddingBottom: 2,
197
+ width: "100%",
198
+ children: periodSelector
199
+ }), (!!headerNode || !isMobileLayout && showHeaderPeriodSelector) && /*#__PURE__*/_jsxs(Box, {
200
+ alignItems: "center",
201
+ justifyContent: "space-between",
202
+ paddingBottom: 2,
203
+ children: [header !== null && header !== void 0 ? header : /*#__PURE__*/_jsx("div", {}), !isMobileLayout && showHeaderPeriodSelector && /*#__PURE__*/_jsx(Box, {
204
+ flexGrow: 0,
205
+ children: periodSelector
206
+ })]
207
+ }), /*#__PURE__*/_jsxs(SparklineInteractiveScrubProvider, {
208
+ children: [/*#__PURE__*/_jsxs(VStack, {
209
+ paddingBottom: (formatHoverDate || formatHoverPrice) && 1,
210
+ children: [!!formatHoverDate && /*#__PURE__*/_jsx(SparklineInteractiveHoverDate, {}), !!formatHoverPrice && /*#__PURE__*/_jsx(SparklineInteractiveHoverPrice, {})]
211
+ }), /*#__PURE__*/_jsx(VisualizationContainer, {
212
+ height: innerSparklineInteractiveHeight,
213
+ width: "100%",
214
+ children: _ref3 => {
215
+ let {
216
+ width,
217
+ height
218
+ } = _ref3;
219
+ return /*#__PURE__*/_jsx(InnerSparklineInteractiveProvider, {
220
+ height: height,
221
+ width: width,
222
+ children: /*#__PURE__*/_jsx(SparklineInteractiveScrubHandler, {
223
+ disabled: disableScrubbing,
224
+ formatHoverDate: formatHoverDate,
225
+ formatHoverPrice: formatHoverPrice,
226
+ getMarker: getMarker,
227
+ onScrub: onScrub,
228
+ onScrubEnd: handleScrubEnd,
229
+ onScrubStart: handleScrubStart,
230
+ selectedPeriod: selectedPeriod,
231
+ children: /*#__PURE__*/_jsxs(Box, {
232
+ height: height,
233
+ position: "relative",
234
+ width: width,
235
+ children: [!!isFallbackVisible && /*#__PURE__*/_jsx(Box, {
236
+ height: "100%",
237
+ justifyContent: "center",
238
+ position: "absolute",
239
+ width: "100%",
240
+ children: fallback !== null && fallback !== void 0 ? fallback : /*#__PURE__*/_jsx(DefaultFallback, {
241
+ fallbackType: fallbackType
242
+ })
243
+ }), /*#__PURE__*/_jsx(Box, {
244
+ height: "100%",
245
+ width: "100%",
246
+ children: !!hasData && !!path && /*#__PURE__*/_jsxs(_Fragment, {
247
+ children: [/*#__PURE__*/_jsx(SparklineInteractivePaths, {
248
+ area: area,
249
+ compact: compact,
250
+ fill: fill,
251
+ hoverData: hoverData,
252
+ path: path,
253
+ selectedPeriod: selectedPeriod,
254
+ showHoverData: isScrubbing,
255
+ strokeColor: color,
256
+ yAxisScalingFactor: yAxisScalingFactor
257
+ }), /*#__PURE__*/_jsx(SparklineInteractiveLineVertical, {
258
+ color: lineVerticalColor
259
+ })]
260
+ })
261
+ })]
262
+ })
263
+ })
264
+ });
265
+ }
266
+ })]
267
+ }), /*#__PURE__*/_jsxs(HStack, {
268
+ alignItems: "flex-end",
269
+ minHeight: 50,
270
+ width: "100%",
271
+ children: [showBottomMarkerDates && /*#__PURE__*/_jsx(SparklineInteractiveMarkerDates, {
272
+ formatDate: formatDate,
273
+ getMarker: getMarker,
274
+ selectedPeriod: selectedPeriod,
275
+ timePeriodGutter: timePeriodGutter
276
+ }), periodSelectorPlacement === 'below' && !isMarkerDateVisible && !hidePeriodSelector && periodSelector]
277
+ })]
278
+ });
279
+ }
280
+
281
+ // typescript doesn't understand the memo with the generic so it gets casted to a base react component
282
+ export const SparklineInteractiveContent = /*#__PURE__*/memo(SparklineInteractiveContentWithGeneric);
283
+ function SparklineInteractiveWithGeneric(_ref4) {
284
+ let {
285
+ compact
286
+ } = _ref4,
287
+ props = _objectWithoutProperties(_ref4, _excluded);
288
+ const [resizeKey, setResizeKey] = useState(0);
289
+ // eslint-disable-next-line react-hooks/exhaustive-deps
290
+ const resizeHandler = useCallback(debounce(() => {
291
+ // no resizing on percy
292
+ if (!isStorybook()) {
293
+ setResizeKey(prev => prev + 1);
294
+ }
295
+ }, 300), []);
296
+ useEffect(() => {
297
+ var _getBrowserGlobals;
298
+ (_getBrowserGlobals = getBrowserGlobals()) === null || _getBrowserGlobals === void 0 || (_getBrowserGlobals = _getBrowserGlobals.window) === null || _getBrowserGlobals === void 0 || _getBrowserGlobals.addEventListener('resize', resizeHandler);
299
+ return () => {
300
+ var _getBrowserGlobals2;
301
+ (_getBrowserGlobals2 = getBrowserGlobals()) === null || _getBrowserGlobals2 === void 0 || (_getBrowserGlobals2 = _getBrowserGlobals2.window) === null || _getBrowserGlobals2 === void 0 || _getBrowserGlobals2.removeEventListener('resize', resizeHandler);
302
+ };
303
+ }, [resizeHandler]);
304
+ return /*#__PURE__*/_jsx(SparklineInteractiveProvider, {
305
+ compact: compact,
306
+ children: /*#__PURE__*/_jsx(SparklineInteractiveContent, _objectSpread({
307
+ compact: compact
308
+ }, props))
309
+ }, resizeKey);
310
+ }
311
+
312
+ // typescript doesn't understand the memo with the generic so it gets casted to a base react component
313
+ export const SparklineInteractive = /*#__PURE__*/memo(SparklineInteractiveWithGeneric);