@coinbase/cds-mobile-visualization 0.0.0 → 3.4.0-beta.1

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 (245) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +3 -0
  3. package/dts/chart/CartesianChart.d.ts +101 -0
  4. package/dts/chart/CartesianChart.d.ts.map +1 -0
  5. package/dts/chart/ChartProvider.d.ts +6 -0
  6. package/dts/chart/ChartProvider.d.ts.map +1 -0
  7. package/dts/chart/Path.d.ts +48 -0
  8. package/dts/chart/Path.d.ts.map +1 -0
  9. package/dts/chart/PeriodSelector.d.ts +85 -0
  10. package/dts/chart/PeriodSelector.d.ts.map +1 -0
  11. package/dts/chart/Point.d.ts +103 -0
  12. package/dts/chart/Point.d.ts.map +1 -0
  13. package/dts/chart/area/Area.d.ts +62 -0
  14. package/dts/chart/area/Area.d.ts.map +1 -0
  15. package/dts/chart/area/AreaChart.d.ts +90 -0
  16. package/dts/chart/area/AreaChart.d.ts.map +1 -0
  17. package/dts/chart/area/DottedArea.d.ts +27 -0
  18. package/dts/chart/area/DottedArea.d.ts.map +1 -0
  19. package/dts/chart/area/GradientArea.d.ts +30 -0
  20. package/dts/chart/area/GradientArea.d.ts.map +1 -0
  21. package/dts/chart/area/SolidArea.d.ts +8 -0
  22. package/dts/chart/area/SolidArea.d.ts.map +1 -0
  23. package/dts/chart/area/index.d.ts +6 -0
  24. package/dts/chart/area/index.d.ts.map +1 -0
  25. package/dts/chart/axis/Axis.d.ts +204 -0
  26. package/dts/chart/axis/Axis.d.ts.map +1 -0
  27. package/dts/chart/axis/XAxis.d.ts +16 -0
  28. package/dts/chart/axis/XAxis.d.ts.map +1 -0
  29. package/dts/chart/axis/YAxis.d.ts +21 -0
  30. package/dts/chart/axis/YAxis.d.ts.map +1 -0
  31. package/dts/chart/axis/index.d.ts +4 -0
  32. package/dts/chart/axis/index.d.ts.map +1 -0
  33. package/dts/chart/bar/Bar.d.ts +89 -0
  34. package/dts/chart/bar/Bar.d.ts.map +1 -0
  35. package/dts/chart/bar/BarChart.d.ts +97 -0
  36. package/dts/chart/bar/BarChart.d.ts.map +1 -0
  37. package/dts/chart/bar/BarPlot.d.ts +29 -0
  38. package/dts/chart/bar/BarPlot.d.ts.map +1 -0
  39. package/dts/chart/bar/BarStack.d.ts +111 -0
  40. package/dts/chart/bar/BarStack.d.ts.map +1 -0
  41. package/dts/chart/bar/BarStackGroup.d.ts +35 -0
  42. package/dts/chart/bar/BarStackGroup.d.ts.map +1 -0
  43. package/dts/chart/bar/DefaultBar.d.ts +7 -0
  44. package/dts/chart/bar/DefaultBar.d.ts.map +1 -0
  45. package/dts/chart/bar/DefaultBarStack.d.ts +7 -0
  46. package/dts/chart/bar/DefaultBarStack.d.ts.map +1 -0
  47. package/dts/chart/bar/index.d.ts +8 -0
  48. package/dts/chart/bar/index.d.ts.map +1 -0
  49. package/dts/chart/index.d.ts +13 -0
  50. package/dts/chart/index.d.ts.map +1 -0
  51. package/dts/chart/line/DottedLine.d.ts +12 -0
  52. package/dts/chart/line/DottedLine.d.ts.map +1 -0
  53. package/dts/chart/line/GradientLine.d.ts +45 -0
  54. package/dts/chart/line/GradientLine.d.ts.map +1 -0
  55. package/dts/chart/line/Line.d.ts +78 -0
  56. package/dts/chart/line/Line.d.ts.map +1 -0
  57. package/dts/chart/line/LineChart.d.ts +84 -0
  58. package/dts/chart/line/LineChart.d.ts.map +1 -0
  59. package/dts/chart/line/ReferenceLine.d.ts +91 -0
  60. package/dts/chart/line/ReferenceLine.d.ts.map +1 -0
  61. package/dts/chart/line/SolidLine.d.ts +12 -0
  62. package/dts/chart/line/SolidLine.d.ts.map +1 -0
  63. package/dts/chart/line/index.d.ts +7 -0
  64. package/dts/chart/line/index.d.ts.map +1 -0
  65. package/dts/chart/scrubber/Scrubber.d.ts +104 -0
  66. package/dts/chart/scrubber/Scrubber.d.ts.map +1 -0
  67. package/dts/chart/scrubber/ScrubberBeacon.d.ts +75 -0
  68. package/dts/chart/scrubber/ScrubberBeacon.d.ts.map +1 -0
  69. package/dts/chart/scrubber/ScrubberProvider.d.ts +17 -0
  70. package/dts/chart/scrubber/ScrubberProvider.d.ts.map +1 -0
  71. package/dts/chart/scrubber/index.d.ts +2 -0
  72. package/dts/chart/scrubber/index.d.ts.map +1 -0
  73. package/dts/chart/text/ChartText.d.ts +90 -0
  74. package/dts/chart/text/ChartText.d.ts.map +1 -0
  75. package/dts/chart/text/SmartChartTextGroup.d.ts +55 -0
  76. package/dts/chart/text/SmartChartTextGroup.d.ts.map +1 -0
  77. package/dts/chart/text/index.d.ts +3 -0
  78. package/dts/chart/text/index.d.ts.map +1 -0
  79. package/dts/chart/utils/axis.d.ts +342 -0
  80. package/dts/chart/utils/axis.d.ts.map +1 -0
  81. package/dts/chart/utils/bar.d.ts +20 -0
  82. package/dts/chart/utils/bar.d.ts.map +1 -0
  83. package/dts/chart/utils/chart.d.ts +97 -0
  84. package/dts/chart/utils/chart.d.ts.map +1 -0
  85. package/dts/chart/utils/context.d.ts +95 -0
  86. package/dts/chart/utils/context.d.ts.map +1 -0
  87. package/dts/chart/utils/index.d.ts +8 -0
  88. package/dts/chart/utils/index.d.ts.map +1 -0
  89. package/dts/chart/utils/path.d.ts +107 -0
  90. package/dts/chart/utils/path.d.ts.map +1 -0
  91. package/dts/chart/utils/point.d.ts +75 -0
  92. package/dts/chart/utils/point.d.ts.map +1 -0
  93. package/dts/chart/utils/scale.d.ts +43 -0
  94. package/dts/chart/utils/scale.d.ts.map +1 -0
  95. package/dts/index.d.ts +3 -0
  96. package/dts/index.d.ts.map +1 -0
  97. package/dts/sparkline/Counter.d.ts +8 -0
  98. package/dts/sparkline/Counter.d.ts.map +1 -0
  99. package/dts/sparkline/Sparkline.d.ts +73 -0
  100. package/dts/sparkline/Sparkline.d.ts.map +1 -0
  101. package/dts/sparkline/SparklineArea.d.ts +14 -0
  102. package/dts/sparkline/SparklineArea.d.ts.map +1 -0
  103. package/dts/sparkline/SparklineAreaPattern.d.ts +14 -0
  104. package/dts/sparkline/SparklineAreaPattern.d.ts.map +1 -0
  105. package/dts/sparkline/SparklineGradient.d.ts +23 -0
  106. package/dts/sparkline/SparklineGradient.d.ts.map +1 -0
  107. package/dts/sparkline/__figma__/Sparkline.figma.d.ts +2 -0
  108. package/dts/sparkline/__figma__/Sparkline.figma.d.ts.map +1 -0
  109. package/dts/sparkline/generateSparklineWithId.d.ts +11 -0
  110. package/dts/sparkline/generateSparklineWithId.d.ts.map +1 -0
  111. package/dts/sparkline/index.d.ts +6 -0
  112. package/dts/sparkline/index.d.ts.map +1 -0
  113. package/dts/sparkline/sparkline-interactive/SparklineAccessibleView.d.ts +23 -0
  114. package/dts/sparkline/sparkline-interactive/SparklineAccessibleView.d.ts.map +1 -0
  115. package/dts/sparkline/sparkline-interactive/SparklineInteractive.d.ts +184 -0
  116. package/dts/sparkline/sparkline-interactive/SparklineInteractive.d.ts.map +1 -0
  117. package/dts/sparkline/sparkline-interactive/SparklineInteractiveAnimatedPath.d.ts +25 -0
  118. package/dts/sparkline/sparkline-interactive/SparklineInteractiveAnimatedPath.d.ts.map +1 -0
  119. package/dts/sparkline/sparkline-interactive/SparklineInteractiveHoverDate.d.ts +28 -0
  120. package/dts/sparkline/sparkline-interactive/SparklineInteractiveHoverDate.d.ts.map +1 -0
  121. package/dts/sparkline/sparkline-interactive/SparklineInteractiveLineVertical.d.ts +13 -0
  122. package/dts/sparkline/sparkline-interactive/SparklineInteractiveLineVertical.d.ts.map +1 -0
  123. package/dts/sparkline/sparkline-interactive/SparklineInteractiveMarkerDates.d.ts +17 -0
  124. package/dts/sparkline/sparkline-interactive/SparklineInteractiveMarkerDates.d.ts.map +1 -0
  125. package/dts/sparkline/sparkline-interactive/SparklineInteractiveMinMax.d.ts +11 -0
  126. package/dts/sparkline/sparkline-interactive/SparklineInteractiveMinMax.d.ts.map +1 -0
  127. package/dts/sparkline/sparkline-interactive/SparklineInteractivePanGestureHandler.d.ts +26 -0
  128. package/dts/sparkline/sparkline-interactive/SparklineInteractivePanGestureHandler.d.ts.map +1 -0
  129. package/dts/sparkline/sparkline-interactive/SparklineInteractivePaths.d.ts +25 -0
  130. package/dts/sparkline/sparkline-interactive/SparklineInteractivePaths.d.ts.map +1 -0
  131. package/dts/sparkline/sparkline-interactive/SparklineInteractivePeriodSelector.d.ts +25 -0
  132. package/dts/sparkline/sparkline-interactive/SparklineInteractivePeriodSelector.d.ts.map +1 -0
  133. package/dts/sparkline/sparkline-interactive/SparklineInteractiveProvider.d.ts +39 -0
  134. package/dts/sparkline/sparkline-interactive/SparklineInteractiveProvider.d.ts.map +1 -0
  135. package/dts/sparkline/sparkline-interactive/SparklineInteractiveTimeseriesPaths.d.ts +31 -0
  136. package/dts/sparkline/sparkline-interactive/SparklineInteractiveTimeseriesPaths.d.ts.map +1 -0
  137. package/dts/sparkline/sparkline-interactive/__figma__/SparklineInteractive.figma.d.ts +2 -0
  138. package/dts/sparkline/sparkline-interactive/__figma__/SparklineInteractive.figma.d.ts.map +1 -0
  139. package/dts/sparkline/sparkline-interactive/useInterruptiblePathAnimation.d.ts +13 -0
  140. package/dts/sparkline/sparkline-interactive/useInterruptiblePathAnimation.d.ts.map +1 -0
  141. package/dts/sparkline/sparkline-interactive/useMinMaxTransform.d.ts +16 -0
  142. package/dts/sparkline/sparkline-interactive/useMinMaxTransform.d.ts.map +1 -0
  143. package/dts/sparkline/sparkline-interactive/useOpacityAnimation.d.ts +6 -0
  144. package/dts/sparkline/sparkline-interactive/useOpacityAnimation.d.ts.map +1 -0
  145. package/dts/sparkline/sparkline-interactive/useSparklineInteractiveConstants.d.ts +22 -0
  146. package/dts/sparkline/sparkline-interactive/useSparklineInteractiveConstants.d.ts.map +1 -0
  147. package/dts/sparkline/sparkline-interactive/useSparklineInteractiveLineStyles.d.ts +34 -0
  148. package/dts/sparkline/sparkline-interactive/useSparklineInteractiveLineStyles.d.ts.map +1 -0
  149. package/dts/sparkline/sparkline-interactive-header/SparklineInteractiveHeader.d.ts +118 -0
  150. package/dts/sparkline/sparkline-interactive-header/SparklineInteractiveHeader.d.ts.map +1 -0
  151. package/dts/sparkline/sparkline-interactive-header/__figma__/SparklineInteractiveHeader.figma.d.ts +2 -0
  152. package/dts/sparkline/sparkline-interactive-header/__figma__/SparklineInteractiveHeader.figma.d.ts.map +1 -0
  153. package/dts/sparkline/sparkline-interactive-header/useSparklineInteractiveHeaderStyles.d.ts +29 -0
  154. package/dts/sparkline/sparkline-interactive-header/useSparklineInteractiveHeaderStyles.d.ts.map +1 -0
  155. package/esm/chart/CartesianChart.js +241 -0
  156. package/esm/chart/ChartProvider.js +10 -0
  157. package/esm/chart/Path.js +133 -0
  158. package/esm/chart/PeriodSelector.js +136 -0
  159. package/esm/chart/Point.js +111 -0
  160. package/esm/chart/__stories__/CartesianChart.stories.js +476 -0
  161. package/esm/chart/__stories__/Chart.stories.js +79 -0
  162. package/esm/chart/__stories__/PeriodSelector.stories.js +294 -0
  163. package/esm/chart/area/Area.js +85 -0
  164. package/esm/chart/area/AreaChart.js +146 -0
  165. package/esm/chart/area/DottedArea.js +128 -0
  166. package/esm/chart/area/GradientArea.js +110 -0
  167. package/esm/chart/area/SolidArea.js +24 -0
  168. package/esm/chart/area/__stories__/AreaChart.stories.js +100 -0
  169. package/esm/chart/area/index.js +7 -0
  170. package/esm/chart/axis/Axis.js +43 -0
  171. package/esm/chart/axis/XAxis.js +181 -0
  172. package/esm/chart/axis/YAxis.js +170 -0
  173. package/esm/chart/axis/__stories__/Axis.stories.js +277 -0
  174. package/esm/chart/axis/index.js +5 -0
  175. package/esm/chart/bar/Bar.js +67 -0
  176. package/esm/chart/bar/BarChart.js +147 -0
  177. package/esm/chart/bar/BarPlot.js +96 -0
  178. package/esm/chart/bar/BarStack.js +514 -0
  179. package/esm/chart/bar/BarStackGroup.js +89 -0
  180. package/esm/chart/bar/DefaultBar.js +78 -0
  181. package/esm/chart/bar/DefaultBarStack.js +82 -0
  182. package/esm/chart/bar/__stories__/BarChart.stories.js +282 -0
  183. package/esm/chart/bar/index.js +9 -0
  184. package/esm/chart/index.js +14 -0
  185. package/esm/chart/line/DottedLine.js +35 -0
  186. package/esm/chart/line/GradientLine.js +62 -0
  187. package/esm/chart/line/Line.js +139 -0
  188. package/esm/chart/line/LineChart.js +115 -0
  189. package/esm/chart/line/ReferenceLine.js +115 -0
  190. package/esm/chart/line/SolidLine.js +31 -0
  191. package/esm/chart/line/__stories__/LineChart.stories.js +2248 -0
  192. package/esm/chart/line/__stories__/ReferenceLine.stories.js +77 -0
  193. package/esm/chart/line/index.js +8 -0
  194. package/esm/chart/scrubber/Scrubber.js +186 -0
  195. package/esm/chart/scrubber/ScrubberBeacon.js +199 -0
  196. package/esm/chart/scrubber/ScrubberProvider.js +143 -0
  197. package/esm/chart/scrubber/index.js +2 -0
  198. package/esm/chart/text/ChartText.js +237 -0
  199. package/esm/chart/text/SmartChartTextGroup.js +210 -0
  200. package/esm/chart/text/index.js +4 -0
  201. package/esm/chart/utils/axis.js +592 -0
  202. package/esm/chart/utils/bar.js +24 -0
  203. package/esm/chart/utils/chart.js +229 -0
  204. package/esm/chart/utils/context.js +15 -0
  205. package/esm/chart/utils/index.js +9 -0
  206. package/esm/chart/utils/path.js +206 -0
  207. package/esm/chart/utils/point.js +118 -0
  208. package/esm/chart/utils/scale.js +48 -0
  209. package/esm/index.js +4 -0
  210. package/esm/sparkline/Counter.js +45 -0
  211. package/esm/sparkline/Sparkline.js +164 -0
  212. package/esm/sparkline/SparklineArea.js +19 -0
  213. package/esm/sparkline/SparklineAreaPattern.js +38 -0
  214. package/esm/sparkline/SparklineGradient.js +76 -0
  215. package/esm/sparkline/__figma__/Sparkline.figma.js +22 -0
  216. package/esm/sparkline/__stories__/Sparkline.stories.js +120 -0
  217. package/esm/sparkline/__stories__/SparklineGradient.stories.js +123 -0
  218. package/esm/sparkline/generateSparklineWithId.js +7 -0
  219. package/esm/sparkline/index.js +5 -0
  220. package/esm/sparkline/sparkline-interactive/SparklineAccessibleView.js +75 -0
  221. package/esm/sparkline/sparkline-interactive/SparklineInteractive.js +307 -0
  222. package/esm/sparkline/sparkline-interactive/SparklineInteractiveAnimatedPath.js +116 -0
  223. package/esm/sparkline/sparkline-interactive/SparklineInteractiveHoverDate.js +131 -0
  224. package/esm/sparkline/sparkline-interactive/SparklineInteractiveLineVertical.js +99 -0
  225. package/esm/sparkline/sparkline-interactive/SparklineInteractiveMarkerDates.js +82 -0
  226. package/esm/sparkline/sparkline-interactive/SparklineInteractiveMinMax.js +103 -0
  227. package/esm/sparkline/sparkline-interactive/SparklineInteractivePanGestureHandler.js +104 -0
  228. package/esm/sparkline/sparkline-interactive/SparklineInteractivePaths.js +57 -0
  229. package/esm/sparkline/sparkline-interactive/SparklineInteractivePeriodSelector.js +124 -0
  230. package/esm/sparkline/sparkline-interactive/SparklineInteractiveProvider.js +80 -0
  231. package/esm/sparkline/sparkline-interactive/SparklineInteractiveTimeseriesPaths.js +109 -0
  232. package/esm/sparkline/sparkline-interactive/__figma__/SparklineInteractive.figma.js +85 -0
  233. package/esm/sparkline/sparkline-interactive/__stories__/SparklineInteractive.stories.js +501 -0
  234. package/esm/sparkline/sparkline-interactive/useInterruptiblePathAnimation.js +58 -0
  235. package/esm/sparkline/sparkline-interactive/useInterruptiblePathAnimation.test.disable.js +37 -0
  236. package/esm/sparkline/sparkline-interactive/useMinMaxTransform.js +56 -0
  237. package/esm/sparkline/sparkline-interactive/useOpacityAnimation.js +23 -0
  238. package/esm/sparkline/sparkline-interactive/useSparklineInteractiveConstants.js +47 -0
  239. package/esm/sparkline/sparkline-interactive/useSparklineInteractiveLineStyles.js +34 -0
  240. package/esm/sparkline/sparkline-interactive-header/SparklineInteractiveHeader.js +233 -0
  241. package/esm/sparkline/sparkline-interactive-header/__figma__/SparklineInteractiveHeader.figma.js +104 -0
  242. package/esm/sparkline/sparkline-interactive-header/__stories__/SparklineInteractiveHeader.stories.js +555 -0
  243. package/esm/sparkline/sparkline-interactive-header/useSparklineInteractiveHeaderStyles.js +117 -0
  244. package/package.json +65 -6
  245. package/index.js +0 -1
