@coinbase/cds-mcp-server 8.47.1 → 8.47.3
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.
- package/CHANGELOG.md +8 -0
- package/mcp-docs/mobile/components/BarChart.txt +8 -8
- package/mcp-docs/mobile/components/CartesianChart.txt +85 -30
- package/mcp-docs/mobile/components/LineChart.txt +16 -16
- package/mcp-docs/mobile/components/MessagingCard.txt +18 -11
- package/mcp-docs/mobile/components/Numpad.txt +2 -2
- package/mcp-docs/mobile/components/Point.txt +2 -2
- package/mcp-docs/mobile/components/ReferenceLine.txt +151 -65
- package/mcp-docs/mobile/components/Scrubber.txt +12 -19
- package/mcp-docs/mobile/components/Select.txt +1 -1
- package/mcp-docs/mobile/components/SelectAlpha.txt +1 -1
- package/mcp-docs/mobile/components/SelectOption.txt +1 -1
- package/mcp-docs/mobile/components/SlideButton.txt +1 -1
- package/mcp-docs/mobile/components/SparklineInteractive.txt +239 -46
- package/mcp-docs/mobile/components/SparklineInteractiveHeader.txt +55 -13
- package/mcp-docs/mobile/components/XAxis.txt +4 -5
- package/mcp-docs/mobile/components/YAxis.txt +2 -2
- package/mcp-docs/mobile/getting-started/theming.txt +1 -1
- package/mcp-docs/web/components/BarChart.txt +40 -48
- package/mcp-docs/web/components/Carousel.txt +2 -2
- package/mcp-docs/web/components/CartesianChart.txt +82 -45
- package/mcp-docs/web/components/Combobox.txt +61 -61
- package/mcp-docs/web/components/LineChart.txt +87 -110
- package/mcp-docs/web/components/MediaQueryProvider.txt +10 -2
- package/mcp-docs/web/components/MessagingCard.txt +21 -12
- package/mcp-docs/web/components/PeriodSelector.txt +57 -39
- package/mcp-docs/web/components/Point.txt +3 -3
- package/mcp-docs/web/components/ReferenceLine.txt +341 -279
- package/mcp-docs/web/components/Scrubber.txt +48 -52
- package/mcp-docs/web/components/SelectChipAlpha.txt +1 -1
- package/mcp-docs/web/components/SparklineInteractive.txt +399 -54
- package/mcp-docs/web/components/SparklineInteractiveHeader.txt +368 -28
- package/mcp-docs/web/components/TabbedChipsAlpha.txt +1 -1
- package/mcp-docs/web/components/XAxis.txt +5 -6
- package/mcp-docs/web/components/YAxis.txt +2 -2
- package/mcp-docs/web/getting-started/theming.txt +1 -1
- package/mcp-docs/web/hooks/useBreakpoints.txt +5 -4
- package/mcp-docs/web/hooks/useMediaQuery.txt +10 -2
- package/package.json +1 -1
|
@@ -14,10 +14,6 @@ import { ReferenceLine } from '@coinbase/cds-mobile-visualization'
|
|
|
14
14
|
|
|
15
15
|
ReferenceLine can be used to add important details to a chart, such as a reference price or date. You can create horizontal lines using `dataY` or vertical lines using `dataX`.
|
|
16
16
|
|
|
17
|
-
#### Simple Reference Line
|
|
18
|
-
|
|
19
|
-
A minimal reference line without labels, useful for marking key thresholds:
|
|
20
|
-
|
|
21
17
|
```jsx
|
|
22
18
|
function SimpleReferenceLineExample() {
|
|
23
19
|
const theme = useTheme();
|
|
@@ -200,75 +196,165 @@ function BoundsExample() {
|
|
|
200
196
|
}
|
|
201
197
|
```
|
|
202
198
|
|
|
203
|
-
#### Custom
|
|
199
|
+
#### Custom Components
|
|
204
200
|
|
|
205
201
|
You can adjust the style of the label using a custom `LabelComponent`.
|
|
206
202
|
|
|
207
203
|
```jsx
|
|
208
|
-
function
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
204
|
+
function CustomLabelExample() {
|
|
205
|
+
const StartPriceLabel = memo((props) => {
|
|
206
|
+
const theme = useTheme();
|
|
207
|
+
return (
|
|
208
|
+
<DefaultReferenceLineLabel
|
|
209
|
+
{...props}
|
|
210
|
+
background={theme.color.bgSecondary}
|
|
211
|
+
borderRadius={12.5}
|
|
212
|
+
color={theme.color.fg}
|
|
213
|
+
font="label1"
|
|
214
|
+
inset={{ top: 4, bottom: 4, left: 8, right: 8 }}
|
|
215
|
+
/>
|
|
216
|
+
);
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
function Example() {
|
|
220
|
+
const theme = useTheme();
|
|
221
|
+
const hourData = useMemo(() => sparklineInteractiveData.hour, []);
|
|
222
|
+
const startPrice = hourData[0].value;
|
|
223
|
+
const endPrice = hourData[hourData.length - 1].value;
|
|
224
|
+
const isPositive = endPrice >= startPrice;
|
|
225
|
+
const seriesColor = isPositive ? theme.color.fgPositive : theme.color.fgNegative;
|
|
226
|
+
|
|
227
|
+
const formattedStartPrice = useMemo(
|
|
228
|
+
() =>
|
|
229
|
+
startPrice.toLocaleString('en-US', {
|
|
230
|
+
minimumFractionDigits: 2,
|
|
231
|
+
maximumFractionDigits: 2,
|
|
232
|
+
}),
|
|
233
|
+
[startPrice],
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
return (
|
|
237
|
+
<LineChart
|
|
238
|
+
enableScrubbing
|
|
239
|
+
showArea
|
|
240
|
+
areaType="dotted"
|
|
241
|
+
height={300}
|
|
242
|
+
series={[
|
|
243
|
+
{
|
|
244
|
+
id: 'hourly-prices',
|
|
245
|
+
data: hourData.map((d) => d.value),
|
|
246
|
+
color: seriesColor,
|
|
247
|
+
},
|
|
248
|
+
]}
|
|
249
|
+
xAxis={{
|
|
250
|
+
range: ({ min, max }) => ({ min, max: max - 24 }),
|
|
251
|
+
}}
|
|
252
|
+
>
|
|
253
|
+
<Scrubber />
|
|
254
|
+
<ReferenceLine
|
|
255
|
+
LabelComponent={StartPriceLabel}
|
|
256
|
+
LineComponent={(props) => (
|
|
257
|
+
<DottedLine {...props} dashIntervals={[0, 16]} strokeWidth={3} />
|
|
258
|
+
)}
|
|
259
|
+
dataY={startPrice}
|
|
260
|
+
label={formattedStartPrice}
|
|
261
|
+
labelDx={-12}
|
|
262
|
+
labelHorizontalAlignment="right"
|
|
263
|
+
stroke={theme.color.fgMuted}
|
|
223
264
|
/>
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
265
|
+
</LineChart>
|
|
266
|
+
);
|
|
267
|
+
}
|
|
227
268
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
<DefaultReferenceLineLabel
|
|
232
|
-
{...props}
|
|
233
|
-
background={theme.color.bg}
|
|
234
|
-
borderRadius={4}
|
|
235
|
-
color={`rgb(${theme.color.yellow70})`}
|
|
236
|
-
dx={-12}
|
|
237
|
-
font="label1"
|
|
238
|
-
horizontalAlignment="right"
|
|
239
|
-
inset={{ top: 2, bottom: 2, left: 4, right: 4 }}
|
|
240
|
-
/>
|
|
241
|
-
)),
|
|
242
|
-
[theme.color.bg, theme.color.yellow70],
|
|
243
|
-
);
|
|
269
|
+
return <Example />;
|
|
270
|
+
}
|
|
271
|
+
```
|
|
244
272
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
273
|
+
You can also optionally hide the label based on user scrubbing.
|
|
274
|
+
|
|
275
|
+
```jsx
|
|
276
|
+
function StartPriceReferenceLine() {
|
|
277
|
+
const StartPriceLabel = memo((props) => {
|
|
278
|
+
const theme = useTheme();
|
|
279
|
+
const { scrubberPosition } = useScrubberContext();
|
|
280
|
+
const { getXSerializableScale, drawingArea } = useCartesianChartContext();
|
|
281
|
+
const xScale = useMemo(() => getXSerializableScale(), [getXSerializableScale]);
|
|
282
|
+
|
|
283
|
+
const fadeZone = 128;
|
|
284
|
+
|
|
285
|
+
const opacity = useDerivedValue(() => {
|
|
286
|
+
if (scrubberPosition.value === undefined) return withTiming(0, { duration: 250 });
|
|
287
|
+
if (!xScale) return withTiming(1, { duration: 250 });
|
|
288
|
+
const scrubX = getPointOnSerializableScale(scrubberPosition.value, xScale);
|
|
289
|
+
const rightEdge = drawingArea.x + drawingArea.width;
|
|
290
|
+
const target = rightEdge - scrubX >= fadeZone ? 1 : 0;
|
|
291
|
+
return withTiming(target, { duration: 250 });
|
|
292
|
+
}, [scrubberPosition, xScale, drawingArea]);
|
|
293
|
+
|
|
294
|
+
return (
|
|
295
|
+
<DefaultReferenceLineLabel
|
|
296
|
+
{...props}
|
|
297
|
+
background={theme.color.bgSecondary}
|
|
298
|
+
borderRadius={12.5}
|
|
299
|
+
color={theme.color.fg}
|
|
300
|
+
font="label1"
|
|
301
|
+
inset={{ top: 4, bottom: 4, left: 8, right: 8 }}
|
|
302
|
+
opacity={opacity}
|
|
269
303
|
/>
|
|
270
|
-
|
|
271
|
-
);
|
|
304
|
+
);
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
function Example() {
|
|
308
|
+
const theme = useTheme();
|
|
309
|
+
const hourData = useMemo(() => sparklineInteractiveData.hour, []);
|
|
310
|
+
const startPrice = hourData[0].value;
|
|
311
|
+
const endPrice = hourData[hourData.length - 1].value;
|
|
312
|
+
const isPositive = endPrice >= startPrice;
|
|
313
|
+
const seriesColor = isPositive ? theme.color.fgPositive : theme.color.fgNegative;
|
|
314
|
+
|
|
315
|
+
const formattedStartPrice = useMemo(
|
|
316
|
+
() =>
|
|
317
|
+
startPrice.toLocaleString('en-US', {
|
|
318
|
+
minimumFractionDigits: 2,
|
|
319
|
+
maximumFractionDigits: 2,
|
|
320
|
+
}),
|
|
321
|
+
[startPrice],
|
|
322
|
+
);
|
|
323
|
+
|
|
324
|
+
return (
|
|
325
|
+
<LineChart
|
|
326
|
+
enableScrubbing
|
|
327
|
+
showArea
|
|
328
|
+
areaType="dotted"
|
|
329
|
+
height={300}
|
|
330
|
+
series={[
|
|
331
|
+
{
|
|
332
|
+
id: 'hourly-prices',
|
|
333
|
+
data: hourData.map((d) => d.value),
|
|
334
|
+
color: seriesColor,
|
|
335
|
+
},
|
|
336
|
+
]}
|
|
337
|
+
xAxis={{
|
|
338
|
+
range: ({ min, max }) => ({ min, max: max - 24 }),
|
|
339
|
+
}}
|
|
340
|
+
>
|
|
341
|
+
<Scrubber />
|
|
342
|
+
<ReferenceLine
|
|
343
|
+
LabelComponent={StartPriceLabel}
|
|
344
|
+
LineComponent={(props) => (
|
|
345
|
+
<DottedLine {...props} dashIntervals={[0, 16]} strokeWidth={3} />
|
|
346
|
+
)}
|
|
347
|
+
dataY={startPrice}
|
|
348
|
+
label={formattedStartPrice}
|
|
349
|
+
labelDx={-12}
|
|
350
|
+
labelHorizontalAlignment="right"
|
|
351
|
+
stroke={theme.color.fgMuted}
|
|
352
|
+
/>
|
|
353
|
+
</LineChart>
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return <Example />;
|
|
272
358
|
}
|
|
273
359
|
```
|
|
274
360
|
|
|
@@ -60,7 +60,7 @@ All series will be scrubbed by default. You can set `seriesIds` to show only spe
|
|
|
60
60
|
Setting `label` on a series will display a label to the side of the scrubber beacon, and
|
|
61
61
|
setting `label` on Scrubber displays a label above the scrubber line.
|
|
62
62
|
|
|
63
|
-
```
|
|
63
|
+
```tsx
|
|
64
64
|
<LineChart
|
|
65
65
|
enableScrubbing
|
|
66
66
|
height={150}
|
|
@@ -179,7 +179,7 @@ function CustomStrokeColor() {
|
|
|
179
179
|
|
|
180
180
|
For more advanced customizations, you can pass a custom component to `BeaconComponent`.
|
|
181
181
|
|
|
182
|
-
```
|
|
182
|
+
```tsx
|
|
183
183
|
function OutlineBeacon() {
|
|
184
184
|
const theme = useTheme();
|
|
185
185
|
|
|
@@ -282,7 +282,7 @@ function OutlineBeacon() {
|
|
|
282
282
|
|
|
283
283
|
You can use `BeaconLabelComponent` to customize the labels for each scrubber beacon.
|
|
284
284
|
|
|
285
|
-
```
|
|
285
|
+
```tsx
|
|
286
286
|
function CustomBeaconLabel() {
|
|
287
287
|
const theme = useTheme();
|
|
288
288
|
// This custom component label shows the percentage value of the data at the scrubber position.
|
|
@@ -365,7 +365,7 @@ function CustomBeaconLabel() {
|
|
|
365
365
|
|
|
366
366
|
You can use `hideBeaconLabels` to hide beacon labels, while still being able to provide a label for a series.
|
|
367
367
|
|
|
368
|
-
```
|
|
368
|
+
```tsx
|
|
369
369
|
<LineChart
|
|
370
370
|
enableScrubbing
|
|
371
371
|
legend
|
|
@@ -387,17 +387,13 @@ You can use `hideBeaconLabels` to hide beacon labels, while still being able to
|
|
|
387
387
|
showArea
|
|
388
388
|
inset={{ top: 60 }}
|
|
389
389
|
>
|
|
390
|
-
<Scrubber
|
|
391
|
-
hideBeaconLabels
|
|
392
|
-
label={(dataIndex: number) => `Day ${dataIndex + 1}`}
|
|
393
|
-
labelElevated
|
|
394
|
-
/>
|
|
390
|
+
<Scrubber hideBeaconLabels label={(dataIndex: number) => `Day ${dataIndex + 1}`} labelElevated />
|
|
395
391
|
</LineChart>
|
|
396
392
|
```
|
|
397
393
|
|
|
398
394
|
Using `labelElevated` will elevate the Scrubber's reference line label with a shadow.
|
|
399
395
|
|
|
400
|
-
```
|
|
396
|
+
```tsx
|
|
401
397
|
<LineChart
|
|
402
398
|
enableScrubbing
|
|
403
399
|
height={200}
|
|
@@ -416,7 +412,7 @@ Using `labelElevated` will elevate the Scrubber's reference line label with a sh
|
|
|
416
412
|
|
|
417
413
|
You can use `LabelComponent` to customize this label even further.
|
|
418
414
|
|
|
419
|
-
```
|
|
415
|
+
```tsx
|
|
420
416
|
function CustomLabelComponent() {
|
|
421
417
|
const CustomLabelComponent = memo((props: ScrubberLabelProps) => {
|
|
422
418
|
const theme = useTheme();
|
|
@@ -462,7 +458,7 @@ function CustomLabelComponent() {
|
|
|
462
458
|
|
|
463
459
|
You can create custom multi-line centered labels using Skia's `ParagraphBuilder` with `TextAlign.Center`. Set `paragraphAlignment={TextAlign.Center}` on your custom label component to ensure proper positioning.
|
|
464
460
|
|
|
465
|
-
```
|
|
461
|
+
```tsx
|
|
466
462
|
function TwoLineCenteredLabel() {
|
|
467
463
|
const theme = useTheme();
|
|
468
464
|
const data = useMemo(() => [10, 22, 29, 45, 98, 45, 22, 52, 21, 4, 68, 20, 21, 58], []);
|
|
@@ -547,7 +543,7 @@ function TwoLineCenteredLabel() {
|
|
|
547
543
|
|
|
548
544
|
You can use `labelFont` to customize the font of the scrubber line label and `beaconLabelFont` to customize the font of the beacon labels.
|
|
549
545
|
|
|
550
|
-
```
|
|
546
|
+
```tsx
|
|
551
547
|
function CustomLabelFonts() {
|
|
552
548
|
const theme = useTheme();
|
|
553
549
|
|
|
@@ -658,7 +654,7 @@ You can use `LineComponent` to customize Scrubber's line. In this case, as a use
|
|
|
658
654
|
|
|
659
655
|
You can use `BeaconComponent` and `BeaconLabelComponent` with the `opacity` prop to hide scrubber beacons and labels when idle.
|
|
660
656
|
|
|
661
|
-
```
|
|
657
|
+
```tsx
|
|
662
658
|
function HiddenScrubberWhenIdle() {
|
|
663
659
|
const MyScrubberBeacon = memo(
|
|
664
660
|
forwardRef((props: ScrubberBeaconProps, ref) => {
|
|
@@ -720,7 +716,7 @@ By default, Scrubber will show an overlay to de-emphasize future data. You can h
|
|
|
720
716
|
|
|
721
717
|
You can use `BeaconLabelComponent` to display a label with the percentage value of the data at the scrubber position.
|
|
722
718
|
|
|
723
|
-
```
|
|
719
|
+
```tsx
|
|
724
720
|
function PercentageBeaconLabels() {
|
|
725
721
|
const theme = useTheme();
|
|
726
722
|
|
|
@@ -777,10 +773,7 @@ function PercentageBeaconLabels() {
|
|
|
777
773
|
if (seriesData !== undefined) {
|
|
778
774
|
const dataAtPosition = seriesData[dataIndex.value];
|
|
779
775
|
|
|
780
|
-
const builder = Skia.ParagraphBuilder.Make(
|
|
781
|
-
{ textAlign: TextAlign.Left },
|
|
782
|
-
fontProvider,
|
|
783
|
-
);
|
|
776
|
+
const builder = Skia.ParagraphBuilder.Make({ textAlign: TextAlign.Left }, fontProvider);
|
|
784
777
|
|
|
785
778
|
builder.pushStyle(boldStyle);
|
|
786
779
|
builder.addText(`${dataAtPosition}%`);
|
|
@@ -16,7 +16,7 @@ The mobile version of `Select` is quite different from web; where on mobile, `Se
|
|
|
16
16
|
|
|
17
17
|
On mobile, all `SelectOption`s must be wrapped in a `Menu`. Think of it as a controlled `Select` on web, where you pass it the `value` and `onChange` handler.
|
|
18
18
|
|
|
19
|
-
```
|
|
19
|
+
```tsx
|
|
20
20
|
const SelectMobile = () => {
|
|
21
21
|
const [isTrayVisible, { toggleOff: handleClose, toggleOn: handleOpenTray }] = useToggler(false);
|
|
22
22
|
const [value, setValue] = useState();
|
|
@@ -20,7 +20,7 @@ import { SelectOption } from '@coinbase/cds-mobile/controls/SelectOption'
|
|
|
20
20
|
|
|
21
21
|
#### Default Composition
|
|
22
22
|
|
|
23
|
-
```
|
|
23
|
+
```tsx
|
|
24
24
|
const SelectMobile = () => {
|
|
25
25
|
const [isTrayVisible, { toggleOff: handleClose, toggleOn: handleOpenTray }] = useToggler(false);
|
|
26
26
|
const [value, setValue] = useState();
|
|
@@ -242,7 +242,7 @@ You can fully customize the background and handle by providing your own componen
|
|
|
242
242
|
alt="Slide button with custom green/red background and handle"
|
|
243
243
|
/>
|
|
244
244
|
|
|
245
|
-
```
|
|
245
|
+
```tsx
|
|
246
246
|
function Example() {
|
|
247
247
|
const [checked, setChecked] = useState(false);
|
|
248
248
|
|