@coinbase/cds-mobile-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 (124) 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 +8 -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/__figma__/Sparkline.figma.d.ts +2 -0
  15. package/dts/sparkline/__figma__/Sparkline.figma.d.ts.map +1 -0
  16. package/dts/sparkline/__stories__/Sparkline.stories.d.ts +3 -0
  17. package/dts/sparkline/__stories__/Sparkline.stories.d.ts.map +1 -0
  18. package/dts/sparkline/__stories__/SparklineGradient.stories.d.ts +3 -0
  19. package/dts/sparkline/__stories__/SparklineGradient.stories.d.ts.map +1 -0
  20. package/dts/sparkline/generateSparklineWithId.d.ts +5 -0
  21. package/dts/sparkline/generateSparklineWithId.d.ts.map +1 -0
  22. package/dts/sparkline/index.d.ts +6 -0
  23. package/dts/sparkline/index.d.ts.map +1 -0
  24. package/dts/sparkline/sparkline-interactive/SparklineAccessibleView.d.ts +18 -0
  25. package/dts/sparkline/sparkline-interactive/SparklineAccessibleView.d.ts.map +1 -0
  26. package/dts/sparkline/sparkline-interactive/SparklineInteractive.d.ts +162 -0
  27. package/dts/sparkline/sparkline-interactive/SparklineInteractive.d.ts.map +1 -0
  28. package/dts/sparkline/sparkline-interactive/SparklineInteractiveAnimatedPath.d.ts +12 -0
  29. package/dts/sparkline/sparkline-interactive/SparklineInteractiveAnimatedPath.d.ts.map +1 -0
  30. package/dts/sparkline/sparkline-interactive/SparklineInteractiveHoverDate.d.ts +17 -0
  31. package/dts/sparkline/sparkline-interactive/SparklineInteractiveHoverDate.d.ts.map +1 -0
  32. package/dts/sparkline/sparkline-interactive/SparklineInteractiveLineVertical.d.ts +8 -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/SparklineInteractiveMinMax.d.ts +9 -0
  37. package/dts/sparkline/sparkline-interactive/SparklineInteractiveMinMax.d.ts.map +1 -0
  38. package/dts/sparkline/sparkline-interactive/SparklineInteractivePanGestureHandler.d.ts +14 -0
  39. package/dts/sparkline/sparkline-interactive/SparklineInteractivePanGestureHandler.d.ts.map +1 -0
  40. package/dts/sparkline/sparkline-interactive/SparklineInteractivePaths.d.ts +11 -0
  41. package/dts/sparkline/sparkline-interactive/SparklineInteractivePaths.d.ts.map +1 -0
  42. package/dts/sparkline/sparkline-interactive/SparklineInteractivePeriodSelector.d.ts +20 -0
  43. package/dts/sparkline/sparkline-interactive/SparklineInteractivePeriodSelector.d.ts.map +1 -0
  44. package/dts/sparkline/sparkline-interactive/SparklineInteractiveProvider.d.ts +33 -0
  45. package/dts/sparkline/sparkline-interactive/SparklineInteractiveProvider.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 +3 -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__/SparklineInteractiveHoverDate.test.d.ts +2 -0
  55. package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractiveHoverDate.test.d.ts.map +1 -0
  56. package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractivePanGestureHandler.test.d.ts +2 -0
  57. package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractivePanGestureHandler.test.d.ts.map +1 -0
  58. package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractivePeriodSelector.test.d.ts +2 -0
  59. package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractivePeriodSelector.test.d.ts.map +1 -0
  60. package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractiveTimeseriesPaths.test.d.ts +2 -0
  61. package/dts/sparkline/sparkline-interactive/__tests__/SparklineInteractiveTimeseriesPaths.test.d.ts.map +1 -0
  62. package/dts/sparkline/sparkline-interactive/__tests__/useMinMaxTransform.test.d.ts +2 -0
  63. package/dts/sparkline/sparkline-interactive/__tests__/useMinMaxTransform.test.d.ts.map +1 -0
  64. package/dts/sparkline/sparkline-interactive/useInterruptiblePathAnimation.d.ts +9 -0
  65. package/dts/sparkline/sparkline-interactive/useInterruptiblePathAnimation.d.ts.map +1 -0
  66. package/dts/sparkline/sparkline-interactive/useInterruptiblePathAnimation.test.disable.d.ts +2 -0
  67. package/dts/sparkline/sparkline-interactive/useInterruptiblePathAnimation.test.disable.d.ts.map +1 -0
  68. package/dts/sparkline/sparkline-interactive/useMinMaxTransform.d.ts +11 -0
  69. package/dts/sparkline/sparkline-interactive/useMinMaxTransform.d.ts.map +1 -0
  70. package/dts/sparkline/sparkline-interactive/useOpacityAnimation.d.ts +3 -0
  71. package/dts/sparkline/sparkline-interactive/useOpacityAnimation.d.ts.map +1 -0
  72. package/dts/sparkline/sparkline-interactive/useSparklineInteractiveConstants.d.ts +22 -0
  73. package/dts/sparkline/sparkline-interactive/useSparklineInteractiveConstants.d.ts.map +1 -0
  74. package/dts/sparkline/sparkline-interactive/useSparklineInteractiveLineStyles.d.ts +31 -0
  75. package/dts/sparkline/sparkline-interactive/useSparklineInteractiveLineStyles.d.ts.map +1 -0
  76. package/dts/sparkline/sparkline-interactive-header/SparklineInteractiveHeader.d.ts +110 -0
  77. package/dts/sparkline/sparkline-interactive-header/SparklineInteractiveHeader.d.ts.map +1 -0
  78. package/dts/sparkline/sparkline-interactive-header/__figma__/SparklineInteractiveHeader.figma.d.ts +2 -0
  79. package/dts/sparkline/sparkline-interactive-header/__figma__/SparklineInteractiveHeader.figma.d.ts.map +1 -0
  80. package/dts/sparkline/sparkline-interactive-header/__stories__/SparklineInteractiveHeader.stories.d.ts +4 -0
  81. package/dts/sparkline/sparkline-interactive-header/__stories__/SparklineInteractiveHeader.stories.d.ts.map +1 -0
  82. package/dts/sparkline/sparkline-interactive-header/__tests__/SparklineInteractiveHeader.test.d.ts +2 -0
  83. package/dts/sparkline/sparkline-interactive-header/__tests__/SparklineInteractiveHeader.test.d.ts.map +1 -0
  84. package/dts/sparkline/sparkline-interactive-header/__tests__/useSparklineInteractiveHeaderStyles.test.d.ts +2 -0
  85. package/dts/sparkline/sparkline-interactive-header/__tests__/useSparklineInteractiveHeaderStyles.test.d.ts.map +1 -0
  86. package/dts/sparkline/sparkline-interactive-header/useSparklineInteractiveHeaderStyles.d.ts +26 -0
  87. package/dts/sparkline/sparkline-interactive-header/useSparklineInteractiveHeaderStyles.d.ts.map +1 -0
  88. package/esm/index.js +1 -0
  89. package/esm/sparkline/Counter.js +45 -0
  90. package/esm/sparkline/Sparkline.js +51 -0
  91. package/esm/sparkline/SparklineArea.js +14 -0
  92. package/esm/sparkline/SparklineAreaPattern.js +36 -0
  93. package/esm/sparkline/SparklineGradient.js +72 -0
  94. package/esm/sparkline/__figma__/Sparkline.figma.js +22 -0
  95. package/esm/sparkline/__stories__/Sparkline.stories.js +120 -0
  96. package/esm/sparkline/__stories__/SparklineGradient.stories.js +123 -0
  97. package/esm/sparkline/generateSparklineWithId.js +6 -0
  98. package/esm/sparkline/index.js +5 -0
  99. package/esm/sparkline/sparkline-interactive/SparklineAccessibleView.js +75 -0
  100. package/esm/sparkline/sparkline-interactive/SparklineInteractive.js +303 -0
  101. package/esm/sparkline/sparkline-interactive/SparklineInteractiveAnimatedPath.js +113 -0
  102. package/esm/sparkline/sparkline-interactive/SparklineInteractiveHoverDate.js +131 -0
  103. package/esm/sparkline/sparkline-interactive/SparklineInteractiveLineVertical.js +99 -0
  104. package/esm/sparkline/sparkline-interactive/SparklineInteractiveMarkerDates.js +82 -0
  105. package/esm/sparkline/sparkline-interactive/SparklineInteractiveMinMax.js +103 -0
  106. package/esm/sparkline/sparkline-interactive/SparklineInteractivePanGestureHandler.js +104 -0
  107. package/esm/sparkline/sparkline-interactive/SparklineInteractivePaths.js +53 -0
  108. package/esm/sparkline/sparkline-interactive/SparklineInteractivePeriodSelector.js +124 -0
  109. package/esm/sparkline/sparkline-interactive/SparklineInteractiveProvider.js +80 -0
  110. package/esm/sparkline/sparkline-interactive/SparklineInteractiveTimeseriesPaths.js +109 -0
  111. package/esm/sparkline/sparkline-interactive/__figma__/SparklineInteractive.figma.js +85 -0
  112. package/esm/sparkline/sparkline-interactive/__stories__/SparklineInteractive.stories.js +474 -0
  113. package/esm/sparkline/sparkline-interactive/useInterruptiblePathAnimation.js +58 -0
  114. package/esm/sparkline/sparkline-interactive/useInterruptiblePathAnimation.test.disable.js +37 -0
  115. package/esm/sparkline/sparkline-interactive/useMinMaxTransform.js +56 -0
  116. package/esm/sparkline/sparkline-interactive/useOpacityAnimation.js +23 -0
  117. package/esm/sparkline/sparkline-interactive/useSparklineInteractiveConstants.js +47 -0
  118. package/esm/sparkline/sparkline-interactive/useSparklineInteractiveLineStyles.js +34 -0
  119. package/esm/sparkline/sparkline-interactive-header/SparklineInteractiveHeader.js +233 -0
  120. package/esm/sparkline/sparkline-interactive-header/__figma__/SparklineInteractiveHeader.figma.js +104 -0
  121. package/esm/sparkline/sparkline-interactive-header/__stories__/SparklineInteractiveHeader.stories.js +555 -0
  122. package/esm/sparkline/sparkline-interactive-header/useSparklineInteractiveHeaderStyles.js +117 -0
  123. package/package.json +64 -5
  124. package/index.js +0 -1
