@coinbase/cds-mobile-visualization 3.4.0-beta.8 → 3.4.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 (170) hide show
  1. package/CHANGELOG.md +142 -0
  2. package/dts/chart/CartesianChart.d.ts +92 -7
  3. package/dts/chart/CartesianChart.d.ts.map +1 -1
  4. package/dts/chart/ChartContextBridge.d.ts.map +1 -1
  5. package/dts/chart/ChartProvider.d.ts +3 -0
  6. package/dts/chart/ChartProvider.d.ts.map +1 -1
  7. package/dts/chart/Path.d.ts +36 -13
  8. package/dts/chart/Path.d.ts.map +1 -1
  9. package/dts/chart/PeriodSelector.d.ts +21 -6
  10. package/dts/chart/PeriodSelector.d.ts.map +1 -1
  11. package/dts/chart/area/Area.d.ts +14 -11
  12. package/dts/chart/area/Area.d.ts.map +1 -1
  13. package/dts/chart/area/AreaChart.d.ts +33 -9
  14. package/dts/chart/area/AreaChart.d.ts.map +1 -1
  15. package/dts/chart/area/DottedArea.d.ts.map +1 -1
  16. package/dts/chart/area/GradientArea.d.ts.map +1 -1
  17. package/dts/chart/area/SolidArea.d.ts.map +1 -1
  18. package/dts/chart/axis/Axis.d.ts +22 -42
  19. package/dts/chart/axis/Axis.d.ts.map +1 -1
  20. package/dts/chart/axis/XAxis.d.ts +6 -0
  21. package/dts/chart/axis/XAxis.d.ts.map +1 -1
  22. package/dts/chart/axis/YAxis.d.ts +1 -0
  23. package/dts/chart/axis/YAxis.d.ts.map +1 -1
  24. package/dts/chart/bar/Bar.d.ts +51 -51
  25. package/dts/chart/bar/Bar.d.ts.map +1 -1
  26. package/dts/chart/bar/BarChart.d.ts +56 -11
  27. package/dts/chart/bar/BarChart.d.ts.map +1 -1
  28. package/dts/chart/bar/BarPlot.d.ts +2 -1
  29. package/dts/chart/bar/BarPlot.d.ts.map +1 -1
  30. package/dts/chart/bar/BarStack.d.ts +45 -20
  31. package/dts/chart/bar/BarStack.d.ts.map +1 -1
  32. package/dts/chart/bar/BarStackGroup.d.ts +2 -1
  33. package/dts/chart/bar/BarStackGroup.d.ts.map +1 -1
  34. package/dts/chart/bar/DefaultBar.d.ts.map +1 -1
  35. package/dts/chart/bar/DefaultBarStack.d.ts.map +1 -1
  36. package/dts/chart/gradient/Gradient.d.ts +5 -0
  37. package/dts/chart/gradient/Gradient.d.ts.map +1 -1
  38. package/dts/chart/index.d.ts +1 -0
  39. package/dts/chart/index.d.ts.map +1 -1
  40. package/dts/chart/legend/DefaultLegendEntry.d.ts +5 -0
  41. package/dts/chart/legend/DefaultLegendEntry.d.ts.map +1 -0
  42. package/dts/chart/legend/DefaultLegendShape.d.ts +5 -0
  43. package/dts/chart/legend/DefaultLegendShape.d.ts.map +1 -0
  44. package/dts/chart/legend/Legend.d.ts +168 -0
  45. package/dts/chart/legend/Legend.d.ts.map +1 -0
  46. package/dts/chart/legend/index.d.ts +4 -0
  47. package/dts/chart/legend/index.d.ts.map +1 -0
  48. package/dts/chart/line/DottedLine.d.ts.map +1 -1
  49. package/dts/chart/line/Line.d.ts +23 -19
  50. package/dts/chart/line/Line.d.ts.map +1 -1
  51. package/dts/chart/line/LineChart.d.ts +26 -9
  52. package/dts/chart/line/LineChart.d.ts.map +1 -1
  53. package/dts/chart/line/ReferenceLine.d.ts +1 -0
  54. package/dts/chart/line/ReferenceLine.d.ts.map +1 -1
  55. package/dts/chart/line/SolidLine.d.ts.map +1 -1
  56. package/dts/chart/point/Point.d.ts +26 -2
  57. package/dts/chart/point/Point.d.ts.map +1 -1
  58. package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts +32 -2
  59. package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts.map +1 -1
  60. package/dts/chart/scrubber/DefaultScrubberLabel.d.ts +2 -1
  61. package/dts/chart/scrubber/DefaultScrubberLabel.d.ts.map +1 -1
  62. package/dts/chart/scrubber/Scrubber.d.ts +86 -17
  63. package/dts/chart/scrubber/Scrubber.d.ts.map +1 -1
  64. package/dts/chart/scrubber/ScrubberAccessibilityView.d.ts +12 -0
  65. package/dts/chart/scrubber/ScrubberAccessibilityView.d.ts.map +1 -0
  66. package/dts/chart/scrubber/ScrubberBeaconGroup.d.ts +10 -0
  67. package/dts/chart/scrubber/ScrubberBeaconGroup.d.ts.map +1 -1
  68. package/dts/chart/scrubber/ScrubberBeaconLabelGroup.d.ts +16 -1
  69. package/dts/chart/scrubber/ScrubberBeaconLabelGroup.d.ts.map +1 -1
  70. package/dts/chart/scrubber/ScrubberProvider.d.ts.map +1 -1
  71. package/dts/chart/utils/axis.d.ts +45 -10
  72. package/dts/chart/utils/axis.d.ts.map +1 -1
  73. package/dts/chart/utils/bar.d.ts +190 -0
  74. package/dts/chart/utils/bar.d.ts.map +1 -1
  75. package/dts/chart/utils/chart.d.ts +32 -0
  76. package/dts/chart/utils/chart.d.ts.map +1 -1
  77. package/dts/chart/utils/context.d.ts +21 -6
  78. package/dts/chart/utils/context.d.ts.map +1 -1
  79. package/dts/chart/utils/gradient.d.ts +3 -1
  80. package/dts/chart/utils/gradient.d.ts.map +1 -1
  81. package/dts/chart/utils/path.d.ts +26 -0
  82. package/dts/chart/utils/path.d.ts.map +1 -1
  83. package/dts/chart/utils/point.d.ts +24 -12
  84. package/dts/chart/utils/point.d.ts.map +1 -1
  85. package/dts/chart/utils/scale.d.ts +11 -0
  86. package/dts/chart/utils/scale.d.ts.map +1 -1
  87. package/dts/chart/utils/scrubber.d.ts +2 -1
  88. package/dts/chart/utils/scrubber.d.ts.map +1 -1
  89. package/dts/chart/utils/transition.d.ts +63 -22
  90. package/dts/chart/utils/transition.d.ts.map +1 -1
  91. package/dts/sparkline/Sparkline.d.ts +2 -1
  92. package/dts/sparkline/Sparkline.d.ts.map +1 -1
  93. package/dts/sparkline/SparklineArea.d.ts +2 -1
  94. package/dts/sparkline/SparklineArea.d.ts.map +1 -1
  95. package/dts/sparkline/SparklineGradient.d.ts +2 -1
  96. package/dts/sparkline/SparklineGradient.d.ts.map +1 -1
  97. package/dts/sparkline/sparkline-interactive/SparklineInteractive.d.ts +2 -1
  98. package/dts/sparkline/sparkline-interactive/SparklineInteractive.d.ts.map +1 -1
  99. package/esm/chart/CartesianChart.js +176 -82
  100. package/esm/chart/ChartContextBridge.js +14 -3
  101. package/esm/chart/ChartProvider.js +2 -2
  102. package/esm/chart/Path.js +34 -29
  103. package/esm/chart/PeriodSelector.js +6 -2
  104. package/esm/chart/__stories__/CartesianChart.stories.js +27 -86
  105. package/esm/chart/__stories__/ChartAccessibility.stories.js +721 -0
  106. package/esm/chart/__stories__/ChartTransitions.stories.js +625 -0
  107. package/esm/chart/__stories__/PeriodSelector.stories.js +102 -4
  108. package/esm/chart/area/Area.js +21 -9
  109. package/esm/chart/area/AreaChart.js +18 -13
  110. package/esm/chart/area/DottedArea.js +28 -18
  111. package/esm/chart/area/GradientArea.js +14 -7
  112. package/esm/chart/area/SolidArea.js +6 -2
  113. package/esm/chart/area/__stories__/AreaChart.stories.js +47 -5
  114. package/esm/chart/axis/Axis.js +5 -41
  115. package/esm/chart/axis/XAxis.js +116 -47
  116. package/esm/chart/axis/YAxis.js +105 -26
  117. package/esm/chart/axis/__stories__/Axis.stories.js +324 -48
  118. package/esm/chart/bar/Bar.js +17 -15
  119. package/esm/chart/bar/BarChart.js +38 -33
  120. package/esm/chart/bar/BarPlot.js +40 -45
  121. package/esm/chart/bar/BarStack.js +92 -475
  122. package/esm/chart/bar/BarStackGroup.js +37 -27
  123. package/esm/chart/bar/DefaultBar.js +27 -18
  124. package/esm/chart/bar/DefaultBarStack.js +25 -9
  125. package/esm/chart/bar/__stories__/BarChart.stories.js +728 -54
  126. package/esm/chart/gradient/Gradient.js +2 -1
  127. package/esm/chart/index.js +1 -0
  128. package/esm/chart/legend/DefaultLegendEntry.js +42 -0
  129. package/esm/chart/legend/DefaultLegendShape.js +64 -0
  130. package/esm/chart/legend/Legend.js +59 -0
  131. package/esm/chart/legend/__stories__/Legend.stories.js +574 -0
  132. package/esm/chart/legend/index.js +3 -0
  133. package/esm/chart/line/DottedLine.js +6 -2
  134. package/esm/chart/line/Line.js +42 -38
  135. package/esm/chart/line/LineChart.js +36 -12
  136. package/esm/chart/line/SolidLine.js +6 -2
  137. package/esm/chart/line/__stories__/LineChart.stories.js +241 -594
  138. package/esm/chart/line/__stories__/ReferenceLine.stories.js +95 -1
  139. package/esm/chart/point/Point.js +35 -36
  140. package/esm/chart/scrubber/DefaultScrubberBeacon.js +41 -38
  141. package/esm/chart/scrubber/DefaultScrubberLabel.js +26 -10
  142. package/esm/chart/scrubber/Scrubber.js +67 -35
  143. package/esm/chart/scrubber/ScrubberAccessibilityView.js +177 -0
  144. package/esm/chart/scrubber/ScrubberBeaconGroup.js +30 -22
  145. package/esm/chart/scrubber/ScrubberBeaconLabelGroup.js +35 -8
  146. package/esm/chart/scrubber/ScrubberProvider.js +29 -24
  147. package/esm/chart/scrubber/__stories__/Scrubber.stories.js +946 -0
  148. package/esm/chart/utils/axis.js +88 -44
  149. package/esm/chart/utils/bar.js +820 -0
  150. package/esm/chart/utils/chart.js +34 -7
  151. package/esm/chart/utils/context.js +7 -0
  152. package/esm/chart/utils/gradient.js +8 -4
  153. package/esm/chart/utils/path.js +91 -61
  154. package/esm/chart/utils/point.js +92 -39
  155. package/esm/chart/utils/scale.js +13 -2
  156. package/esm/chart/utils/scrubber.js +12 -5
  157. package/esm/chart/utils/transition.js +108 -60
  158. package/esm/sparkline/Sparkline.js +2 -1
  159. package/esm/sparkline/SparklineArea.js +2 -1
  160. package/esm/sparkline/SparklineGradient.js +2 -1
  161. package/esm/sparkline/__figma__/Sparkline.figma.js +1 -1
  162. package/esm/sparkline/__stories__/Sparkline.stories.js +11 -7
  163. package/esm/sparkline/__stories__/SparklineGradient.stories.js +7 -4
  164. package/esm/sparkline/sparkline-interactive/SparklineInteractive.js +2 -1
  165. package/esm/sparkline/sparkline-interactive/__figma__/SparklineInteractive.figma.js +1 -1
  166. package/esm/sparkline/sparkline-interactive/__stories__/SparklineInteractive.stories.js +51 -26
  167. package/esm/sparkline/sparkline-interactive-header/__figma__/SparklineInteractiveHeader.figma.js +1 -1
  168. package/esm/sparkline/sparkline-interactive-header/__stories__/SparklineInteractiveHeader.stories.js +19 -9
  169. package/package.json +13 -10
  170. package/esm/chart/__stories__/Chart.stories.js +0 -77