@@ -0,0 +1,85 @@
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 { figma } from '@figma/code-connect';
4
+ import { SparklineInteractive } from '../SparklineInteractive';
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ figma.connect(SparklineInteractive, 'https://www.figma.com/design/k5CtyJccNQUGMI5bI4lJ2g/%E2%9C%A8-CDS-Components?node-id=320-14858&m=dev', {
7
+ imports: ["import { SparklineInteractive } from '@coinbase/cds-web-visualization';"],
8
+ props: {
9
+ compact: figma.boolean('compact'),
10
+ disableScrubbing: figma.boolean('scrubbing', {
11
+ false: true,
12
+ true: false
13
+ })
14
+ },
15
+ example: props => {
16
+ const periods = [{
17
+ label: '1H',
18
+ value: 'hour'
19
+ }, {
20
+ label: '1D',
21
+ value: 'day'
22
+ }, {
23
+ label: '1W',
24
+ value: 'week'
25
+ }, {
26
+ label: '1M',
27
+ value: 'month'
28
+ }, {
29
+ label: '1Y',
30
+ value: 'year'
31
+ }, {
32
+ label: 'All',
33
+ value: 'all'
34
+ }];
35
+ const data = {
36
+ hour: [],
37
+ day: [{
38
+ value: 49259.38,
39
+ date: new Date('2021-12-05T04:00:00.000Z')
40
+ }, {
41
+ value: 49163.79,
42
+ date: new Date('2021-12-05T04:05:00.000Z')
43
+ }, {
44
+ value: 49146.66,
45
+ date: new Date('2021-12-05T04:10:00.000Z')
46
+ }, {
47
+ value: 49083.92,
48
+ date: new Date('2021-12-05T04:15:00.000Z')
49
+ }, {
50
+ value: 49115.3,
51
+ date: new Date('2021-12-05T04:20:00.000Z')
52
+ }, {
53
+ value: 48992.14,
54
+ date: new Date('2021-12-05T04:25:00.000Z')
55
+ }, {
56
+ value: 49075.75,
57
+ date: new Date('2021-12-05T04:30:00.000Z')
58
+ }, {
59
+ value: 49025.78,
60
+ date: new Date('2021-12-05T04:35:00.000Z')
61
+ }, {
62
+ value: 49066.23,
63
+ date: new Date('2021-12-05T04:40:00.000Z')
64
+ }, {
65
+ value: 49247.82,
66
+ date: new Date('2021-12-05T04:45:00.000Z')
67
+ }],
68
+ week: [],
69
+ month: [],
70
+ year: [],
71
+ all: []
72
+ };
73
+ return /*#__PURE__*/_jsx(SparklineInteractive, _extends({
74
+ data: data,
75
+ defaultPeriod: "day",
76
+ formatDate: date => date.toLocaleString('en-US', {
77
+ timeZone: 'America/New_York',
78
+ hour: 'numeric',
79
+ minute: 'numeric'
80
+ }),
81
+ periods: periods,
82
+ strokeColor: "#cb51bb"
83
+ }, props));
84
+ }
85
+ });
@@ -0,0 +1,501 @@
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, { memo, useCallback, useMemo, useRef, useState } from 'react';
3
+ import { sparklineInteractiveData, sparklineInteractiveHoverData, strokeColor } from '@coinbase/cds-common/internal/visualizations/SparklineInteractiveData';
4
+ import { Example, ExampleScreen } from '@coinbase/cds-mobile/examples/ExampleScreen';
5
+ import { Box } from '@coinbase/cds-mobile/layout';
6
+ import { TextTitle3 } from '@coinbase/cds-mobile/typography/TextTitle3';
7
+ import { SparklineInteractiveHeader } from '../../sparkline-interactive-header/SparklineInteractiveHeader';
8
+ import { SparklineInteractive } from '../SparklineInteractive';
9
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
+ const DEFAULT_PERIOD = 'day';
11
+ function numToLocaleString(num) {
12
+ return num.toLocaleString('en-US', {
13
+ maximumFractionDigits: 2
14
+ });
15
+ }
16
+ const getFormattingConfigForPeriod = period => {
17
+ switch (period) {
18
+ case 'hour':
19
+ case 'day':
20
+ return {
21
+ hour: 'numeric',
22
+ minute: 'numeric'
23
+ };
24
+ case 'week':
25
+ case 'month':
26
+ return {
27
+ month: 'numeric',
28
+ day: 'numeric'
29
+ };
30
+ case 'year':
31
+ case 'all':
32
+ return {
33
+ month: 'numeric',
34
+ year: 'numeric'
35
+ };
36
+ }
37
+ };
38
+ const getDateHoverOptions = period => {
39
+ switch (period) {
40
+ case 'hour':
41
+ case 'day':
42
+ case 'week':
43
+ case 'month':
44
+ return {
45
+ weekday: 'short',
46
+ month: 'short',
47
+ day: 'numeric',
48
+ hour: 'numeric',
49
+ minute: 'numeric'
50
+ };
51
+ default:
52
+ return {
53
+ weekday: 'short',
54
+ year: 'numeric',
55
+ month: 'short',
56
+ day: 'numeric'
57
+ };
58
+ }
59
+ };
60
+ const periods = [{
61
+ label: '1H',
62
+ value: 'hour'
63
+ }, {
64
+ label: '1D',
65
+ value: 'day'
66
+ }, {
67
+ label: '1W',
68
+ value: 'week'
69
+ }, {
70
+ label: '1M',
71
+ value: 'month'
72
+ }, {
73
+ label: '1Y',
74
+ value: 'year'
75
+ }, {
76
+ label: 'All',
77
+ value: 'all'
78
+ }];
79
+ const SparklineInteractiveBuild = /*#__PURE__*/memo(props => {
80
+ var _props$defaultPeriod;
81
+ const formatDateWithConfig = useCallback((value, period) => {
82
+ const config = getFormattingConfigForPeriod(period);
83
+ return value.toLocaleString('en-US', _extends({}, config));
84
+ }, []);
85
+ const formatHoverDate = useCallback((date, period) => {
86
+ return date.toLocaleString('en-US', _extends({}, getDateHoverOptions(period)));
87
+ }, []);
88
+ const formatMinMaxLabel = useCallback(amount => {
89
+ return "$" + numToLocaleString(parseInt(amount, 10));
90
+ }, []);
91
+ return /*#__PURE__*/_jsx(SparklineInteractive, _extends({
92
+ disableScrubbing: !__DEV__
93
+ }, props, {
94
+ defaultPeriod: (_props$defaultPeriod = props.defaultPeriod) != null ? _props$defaultPeriod : DEFAULT_PERIOD,
95
+ formatDate: formatDateWithConfig,
96
+ formatHoverDate: !props.hideHoverDate ? formatHoverDate : undefined,
97
+ formatMinMaxLabel: formatMinMaxLabel,
98
+ periods: periods
99
+ }));
100
+ });
101
+ const generateSubHead = (point, period, sparklineInteractiveData) => {
102
+ const data = sparklineInteractiveData[period];
103
+ const firstPoint = data[0];
104
+ const increase = point.value > firstPoint.value;
105
+ return {
106
+ percent: numToLocaleString(Math.abs((point.value - firstPoint.value) / firstPoint.value) * 100) + "%",
107
+ sign: increase ? 'upwardTrend' : 'downwardTrend',
108
+ variant: increase ? 'positive' : 'negative',
109
+ accessibilityLabel: "" + (increase ? 'up' : 'down'),
110
+ priceChange: "$" + numToLocaleString(Math.abs(point.value - firstPoint.value))
111
+ };
112
+ };
113
+ const SparklineInteractiveWithHeaderBuild = /*#__PURE__*/memo(props => {
114
+ var _props$defaultPeriod2;
115
+ const {
116
+ data: sparklineData,
117
+ trailing,
118
+ labelNode,
119
+ compact
120
+ } = props;
121
+ const sparklineInteractiveData = sparklineData;
122
+ const headerRef = useRef(null);
123
+ const [currentPeriod, setCurrentPeriod] = useState((_props$defaultPeriod2 = props.defaultPeriod) != null ? _props$defaultPeriod2 : DEFAULT_PERIOD);
124
+ const data = sparklineInteractiveData[currentPeriod];
125
+ const lastPoint = data[data.length - 1];
126
+ const handleScrub = useCallback(_ref => {
127
+ var _headerRef$current;
128
+ let {
129
+ point,
130
+ period
131
+ } = _ref;
132
+ (_headerRef$current = headerRef.current) == null || _headerRef$current.update({
133
+ title: "$" + point.value.toLocaleString('en-US'),
134
+ subHead: generateSubHead(point, period, sparklineInteractiveData)
135
+ });
136
+ }, [sparklineInteractiveData, headerRef]);
137
+ const handleScrubEnd = useCallback(() => {
138
+ var _headerRef$current2;
139
+ (_headerRef$current2 = headerRef.current) == null || _headerRef$current2.update({
140
+ title: "$" + numToLocaleString(lastPoint.value),
141
+ subHead: generateSubHead(lastPoint, currentPeriod, sparklineInteractiveData)
142
+ });
143
+ }, [currentPeriod, sparklineInteractiveData, lastPoint, headerRef]);
144
+ const handleOnPeriodChanged = useCallback(period => {
145
+ var _headerRef$current3;
146
+ setCurrentPeriod(period);
147
+ const newData = sparklineInteractiveData[period];
148
+ const newLastPoint = newData[newData.length - 1];
149
+ (_headerRef$current3 = headerRef.current) == null || _headerRef$current3.update({
150
+ title: "$" + numToLocaleString(newLastPoint.value),
151
+ subHead: generateSubHead(newLastPoint, period, sparklineInteractiveData)
152
+ });
153
+ }, [sparklineInteractiveData, headerRef]);
154
+ const header = useMemo(() => /*#__PURE__*/_jsx(SparklineInteractiveHeader, {
155
+ ref: headerRef,
156
+ compact: compact,
157
+ defaultLabel: labelNode ? 'CustomHeader' : 'Bitcoin Price',
158
+ defaultSubHead: generateSubHead(lastPoint, currentPeriod, sparklineInteractiveData),
159
+ defaultTitle: "$" + numToLocaleString(lastPoint.value),
160
+ labelNode: labelNode,
161
+ trailing: trailing
162
+ }), [compact, labelNode, lastPoint, currentPeriod, sparklineInteractiveData, trailing]);
163
+ return /*#__PURE__*/_jsx(SparklineInteractiveBuild, _extends({}, props, {
164
+ headerNode: header,
165
+ onPeriodChanged: handleOnPeriodChanged,
166
+ onScrub: handleScrub,
167
+ onScrubEnd: handleScrubEnd
168
+ }));
169
+ });
170
+ const rgbaStrokeColor = 'rgba(123, 1, 1, 5)';
171
+ const rgbStrokeColor = 'rgb(123, 1, 121)';
172
+ const autoStrokeColor = 'auto';
173
+ const SparklineInteractiveScreen = () => {
174
+ return /*#__PURE__*/_jsxs(ExampleScreen, {
175
+ children: [/*#__PURE__*/_jsx(Example, {
176
+ padding: 0,
177
+ children: /*#__PURE__*/_jsxs(Box, {
178
+ children: [/*#__PURE__*/_jsx(TextTitle3, {
179
+ paddingX: 3,
180
+ paddingY: 3,
181
+ children: "Default"
182
+ }), /*#__PURE__*/_jsx(SparklineInteractiveBuild, {
183
+ data: sparklineInteractiveData,
184
+ strokeColor: strokeColor
185
+ })]
186
+ })
187
+ }), /*#__PURE__*/_jsx(Example, {
188
+ padding: 0,
189
+ children: /*#__PURE__*/_jsxs(Box, {
190
+ children: [/*#__PURE__*/_jsx(TextTitle3, {
191
+ paddingX: 3,
192
+ paddingY: 3,
193
+ children: "Compact"
194
+ }), /*#__PURE__*/_jsx(SparklineInteractiveBuild, {
195
+ compact: true,
196
+ data: sparklineInteractiveData,
197
+ strokeColor: strokeColor
198
+ })]
199
+ })
200
+ }), /*#__PURE__*/_jsx(Example, {
201
+ padding: 0,
202
+ children: /*#__PURE__*/_jsxs(Box, {
203
+ children: [/*#__PURE__*/_jsx(TextTitle3, {
204
+ paddingX: 3,
205
+ paddingY: 3,
206
+ children: "Disable Scrubbing"
207
+ }), /*#__PURE__*/_jsx(SparklineInteractiveBuild, {
208
+ disableScrubbing: true,
209
+ data: sparklineInteractiveData,
210
+ strokeColor: strokeColor
211
+ })]
212
+ })
213
+ }), /*#__PURE__*/_jsx(Example, {
214
+ padding: 0,
215
+ children: /*#__PURE__*/_jsxs(Box, {
216
+ children: [/*#__PURE__*/_jsx(TextTitle3, {
217
+ paddingX: 3,
218
+ paddingY: 3,
219
+ children: "Hide period selector"
220
+ }), /*#__PURE__*/_jsx(SparklineInteractiveBuild, {
221
+ hidePeriodSelector: true,
222
+ data: sparklineInteractiveData,
223
+ strokeColor: strokeColor
224
+ })]
225
+ })
226
+ }), /*#__PURE__*/_jsx(Example, {
227
+ padding: 0,
228
+ children: /*#__PURE__*/_jsxs(Box, {
229
+ children: [/*#__PURE__*/_jsx(TextTitle3, {
230
+ paddingX: 3,
231
+ paddingY: 3,
232
+ children: "Hide min/max label"
233
+ }), /*#__PURE__*/_jsx(SparklineInteractiveBuild, {
234
+ hideMinMaxLabel: true,
235
+ data: sparklineInteractiveData,
236
+ strokeColor: strokeColor
237
+ })]
238
+ })
239
+ }), /*#__PURE__*/_jsx(Example, {
240
+ padding: 0,
241
+ children: /*#__PURE__*/_jsxs(Box, {
242
+ children: [/*#__PURE__*/_jsx(TextTitle3, {
243
+ paddingX: 3,
244
+ paddingY: 3,
245
+ children: "Default period All"
246
+ }), /*#__PURE__*/_jsx(SparklineInteractiveBuild, {
247
+ data: sparklineInteractiveData,
248
+ defaultPeriod: "all",
249
+ strokeColor: strokeColor
250
+ })]
251
+ })
252
+ }), /*#__PURE__*/_jsx(Example, {
253
+ padding: 0,
254
+ children: /*#__PURE__*/_jsxs(Box, {
255
+ children: [/*#__PURE__*/_jsx(TextTitle3, {
256
+ paddingX: 3,
257
+ paddingY: 3,
258
+ children: "Fill Disabled"
259
+ }), /*#__PURE__*/_jsx(SparklineInteractiveBuild, {
260
+ data: sparklineInteractiveData,
261
+ fill: false,
262
+ strokeColor: strokeColor
263
+ })]
264
+ })
265
+ }), /*#__PURE__*/_jsx(Example, {
266
+ padding: 0,
267
+ children: /*#__PURE__*/_jsxs(Box, {
268
+ children: [/*#__PURE__*/_jsx(TextTitle3, {
269
+ paddingX: 3,
270
+ paddingY: 3,
271
+ children: "Y axis scaling"
272
+ }), /*#__PURE__*/_jsx(SparklineInteractiveBuild, {
273
+ data: sparklineInteractiveData,
274
+ strokeColor: strokeColor,
275
+ yAxisScalingFactor: 0.1
276
+ })]
277
+ })
278
+ }), /*#__PURE__*/_jsx(Example, {
279
+ padding: 0,
280
+ children: /*#__PURE__*/_jsxs(Box, {
281
+ children: [/*#__PURE__*/_jsx(TextTitle3, {
282
+ paddingX: 3,
283
+ paddingY: 3,
284
+ children: "Fallback"
285
+ }), /*#__PURE__*/_jsx(SparklineInteractiveBuild, {
286
+ strokeColor: strokeColor
287
+ })]
288
+ })
289
+ }), /*#__PURE__*/_jsx(Example, {
290
+ padding: 0,
291
+ children: /*#__PURE__*/_jsxs(Box, {
292
+ children: [/*#__PURE__*/_jsx(TextTitle3, {
293
+ paddingX: 3,
294
+ paddingY: 3,
295
+ children: "Fallback Negative"
296
+ }), /*#__PURE__*/_jsx(SparklineInteractiveBuild, {
297
+ fallbackType: "negative",
298
+ strokeColor: strokeColor
299
+ })]
300
+ })
301
+ }), /*#__PURE__*/_jsx(Example, {
302
+ padding: 0,
303
+ children: /*#__PURE__*/_jsxs(Box, {
304
+ children: [/*#__PURE__*/_jsx(TextTitle3, {
305
+ paddingX: 3,
306
+ paddingY: 3,
307
+ children: "Fallback Compact"
308
+ }), /*#__PURE__*/_jsx(SparklineInteractiveBuild, {
309
+ compact: true,
310
+ strokeColor: strokeColor
311
+ })]
312
+ })
313
+ }), /*#__PURE__*/_jsx(Example, {
314
+ padding: 0,
315
+ children: /*#__PURE__*/_jsxs(Box, {
316
+ children: [/*#__PURE__*/_jsx(TextTitle3, {
317
+ paddingX: 3,
318
+ paddingY: 3,
319
+ children: "No Hover Date"
320
+ }), /*#__PURE__*/_jsx(SparklineInteractiveBuild, {
321
+ hideHoverDate: true,
322
+ data: sparklineInteractiveData,
323
+ strokeColor: strokeColor
324
+ })]
325
+ })
326
+ }), /*#__PURE__*/_jsx(Example, {
327
+ padding: 0,
328
+ children: /*#__PURE__*/_jsxs(Box, {
329
+ children: [/*#__PURE__*/_jsx(TextTitle3, {
330
+ paddingX: 3,
331
+ paddingY: 3,
332
+ children: "With Header Node"
333
+ }), /*#__PURE__*/_jsx(SparklineInteractiveWithHeaderBuild, {
334
+ data: sparklineInteractiveData,
335
+ strokeColor: "#F7931A"
336
+ })]
337
+ })
338
+ }), /*#__PURE__*/_jsx(Example, {
339
+ padding: 0,
340
+ children: /*#__PURE__*/_jsxs(Box, {
341
+ children: [/*#__PURE__*/_jsx(TextTitle3, {
342
+ paddingX: 3,
343
+ paddingY: 3,
344
+ children: "No padding"
345
+ }), /*#__PURE__*/_jsx(SparklineInteractiveBuild, {
346
+ data: sparklineInteractiveData,
347
+ gutter: 0,
348
+ strokeColor: "#F7931A",
349
+ timePeriodGutter: 3
350
+ })]
351
+ })
352
+ }), /*#__PURE__*/_jsx(Example, {
353
+ padding: 4,
354
+ children: /*#__PURE__*/_jsxs(Box, {
355
+ children: [/*#__PURE__*/_jsx(TextTitle3, {
356
+ paddingY: 3,
357
+ children: "In Container With 4 padding"
358
+ }), /*#__PURE__*/_jsx(SparklineInteractiveWithHeaderBuild, {
359
+ disableHorizontalPadding: true,
360
+ data: sparklineInteractiveData,
361
+ gutter: 4,
362
+ strokeColor: "#F7931A"
363
+ })]
364
+ })
365
+ }), /*#__PURE__*/_jsx(Example, {
366
+ padding: 0,
367
+ children: /*#__PURE__*/_jsxs(Box, {
368
+ children: [/*#__PURE__*/_jsx(TextTitle3, {
369
+ paddingX: 3,
370
+ paddingY: 3,
371
+ children: "Custom screen padding 6"
372
+ }), /*#__PURE__*/_jsx(SparklineInteractiveBuild, {
373
+ data: sparklineInteractiveData,
374
+ gutter: 6,
375
+ strokeColor: "#F7931A"
376
+ })]
377
+ })
378
+ }), /*#__PURE__*/_jsx(Example, {
379
+ padding: 0,
380
+ children: /*#__PURE__*/_jsxs(Box, {
381
+ children: [/*#__PURE__*/_jsx(TextTitle3, {
382
+ paddingX: 3,
383
+ paddingY: 3,
384
+ children: "Hover data"
385
+ }), /*#__PURE__*/_jsx(SparklineInteractiveBuild, {
386
+ data: sparklineInteractiveData,
387
+ hoverData: sparklineInteractiveHoverData,
388
+ strokeColor: strokeColor
389
+ })]
390
+ })
391
+ }), /*#__PURE__*/_jsx(Example, {
392
+ padding: 0,
393
+ children: /*#__PURE__*/_jsxs(Box, {
394
+ children: [/*#__PURE__*/_jsx(TextTitle3, {
395
+ paddingX: 3,
396
+ paddingY: 3,
397
+ children: "Auto Stoke Color"
398
+ }), /*#__PURE__*/_jsx(SparklineInteractiveBuild, {
399
+ data: sparklineInteractiveData,
400
+ strokeColor: autoStrokeColor
401
+ })]
402
+ })
403
+ }), /*#__PURE__*/_jsx(Example, {
404
+ padding: 0,
405
+ children: /*#__PURE__*/_jsxs(Box, {
406
+ children: [/*#__PURE__*/_jsx(TextTitle3, {
407
+ paddingX: 3,
408
+ paddingY: 3,
409
+ children: "Custom RGB Stoke Color"
410
+ }), /*#__PURE__*/_jsx(SparklineInteractiveBuild, {
411
+ data: sparklineInteractiveData,
412
+ strokeColor: rgbStrokeColor
413
+ })]
414
+ })
415
+ }), /*#__PURE__*/_jsx(Example, {
416
+ padding: 0,
417
+ children: /*#__PURE__*/_jsxs(Box, {
418
+ children: [/*#__PURE__*/_jsx(TextTitle3, {
419
+ paddingX: 3,
420
+ paddingY: 3,
421
+ children: "Custom RGBA Stoke Color"
422
+ }), /*#__PURE__*/_jsx(SparklineInteractiveBuild, {
423
+ data: sparklineInteractiveData,
424
+ strokeColor: rgbaStrokeColor
425
+ })]
426
+ })
427
+ }), /*#__PURE__*/_jsx(Example, {
428
+ padding: 0,
429
+ children: /*#__PURE__*/_jsxs(Box, {
430
+ children: [/*#__PURE__*/_jsx(TextTitle3, {
431
+ paddingX: 3,
432
+ paddingY: 3,
433
+ children: "No Data In SelectedPeriod"
434
+ }), /*#__PURE__*/_jsx(SparklineInteractiveBuild, {
435
+ data: _extends({}, sparklineInteractiveData, {
436
+ hour: []
437
+ }),
438
+ strokeColor: rgbaStrokeColor
439
+ })]
440
+ })
441
+ }), /*#__PURE__*/_jsx(Example, {
442
+ padding: 0,
443
+ children: /*#__PURE__*/_jsxs(Box, {
444
+ children: [/*#__PURE__*/_jsx(TextTitle3, {
445
+ paddingX: 3,
446
+ paddingY: 3,
447
+ children: "Enable Interaction When Outside"
448
+ }), /*#__PURE__*/_jsx(SparklineInteractiveBuild, {
449
+ allowOverflowGestures: true,
450
+ data: sparklineInteractiveData,
451
+ strokeColor: strokeColor
452
+ })]
453
+ })
454
+ }), /*#__PURE__*/_jsx(Example, {
455
+ padding: 0,
456
+ children: /*#__PURE__*/_jsxs(Box, {
457
+ children: [/*#__PURE__*/_jsx(TextTitle3, {
458
+ paddingX: 3,
459
+ paddingY: 3,
460
+ children: "Custom Node Header Styles"
461
+ }), /*#__PURE__*/_jsx(SparklineInteractiveWithHeaderBuild, {
462
+ data: sparklineInteractiveData,
463
+ strokeColor: "#F7931A",
464
+ styles: {
465
+ header: {
466
+ paddingBottom: 0
467
+ }
468
+ }
469
+ })]
470
+ })
471
+ }), /*#__PURE__*/_jsx(Example, {
472
+ padding: 0,
473
+ children: /*#__PURE__*/_jsxs(Box, {
474
+ children: [/*#__PURE__*/_jsx(TextTitle3, {
475
+ paddingX: 3,
476
+ paddingY: 3,
477
+ children: "Dotted Fill Type"
478
+ }), /*#__PURE__*/_jsx(SparklineInteractiveBuild, {
479
+ data: sparklineInteractiveData,
480
+ fillType: "dotted",
481
+ strokeColor: strokeColor
482
+ })]
483
+ })
484
+ }), /*#__PURE__*/_jsx(Example, {
485
+ padding: 0,
486
+ children: /*#__PURE__*/_jsxs(Box, {
487
+ children: [/*#__PURE__*/_jsx(TextTitle3, {
488
+ paddingX: 3,
489
+ paddingY: 3,
490
+ children: "Y Scale Custom"
491
+ }), /*#__PURE__*/_jsx(SparklineInteractiveBuild, {
492
+ data: sparklineInteractiveData,
493
+ fillType: "dotted",
494
+ strokeColor: strokeColor,
495
+ yAxisScalingFactor: 0.1
496
+ })]
497
+ })
498
+ })]
499
+ });
500
+ };
501
+ export default SparklineInteractiveScreen;
@@ -0,0 +1,58 @@
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 { useCallback, useEffect, useRef } from 'react';
3
+ import { Animated } from 'react-native';
4
+ import { animatedPathConfig } from '@coinbase/cds-common/animation/sparkline';
5
+ import { useSparklineInteractiveContext } from './SparklineInteractiveProvider';
6
+ const animationConfig = _extends({}, animatedPathConfig, {
7
+ toValue: 1,
8
+ useNativeDriver: true
9
+ });
10
+ export const useInterruptiblePathAnimation = _ref => {
11
+ let {
12
+ animationListener,
13
+ onInterrupt,
14
+ ignoreMinMax
15
+ } = _ref;
16
+ const {
17
+ animateMinMaxIn
18
+ } = useSparklineInteractiveContext();
19
+ const isRunning = useRef(false);
20
+ const animationProgress = useRef(new Animated.Value(0)).current;
21
+ const animations = [Animated.timing(animationProgress, animationConfig)];
22
+ if (!ignoreMinMax) {
23
+ animations.push(animateMinMaxIn);
24
+ }
25
+ const animation = Animated.sequence(animations);
26
+ const onFinishAnimation = useCallback(_ref2 => {
27
+ let {
28
+ finished
29
+ } = _ref2;
30
+ if (finished) {
31
+ animationProgress.removeAllListeners();
32
+ animationProgress.setValue(0);
33
+ isRunning.current = false;
34
+ }
35
+ }, [animationProgress]);
36
+
37
+ // Clean up listeners
38
+ useEffect(() => {
39
+ return () => {
40
+ animationProgress.removeAllListeners();
41
+ };
42
+ }, [animationProgress]);
43
+ return useCallback(() => {
44
+ // If try to re-run animation while currently running
45
+ // we should interrupt it and start new one
46
+ if (isRunning.current) {
47
+ animation.stop();
48
+ onFinishAnimation({
49
+ finished: true
50
+ });
51
+ onInterrupt();
52
+ } else {
53
+ isRunning.current = true;
54
+ animationProgress.addListener(animationListener);
55
+ animation.start(onFinishAnimation);
56
+ }
57
+ }, [animation, animationListener, animationProgress, onFinishAnimation, onInterrupt]);
58
+ };
@@ -0,0 +1,37 @@
1
+ import { Animated } from 'react-native';
2
+ import { renderHook } from '@testing-library/react-hooks';
3
+ import { useInterruptiblePathAnimation } from './useInterruptiblePathAnimation';
4
+ jest.useFakeTimers({
5
+ legacyFakeTimers: true
6
+ });
7
+ describe('useInterruptiblePathAnimation', () => {
8
+ const animationListenerSpy = jest.fn();
9
+ const onInterruptSpy = jest.fn();
10
+ it('plays correctly', () => {
11
+ const {
12
+ result
13
+ } = renderHook(() => {
14
+ return useInterruptiblePathAnimation({
15
+ animationListener: animationListenerSpy,
16
+ onInterrupt: onInterruptSpy
17
+ });
18
+ });
19
+ result.current();
20
+ expect(Animated.timing).toHaveBeenCalled();
21
+ });
22
+ it('interrupts correctly if triggering play while already playing', () => {
23
+ const {
24
+ result
25
+ } = renderHook(() => {
26
+ return useInterruptiblePathAnimation({
27
+ animationListener: animationListenerSpy,
28
+ onInterrupt: onInterruptSpy
29
+ });
30
+ });
31
+ result.current();
32
+ expect(Animated.timing).toHaveBeenCalled();
33
+ result.current();
34
+ expect(onInterruptSpy).toHaveBeenCalled();
35
+ jest.runAllTimers();
36
+ });
37
+ });