@@ -0,0 +1,120 @@
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
+ import React from 'react';
3
+ import { Dimensions } from 'react-native';
4
+ import { assets } from '@coinbase/cds-common/internal/data/assets';
5
+ import { prices, pricesWithScalingFactor } from '@coinbase/cds-common/internal/data/prices';
6
+ import { gutter } from '@coinbase/cds-common/tokens/sizing';
7
+ import { useSparklineArea } from '@coinbase/cds-common/visualizations/useSparklineArea';
8
+ import { useSparklinePath } from '@coinbase/cds-common/visualizations/useSparklinePath';
9
+ import { Cell } from '@coinbase/cds-mobile/cells/Cell';
10
+ import { CellMedia } from '@coinbase/cds-mobile/cells/CellMedia';
11
+ import { Example, ExampleScreen } from '@coinbase/cds-mobile/examples/ExampleScreen';
12
+ import { useTheme } from '@coinbase/cds-mobile/hooks/useTheme';
13
+ import { HStack } from '@coinbase/cds-mobile/layout/HStack';
14
+ import { VStack } from '@coinbase/cds-mobile/layout/VStack';
15
+ import { TextBody } from '@coinbase/cds-mobile/typography/TextBody';
16
+ import { TextHeadline } from '@coinbase/cds-mobile/typography/TextHeadline';
17
+ import { Sparkline } from '../Sparkline';
18
+ import { SparklineArea } from '../SparklineArea';
19
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
20
+ const SparklineExample = _ref => {
21
+ let {
22
+ imageUrl,
23
+ name,
24
+ symbol,
25
+ color
26
+ } = _ref;
27
+ const dimensions = {
28
+ width: 64,
29
+ height: 20
30
+ };
31
+ const path = useSparklinePath(_extends({}, dimensions, {
32
+ data: prices
33
+ }));
34
+ return /*#__PURE__*/_jsx(Cell, {
35
+ detail: /*#__PURE__*/_jsxs(HStack, {
36
+ alignItems: "center",
37
+ children: [/*#__PURE__*/_jsx(Sparkline, _extends({}, dimensions, {
38
+ color: color,
39
+ path: path
40
+ })), /*#__PURE__*/_jsxs(VStack, {
41
+ alignContent: "flex-end",
42
+ alignItems: "flex-end",
43
+ justifyContent: "center",
44
+ paddingStart: 2,
45
+ children: [/*#__PURE__*/_jsx(TextBody, {
46
+ align: "end",
47
+ numberOfLines: 1,
48
+ children: "$2,874.49"
49
+ }), /*#__PURE__*/_jsx(TextBody, {
50
+ align: "end",
51
+ color: "fgMuted",
52
+ numberOfLines: 1,
53
+ children: "+36.08%"
54
+ })]
55
+ })]
56
+ }),
57
+ media: /*#__PURE__*/_jsx(CellMedia, {
58
+ source: imageUrl,
59
+ title: "Title",
60
+ type: "image"
61
+ }),
62
+ children: /*#__PURE__*/_jsxs(VStack, {
63
+ justifyContent: "center",
64
+ children: [/*#__PURE__*/_jsx(TextHeadline, {
65
+ ellipsize: "tail",
66
+ numberOfLines: 1,
67
+ children: name
68
+ }), /*#__PURE__*/_jsx(TextBody, {
69
+ ellipsize: "tail",
70
+ numberOfLines: 1,
71
+ children: symbol
72
+ })]
73
+ })
74
+ });
75
+ };
76
+ const SparklineScalingExample = props => {
77
+ const theme = useTheme();
78
+ const chartHorizontalGutter = theme.space[gutter];
79
+ const width = Dimensions.get('screen').width - chartHorizontalGutter * 2;
80
+ const dimensions = {
81
+ width,
82
+ height: 320
83
+ };
84
+ const path = useSparklinePath(_extends({}, dimensions, props));
85
+ const area = useSparklineArea(_extends({}, dimensions, props));
86
+ return /*#__PURE__*/_jsxs(VStack, {
87
+ children: [/*#__PURE__*/_jsxs(TextHeadline, {
88
+ ellipsize: "tail",
89
+ numberOfLines: 1,
90
+ children: ["Scale: ", props.yAxisScalingFactor]
91
+ }), /*#__PURE__*/_jsx(Sparkline, _extends({}, dimensions, {
92
+ color: "#F7931A",
93
+ path: path,
94
+ yAxisScalingFactor: props.yAxisScalingFactor,
95
+ children: props.fill && /*#__PURE__*/_jsx(SparklineArea, {
96
+ area: area
97
+ })
98
+ }))]
99
+ });
100
+ };
101
+ const PressableOpacityScreen = () => {
102
+ return /*#__PURE__*/_jsxs(ExampleScreen, {
103
+ children: [/*#__PURE__*/_jsx(Example, {
104
+ title: "Sparkline",
105
+ children: /*#__PURE__*/_jsxs(VStack, {
106
+ marginX: -2,
107
+ children: [/*#__PURE__*/_jsx(SparklineExample, _extends({}, assets.btc)), /*#__PURE__*/_jsx(SparklineExample, _extends({}, assets.eth)), /*#__PURE__*/_jsx(SparklineExample, _extends({}, assets.xrp)), /*#__PURE__*/_jsx(SparklineExample, _extends({}, assets.dai)), /*#__PURE__*/_jsx(SparklineExample, _extends({}, assets.sushi))]
108
+ })
109
+ }), /*#__PURE__*/_jsx(Example, {
110
+ title: "SparklineWithScale",
111
+ children: pricesWithScalingFactor.map(item => /*#__PURE__*/_jsx(SparklineScalingExample, _extends({}, item), item.yAxisScalingFactor))
112
+ }), /*#__PURE__*/_jsx(Example, {
113
+ title: "SparklineWithScaleAndFill",
114
+ children: pricesWithScalingFactor.map(item => /*#__PURE__*/_jsx(SparklineScalingExample, _extends({}, item, {
115
+ fill: true
116
+ }), item.yAxisScalingFactor))
117
+ })]
118
+ });
119
+ };
120
+ export default PressableOpacityScreen;
@@ -0,0 +1,123 @@
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
+ import React from 'react';
3
+ import { Dimensions } from 'react-native';
4
+ import { assets } from '@coinbase/cds-common/internal/data/assets';
5
+ import { prices, pricesWithScalingFactor } from '@coinbase/cds-common/internal/data/prices';
6
+ import { gutter } from '@coinbase/cds-common/tokens/sizing';
7
+ import { useSparklineArea } from '@coinbase/cds-common/visualizations/useSparklineArea';
8
+ import { useSparklinePath } from '@coinbase/cds-common/visualizations/useSparklinePath';
9
+ import { Cell } from '@coinbase/cds-mobile/cells/Cell';
10
+ import { CellMedia } from '@coinbase/cds-mobile/cells/CellMedia';
11
+ import { Example, ExampleScreen } from '@coinbase/cds-mobile/examples/ExampleScreen';
12
+ import { useTheme } from '@coinbase/cds-mobile/hooks/useTheme';
13
+ import { VStack } from '@coinbase/cds-mobile/layout';
14
+ import { TextBody, TextHeadline } from '@coinbase/cds-mobile/typography';
15
+ import { SparklineArea } from '../SparklineArea';
16
+ import { SparklineGradient } from '../SparklineGradient';
17
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
18
+ const height = 320;
19
+ const SparklineGradientExample = _ref => {
20
+ let {
21
+ imageUrl,
22
+ name,
23
+ symbol,
24
+ color,
25
+ fill
26
+ } = _ref;
27
+ const theme = useTheme();
28
+ const chartHorizontalGutter = theme.space[gutter];
29
+ const width = Dimensions.get('screen').width - chartHorizontalGutter * 2;
30
+ const dimensions = {
31
+ width,
32
+ height
33
+ };
34
+ const path = useSparklinePath(_extends({}, dimensions, {
35
+ data: prices
36
+ }));
37
+ const area = useSparklineArea(_extends({}, dimensions, {
38
+ data: prices
39
+ }));
40
+ return /*#__PURE__*/_jsxs(VStack, {
41
+ children: [/*#__PURE__*/_jsx(Cell, {
42
+ media: /*#__PURE__*/_jsx(CellMedia, {
43
+ source: imageUrl,
44
+ type: "image"
45
+ }),
46
+ children: /*#__PURE__*/_jsxs(VStack, {
47
+ justifyContent: "center",
48
+ children: [/*#__PURE__*/_jsx(TextHeadline, {
49
+ ellipsize: "tail",
50
+ numberOfLines: 1,
51
+ children: name
52
+ }), /*#__PURE__*/_jsx(TextBody, {
53
+ ellipsize: "tail",
54
+ numberOfLines: 1,
55
+ children: symbol
56
+ })]
57
+ })
58
+ }), /*#__PURE__*/_jsx(SparklineGradient, _extends({}, dimensions, {
59
+ color: color,
60
+ path: path,
61
+ children: fill && /*#__PURE__*/_jsx(SparklineArea, {
62
+ area: area
63
+ })
64
+ }))]
65
+ });
66
+ };
67
+ const SparklineScalingExample = props => {
68
+ const theme = useTheme();
69
+ const chartHorizontalGutter = theme.space[gutter];
70
+ const width = Dimensions.get('screen').width - chartHorizontalGutter * 2;
71
+ const dimensions = {
72
+ width,
73
+ height
74
+ };
75
+ const path = useSparklinePath(_extends({}, dimensions, props));
76
+ const area = useSparklineArea(_extends({}, dimensions, props));
77
+ return /*#__PURE__*/_jsxs(VStack, {
78
+ children: [/*#__PURE__*/_jsxs(TextHeadline, {
79
+ ellipsize: "tail",
80
+ numberOfLines: 1,
81
+ children: ["Scale: ", props.yAxisScalingFactor]
82
+ }), /*#__PURE__*/_jsx(SparklineGradient, _extends({}, dimensions, {
83
+ color: "#F7931A",
84
+ path: path,
85
+ yAxisScalingFactor: props.yAxisScalingFactor,
86
+ children: props.fill && /*#__PURE__*/_jsx(SparklineArea, {
87
+ area: area
88
+ })
89
+ }))]
90
+ });
91
+ };
92
+ const PressableOpacityScreen = () => {
93
+ return /*#__PURE__*/_jsxs(ExampleScreen, {
94
+ children: [/*#__PURE__*/_jsxs(Example, {
95
+ title: "SparklineGradient",
96
+ children: [/*#__PURE__*/_jsx(SparklineGradientExample, _extends({}, assets.btc)), /*#__PURE__*/_jsx(SparklineGradientExample, _extends({}, assets.eth)), /*#__PURE__*/_jsx(SparklineGradientExample, _extends({}, assets.ltc)), /*#__PURE__*/_jsx(SparklineGradientExample, _extends({}, assets.xrp)), /*#__PURE__*/_jsx(SparklineGradientExample, _extends({}, assets.dai)), /*#__PURE__*/_jsx(SparklineGradientExample, _extends({}, assets.sushi))]
97
+ }), /*#__PURE__*/_jsxs(Example, {
98
+ title: "SparklineGradientWithArea",
99
+ children: [/*#__PURE__*/_jsx(SparklineGradientExample, _extends({}, assets.btc, {
100
+ fill: true
101
+ })), /*#__PURE__*/_jsx(SparklineGradientExample, _extends({}, assets.eth, {
102
+ fill: true
103
+ })), /*#__PURE__*/_jsx(SparklineGradientExample, _extends({}, assets.ltc, {
104
+ fill: true
105
+ })), /*#__PURE__*/_jsx(SparklineGradientExample, _extends({}, assets.xrp, {
106
+ fill: true
107
+ })), /*#__PURE__*/_jsx(SparklineGradientExample, _extends({}, assets.dai, {
108
+ fill: true
109
+ })), /*#__PURE__*/_jsx(SparklineGradientExample, _extends({}, assets.sushi, {
110
+ fill: true
111
+ }))]
112
+ }), /*#__PURE__*/_jsx(Example, {
113
+ title: "SparklineGradientWithScale",
114
+ children: pricesWithScalingFactor.map(item => /*#__PURE__*/_jsx(SparklineScalingExample, _extends({}, item), item.yAxisScalingFactor))
115
+ }), /*#__PURE__*/_jsx(Example, {
116
+ title: "SparklineGradientWithAreaAndScale",
117
+ children: pricesWithScalingFactor.map(item => /*#__PURE__*/_jsx(SparklineScalingExample, _extends({}, item, {
118
+ fill: true
119
+ }), item.yAxisScalingFactor))
120
+ })]
121
+ });
122
+ };
123
+ export default PressableOpacityScreen;
@@ -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,75 @@
1
+ import React, { memo, useCallback } from 'react';
2
+ import { StyleSheet, View } from 'react-native';
3
+ import chunk from 'lodash/chunk';
4
+ import { jsx as _jsx } from "react/jsx-runtime";
5
+ const styles = StyleSheet.create({
6
+ container: {
7
+ flexDirection: 'row',
8
+ flex: 1,
9
+ position: 'absolute',
10
+ left: 0,
11
+ top: 0,
12
+ right: 0,
13
+ bottom: 0
14
+ }
15
+ });
16
+
17
+ /**
18
+ * SparklineAccessibleView renders an accessible view for Sparkline Chart.
19
+ *
20
+ * It chunks the sparkline data into 10 (or fewer) pieces, rendering each as a View with
21
+ * flex width proportional to the chunk size. The first data point in each chunk is used
22
+ * to generate an accessibilityLabel with the date and value.
23
+ *
24
+ * @param data - The sparkline data mapped by time period
25
+ * @param selectedPeriod - The currently selected time period
26
+ */
27
+ export const SparklineAccessibleView = /*#__PURE__*/memo(function SparklineAccessibleView(_ref) {
28
+ let {
29
+ data,
30
+ selectedPeriod
31
+ } = _ref;
32
+ const chunkedData = data ? chunk(data[selectedPeriod], data[selectedPeriod].length / 10) : [];
33
+ // if the data is not evenly divisible by 10, the last chunk will be smaller than the rest
34
+ // so we need to combine it with the previous chunk
35
+ if (chunkedData.length === 11) {
36
+ const lastChunk = chunkedData.pop();
37
+ chunkedData[chunkedData.length - 1] = chunkedData[chunkedData.length - 1].concat(lastChunk != null ? lastChunk : []);
38
+ }
39
+ const getStyleByLength = useCallback(length => ({
40
+ flex: length
41
+ }), []);
42
+ return /*#__PURE__*/_jsx(View, {
43
+ style: styles.container,
44
+ children: chunkedData.map(dataChunk => {
45
+ // use the first data point in chunk for accessibility label
46
+ const item = dataChunk[0];
47
+
48
+ // only announce time for hour and day
49
+ const shouldAnnounceTime = selectedPeriod === 'hour' || selectedPeriod === 'day';
50
+
51
+ // Extract date formatting options
52
+ const timeOptions = {
53
+ hour: 'numeric',
54
+ minute: 'numeric',
55
+ hour12: true
56
+ };
57
+ const dateOptions = {
58
+ month: 'long',
59
+ day: 'numeric',
60
+ year: 'numeric'
61
+ };
62
+
63
+ // TODO: localize date and time
64
+ const dateTime = item.date.toLocaleString('en-US', shouldAnnounceTime ? timeOptions : dateOptions);
65
+ const price = item.value.toFixed(2);
66
+ return /*#__PURE__*/_jsx(View, {
67
+ accessible: true,
68
+ accessibilityLabel: dateTime + ", $" + price
69
+ // variable width base on chunk length
70
+ ,
71
+ style: getStyleByLength(dataChunk.length)
72
+ }, String(item.date));
73
+ })
74
+ });
75
+ });
@@ -0,0 +1,303 @@
1
+ const _excluded = ["compact", "gutter"];
2
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
3
+ 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
+ import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
5
+ import { Animated, StyleSheet, View } from 'react-native';
6
+ import { minMax } from '@coinbase/cds-common/utils/chart';
7
+ import { getAccessibleColor } from '@coinbase/cds-common/utils/getAccessibleColor';
8
+ import { useSparklineCoordinates } from '@coinbase/cds-common/visualizations/useSparklineCoordinates';
9
+ import { chartFallbackNegative, chartFallbackPositive } from '@coinbase/cds-lottie-files';
10
+ import { Lottie } from '@coinbase/cds-mobile/animation';
11
+ import { useScreenReaderStatus } from '@coinbase/cds-mobile/hooks/useScreenReaderStatus';
12
+ import { useTheme } from '@coinbase/cds-mobile/hooks/useTheme';
13
+ import { Box } from '@coinbase/cds-mobile/layout';
14
+ import { emptyArray, noop } from '@coinbase/cds-utils';
15
+ import isEqual from 'lodash/isEqual';
16
+ import isObject from 'lodash/isObject';
17
+ import { SparklineAccessibleView } from './SparklineAccessibleView';
18
+ import { SparklineInteractiveHoverDate } from './SparklineInteractiveHoverDate';
19
+ import { SparklineInteractiveLineVertical } from './SparklineInteractiveLineVertical';
20
+ import { SparklineInteractiveMarkerDates } from './SparklineInteractiveMarkerDates';
21
+ import { SparklineInteractiveMinMax } from './SparklineInteractiveMinMax';
22
+ import { SparklineInteractivePanGestureHandler } from './SparklineInteractivePanGestureHandler';
23
+ import { SparklineInteractivePaths } from './SparklineInteractivePaths';
24
+ import { SparklineInteractivePeriodSelector } from './SparklineInteractivePeriodSelector';
25
+ import { SparklineInteractiveProvider, useSparklineInteractiveContext } from './SparklineInteractiveProvider';
26
+ import { useSparklineInteractiveConstants } from './useSparklineInteractiveConstants';
27
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
28
+ export * from '@coinbase/cds-common/types/Chart';
29
+ const DefaultFallback = /*#__PURE__*/memo(_ref => {
30
+ let {
31
+ fallbackType
32
+ } = _ref;
33
+ const source = fallbackType === 'negative' ? chartFallbackNegative : chartFallbackPositive;
34
+ return /*#__PURE__*/_jsx(Box, {
35
+ alignItems: "center",
36
+ justifyContent: "center",
37
+ children: /*#__PURE__*/_jsx(Lottie, {
38
+ autoplay: true,
39
+ loop: true,
40
+ height: "100%",
41
+ source: source
42
+ })
43
+ });
44
+ });
45
+ function defaultFormatMinMaxLabel(value) {
46
+ return "" + value;
47
+ }
48
+ function BelowChartWithGeneric(_ref2) {
49
+ let {
50
+ color,
51
+ formatDate,
52
+ getMarker,
53
+ periods,
54
+ selectedPeriod,
55
+ setSelectedPeriod,
56
+ timePeriodGutter
57
+ } = _ref2;
58
+ const theme = useTheme();
59
+ const style = useMemo(() => {
60
+ if (timePeriodGutter) {
61
+ return {
62
+ paddingHorizontal: theme.space[timePeriodGutter]
63
+ };
64
+ }
65
+ return {};
66
+ }, [theme.space, timePeriodGutter]);
67
+ return /*#__PURE__*/_jsxs(View, {
68
+ style: style,
69
+ children: [/*#__PURE__*/_jsx(SparklineInteractiveMarkerDates, {
70
+ formatDate: formatDate,
71
+ getMarker: getMarker,
72
+ selectedPeriod: selectedPeriod,
73
+ timePeriodGutter: timePeriodGutter
74
+ }), /*#__PURE__*/_jsx(SparklineInteractivePeriodSelector, {
75
+ color: color,
76
+ periods: periods,
77
+ selectedPeriod: selectedPeriod,
78
+ setSelectedPeriod: setSelectedPeriod
79
+ })]
80
+ });
81
+ }
82
+ const BelowChart = /*#__PURE__*/memo(BelowChartWithGeneric);
83
+ function SparklineInteractiveContentWithGeneric(_ref3) {
84
+ let {
85
+ data,
86
+ periods,
87
+ defaultPeriod,
88
+ onPeriodChanged,
89
+ strokeColor,
90
+ onScrub = noop,
91
+ onScrubStart = noop,
92
+ onScrubEnd = noop,
93
+ formatMinMaxLabel = defaultFormatMinMaxLabel,
94
+ formatDate,
95
+ fallback = null,
96
+ hideMinMaxLabel = false,
97
+ hidePeriodSelector = false,
98
+ disableScrubbing = false,
99
+ fill = true,
100
+ yAxisScalingFactor = 1.0,
101
+ formatHoverDate,
102
+ headerNode,
103
+ fallbackType = 'positive',
104
+ disableHorizontalPadding = false,
105
+ hoverData,
106
+ timePeriodGutter,
107
+ allowOverflowGestures,
108
+ style,
109
+ styles,
110
+ headerTestID
111
+ } = _ref3;
112
+ const [isScrubbing, setIsScrubbing] = useState(false);
113
+ const {
114
+ isFallbackVisible,
115
+ showFallback,
116
+ chartOpacity,
117
+ minMaxOpacity,
118
+ compact
119
+ } = useSparklineInteractiveContext();
120
+ const color = strokeColor;
121
+ const [selectedPeriod, setSelectedPeriod] = useState(defaultPeriod);
122
+ const chartHoverTextInputRef = useRef(null);
123
+ const theme = useTheme();
124
+ const isScreenReaderEnabled = useScreenReaderStatus();
125
+ const lineVerticalColor = useMemo(() => {
126
+ const lineColor = color !== 'auto' ? color : getAccessibleColor({
127
+ background: theme.color.bg,
128
+ foreground: 'auto',
129
+ usage: 'graphic'
130
+ });
131
+ return hoverData ? theme.color.bgLineHeavy : lineColor;
132
+ }, [hoverData, color, theme.color.bg, theme.color.bgLineHeavy]);
133
+ const dataForPeriod = useMemo(() => {
134
+ var _data$selectedPeriod;
135
+ if (!data) {
136
+ return emptyArray;
137
+ }
138
+ return (_data$selectedPeriod = data[selectedPeriod]) != null ? _data$selectedPeriod : emptyArray;
139
+ }, [data, selectedPeriod]);
140
+
141
+ // If dataForPeriod is empty we know that we are either loading
142
+ // or backend returned bad data and we should show fallback UI.
143
+ const hasData = dataForPeriod.length > 0;
144
+ const [min, max] = useMemo(() => {
145
+ return minMax(dataForPeriod, d => d.value);
146
+ }, [dataForPeriod]);
147
+ const chartOpacityStyle = useMemo(() => {
148
+ return {
149
+ opacity: chartOpacity
150
+ };
151
+ }, [chartOpacity]);
152
+ useEffect(() => {
153
+ var _data$selectedPeriod2;
154
+ // If there is no data for selected period show fallback loader
155
+ if (isObject(data) && !((_data$selectedPeriod2 = data[selectedPeriod]) != null && _data$selectedPeriod2.length) && !isFallbackVisible) {
156
+ showFallback();
157
+ }
158
+ }, [data, isFallbackVisible, selectedPeriod, showFallback]);
159
+ const updatePeriod = useCallback(period => {
160
+ if (isObject(data) && period !== selectedPeriod) {
161
+ // This can sometimes happen for newer assets which
162
+ // will have their 'all' chart data be the same as
163
+ // their 'year' chart data. In those cases we don't
164
+ // want to animate out the min/max since we rely on
165
+ // AnimatedChartPath to animate those components back in -
166
+ // and AnimatedChartPath will not trigger an animation
167
+ // if it's chartData is the same between re-renders
168
+ if (!isEqual(data[period], data[selectedPeriod])) {
169
+ minMaxOpacity.setValue(0);
170
+ }
171
+ setSelectedPeriod(period);
172
+ onPeriodChanged == null || onPeriodChanged(period);
173
+ }
174
+ }, [data, selectedPeriod, onPeriodChanged, minMaxOpacity]);
175
+ const {
176
+ chartHorizontalGutter,
177
+ chartDimensionStyles,
178
+ chartWidth,
179
+ chartHeight
180
+ } = useSparklineInteractiveConstants({
181
+ compact
182
+ });
183
+ const {
184
+ xFunction,
185
+ path,
186
+ area,
187
+ getMarker
188
+ } = useSparklineCoordinates({
189
+ data: dataForPeriod,
190
+ width: chartWidth,
191
+ height: chartHeight,
192
+ yAxisScalingFactor
193
+ });
194
+ const handleScrub = useCallback(params => {
195
+ var _chartHoverTextInputR;
196
+ (_chartHoverTextInputR = chartHoverTextInputRef.current) == null || _chartHoverTextInputR.update(params);
197
+ onScrub == null || onScrub(params);
198
+ }, [onScrub]);
199
+ const handleScrubStart = useCallback(() => {
200
+ if (hoverData) {
201
+ setIsScrubbing(true);
202
+ }
203
+ onScrubStart == null || onScrubStart();
204
+ }, [hoverData, onScrubStart]);
205
+ const handleScrubEnd = useCallback(() => {
206
+ if (hoverData) {
207
+ setIsScrubbing(false);
208
+ }
209
+ onScrubEnd == null || onScrubEnd();
210
+ }, [hoverData, onScrubEnd]);
211
+ let header;
212
+ if (headerNode) {
213
+ header = /*#__PURE__*/_jsx(Box, {
214
+ paddingBottom: 2,
215
+ style: styles == null ? void 0 : styles.header,
216
+ testID: headerTestID,
217
+ children: headerNode
218
+ });
219
+ }
220
+ const rootStyles = useMemo(() => {
221
+ return [!disableHorizontalPadding && {
222
+ paddingHorizontal: chartHorizontalGutter
223
+ }, style, styles == null ? void 0 : styles.root];
224
+ }, [style, styles == null ? void 0 : styles.root, chartHorizontalGutter, disableHorizontalPadding]);
225
+ return /*#__PURE__*/_jsxs(Animated.View, {
226
+ style: rootStyles,
227
+ children: [header, /*#__PURE__*/_jsxs(SparklineInteractivePanGestureHandler, {
228
+ allowOverflowGestures: allowOverflowGestures,
229
+ disabled: disableScrubbing,
230
+ getMarker: getMarker,
231
+ onScrub: handleScrub,
232
+ onScrubEnd: handleScrubEnd,
233
+ onScrubStart: handleScrubStart,
234
+ selectedPeriod: selectedPeriod,
235
+ children: [!!formatHoverDate && /*#__PURE__*/_jsx(SparklineInteractiveHoverDate, {
236
+ ref: chartHoverTextInputRef,
237
+ formatHoverDate: formatHoverDate,
238
+ shouldTakeUpHeight: hideMinMaxLabel
239
+ }), !hideMinMaxLabel && /*#__PURE__*/_jsx(SparklineInteractiveMinMax, {
240
+ dataPoint: max,
241
+ formatMinMaxLabel: formatMinMaxLabel,
242
+ xFunction: xFunction
243
+ }), /*#__PURE__*/_jsxs(View, {
244
+ style: chartDimensionStyles,
245
+ children: [isScreenReaderEnabled && /*#__PURE__*/_jsx(SparklineAccessibleView, {
246
+ data: data,
247
+ selectedPeriod: selectedPeriod
248
+ }), !!isFallbackVisible && /*#__PURE__*/_jsx(View, {
249
+ style: StyleSheet.absoluteFill,
250
+ children: fallback != null ? fallback : /*#__PURE__*/_jsx(DefaultFallback, {
251
+ fallbackType: fallbackType
252
+ })
253
+ }), /*#__PURE__*/_jsx(Animated.View, {
254
+ style: chartOpacityStyle,
255
+ children: !!hasData && !!path && /*#__PURE__*/_jsxs(_Fragment, {
256
+ children: [/*#__PURE__*/_jsx(SparklineInteractiveLineVertical, {
257
+ color: lineVerticalColor,
258
+ showHoverDate: !!formatHoverDate
259
+ }), /*#__PURE__*/_jsx(SparklineInteractivePaths, {
260
+ area: area,
261
+ compact: compact,
262
+ fill: fill,
263
+ hoverData: hoverData,
264
+ path: path,
265
+ selectedPeriod: selectedPeriod,
266
+ showHoverData: isScrubbing,
267
+ strokeColor: color,
268
+ yAxisScalingFactor: yAxisScalingFactor
269
+ })]
270
+ })
271
+ })]
272
+ }), !hideMinMaxLabel && /*#__PURE__*/_jsx(SparklineInteractiveMinMax, {
273
+ dataPoint: min,
274
+ formatMinMaxLabel: formatMinMaxLabel,
275
+ xFunction: xFunction
276
+ })]
277
+ }), !hidePeriodSelector && /*#__PURE__*/_jsx(BelowChart, {
278
+ color: color,
279
+ formatDate: formatDate,
280
+ getMarker: getMarker,
281
+ periods: periods,
282
+ selectedPeriod: selectedPeriod,
283
+ setSelectedPeriod: updatePeriod,
284
+ timePeriodGutter: timePeriodGutter
285
+ })]
286
+ });
287
+ }
288
+ const SparklineInteractiveContent = /*#__PURE__*/memo(SparklineInteractiveContentWithGeneric);
289
+ function SparklineInteractiveWithGeneric(_ref4) {
290
+ let {
291
+ compact,
292
+ gutter
293
+ } = _ref4,
294
+ props = _objectWithoutPropertiesLoose(_ref4, _excluded);
295
+ return /*#__PURE__*/_jsx(SparklineInteractiveProvider, {
296
+ compact: compact,
297
+ gutter: gutter,
298
+ children: /*#__PURE__*/_jsx(SparklineInteractiveContent, _extends({}, props))
299
+ });
300
+ }
301
+
302
+ // typescript doesn't understand the memo with the generic so it gets casted to a base react component
303
+ export const SparklineInteractive = /*#__PURE__*/memo(SparklineInteractiveWithGeneric);