@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,105 @@
1
+ import 'd3-transition'; // Important! do not remove this, it sets up the linkage so you can use select().transition()
2
+
3
+ import React, { memo, useCallback, useEffect, useMemo, useRef } from 'react';
4
+ import { animatedPathConfig } from '@coinbase/cds-common/animation/sparkline';
5
+ import { useValueChanges } from '@coinbase/cds-common/hooks/useValueChanges';
6
+ import { interpolatePath } from 'd3-interpolate-path';
7
+ import { select } from 'd3-selection';
8
+ import { SparklineArea } from '../SparklineArea';
9
+ import { SparklineGradient } from '../SparklineGradient';
10
+ import { useSparklineInteractiveContext } from './SparklineInteractiveProvider';
11
+ import { useSparklineInteractiveConstants } from './useSparklineInteractiveConstants';
12
+ import { jsx as _jsx } from "react/jsx-runtime";
13
+ const {
14
+ duration,
15
+ easing
16
+ } = animatedPathConfig;
17
+ export const SparklineInteractiveAnimatedPath = /*#__PURE__*/memo(_ref => {
18
+ let {
19
+ d = '',
20
+ color,
21
+ selectedPeriod,
22
+ area,
23
+ yAxisScalingFactor,
24
+ initialPath,
25
+ initialArea
26
+ } = _ref;
27
+ const pathRef = useRef(null);
28
+ const areaRef = useRef(null);
29
+ const {
30
+ chartWidth,
31
+ chartHeight
32
+ } = useSparklineInteractiveConstants();
33
+ const {
34
+ isFallbackVisible,
35
+ hideFallback
36
+ } = useSparklineInteractiveContext();
37
+
38
+ // Only tween animation on period changes
39
+ const {
40
+ hasNotChanged: skipAnimation,
41
+ addPreviousValue: addPreviousPeriod
42
+ } = useValueChanges(selectedPeriod);
43
+ const {
44
+ previousValue: previousPath,
45
+ newValue: newPath,
46
+ hasChanged: shouldUpdatePath,
47
+ addPreviousValue: addPreviousPath
48
+ } = useValueChanges(d);
49
+ const {
50
+ previousValue: previousArea,
51
+ newValue: newArea,
52
+ hasChanged: shouldUpdateArea,
53
+ addPreviousValue: addPreviousArea
54
+ } = useValueChanges(area !== null && area !== void 0 ? area : '');
55
+ const pathInterpolator = useMemo(() => interpolatePath(previousPath !== null && previousPath !== void 0 ? previousPath : initialPath, newPath), [previousPath, initialPath, newPath]);
56
+ const areaInterpolator = useMemo(() => interpolatePath(previousArea !== null && previousArea !== void 0 ? previousArea : initialArea, newArea), [previousArea, initialArea, newArea]);
57
+ const updatePathWithoutAnimation = useCallback(() => {
58
+ select(pathRef.current).attr('d', pathInterpolator(1));
59
+ select(areaRef.current).attr('d', areaInterpolator(1));
60
+ }, [areaInterpolator, pathInterpolator]);
61
+ const playAnimation = useCallback(() => {
62
+ select(pathRef.current).transition().duration(duration).ease(easing).attrTween('d', function tween() {
63
+ const previous = select(this).attr('d');
64
+ const current = d;
65
+ return interpolatePath(previous !== null && previous !== void 0 ? previous : initialPath, current);
66
+ });
67
+ if (area) {
68
+ select(areaRef.current).transition().duration(duration).ease(easing).attrTween('d', function tween() {
69
+ const previous = select(this).attr('d');
70
+ const current = area;
71
+ return interpolatePath(previous !== null && previous !== void 0 ? previous : initialArea, current);
72
+ });
73
+ }
74
+ }, [area, d, initialArea, initialPath]);
75
+ useEffect(() => {
76
+ addPreviousPeriod(selectedPeriod);
77
+ }, [addPreviousPeriod, selectedPeriod]);
78
+ useEffect(() => {
79
+ // only update these values when they are used
80
+ addPreviousArea(newArea);
81
+ addPreviousPath(newPath);
82
+ if (shouldUpdatePath) {
83
+ if (isFallbackVisible) {
84
+ hideFallback();
85
+ updatePathWithoutAnimation();
86
+ } else if (skipAnimation) {
87
+ updatePathWithoutAnimation();
88
+ } else {
89
+ playAnimation();
90
+ }
91
+ } else if (shouldUpdateArea) {
92
+ updatePathWithoutAnimation();
93
+ }
94
+ }, [addPreviousArea, addPreviousPath, hideFallback, isFallbackVisible, newArea, newPath, playAnimation, shouldUpdateArea, shouldUpdatePath, skipAnimation, updatePathWithoutAnimation]);
95
+ return /*#__PURE__*/_jsx(SparklineGradient, {
96
+ ref: pathRef,
97
+ color: color,
98
+ height: chartHeight,
99
+ width: chartWidth,
100
+ yAxisScalingFactor: yAxisScalingFactor,
101
+ children: !!area && /*#__PURE__*/_jsx(SparklineArea, {
102
+ ref: areaRef
103
+ })
104
+ });
105
+ });
@@ -0,0 +1,2 @@
1
+ .cds-resetFadeCss-r1flhiq9{opacity:0;}
2
+ .cds-textCss-t1ofwd95{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}
@@ -0,0 +1,26 @@
1
+ import React, { memo, useCallback } from 'react';
2
+ import { cx } from '@coinbase/cds-web';
3
+ import { TextLabel2 } from '@coinbase/cds-web/typography/TextLabel2';
4
+ import { useSparklineInteractiveScrubContext } from './SparklineInteractiveScrubProvider';
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ const resetFadeCss = "cds-resetFadeCss-r1flhiq9";
7
+ const textCss = "cds-textCss-t1ofwd95";
8
+ export const SparklineInteractiveHoverDate = /*#__PURE__*/memo(() => {
9
+ const {
10
+ setHoverDateDOMNode
11
+ } = useSparklineInteractiveScrubContext();
12
+ const dateString = new Date().toLocaleString();
13
+ const setupDateRef = useCallback(ref => {
14
+ setHoverDateDOMNode(ref !== null && ref !== void 0 ? ref : null);
15
+ }, [setHoverDateDOMNode]);
16
+ return /*#__PURE__*/_jsx(TextLabel2, {
17
+ tabularNumbers: true,
18
+ as: "div",
19
+ children: /*#__PURE__*/_jsx("span", {
20
+ ref: setupDateRef,
21
+ className: cx(resetFadeCss, textCss),
22
+ children: dateString
23
+ })
24
+ });
25
+ });
26
+ import "./SparklineInteractiveHoverDate.css";
@@ -0,0 +1,2 @@
1
+ .cds-resetFadeCss-r1armfip{opacity:0;}
2
+ .cds-textCss-t1es6xjy{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}
@@ -0,0 +1,24 @@
1
+ import React, { memo, useCallback } from 'react';
2
+ import { cx } from '@coinbase/cds-web';
3
+ import { TextLabel2 } from '@coinbase/cds-web/typography/TextLabel2';
4
+ import { useSparklineInteractiveScrubContext } from './SparklineInteractiveScrubProvider';
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ const resetFadeCss = "cds-resetFadeCss-r1armfip";
7
+ const textCss = "cds-textCss-t1es6xjy";
8
+ export const SparklineInteractiveHoverPrice = /*#__PURE__*/memo(() => {
9
+ const {
10
+ setHoverPriceDOMNode
11
+ } = useSparklineInteractiveScrubContext();
12
+ const setupPriceRef = useCallback(ref => {
13
+ setHoverPriceDOMNode(ref !== null && ref !== void 0 ? ref : null);
14
+ }, [setHoverPriceDOMNode]);
15
+ return /*#__PURE__*/_jsx(TextLabel2, {
16
+ tabularNumbers: true,
17
+ as: "div",
18
+ children: /*#__PURE__*/_jsx("span", {
19
+ ref: setupPriceRef,
20
+ className: cx(resetFadeCss, textCss)
21
+ })
22
+ });
23
+ });
24
+ import "./SparklineInteractiveHoverPrice.css";
@@ -0,0 +1,4 @@
1
+ .cds-resetFadeCss-r1p330gi{opacity:0;}
2
+ .cds-verticalLineCss-vjctcux{position:absolute;pointer-events:none;width:100%;height:100%;overflow:hidden;}
3
+ .cds-lineContainerCss-lfwfzju{width:2px;height:100%;}
4
+ .cds-maskCss-mc4jbg4{width:100%;height:100%;opacity:0;position:absolute;left:0;right:0;top:0;bottom:0;}
@@ -0,0 +1,65 @@
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, useCallback } from 'react';
7
+ import { borderWidth, lineDashArray } from '@coinbase/cds-common/tokens/sparkline';
8
+ import { cx } from '@coinbase/cds-web';
9
+ import { useSparklineInteractiveContext } from './SparklineInteractiveProvider';
10
+ import { useSparklineInteractiveScrubContext } from './SparklineInteractiveScrubProvider';
11
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
12
+ const resetFadeCss = "cds-resetFadeCss-r1p330gi";
13
+ const verticalLineCss = "cds-verticalLineCss-vjctcux";
14
+ const lineContainerCss = "cds-lineContainerCss-lfwfzju";
15
+ const maskCss = "cds-maskCss-mc4jbg4";
16
+ const lineProps = {
17
+ x1: 0,
18
+ x2: 0,
19
+ y1: 0,
20
+ y2: 0,
21
+ strokeDasharray: lineDashArray.join(','),
22
+ strokeWidth: borderWidth
23
+ };
24
+ export const SparklineInteractiveLineVertical = /*#__PURE__*/memo(_ref => {
25
+ let {
26
+ color
27
+ } = _ref;
28
+ const {
29
+ setLineDOMNode,
30
+ setMaskDOMNode
31
+ } = useSparklineInteractiveScrubContext();
32
+ const {
33
+ height
34
+ } = useSparklineInteractiveContext();
35
+ const setupLineRef = useCallback(ref => {
36
+ setLineDOMNode(ref !== null && ref !== void 0 ? ref : null);
37
+ }, [setLineDOMNode]);
38
+ const setupMaskRef = useCallback(ref => {
39
+ setMaskDOMNode(ref !== null && ref !== void 0 ? ref : null);
40
+ }, [setMaskDOMNode]);
41
+ const maskStyle = {
42
+ backgroundColor: 'var(--color-bg)'
43
+ };
44
+
45
+ // hook up the line and mask
46
+ return /*#__PURE__*/_jsxs("div", {
47
+ className: verticalLineCss,
48
+ children: [/*#__PURE__*/_jsx("div", {
49
+ ref: setupMaskRef,
50
+ className: cx(maskCss, resetFadeCss),
51
+ style: maskStyle
52
+ }), /*#__PURE__*/_jsx("div", {
53
+ ref: setupLineRef,
54
+ className: cx(lineContainerCss, resetFadeCss),
55
+ children: /*#__PURE__*/_jsx("svg", {
56
+ className: lineContainerCss,
57
+ children: /*#__PURE__*/_jsx("line", _objectSpread(_objectSpread({}, lineProps), {}, {
58
+ stroke: color,
59
+ y2: height
60
+ }))
61
+ })
62
+ })]
63
+ });
64
+ });
65
+ import "./SparklineInteractiveLineVertical.css";
@@ -0,0 +1 @@
1
+ .cds-fadeInCss-f1yvdjq7.cds-fadeInCss-f1yvdjq7{-webkit-animation:cdsSparklineInteractiveFadeIn-cds-fadeInCss-f1yvdjq7 200ms cubic-bezier(0.6,0,0.15,1);animation:cdsSparklineInteractiveFadeIn-cds-fadeInCss-f1yvdjq7 200ms cubic-bezier(0.6,0,0.15,1);opacity:1;}@-webkit-keyframes cdsSparklineInteractiveFadeIn-cds-fadeInCss-f1yvdjq7{0%{opacity:0;}100%{opacity:1;}}@keyframes cdsSparklineInteractiveFadeIn-cds-fadeInCss-f1yvdjq7{0%{opacity:0;}100%{opacity:1;}}
@@ -0,0 +1,80 @@
1
+ import React, { memo, useCallback, useMemo, useState } from 'react';
2
+ import { fadeDuration } from '@coinbase/cds-common/tokens/sparkline';
3
+ import { useDateLookup } from '@coinbase/cds-common/visualizations/useDateLookup';
4
+ import { cubicBezier } from '@coinbase/cds-web/animation/convertMotionConfig';
5
+ import { HStack } from '@coinbase/cds-web/layout';
6
+ import { TextLabel2 } from '@coinbase/cds-web/typography/TextLabel2';
7
+ import times from 'lodash/times';
8
+ import { jsx as _jsx } from "react/jsx-runtime";
9
+ const fadeInCss = "cds-fadeInCss-f1yvdjq7";
10
+ const labelWidth = 125;
11
+ const noPointerEvents = {
12
+ pointerEvents: 'none'
13
+ };
14
+ const SparklineInteractiveMarkerDate = /*#__PURE__*/memo(_ref => {
15
+ let {
16
+ getFormattedDate
17
+ } = _ref;
18
+ const [xPos, setXPos] = useState(0);
19
+ const setupRef = useCallback(ref => {
20
+ if (ref) {
21
+ setXPos(ref.offsetLeft + ref.offsetWidth / 2);
22
+ }
23
+ }, []);
24
+ const dateStr = getFormattedDate(xPos);
25
+
26
+ // take up space while loading so when it finishes loading there is no jump
27
+ const fallback = /*#__PURE__*/_jsx("span", {
28
+ style: {
29
+ visibility: 'hidden'
30
+ },
31
+ children: "-"
32
+ });
33
+ return /*#__PURE__*/_jsx("span", {
34
+ ref: setupRef,
35
+ children: /*#__PURE__*/_jsx(TextLabel2, {
36
+ as: "span",
37
+ color: "fgMuted",
38
+ textAlign: "center",
39
+ children: dateStr || fallback
40
+ })
41
+ });
42
+ });
43
+ function SparklineInteractiveMarkerDatesWithGeneric(_ref2) {
44
+ let {
45
+ formatDate,
46
+ selectedPeriod,
47
+ getMarker,
48
+ timePeriodGutter = 2
49
+ } = _ref2;
50
+ const [numberOfLabels, setNumberOfLabels] = useState(0);
51
+ const getFormattedDate = useDateLookup({
52
+ getMarker,
53
+ formatDate,
54
+ selectedPeriod
55
+ });
56
+ const setupRef = useCallback(ref => {
57
+ if (ref) {
58
+ const numberOfLabelsFromWidth = Math.floor(ref.offsetWidth / labelWidth);
59
+ setNumberOfLabels(Math.max(numberOfLabelsFromWidth, 4));
60
+ }
61
+ }, []);
62
+ const markers = useMemo(() => {
63
+ return times(numberOfLabels).map((_, i) => {
64
+ return /*#__PURE__*/_jsx(SparklineInteractiveMarkerDate, {
65
+ getFormattedDate: getFormattedDate
66
+ }, i);
67
+ });
68
+ }, [getFormattedDate, numberOfLabels]);
69
+ return /*#__PURE__*/_jsx(HStack, {
70
+ ref: setupRef,
71
+ className: fadeInCss,
72
+ justifyContent: "space-between",
73
+ paddingX: timePeriodGutter,
74
+ style: noPointerEvents,
75
+ width: "100%",
76
+ children: markers
77
+ }, selectedPeriod);
78
+ }
79
+ export const SparklineInteractiveMarkerDates = /*#__PURE__*/memo(SparklineInteractiveMarkerDatesWithGeneric);
80
+ import "./SparklineInteractiveMarkerDates.css";
@@ -0,0 +1,52 @@
1
+ import React, { memo, useCallback, useRef } from 'react';
2
+ import { chartCompactHeight, chartHeight } from '@coinbase/cds-common/tokens/sparkline';
3
+ import { SparklineInteractiveAnimatedPath } from './SparklineInteractiveAnimatedPath';
4
+ import { SparklineInteractiveTimeseriesPaths } from './SparklineInteractiveTimeseriesPaths';
5
+ import { useSparklineInteractiveConstants } from './useSparklineInteractiveConstants';
6
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
7
+ function SparklineInteractivePathsWithGeneric(_ref) {
8
+ let {
9
+ showHoverData,
10
+ fill,
11
+ path,
12
+ area,
13
+ selectedPeriod,
14
+ yAxisScalingFactor,
15
+ strokeColor,
16
+ hoverData,
17
+ compact
18
+ } = _ref;
19
+ const hoverPathRef = useRef(undefined);
20
+ const hoverAreaRef = useRef(undefined);
21
+ const shouldShowFill = !!fill;
22
+ const {
23
+ chartWidth
24
+ } = useSparklineInteractiveConstants();
25
+ const innerSparklineInteractiveHeight = compact ? chartCompactHeight : chartHeight;
26
+ const handleMultiTimeseriesRender = useCallback(_ref2 => {
27
+ let {
28
+ area: timeseriesArea,
29
+ path: timeseriesPath
30
+ } = _ref2;
31
+ hoverPathRef.current = timeseriesPath;
32
+ hoverAreaRef.current = timeseriesArea;
33
+ }, []);
34
+ return /*#__PURE__*/_jsxs(_Fragment, {
35
+ children: [!showHoverData && /*#__PURE__*/_jsx(SparklineInteractiveAnimatedPath, {
36
+ area: shouldShowFill ? area : undefined,
37
+ color: strokeColor,
38
+ d: path,
39
+ initialArea: hoverAreaRef.current,
40
+ initialPath: hoverPathRef.current,
41
+ selectedPeriod: selectedPeriod,
42
+ yAxisScalingFactor: yAxisScalingFactor
43
+ }), !!showHoverData && /*#__PURE__*/_jsx(SparklineInteractiveTimeseriesPaths, {
44
+ data: hoverData === null || hoverData === void 0 ? void 0 : hoverData[selectedPeriod],
45
+ height: innerSparklineInteractiveHeight,
46
+ initialPath: path,
47
+ onRender: handleMultiTimeseriesRender,
48
+ width: chartWidth
49
+ })]
50
+ });
51
+ }
52
+ export const SparklineInteractivePaths = /*#__PURE__*/memo(SparklineInteractivePathsWithGeneric);
@@ -0,0 +1,70 @@
1
+ import React, { memo, useCallback, useMemo } from 'react';
2
+ import { periodLabelMap } from '@coinbase/cds-common/tokens/sparkline';
3
+ import { getAccessibleColor } from '@coinbase/cds-common/utils/getAccessibleColor';
4
+ import { useTheme } from '@coinbase/cds-web/hooks/useTheme';
5
+ import { Box, HStack } from '@coinbase/cds-web/layout';
6
+ import { Pressable } from '@coinbase/cds-web/system/Pressable';
7
+ import { TextLabel1 } from '@coinbase/cds-web/typography/TextLabel1';
8
+ import { jsx as _jsx } from "react/jsx-runtime";
9
+ function SparklineInteractivePeriodWithGeneric(_ref) {
10
+ var _periodLabelMap$perio;
11
+ let {
12
+ period,
13
+ selectedPeriod,
14
+ setSelectedPeriod,
15
+ color
16
+ } = _ref;
17
+ const periodLabel = (_periodLabelMap$perio = periodLabelMap[period.label]) !== null && _periodLabelMap$perio !== void 0 ? _periodLabelMap$perio : period.label;
18
+ const isSelected = period.value === selectedPeriod;
19
+ const handleOnClick = useCallback(() => {
20
+ setSelectedPeriod(period.value);
21
+ }, [period, setSelectedPeriod]);
22
+ const background = useMemo(() => isSelected ? 'bgPrimaryWash' : 'transparent', [isSelected]);
23
+ return /*#__PURE__*/_jsx(Box, {
24
+ alignItems: "center",
25
+ height: "fit-content",
26
+ justifyContent: "center",
27
+ children: /*#__PURE__*/_jsx(Pressable, {
28
+ accessibilityLabel: periodLabel,
29
+ "aria-pressed": isSelected,
30
+ background: background,
31
+ borderRadius: 200,
32
+ onClick: handleOnClick,
33
+ children: /*#__PURE__*/_jsx(TextLabel1, {
34
+ noWrap: true,
35
+ as: "span",
36
+ dangerouslySetColor: isSelected ? color : 'var(--color-fgMuted)',
37
+ display: "block",
38
+ paddingX: 2,
39
+ paddingY: 1,
40
+ children: period.label
41
+ })
42
+ })
43
+ });
44
+ }
45
+ const SparklineInteractivePeriod = /*#__PURE__*/memo(SparklineInteractivePeriodWithGeneric);
46
+ export const SparklineInteractivePeriodSelector = _ref2 => {
47
+ let {
48
+ selectedPeriod,
49
+ setSelectedPeriod,
50
+ periods,
51
+ color
52
+ } = _ref2;
53
+ const theme = useTheme();
54
+ const accessibleForeground = color !== 'auto' ? color : getAccessibleColor({
55
+ background: theme.color.bg,
56
+ foreground: 'auto',
57
+ enhanced: true
58
+ });
59
+ return /*#__PURE__*/_jsx(HStack, {
60
+ justifyContent: "space-between",
61
+ paddingX: 1,
62
+ width: "100%",
63
+ children: periods.map(period => /*#__PURE__*/_jsx(SparklineInteractivePeriod, {
64
+ color: accessibleForeground,
65
+ period: period,
66
+ selectedPeriod: selectedPeriod,
67
+ setSelectedPeriod: setSelectedPeriod
68
+ }, period.value))
69
+ });
70
+ };
@@ -0,0 +1,45 @@
1
+ import React, { createContext, memo, useCallback, useContext, useMemo, useState } from 'react';
2
+ import { noop } from '@coinbase/cds-utils';
3
+ import { jsx as _jsx } from "react/jsx-runtime";
4
+ const SparklineInteractiveContext = /*#__PURE__*/createContext({
5
+ isFallbackVisible: true,
6
+ compact: false,
7
+ width: 0,
8
+ height: 0,
9
+ showFallback: noop,
10
+ hideFallback: noop,
11
+ setWidth: noop,
12
+ setHeight: noop
13
+ });
14
+ export const SparklineInteractiveProvider = /*#__PURE__*/memo(_ref => {
15
+ let {
16
+ children,
17
+ compact = false
18
+ } = _ref;
19
+ const [isFallbackVisible, setIsFallbackVisible] = useState(true);
20
+ const [width, setWidth] = useState(0);
21
+ const [height, setHeight] = useState(0);
22
+ const showFallback = useCallback(() => {
23
+ setIsFallbackVisible(true);
24
+ }, [setIsFallbackVisible]);
25
+ const hideFallback = useCallback(() => {
26
+ setIsFallbackVisible(false);
27
+ }, [setIsFallbackVisible]);
28
+ const value = useMemo(() => ({
29
+ compact,
30
+ width,
31
+ height,
32
+ showFallback,
33
+ hideFallback,
34
+ isFallbackVisible,
35
+ setHeight,
36
+ setWidth
37
+ }), [compact, height, hideFallback, isFallbackVisible, showFallback, width]);
38
+ return /*#__PURE__*/_jsx(SparklineInteractiveContext.Provider, {
39
+ value: value,
40
+ children: children
41
+ });
42
+ });
43
+ export function useSparklineInteractiveContext() {
44
+ return useContext(SparklineInteractiveContext);
45
+ }
@@ -0,0 +1,5 @@
1
+ .cds-insetFocusRingCss-is0dyrn{position:relative;}.cds-insetFocusRingCss-is0dyrn:focus{outline:none;}.cds-insetFocusRingCss-is0dyrn:focus-visible{outline-style:solid;outline-width:2px;outline-color:var(--color-bgPrimary);outline-offset:0;}
2
+ .cds-scrubHandlerContainerCss-s9euk9d{position:relative;width:100%;height:100%;}
3
+ .cds-scrubHandlerCss-s6b8h5z.cds-sparkline--scrubhandler{position:absolute;width:100%;height:100%;top:0;left:0;}
4
+ .cds-fadeInMaskCss-f1bwvdrs.cds-fadeInMaskCss-f1bwvdrs{-webkit-animation:cdsSparklineInteractiveScrubFadeInMask-cds-fadeInMaskCss-f1bwvdrs 200ms cubic-bezier(0.6,0,0.15,1);animation:cdsSparklineInteractiveScrubFadeInMask-cds-fadeInMaskCss-f1bwvdrs 200ms cubic-bezier(0.6,0,0.15,1);opacity:0.8;}@-webkit-keyframes cdsSparklineInteractiveScrubFadeInMask-cds-fadeInMaskCss-f1bwvdrs{0%{opacity:0;}100%{opacity:0.8;}}@keyframes cdsSparklineInteractiveScrubFadeInMask-cds-fadeInMaskCss-f1bwvdrs{0%{opacity:0;}100%{opacity:0.8;}}
5
+ .cds-fadeOutMaskCss-f19rjrl4.cds-fadeOutMaskCss-f19rjrl4{-webkit-animation:cdsSparklineInteractiveScrubFadeOutMask-cds-fadeOutMaskCss-f19rjrl4 200ms cubic-bezier(0.6,0,0.15,1);animation:cdsSparklineInteractiveScrubFadeOutMask-cds-fadeOutMaskCss-f19rjrl4 200ms cubic-bezier(0.6,0,0.15,1);opacity:0;}@-webkit-keyframes cdsSparklineInteractiveScrubFadeOutMask-cds-fadeOutMaskCss-f19rjrl4{0%{opacity:0.8;}100%{opacity:0;}}@keyframes cdsSparklineInteractiveScrubFadeOutMask-cds-fadeOutMaskCss-f19rjrl4{0%{opacity:0.8;}100%{opacity:0;}}