@@ -0,0 +1,946 @@
1
+ const _excluded = ["seriesId", "color", "label"],
2
+ _excluded2 = ["seriesId", "color", "label"],
3
+ _excluded3 = ["seriesId", "color"];
4
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
5
+ 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); }
6
+ import { memo, useCallback, useMemo, useRef, useState } from 'react';
7
+ import { useDerivedValue } from 'react-native-reanimated';
8
+ import { assets } from '@coinbase/cds-common/internal/data/assets';
9
+ import { useTheme } from '@coinbase/cds-mobile';
10
+ import { Button, IconButton } from '@coinbase/cds-mobile/buttons';
11
+ import { ExampleScreen } from '@coinbase/cds-mobile/examples/ExampleScreen';
12
+ import { Box, HStack, VStack } from '@coinbase/cds-mobile/layout';
13
+ import { Text } from '@coinbase/cds-mobile/typography';
14
+ import { FontWeight, Skia, TextAlign } from '@shopify/react-native-skia';
15
+ import { useCartesianChartContext } from '../../ChartProvider';
16
+ import { LineChart, SolidLine } from '../../line';
17
+ import { getLineData, unwrapAnimatedValue, useScrubberContext } from '../../utils';
18
+ import { DefaultScrubberBeacon, DefaultScrubberBeaconLabel, DefaultScrubberLabel, Scrubber } from '..';
19
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
20
+ const sampleData = [10, 22, 29, 45, 98, 45, 22, 52, 21, 4, 68, 20, 21, 58];
21
+ const chartAccessibilityLabel = "Price chart with " + sampleData.length + " data points. Swipe to navigate.";
22
+ const getScrubberAccessibilityLabel = index => "Point " + (index + 1) + ": " + sampleData[index];
23
+ const BasicScrubber = () => {
24
+ return /*#__PURE__*/_jsx(LineChart, {
25
+ enableScrubbing: true,
26
+ showArea: true,
27
+ showYAxis: true,
28
+ accessibilityLabel: chartAccessibilityLabel,
29
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
30
+ height: 150,
31
+ series: [{
32
+ id: 'prices',
33
+ data: sampleData
34
+ }],
35
+ xAxis: {
36
+ range: _ref => {
37
+ let {
38
+ min,
39
+ max
40
+ } = _ref;
41
+ return {
42
+ min,
43
+ max: max - 8
44
+ };
45
+ }
46
+ },
47
+ yAxis: {
48
+ showGrid: true
49
+ },
50
+ children: /*#__PURE__*/_jsx(Scrubber, {
51
+ idlePulse: true
52
+ })
53
+ });
54
+ };
55
+ const seriesFilterData = {
56
+ top: [15, 28, 32, 44, 46, 36, 40, 45, 48, 38],
57
+ upperMiddle: [12, 23, 21, 29, 34, 28, 31, 38, 42, 35],
58
+ lowerMiddle: [8, 15, 14, 25, 20, 18, 22, 28, 24, 30],
59
+ bottom: [4, 8, 11, 15, 16, 14, 16, 10, 12, 14]
60
+ };
61
+ const SeriesFilter = () => {
62
+ const getScrubberAccessibilityLabel = useCallback(index => "Point " + (index + 1) + ": top " + seriesFilterData.top[index] + ", lowerMiddle " + seriesFilterData.lowerMiddle[index], []);
63
+ return /*#__PURE__*/_jsx(LineChart, {
64
+ enableScrubbing: true,
65
+ accessibilityLabel: "Chart with multiple series. Swipe to navigate.",
66
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
67
+ height: 150,
68
+ series: [{
69
+ id: 'top',
70
+ data: seriesFilterData.top
71
+ }, {
72
+ id: 'upperMiddle',
73
+ data: seriesFilterData.upperMiddle,
74
+ color: '#ef4444',
75
+ type: 'dotted'
76
+ }, {
77
+ id: 'lowerMiddle',
78
+ data: seriesFilterData.lowerMiddle,
79
+ color: '#f59e0b',
80
+ curve: 'natural'
81
+ }, {
82
+ id: 'bottom',
83
+ data: seriesFilterData.bottom,
84
+ color: '#800080',
85
+ curve: 'step',
86
+ showArea: true
87
+ }],
88
+ children: /*#__PURE__*/_jsx(Scrubber, {
89
+ seriesIds: ['top', 'lowerMiddle']
90
+ })
91
+ });
92
+ };
93
+ const WithLabels = () => {
94
+ return /*#__PURE__*/_jsx(LineChart, {
95
+ enableScrubbing: true,
96
+ showArea: true,
97
+ accessibilityLabel: chartAccessibilityLabel,
98
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
99
+ height: 150,
100
+ series: [{
101
+ id: 'prices',
102
+ data: sampleData,
103
+ label: 'Price'
104
+ }],
105
+ children: /*#__PURE__*/_jsx(Scrubber, {
106
+ label: dataIndex => "Day " + (dataIndex + 1)
107
+ })
108
+ });
109
+ };
110
+ const IdlePulse = () => {
111
+ const theme = useTheme();
112
+ return /*#__PURE__*/_jsx(LineChart, {
113
+ enableScrubbing: true,
114
+ showArea: true,
115
+ accessibilityLabel: chartAccessibilityLabel,
116
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
117
+ height: 150,
118
+ series: [{
119
+ id: 'prices',
120
+ data: sampleData,
121
+ color: theme.color.fgPositive
122
+ }],
123
+ children: /*#__PURE__*/_jsx(Scrubber, {
124
+ idlePulse: true
125
+ })
126
+ });
127
+ };
128
+ const ImperativePulse = () => {
129
+ const scrubberRef = useRef(null);
130
+ return /*#__PURE__*/_jsxs(VStack, {
131
+ gap: 2,
132
+ children: [/*#__PURE__*/_jsx(LineChart, {
133
+ enableScrubbing: true,
134
+ showArea: true,
135
+ accessibilityLabel: chartAccessibilityLabel,
136
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
137
+ height: 150,
138
+ series: [{
139
+ id: 'prices',
140
+ data: sampleData
141
+ }],
142
+ children: /*#__PURE__*/_jsx(Scrubber, {
143
+ ref: scrubberRef
144
+ })
145
+ }), /*#__PURE__*/_jsx(Button, {
146
+ onPress: () => {
147
+ var _scrubberRef$current;
148
+ return (_scrubberRef$current = scrubberRef.current) == null ? void 0 : _scrubberRef$current.pulse();
149
+ },
150
+ children: "Pulse"
151
+ })]
152
+ });
153
+ };
154
+ const BeaconStroke = () => {
155
+ const theme = useTheme();
156
+ const backgroundColor = "rgb(" + theme.spectrum.red40 + ")";
157
+ const foregroundColor = "rgb(" + theme.spectrum.gray0 + ")";
158
+ return /*#__PURE__*/_jsx(Box, {
159
+ borderRadius: 300,
160
+ padding: 2,
161
+ style: {
162
+ backgroundColor
163
+ },
164
+ children: /*#__PURE__*/_jsx(LineChart, {
165
+ enableScrubbing: true,
166
+ showArea: true,
167
+ accessibilityLabel: chartAccessibilityLabel,
168
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
169
+ height: 150,
170
+ series: [{
171
+ id: 'prices',
172
+ data: sampleData,
173
+ color: foregroundColor
174
+ }],
175
+ children: /*#__PURE__*/_jsx(Scrubber, {
176
+ hideOverlay: true,
177
+ idlePulse: true,
178
+ beaconStroke: backgroundColor,
179
+ lineStroke: foregroundColor
180
+ })
181
+ })
182
+ });
183
+ };
184
+ const CustomBeacon = () => {
185
+ const theme = useTheme();
186
+ const InvertedBeacon = /*#__PURE__*/memo(props => /*#__PURE__*/_jsx(DefaultScrubberBeacon, _extends({}, props, {
187
+ color: theme.color.bg,
188
+ radius: 5,
189
+ stroke: theme.color.fg,
190
+ strokeWidth: 3
191
+ })));
192
+ return /*#__PURE__*/_jsx(LineChart, {
193
+ enableScrubbing: true,
194
+ showArea: true,
195
+ showYAxis: true,
196
+ accessibilityLabel: chartAccessibilityLabel,
197
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
198
+ height: 150,
199
+ series: [{
200
+ id: 'prices',
201
+ data: sampleData,
202
+ color: theme.color.fg
203
+ }],
204
+ xAxis: {
205
+ range: _ref2 => {
206
+ let {
207
+ min,
208
+ max
209
+ } = _ref2;
210
+ return {
211
+ min,
212
+ max: max - 16
213
+ };
214
+ }
215
+ },
216
+ yAxis: {
217
+ showGrid: true,
218
+ domain: {
219
+ min: 0,
220
+ max: 100
221
+ }
222
+ },
223
+ children: /*#__PURE__*/_jsx(Scrubber, {
224
+ BeaconComponent: InvertedBeacon
225
+ })
226
+ });
227
+ };
228
+ const CustomBeaconLabel = () => {
229
+ const theme = useTheme();
230
+ const MyScrubberBeaconLabel = /*#__PURE__*/memo(_ref3 => {
231
+ let {
232
+ seriesId,
233
+ color,
234
+ label
235
+ } = _ref3,
236
+ props = _objectWithoutPropertiesLoose(_ref3, _excluded);
237
+ const {
238
+ getSeriesData,
239
+ series
240
+ } = useCartesianChartContext();
241
+ const {
242
+ scrubberPosition
243
+ } = useScrubberContext();
244
+ const seriesData = useMemo(() => getLineData(getSeriesData(seriesId)), [getSeriesData, seriesId]);
245
+ const dataLength = useMemo(() => {
246
+ var _series$reduce;
247
+ return (_series$reduce = series == null ? void 0 : series.reduce((max, s) => {
248
+ var _data$length;
249
+ const data = getSeriesData(s.id);
250
+ return Math.max(max, (_data$length = data == null ? void 0 : data.length) != null ? _data$length : 0);
251
+ }, 0)) != null ? _series$reduce : 0;
252
+ }, [series, getSeriesData]);
253
+ const dataIndex = useDerivedValue(() => {
254
+ var _scrubberPosition$val;
255
+ return (_scrubberPosition$val = scrubberPosition.value) != null ? _scrubberPosition$val : Math.max(0, dataLength - 1);
256
+ }, [scrubberPosition, dataLength]);
257
+ const percentageLabel = useDerivedValue(() => {
258
+ if (seriesData !== undefined) {
259
+ const dataAtPosition = seriesData[dataIndex.value];
260
+ return unwrapAnimatedValue(label) + " \xB7 " + dataAtPosition + "%";
261
+ }
262
+ return unwrapAnimatedValue(label);
263
+ }, [label, seriesData, dataIndex]);
264
+ return /*#__PURE__*/_jsx(DefaultScrubberBeaconLabel, _extends({}, props, {
265
+ background: color,
266
+ color: theme.color.bg,
267
+ label: percentageLabel,
268
+ seriesId: seriesId
269
+ }));
270
+ });
271
+ return /*#__PURE__*/_jsx(LineChart, {
272
+ enableScrubbing: true,
273
+ showArea: true,
274
+ showYAxis: true,
275
+ accessibilityLabel: "Temperature chart with 6 data points. Swipe to navigate.",
276
+ areaType: "dotted",
277
+ getScrubberAccessibilityLabel: index => "Point " + (index + 1) + ": " + [25, 30, 35, 45, 60, 100][index] + "\xB0F",
278
+ height: 150,
279
+ series: [{
280
+ id: 'Boston',
281
+ data: [25, 30, 35, 45, 60, 100],
282
+ color: "rgb(" + theme.spectrum.green40 + ")",
283
+ label: 'Boston'
284
+ }, {
285
+ id: 'Miami',
286
+ data: [20, 25, 30, 35, 20, 0],
287
+ color: "rgb(" + theme.spectrum.blue40 + ")",
288
+ label: 'Miami'
289
+ }, {
290
+ id: 'Denver',
291
+ data: [10, 15, 20, 25, 40, 0],
292
+ color: "rgb(" + theme.spectrum.orange40 + ")",
293
+ label: 'Denver'
294
+ }, {
295
+ id: 'Phoenix',
296
+ data: [15, 10, 5, 0, 0, 0],
297
+ color: "rgb(" + theme.spectrum.red40 + ")",
298
+ label: 'Phoenix'
299
+ }],
300
+ yAxis: {
301
+ showGrid: true
302
+ },
303
+ children: /*#__PURE__*/_jsx(Scrubber, {
304
+ BeaconLabelComponent: MyScrubberBeaconLabel
305
+ })
306
+ });
307
+ };
308
+ const PercentageBeaconLabels = () => {
309
+ const theme = useTheme();
310
+ const PercentageScrubberBeaconLabel = /*#__PURE__*/memo(_ref4 => {
311
+ let {
312
+ seriesId,
313
+ color,
314
+ label
315
+ } = _ref4,
316
+ props = _objectWithoutPropertiesLoose(_ref4, _excluded2);
317
+ const {
318
+ getSeriesData,
319
+ series,
320
+ fontProvider
321
+ } = useCartesianChartContext();
322
+ const {
323
+ scrubberPosition
324
+ } = useScrubberContext();
325
+ const seriesData = useMemo(() => getLineData(getSeriesData(seriesId)), [getSeriesData, seriesId]);
326
+ const dataLength = useMemo(() => {
327
+ var _series$reduce2;
328
+ return (_series$reduce2 = series == null ? void 0 : series.reduce((max, s) => {
329
+ var _data$length2;
330
+ const data = getSeriesData(s.id);
331
+ return Math.max(max, (_data$length2 = data == null ? void 0 : data.length) != null ? _data$length2 : 0);
332
+ }, 0)) != null ? _series$reduce2 : 0;
333
+ }, [series, getSeriesData]);
334
+ const dataIndex = useDerivedValue(() => {
335
+ var _scrubberPosition$val2;
336
+ return (_scrubberPosition$val2 = scrubberPosition.value) != null ? _scrubberPosition$val2 : Math.max(0, dataLength - 1);
337
+ }, [scrubberPosition, dataLength]);
338
+ const labelColor = "rgb(" + theme.spectrum.gray0 + ")";
339
+ const regularStyle = useMemo(() => ({
340
+ fontFamilies: ['Inter'],
341
+ fontSize: 14,
342
+ fontStyle: {
343
+ weight: FontWeight.Normal
344
+ },
345
+ color: Skia.Color(labelColor)
346
+ }), [labelColor]);
347
+ const boldStyle = useMemo(() => _extends({}, regularStyle, {
348
+ fontStyle: {
349
+ weight: FontWeight.Bold
350
+ }
351
+ }), [regularStyle]);
352
+ const percentageLabel = useDerivedValue(() => {
353
+ const labelValue = unwrapAnimatedValue(label);
354
+ if (seriesData !== undefined) {
355
+ const dataAtPosition = seriesData[dataIndex.value];
356
+ const builder = Skia.ParagraphBuilder.Make({
357
+ textAlign: TextAlign.Left
358
+ }, fontProvider);
359
+ builder.pushStyle(boldStyle);
360
+ builder.addText(dataAtPosition + "%");
361
+ builder.pushStyle(regularStyle);
362
+ builder.addText(" " + labelValue);
363
+ const para = builder.build();
364
+ para.layout(512);
365
+ return para;
366
+ }
367
+ return labelValue;
368
+ }, [label, seriesData, dataIndex, fontProvider, boldStyle, regularStyle]);
369
+ return /*#__PURE__*/_jsx(DefaultScrubberBeaconLabel, _extends({}, props, {
370
+ background: color,
371
+ label: percentageLabel,
372
+ seriesId: seriesId
373
+ }));
374
+ });
375
+ const isLightTheme = theme.activeColorScheme === 'light';
376
+ const background = isLightTheme ? "rgb(" + theme.spectrum.gray90 + ")" : "rgb(" + theme.spectrum.gray0 + ")";
377
+ const scrubberLineStroke = isLightTheme ? "rgb(" + theme.spectrum.gray0 + ")" : "rgb(" + theme.spectrum.gray90 + ")";
378
+ const seriesData = [{
379
+ id: 'prices2',
380
+ data: [90, 78, 71, 55, 2, 55, 78, 48, 79, 96, 32, 80, 79, 42],
381
+ color: "rgb(" + theme.spectrum.blue40 + ")",
382
+ label: 'ATL'
383
+ }, {
384
+ id: 'prices',
385
+ data: [10, 22, 29, 45, 98, 45, 22, 52, 21, 4, 68, 20, 21, 58],
386
+ color: "rgb(" + theme.spectrum.chartreuse40 + ")",
387
+ label: 'NYC'
388
+ }];
389
+ return /*#__PURE__*/_jsxs(VStack, {
390
+ gap: 4,
391
+ children: [/*#__PURE__*/_jsx(Box, {
392
+ borderRadius: 300,
393
+ padding: 2,
394
+ style: {
395
+ backgroundColor: background
396
+ },
397
+ children: /*#__PURE__*/_jsx(LineChart, {
398
+ enableScrubbing: true,
399
+ showArea: true,
400
+ accessibilityLabel: "NYC vs ATL comparison chart. Swipe to navigate.",
401
+ areaType: "dotted",
402
+ getScrubberAccessibilityLabel: index => "Point " + (index + 1),
403
+ height: 150,
404
+ inset: {
405
+ bottom: 8,
406
+ left: 8,
407
+ top: 8,
408
+ right: 0
409
+ },
410
+ series: seriesData,
411
+ xAxis: {
412
+ range: _ref5 => {
413
+ let {
414
+ min,
415
+ max
416
+ } = _ref5;
417
+ return {
418
+ min,
419
+ max: max - 92
420
+ };
421
+ }
422
+ },
423
+ children: /*#__PURE__*/_jsx(Scrubber, {
424
+ hideOverlay: true,
425
+ idlePulse: true,
426
+ BeaconLabelComponent: PercentageScrubberBeaconLabel,
427
+ beaconStroke: background,
428
+ lineStroke: scrubberLineStroke
429
+ })
430
+ })
431
+ }), /*#__PURE__*/_jsx(Box, {
432
+ borderRadius: 300,
433
+ padding: 2,
434
+ style: {
435
+ backgroundColor: background
436
+ },
437
+ children: /*#__PURE__*/_jsx(LineChart, {
438
+ enableScrubbing: true,
439
+ showArea: true,
440
+ accessibilityLabel: "NYC vs ATL comparison chart. Swipe to navigate.",
441
+ areaType: "dotted",
442
+ getScrubberAccessibilityLabel: index => "Point " + (index + 1),
443
+ height: 150,
444
+ inset: {
445
+ bottom: 8,
446
+ left: 8,
447
+ top: 8,
448
+ right: 0
449
+ },
450
+ series: seriesData,
451
+ xAxis: {
452
+ range: _ref6 => {
453
+ let {
454
+ min,
455
+ max
456
+ } = _ref6;
457
+ return {
458
+ min,
459
+ max: max - 92
460
+ };
461
+ }
462
+ },
463
+ children: /*#__PURE__*/_jsx(Scrubber, {
464
+ hideOverlay: true,
465
+ idlePulse: true,
466
+ BeaconLabelComponent: PercentageScrubberBeaconLabel,
467
+ beaconLabelPreferredSide: "left",
468
+ beaconStroke: background,
469
+ lineStroke: scrubberLineStroke
470
+ })
471
+ })
472
+ })]
473
+ });
474
+ };
475
+ const HideBeaconLabels = () => {
476
+ const theme = useTheme();
477
+ return /*#__PURE__*/_jsx(LineChart, {
478
+ enableScrubbing: true,
479
+ legend: true,
480
+ showArea: true,
481
+ accessibilityLabel: "Website visitors across 7 pages. Swipe to navigate.",
482
+ getScrubberAccessibilityLabel: index => "Page " + (index + 1) + ": " + [2400, 1398, 9800, 3908, 4800, 3800, 4300][index] + " views",
483
+ height: 200,
484
+ inset: {
485
+ top: 60
486
+ },
487
+ series: [{
488
+ id: 'pageViews',
489
+ data: [2400, 1398, 9800, 3908, 4800, 3800, 4300],
490
+ color: theme.color.accentBoldGreen,
491
+ label: 'Page Views'
492
+ }, {
493
+ id: 'uniqueVisitors',
494
+ data: [4000, 3000, 2000, 2780, 1890, 2390, 3490],
495
+ color: theme.color.accentBoldPurple,
496
+ label: 'Unique Visitors'
497
+ }],
498
+ children: /*#__PURE__*/_jsx(Scrubber, {
499
+ hideBeaconLabels: true,
500
+ labelElevated: true,
501
+ label: dataIndex => "Day " + (dataIndex + 1)
502
+ })
503
+ });
504
+ };
505
+ const LabelElevated = () => {
506
+ return /*#__PURE__*/_jsx(LineChart, {
507
+ enableScrubbing: true,
508
+ showArea: true,
509
+ accessibilityLabel: chartAccessibilityLabel,
510
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
511
+ height: 200,
512
+ inset: {
513
+ top: 60
514
+ },
515
+ series: [{
516
+ id: 'prices',
517
+ data: sampleData
518
+ }],
519
+ children: /*#__PURE__*/_jsx(Scrubber, {
520
+ labelElevated: true,
521
+ label: dataIndex => "Day " + (dataIndex + 1)
522
+ })
523
+ });
524
+ };
525
+ const CustomLabelComponent = () => {
526
+ const theme = useTheme();
527
+ const MyLabelComponent = /*#__PURE__*/memo(props => {
528
+ const {
529
+ drawingArea
530
+ } = useCartesianChartContext();
531
+ if (!drawingArea) return null;
532
+ return /*#__PURE__*/_jsx(DefaultScrubberLabel, _extends({}, props, {
533
+ elevated: true,
534
+ background: theme.color.bgPrimary,
535
+ color: theme.color.bgPrimaryWash,
536
+ dy: 32,
537
+ fontWeight: FontWeight.Bold,
538
+ y: drawingArea.y + drawingArea.height
539
+ }));
540
+ });
541
+ return /*#__PURE__*/_jsx(LineChart, {
542
+ enableScrubbing: true,
543
+ showArea: true,
544
+ accessibilityLabel: chartAccessibilityLabel,
545
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
546
+ height: 200,
547
+ inset: {
548
+ top: 16,
549
+ bottom: 64
550
+ },
551
+ series: [{
552
+ id: 'prices',
553
+ data: sampleData
554
+ }],
555
+ children: /*#__PURE__*/_jsx(Scrubber, {
556
+ LabelComponent: MyLabelComponent,
557
+ label: dataIndex => "Day " + (dataIndex + 1)
558
+ })
559
+ });
560
+ };
561
+ const ethData = [5, 15, 18, 30, 65, 30, 15, 35, 15, 2, 45, 12, 15, 40];
562
+ const LabelFonts = () => {
563
+ const getScrubberAccessibilityLabel = useCallback(index => "Day " + (index + 1) + ": BTC " + sampleData[index] + ", ETH " + ethData[index], []);
564
+ return /*#__PURE__*/_jsx(LineChart, {
565
+ enableScrubbing: true,
566
+ showArea: true,
567
+ showYAxis: true,
568
+ accessibilityLabel: "BTC and ETH comparison chart. Swipe to navigate.",
569
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
570
+ height: 150,
571
+ series: [{
572
+ id: 'btc',
573
+ data: sampleData,
574
+ label: 'BTC',
575
+ color: assets.btc.color
576
+ }, {
577
+ id: 'eth',
578
+ data: ethData,
579
+ label: 'ETH',
580
+ color: assets.eth.color
581
+ }],
582
+ yAxis: {
583
+ showGrid: true
584
+ },
585
+ children: /*#__PURE__*/_jsx(Scrubber, {
586
+ beaconLabelFont: "legal",
587
+ label: dataIndex => "Day " + (dataIndex + 1),
588
+ labelFont: "legal"
589
+ })
590
+ });
591
+ };
592
+ const LabelBoundsInset = () => {
593
+ return /*#__PURE__*/_jsxs(VStack, {
594
+ gap: 4,
595
+ children: [/*#__PURE__*/_jsx(LineChart, {
596
+ enableScrubbing: true,
597
+ showArea: true,
598
+ accessibilityLabel: chartAccessibilityLabel,
599
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
600
+ height: 150,
601
+ inset: {
602
+ left: 0,
603
+ right: 0
604
+ },
605
+ series: [{
606
+ id: 'prices',
607
+ data: sampleData
608
+ }],
609
+ children: /*#__PURE__*/_jsx(Scrubber, {
610
+ label: "Without bounds - text touches edge",
611
+ labelBoundsInset: 0
612
+ })
613
+ }), /*#__PURE__*/_jsx(LineChart, {
614
+ enableScrubbing: true,
615
+ showArea: true,
616
+ accessibilityLabel: chartAccessibilityLabel,
617
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
618
+ height: 150,
619
+ inset: {
620
+ left: 0,
621
+ right: 0
622
+ },
623
+ series: [{
624
+ id: 'prices',
625
+ data: sampleData
626
+ }],
627
+ children: /*#__PURE__*/_jsx(Scrubber, {
628
+ label: "With bounds inset - text has space",
629
+ labelBoundsInset: {
630
+ top: 0,
631
+ bottom: 0,
632
+ left: 12,
633
+ right: 12
634
+ }
635
+ })
636
+ })]
637
+ });
638
+ };
639
+ const CustomLine = () => {
640
+ return /*#__PURE__*/_jsx(LineChart, {
641
+ enableScrubbing: true,
642
+ showArea: true,
643
+ accessibilityLabel: chartAccessibilityLabel,
644
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
645
+ height: 150,
646
+ series: [{
647
+ id: 'prices',
648
+ data: sampleData
649
+ }],
650
+ children: /*#__PURE__*/_jsx(Scrubber, {
651
+ LineComponent: SolidLine
652
+ })
653
+ });
654
+ };
655
+ const HiddenScrubberWhenIdle = () => {
656
+ const MyScrubberBeacon = /*#__PURE__*/memo(props => {
657
+ const {
658
+ scrubberPosition
659
+ } = useScrubberContext();
660
+ const beaconOpacity = useDerivedValue(() => scrubberPosition.value !== undefined ? 1 : 0, [scrubberPosition]);
661
+ return /*#__PURE__*/_jsx(DefaultScrubberBeacon, _extends({}, props, {
662
+ opacity: beaconOpacity
663
+ }));
664
+ });
665
+ const MyScrubberBeaconLabel = /*#__PURE__*/memo(props => {
666
+ const {
667
+ scrubberPosition
668
+ } = useScrubberContext();
669
+ const labelOpacity = useDerivedValue(() => scrubberPosition.value !== undefined ? 1 : 0, [scrubberPosition]);
670
+ return /*#__PURE__*/_jsx(DefaultScrubberBeaconLabel, _extends({}, props, {
671
+ opacity: labelOpacity
672
+ }));
673
+ });
674
+ return /*#__PURE__*/_jsx(LineChart, {
675
+ enableScrubbing: true,
676
+ showArea: true,
677
+ accessibilityLabel: chartAccessibilityLabel,
678
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
679
+ height: 150,
680
+ series: [{
681
+ id: 'prices',
682
+ data: sampleData,
683
+ label: 'Price'
684
+ }],
685
+ children: /*#__PURE__*/_jsx(Scrubber, {
686
+ BeaconComponent: MyScrubberBeacon,
687
+ BeaconLabelComponent: MyScrubberBeaconLabel
688
+ })
689
+ });
690
+ };
691
+ const HideOverlay = () => {
692
+ return /*#__PURE__*/_jsx(LineChart, {
693
+ enableScrubbing: true,
694
+ showArea: true,
695
+ accessibilityLabel: chartAccessibilityLabel,
696
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
697
+ height: 150,
698
+ series: [{
699
+ id: 'prices',
700
+ data: sampleData
701
+ }],
702
+ children: /*#__PURE__*/_jsx(Scrubber, {
703
+ hideOverlay: true
704
+ })
705
+ });
706
+ };
707
+ const matchupBlueData = [47, 50, 51, 52, 53, 53, 53, 53, 52, 51, 51, 52, 53, 55, 57, 58, 59, 61, 63, 65, 64, 64, 64, 64, 64, 63, 63, 63, 64, 66, 68, 70, 71, 72, 74, 76, 76, 75, 74, 73, 74, 75, 75, 78];
708
+ const matchupRedData = matchupBlueData.map(value => 100 - value);
709
+ const matchupTeamLabels = {
710
+ blue: 'BLUE',
711
+ red: 'RED'
712
+ };
713
+ const MatchupBeaconLabels = () => {
714
+ const theme = useTheme();
715
+ const MatchupScrubberBeaconLabel = /*#__PURE__*/memo(_ref7 => {
716
+ var _matchupTeamLabels$se;
717
+ let {
718
+ seriesId,
719
+ color
720
+ } = _ref7,
721
+ props = _objectWithoutPropertiesLoose(_ref7, _excluded3);
722
+ const {
723
+ getSeriesData,
724
+ series,
725
+ fontProvider
726
+ } = useCartesianChartContext();
727
+ const {
728
+ scrubberPosition
729
+ } = useScrubberContext();
730
+ const seriesData = useMemo(() => getLineData(getSeriesData(seriesId)), [getSeriesData, seriesId]);
731
+ const dataLength = useMemo(() => {
732
+ var _series$reduce3;
733
+ return (_series$reduce3 = series == null ? void 0 : series.reduce((max, currentSeries) => {
734
+ var _data$length3;
735
+ const data = getSeriesData(currentSeries.id);
736
+ return Math.max(max, (_data$length3 = data == null ? void 0 : data.length) != null ? _data$length3 : 0);
737
+ }, 0)) != null ? _series$reduce3 : 0;
738
+ }, [series, getSeriesData]);
739
+ const dataIndex = useDerivedValue(() => {
740
+ var _scrubberPosition$val3;
741
+ return (_scrubberPosition$val3 = scrubberPosition.value) != null ? _scrubberPosition$val3 : Math.max(0, dataLength - 1);
742
+ }, [scrubberPosition, dataLength]);
743
+ const teamLabel = (_matchupTeamLabels$se = matchupTeamLabels[seriesId]) != null ? _matchupTeamLabels$se : String(seriesId).toUpperCase();
744
+ const labelColor = color != null ? color : theme.color.fgPrimary;
745
+ const legalFontSize = theme.fontSize.legal;
746
+ const title3FontSize = theme.fontSize.title3;
747
+ const teamStyle = useMemo(() => ({
748
+ fontFamilies: ['Inter'],
749
+ fontSize: legalFontSize,
750
+ fontStyle: {
751
+ weight: FontWeight.Normal
752
+ },
753
+ color: Skia.Color(labelColor)
754
+ }), [labelColor, legalFontSize]);
755
+ const percentageStyle = useMemo(() => ({
756
+ fontFamilies: ['Inter'],
757
+ fontSize: title3FontSize,
758
+ fontStyle: {
759
+ weight: FontWeight.Bold
760
+ },
761
+ color: Skia.Color(labelColor)
762
+ }), [title3FontSize, labelColor]);
763
+ const matchupLabel = useDerivedValue(() => {
764
+ if (seriesData === undefined) {
765
+ return teamLabel;
766
+ }
767
+ const value = seriesData[dataIndex.value];
768
+ const builder = Skia.ParagraphBuilder.Make({
769
+ textAlign: TextAlign.Left
770
+ }, fontProvider);
771
+ builder.pushStyle(teamStyle);
772
+ builder.addText(teamLabel);
773
+ builder.addText('\n');
774
+ builder.pushStyle(percentageStyle);
775
+ builder.addText(value + "%");
776
+ const paragraph = builder.build();
777
+ paragraph.layout(240);
778
+ return paragraph;
779
+ }, [dataIndex, fontProvider, percentageStyle, seriesData, teamLabel, teamStyle]);
780
+ return /*#__PURE__*/_jsx(DefaultScrubberBeaconLabel, _extends({}, props, {
781
+ background: "transparent",
782
+ color: labelColor,
783
+ elevated: false,
784
+ inset: 0,
785
+ label: matchupLabel,
786
+ seriesId: seriesId
787
+ }));
788
+ });
789
+ const getScrubberAccessibilityLabel = useCallback(index => "Point " + (index + 1) + ": BLUE " + matchupBlueData[index] + "%, RED " + matchupRedData[index] + "%", []);
790
+ return /*#__PURE__*/_jsx(LineChart, {
791
+ enableScrubbing: true,
792
+ showArea: true,
793
+ accessibilityLabel: "BLUE vs RED matchup chart. Swipe to navigate.",
794
+ areaType: "dotted",
795
+ getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
796
+ height: 300,
797
+ inset: {
798
+ bottom: 8,
799
+ left: 8,
800
+ top: 8,
801
+ right: 0
802
+ },
803
+ series: [{
804
+ id: 'blue',
805
+ data: matchupBlueData,
806
+ color: "rgb(" + theme.spectrum.blue50 + ")",
807
+ label: 'BLUE'
808
+ }, {
809
+ id: 'red',
810
+ data: matchupRedData,
811
+ color: "rgb(" + theme.spectrum.red50 + ")",
812
+ label: 'RED'
813
+ }],
814
+ xAxis: {
815
+ range: _ref8 => {
816
+ let {
817
+ min,
818
+ max
819
+ } = _ref8;
820
+ return {
821
+ min,
822
+ max: max - 64
823
+ };
824
+ }
825
+ },
826
+ yAxis: {
827
+ domain: {
828
+ min: 0,
829
+ max: 100
830
+ }
831
+ },
832
+ children: /*#__PURE__*/_jsx(Scrubber, {
833
+ idlePulse: true,
834
+ BeaconLabelComponent: MatchupScrubberBeaconLabel,
835
+ beaconLabelHorizontalOffset: 16,
836
+ beaconLabelPreferredSide: "right"
837
+ })
838
+ });
839
+ };
840
+ const ExampleNavigator = () => {
841
+ const [currentIndex, setCurrentIndex] = useState(0);
842
+ const examples = useMemo(() => [{
843
+ title: 'Basic',
844
+ component: /*#__PURE__*/_jsx(BasicScrubber, {})
845
+ }, {
846
+ title: 'Series Filter',
847
+ component: /*#__PURE__*/_jsx(SeriesFilter, {})
848
+ }, {
849
+ title: 'With Labels',
850
+ component: /*#__PURE__*/_jsx(WithLabels, {})
851
+ }, {
852
+ title: 'Idle Pulse',
853
+ component: /*#__PURE__*/_jsx(IdlePulse, {})
854
+ }, {
855
+ title: 'Imperative Pulse',
856
+ component: /*#__PURE__*/_jsx(ImperativePulse, {})
857
+ }, {
858
+ title: 'Beacon Stroke',
859
+ component: /*#__PURE__*/_jsx(BeaconStroke, {})
860
+ }, {
861
+ title: 'Custom Beacon',
862
+ component: /*#__PURE__*/_jsx(CustomBeacon, {})
863
+ }, {
864
+ title: 'Custom Beacon Label',
865
+ component: /*#__PURE__*/_jsx(CustomBeaconLabel, {})
866
+ }, {
867
+ title: 'Percentage Beacon Labels',
868
+ component: /*#__PURE__*/_jsx(PercentageBeaconLabels, {})
869
+ }, {
870
+ title: 'Hide Beacon Labels',
871
+ component: /*#__PURE__*/_jsx(HideBeaconLabels, {})
872
+ }, {
873
+ title: 'Label Elevated',
874
+ component: /*#__PURE__*/_jsx(LabelElevated, {})
875
+ }, {
876
+ title: 'Custom Label Component',
877
+ component: /*#__PURE__*/_jsx(CustomLabelComponent, {})
878
+ }, {
879
+ title: 'Label Fonts',
880
+ component: /*#__PURE__*/_jsx(LabelFonts, {})
881
+ }, {
882
+ title: 'Label Bounds Inset',
883
+ component: /*#__PURE__*/_jsx(LabelBoundsInset, {})
884
+ }, {
885
+ title: 'Custom Line',
886
+ component: /*#__PURE__*/_jsx(CustomLine, {})
887
+ }, {
888
+ title: 'Hidden Scrubber When Idle',
889
+ component: /*#__PURE__*/_jsx(HiddenScrubberWhenIdle, {})
890
+ }, {
891
+ title: 'Hide Overlay',
892
+ component: /*#__PURE__*/_jsx(HideOverlay, {})
893
+ }, {
894
+ title: 'Matchup Beacon Labels',
895
+ component: /*#__PURE__*/_jsx(MatchupBeaconLabels, {})
896
+ }], []);
897
+ const currentExample = examples[currentIndex];
898
+ const isFirstExample = currentIndex === 0;
899
+ const isLastExample = currentIndex === examples.length - 1;
900
+ const handlePrevious = useCallback(() => {
901
+ setCurrentIndex(prev => Math.max(0, prev - 1));
902
+ }, []);
903
+ const handleNext = useCallback(() => {
904
+ setCurrentIndex(prev => Math.min(examples.length - 1, prev + 1));
905
+ }, [examples.length]);
906
+ return /*#__PURE__*/_jsx(ExampleScreen, {
907
+ children: /*#__PURE__*/_jsxs(VStack, {
908
+ gap: 4,
909
+ children: [/*#__PURE__*/_jsxs(HStack, {
910
+ alignItems: "center",
911
+ justifyContent: "space-between",
912
+ paddingY: 2,
913
+ children: [/*#__PURE__*/_jsx(IconButton, {
914
+ accessibilityHint: "Navigate to previous example",
915
+ accessibilityLabel: "Previous",
916
+ disabled: isFirstExample,
917
+ name: "arrowLeft",
918
+ onPress: handlePrevious,
919
+ variant: "secondary"
920
+ }), /*#__PURE__*/_jsxs(VStack, {
921
+ alignItems: "center",
922
+ gap: 1,
923
+ children: [/*#__PURE__*/_jsx(Text, {
924
+ font: "title3",
925
+ children: currentExample.title
926
+ }), /*#__PURE__*/_jsxs(Text, {
927
+ color: "fgMuted",
928
+ font: "label1",
929
+ children: [currentIndex + 1, " / ", examples.length]
930
+ })]
931
+ }), /*#__PURE__*/_jsx(IconButton, {
932
+ accessibilityHint: "Navigate to next example",
933
+ accessibilityLabel: "Next",
934
+ disabled: isLastExample,
935
+ name: "arrowRight",
936
+ onPress: handleNext,
937
+ variant: "secondary"
938
+ })]
939
+ }), /*#__PURE__*/_jsx(Box, {
940
+ padding: 1,
941
+ children: currentExample.component
942
+ })]
943
+ })
944
+ });
945
+ };
946
+ export default ExampleNavigator;