@coinbase/cds-mcp-server 8.28.2 → 8.30.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.
- package/CHANGELOG.md +8 -0
- package/mcp-docs/mobile/components/Accordion.txt +3 -1
- package/mcp-docs/mobile/components/Alert.txt +3 -1
- package/mcp-docs/mobile/components/Banner.txt +14 -14
- package/mcp-docs/mobile/components/Carousel.txt +24 -24
- package/mcp-docs/mobile/components/Combobox.txt +187 -0
- package/mcp-docs/mobile/components/ContainedAssetCard.txt +4 -4
- package/mcp-docs/mobile/components/ContentCard.txt +29 -27
- package/mcp-docs/mobile/components/ContentCardBody.txt +4 -4
- package/mcp-docs/mobile/components/ContentCardHeader.txt +2 -2
- package/mcp-docs/mobile/components/FloatingAssetCard.txt +6 -6
- package/mcp-docs/mobile/components/LineChart.txt +3 -2
- package/mcp-docs/mobile/components/MultiContentModule.txt +6 -6
- package/mcp-docs/mobile/components/Numpad.txt +2 -2
- package/mcp-docs/mobile/components/PageHeader.txt +3 -1
- package/mcp-docs/mobile/components/PeriodSelector.txt +4 -4
- package/mcp-docs/mobile/components/Pressable.txt +6 -2
- package/mcp-docs/mobile/components/ProgressBarWithFixedLabels.txt +4 -4
- package/mcp-docs/mobile/components/ProgressBarWithFloatLabel.txt +2 -2
- package/mcp-docs/mobile/components/ProgressCircle.txt +5 -1
- package/mcp-docs/mobile/components/SelectChip.txt +2 -0
- package/mcp-docs/mobile/components/SelectChipAlpha.txt +88 -1
- package/mcp-docs/mobile/components/SlideButton.txt +2 -2
- package/mcp-docs/mobile/components/Sparkline.txt +3 -1
- package/mcp-docs/mobile/components/SparklineGradient.txt +3 -1
- package/mcp-docs/mobile/components/SparklineInteractiveHeader.txt +3 -1
- package/mcp-docs/mobile/components/TabbedChips.txt +3 -1
- package/mcp-docs/mobile/components/TabbedChipsAlpha.txt +30 -0
- package/mcp-docs/mobile/components/Tag.txt +19 -9
- package/mcp-docs/mobile/components/TextInput.txt +9 -3
- package/mcp-docs/mobile/components/Tray.txt +2 -0
- package/mcp-docs/mobile/components/UpsellCard.txt +16 -16
- package/mcp-docs/mobile/hooks/useDimensions.txt +4 -4
- package/mcp-docs/mobile/hooks/useMergeRefs.txt +4 -4
- package/mcp-docs/mobile/hooks/usePreviousValue.txt +5 -5
- package/mcp-docs/mobile/hooks/useRefMap.txt +6 -6
- package/mcp-docs/mobile/routes.txt +1 -0
- package/mcp-docs/web/components/Accordion.txt +3 -1
- package/mcp-docs/web/components/Alert.txt +3 -1
- package/mcp-docs/web/components/Banner.txt +14 -14
- package/mcp-docs/web/components/Carousel.txt +71 -65
- package/mcp-docs/web/components/Chip.txt +1 -1
- package/mcp-docs/web/components/Combobox.txt +176 -0
- package/mcp-docs/web/components/ContainedAssetCard.txt +4 -4
- package/mcp-docs/web/components/ContentCard.txt +29 -27
- package/mcp-docs/web/components/ContentCardBody.txt +4 -4
- package/mcp-docs/web/components/ContentCardHeader.txt +2 -2
- package/mcp-docs/web/components/FloatingAssetCard.txt +6 -6
- package/mcp-docs/web/components/FullscreenModal.txt +12 -4
- package/mcp-docs/web/components/GridColumn.txt +12 -4
- package/mcp-docs/web/components/InputChip.txt +1 -1
- package/mcp-docs/web/components/LineChart.txt +3 -2
- package/mcp-docs/web/components/MediaChip.txt +1 -1
- package/mcp-docs/web/components/MultiContentModule.txt +6 -6
- package/mcp-docs/web/components/PageHeader.txt +11 -9
- package/mcp-docs/web/components/ProgressBarWithFixedLabels.txt +4 -4
- package/mcp-docs/web/components/ProgressBarWithFloatLabel.txt +2 -2
- package/mcp-docs/web/components/ProgressCircle.txt +5 -1
- package/mcp-docs/web/components/SelectChip.txt +1 -1
- package/mcp-docs/web/components/SelectChipAlpha.txt +87 -3
- package/mcp-docs/web/components/Sidebar.txt +2 -2
- package/mcp-docs/web/components/Sparkline.txt +3 -1
- package/mcp-docs/web/components/SparklineGradient.txt +3 -1
- package/mcp-docs/web/components/SparklineInteractiveHeader.txt +3 -1
- package/mcp-docs/web/components/TabbedChips.txt +3 -1
- package/mcp-docs/web/components/TabbedChipsAlpha.txt +35 -1
- package/mcp-docs/web/components/TableBody.txt +2 -2
- package/mcp-docs/web/components/TableCaption.txt +2 -2
- package/mcp-docs/web/components/TableCell.txt +6 -6
- package/mcp-docs/web/components/Tag.txt +19 -9
- package/mcp-docs/web/components/TextInput.txt +9 -3
- package/mcp-docs/web/components/Tray.txt +2 -1
- package/mcp-docs/web/components/UpsellCard.txt +16 -16
- package/mcp-docs/web/hooks/useDimensions.txt +4 -4
- package/mcp-docs/web/hooks/useHasMounted.txt +7 -3
- package/mcp-docs/web/hooks/useIsoEffect.txt +1 -1
- package/mcp-docs/web/hooks/useMergeRefs.txt +4 -4
- package/mcp-docs/web/hooks/useOverlayContentContext.txt +8 -8
- package/mcp-docs/web/hooks/usePreviousValue.txt +5 -5
- package/mcp-docs/web/hooks/useRefMap.txt +6 -6
- package/mcp-docs/web/hooks/useScrollBlocker.txt +1 -1
- package/mcp-docs/web/hooks/useTheme.txt +3 -3
- package/mcp-docs/web/routes.txt +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,14 @@ All notable changes to this project will be documented in this file.
|
|
|
8
8
|
|
|
9
9
|
<!-- template-start -->
|
|
10
10
|
|
|
11
|
+
## 8.30.0 ((12/12/2025, 02:53 PM PST))
|
|
12
|
+
|
|
13
|
+
This is an artificial version bump with no new change.
|
|
14
|
+
|
|
15
|
+
## 8.29.0 ((12/12/2025, 01:12 PM PST))
|
|
16
|
+
|
|
17
|
+
This is an artificial version bump with no new change.
|
|
18
|
+
|
|
11
19
|
## 8.28.2 ((12/12/2025, 06:23 AM PST))
|
|
12
20
|
|
|
13
21
|
This is an artificial version bump with no new change.
|
|
@@ -38,7 +38,9 @@ Check [here](/components/layout/AccordionItem) for AccordionItem Props.
|
|
|
38
38
|
media={<CellMedia active type="icon" name="wallet" title="BTC" />}
|
|
39
39
|
onPress={(itemKey) => console.log(itemKey)}
|
|
40
40
|
>
|
|
41
|
-
<
|
|
41
|
+
<Text as="p" font="body">
|
|
42
|
+
{loremIpsum.repeat(20)}
|
|
43
|
+
</Text>
|
|
42
44
|
</AccordionItem>
|
|
43
45
|
</Accordion>
|
|
44
46
|
```
|
|
@@ -111,7 +111,9 @@ function AlertOnModalExample() {
|
|
|
111
111
|
openModal(
|
|
112
112
|
<Modal visible onRequestClose={closeModal}>
|
|
113
113
|
<ModalBody>
|
|
114
|
-
<
|
|
114
|
+
<Text as="p" font="body">
|
|
115
|
+
{loremIpsum}
|
|
116
|
+
</Text>
|
|
115
117
|
</ModalBody>
|
|
116
118
|
<ModalFooter
|
|
117
119
|
primaryAction={<Button onPress={closeModal}>Save</Button>}
|
|
@@ -25,10 +25,10 @@ The global warning banner is used to communicate important alerts or warnings to
|
|
|
25
25
|
primaryAction={<Link to="https://www.coinbase.com">Primary</Link>}
|
|
26
26
|
secondaryAction={<Link to="https://www.coinbase.com">Secondary</Link>}
|
|
27
27
|
>
|
|
28
|
-
<
|
|
28
|
+
<Text font="label2">
|
|
29
29
|
Your funds are safe. We’re looking into it and expect our usual service to return soon.
|
|
30
30
|
<Link to="https://www.coinbase.com">Learn more</Link>
|
|
31
|
-
</
|
|
31
|
+
</Text>
|
|
32
32
|
</Banner>
|
|
33
33
|
```
|
|
34
34
|
|
|
@@ -46,10 +46,10 @@ The In-line Error Banner is used to display specific error messages directly ben
|
|
|
46
46
|
primaryAction={<Link to="https://www.coinbase.com">Primary</Link>}
|
|
47
47
|
secondaryAction={<Link to="https://www.coinbase.com">Secondary</Link>}
|
|
48
48
|
>
|
|
49
|
-
<
|
|
49
|
+
<Text font="label2">
|
|
50
50
|
Your funds are safe. We’re looking into it and expect our usual service to return soon.
|
|
51
51
|
<Link to="https://www.coinbase.com">Learn more</Link>
|
|
52
|
-
</
|
|
52
|
+
</Text>
|
|
53
53
|
</Banner>
|
|
54
54
|
```
|
|
55
55
|
|
|
@@ -65,10 +65,10 @@ The Contextual Promotional Banner is used to highlight special offers, promotion
|
|
|
65
65
|
title="Some features are temporarily unavailable"
|
|
66
66
|
variant="promotional"
|
|
67
67
|
>
|
|
68
|
-
<
|
|
68
|
+
<Text font="label2">
|
|
69
69
|
Your funds are safe. We’re looking into it and expect our usual service to return soon.
|
|
70
70
|
<Link to="https://www.coinbase.com">Learn more</Link>
|
|
71
|
-
</
|
|
71
|
+
</Text>
|
|
72
72
|
</Banner>
|
|
73
73
|
```
|
|
74
74
|
|
|
@@ -87,10 +87,10 @@ The in-line Informational Banner is used to provide users with additional inform
|
|
|
87
87
|
primaryAction={<Link to="https://www.coinbase.com">Primary</Link>}
|
|
88
88
|
secondaryAction={<Link to="https://www.coinbase.com">Secondary</Link>}
|
|
89
89
|
>
|
|
90
|
-
<
|
|
90
|
+
<Text font="label2">
|
|
91
91
|
Your funds are safe. We’re looking into it and expect our usual service to return soon.
|
|
92
92
|
<Link to="https://www.coinbase.com">Learn more</Link>
|
|
93
|
-
</
|
|
93
|
+
</Text>
|
|
94
94
|
</Banner>
|
|
95
95
|
<Banner
|
|
96
96
|
startIcon="warning"
|
|
@@ -99,9 +99,9 @@ The in-line Informational Banner is used to provide users with additional inform
|
|
|
99
99
|
title="Some features are temporarily unavailable"
|
|
100
100
|
variant="warning"
|
|
101
101
|
>
|
|
102
|
-
<
|
|
102
|
+
<Text font="label2">
|
|
103
103
|
<Link to="https://www.coinbase.com">Retry</Link>
|
|
104
|
-
</
|
|
104
|
+
</Text>
|
|
105
105
|
</Banner>
|
|
106
106
|
</VStack>
|
|
107
107
|
```
|
|
@@ -120,9 +120,9 @@ Customize `borderRadius` to align contextual or in-line banners with surrounding
|
|
|
120
120
|
title="Rounded contextual banner"
|
|
121
121
|
variant="informational"
|
|
122
122
|
>
|
|
123
|
-
<
|
|
123
|
+
<Text font="label2">
|
|
124
124
|
Use moderate rounding to soften banners that live within card-based layouts.
|
|
125
|
-
</
|
|
125
|
+
</Text>
|
|
126
126
|
</Banner>
|
|
127
127
|
<Banner
|
|
128
128
|
borderRadius={400}
|
|
@@ -134,9 +134,9 @@ Customize `borderRadius` to align contextual or in-line banners with surrounding
|
|
|
134
134
|
title="Rounded inline banner"
|
|
135
135
|
variant="promotional"
|
|
136
136
|
>
|
|
137
|
-
<
|
|
137
|
+
<Text font="label2">
|
|
138
138
|
Larger radii can help inline banners feel cohesive with pill-shaped buttons or chips nearby.
|
|
139
|
-
</
|
|
139
|
+
</Text>
|
|
140
140
|
</Banner>
|
|
141
141
|
</VStack>
|
|
142
142
|
```
|
|
@@ -107,9 +107,9 @@ function DynamicSizingCarousel() {
|
|
|
107
107
|
action="Start earning"
|
|
108
108
|
dangerouslySetBackground="rgb(var(--purple70))"
|
|
109
109
|
description={
|
|
110
|
-
<
|
|
110
|
+
<Text as="p" font="label2" numberOfLines={3} color="fgInverse">
|
|
111
111
|
Earn staking rewards on ETH by holding it on Coinbase
|
|
112
|
-
</
|
|
112
|
+
</Text>
|
|
113
113
|
}
|
|
114
114
|
media={
|
|
115
115
|
<Box left={16} position="relative" top={12}>
|
|
@@ -119,9 +119,9 @@ function DynamicSizingCarousel() {
|
|
|
119
119
|
minWidth="0"
|
|
120
120
|
onActionPress={NoopFn}
|
|
121
121
|
title={
|
|
122
|
-
<
|
|
122
|
+
<Text color="fgInverse" as="h3" font="headline">
|
|
123
123
|
Up to 3.29% APR on ETHs
|
|
124
|
-
</
|
|
124
|
+
</Text>
|
|
125
125
|
}
|
|
126
126
|
width="100%"
|
|
127
127
|
/>
|
|
@@ -417,9 +417,9 @@ Similar to web, you are provided the `isVisible` render prop, however it is not
|
|
|
417
417
|
}
|
|
418
418
|
minWidth="0"
|
|
419
419
|
title={
|
|
420
|
-
<
|
|
420
|
+
<Text as="h3" font="headline" id="recurring-buy-label">
|
|
421
421
|
Recurring Buy
|
|
422
|
-
</
|
|
422
|
+
</Text>
|
|
423
423
|
}
|
|
424
424
|
width="100%"
|
|
425
425
|
/>
|
|
@@ -497,9 +497,9 @@ function CustomComponentsCarousel() {
|
|
|
497
497
|
carousel: { gap: horizontalGap },
|
|
498
498
|
}}
|
|
499
499
|
title={
|
|
500
|
-
<
|
|
500
|
+
<Text as="h3" font="headline">
|
|
501
501
|
Learn more
|
|
502
|
-
</
|
|
502
|
+
</Text>
|
|
503
503
|
}
|
|
504
504
|
>
|
|
505
505
|
<CarouselItem id="recurring-buy" width={itemWidth}>
|
|
@@ -522,9 +522,9 @@ function CustomComponentsCarousel() {
|
|
|
522
522
|
action="Start earning"
|
|
523
523
|
dangerouslySetBackground="rgb(var(--purple70))"
|
|
524
524
|
description={
|
|
525
|
-
<
|
|
525
|
+
<Text as="p" font="label2" numberOfLines={3} color="fgInverse">
|
|
526
526
|
Earn staking rewards on ETH by holding it on Coinbase
|
|
527
|
-
</
|
|
527
|
+
</Text>
|
|
528
528
|
}
|
|
529
529
|
media={
|
|
530
530
|
<Box left={16} position="relative" top={12}>
|
|
@@ -534,9 +534,9 @@ function CustomComponentsCarousel() {
|
|
|
534
534
|
minWidth={0}
|
|
535
535
|
onActionPress={NoopFn}
|
|
536
536
|
title={
|
|
537
|
-
<
|
|
537
|
+
<Text color="fgInverse" as="h3" font="headline">
|
|
538
538
|
Up to 3.29% APR on ETHs
|
|
539
|
-
</
|
|
539
|
+
</Text>
|
|
540
540
|
}
|
|
541
541
|
width="100%"
|
|
542
542
|
/>
|
|
@@ -546,9 +546,9 @@ function CustomComponentsCarousel() {
|
|
|
546
546
|
action="Start chatting"
|
|
547
547
|
dangerouslySetBackground="rgb(var(--teal70))"
|
|
548
548
|
description={
|
|
549
|
-
<
|
|
549
|
+
<Text as="p" font="label2" numberOfLines={3} color="fgInverse">
|
|
550
550
|
Chat with other devs in our Discord community
|
|
551
|
-
</
|
|
551
|
+
</Text>
|
|
552
552
|
}
|
|
553
553
|
media={
|
|
554
554
|
<Box left={16} position="relative" top={4}>
|
|
@@ -558,9 +558,9 @@ function CustomComponentsCarousel() {
|
|
|
558
558
|
minWidth={0}
|
|
559
559
|
onActionPress={NoopFn}
|
|
560
560
|
title={
|
|
561
|
-
<
|
|
561
|
+
<Text color="fgInverse" as="h3" font="headline">
|
|
562
562
|
Join the community
|
|
563
|
-
</
|
|
563
|
+
</Text>
|
|
564
564
|
}
|
|
565
565
|
width="100%"
|
|
566
566
|
/>
|
|
@@ -570,9 +570,9 @@ function CustomComponentsCarousel() {
|
|
|
570
570
|
action="Get 60 days free"
|
|
571
571
|
dangerouslySetBackground="rgb(var(--blue80))"
|
|
572
572
|
description={
|
|
573
|
-
<
|
|
573
|
+
<Text as="p" font="label2" numberOfLines={3} color="fgInverse">
|
|
574
574
|
Use code NOV60 when you sign up for Coinbase One
|
|
575
|
-
</
|
|
575
|
+
</Text>
|
|
576
576
|
}
|
|
577
577
|
media={
|
|
578
578
|
<Box left={16} position="relative" top={0}>
|
|
@@ -582,9 +582,9 @@ function CustomComponentsCarousel() {
|
|
|
582
582
|
minWidth={0}
|
|
583
583
|
onActionPress={NoopFn}
|
|
584
584
|
title={
|
|
585
|
-
<
|
|
585
|
+
<Text color="fgInverse" as="h3" font="headline">
|
|
586
586
|
Coinbase One offer
|
|
587
|
-
</
|
|
587
|
+
</Text>
|
|
588
588
|
}
|
|
589
589
|
width="100%"
|
|
590
590
|
/>
|
|
@@ -594,9 +594,9 @@ function CustomComponentsCarousel() {
|
|
|
594
594
|
action="Get started"
|
|
595
595
|
dangerouslySetBackground="rgb(var(--gray100))"
|
|
596
596
|
description={
|
|
597
|
-
<
|
|
597
|
+
<Text as="p" font="label2" numberOfLines={3} color="fgInverse">
|
|
598
598
|
Spend USDC to get rewards with our Visa® debit card
|
|
599
|
-
</
|
|
599
|
+
</Text>
|
|
600
600
|
}
|
|
601
601
|
media={
|
|
602
602
|
<Box left={16} position="relative" top={0}>
|
|
@@ -606,9 +606,9 @@ function CustomComponentsCarousel() {
|
|
|
606
606
|
minWidth={0}
|
|
607
607
|
onActionPress={NoopFn}
|
|
608
608
|
title={
|
|
609
|
-
<
|
|
609
|
+
<Text color="fgInverse" as="h3" font="headline">
|
|
610
610
|
Coinbase Card
|
|
611
|
-
</
|
|
611
|
+
</Text>
|
|
612
612
|
}
|
|
613
613
|
width="100%"
|
|
614
614
|
/>
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# Combobox
|
|
2
|
+
|
|
3
|
+
A flexible combobox component for both single and multi-selection, built for mobile applications with comprehensive accessibility support.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { Combobox } from '@coinbase/cds-mobile/alpha/combobox'
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Examples
|
|
12
|
+
|
|
13
|
+
### A note on search logic
|
|
14
|
+
|
|
15
|
+
We use [fuse.js](https://www.fusejs.io/) to power the fuzzy search logic for Combobox. You can override this search logic with your own using the `filterFunction` prop.
|
|
16
|
+
|
|
17
|
+
### Multi-Select
|
|
18
|
+
|
|
19
|
+
Basic multi-selection combobox with search.
|
|
20
|
+
|
|
21
|
+
```jsx
|
|
22
|
+
function MultiSelect() {
|
|
23
|
+
const multiSelectOptions = [
|
|
24
|
+
{ value: '1', label: 'Option 1' },
|
|
25
|
+
{ value: '2', label: 'Option 2' },
|
|
26
|
+
{ value: '3', label: 'Option 3' },
|
|
27
|
+
{ value: '4', label: 'Option 4' },
|
|
28
|
+
{ value: '5', label: 'Option 5' },
|
|
29
|
+
{ value: '6', label: 'Option 6' },
|
|
30
|
+
{ value: '7', label: 'Option 7' },
|
|
31
|
+
{ value: '8', label: 'Option 8' },
|
|
32
|
+
{ value: '9', label: 'Option 9' },
|
|
33
|
+
{ value: '10', label: 'Option 10' },
|
|
34
|
+
];
|
|
35
|
+
const { value, onChange } = useMultiSelect({ initialValue: ['1'] });
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<Combobox
|
|
39
|
+
label="Multi Select"
|
|
40
|
+
onChange={onChange}
|
|
41
|
+
options={multiSelectOptions}
|
|
42
|
+
placeholder="Search..."
|
|
43
|
+
type="multi"
|
|
44
|
+
value={value}
|
|
45
|
+
/>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Single Select
|
|
51
|
+
|
|
52
|
+
Single selection combobox with an option to clear the current choice.
|
|
53
|
+
|
|
54
|
+
```jsx
|
|
55
|
+
function SingleSelect() {
|
|
56
|
+
const singleSelectOptions = [
|
|
57
|
+
{ value: null, label: 'Remove selection' },
|
|
58
|
+
{ value: '1', label: 'Option 1' },
|
|
59
|
+
{ value: '2', label: 'Option 2' },
|
|
60
|
+
{ value: '3', label: 'Option 3' },
|
|
61
|
+
];
|
|
62
|
+
const [value, setValue] = useState(null);
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<Combobox
|
|
66
|
+
label="Single Select"
|
|
67
|
+
onChange={setValue}
|
|
68
|
+
options={singleSelectOptions}
|
|
69
|
+
placeholder="Search..."
|
|
70
|
+
value={value}
|
|
71
|
+
/>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Controlled Search
|
|
77
|
+
|
|
78
|
+
Manage the search text externally while letting the combobox stay in sync.
|
|
79
|
+
|
|
80
|
+
```jsx
|
|
81
|
+
function ControlledSearch() {
|
|
82
|
+
const { value, onChange } = useMultiSelect({ initialValue: [] });
|
|
83
|
+
const [searchText, setSearchText] = useState('');
|
|
84
|
+
|
|
85
|
+
const fruitOptions = [
|
|
86
|
+
{ value: 'apple', label: 'Apple' },
|
|
87
|
+
{ value: 'banana', label: 'Banana' },
|
|
88
|
+
{ value: 'cherry', label: 'Cherry' },
|
|
89
|
+
{ value: 'date', label: 'Date' },
|
|
90
|
+
];
|
|
91
|
+
|
|
92
|
+
return (
|
|
93
|
+
<Combobox
|
|
94
|
+
label="Controlled search"
|
|
95
|
+
onChange={onChange}
|
|
96
|
+
onSearch={setSearchText}
|
|
97
|
+
options={fruitOptions}
|
|
98
|
+
placeholder="Type to search..."
|
|
99
|
+
searchText={searchText}
|
|
100
|
+
type="multi"
|
|
101
|
+
value={value}
|
|
102
|
+
/>
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Helper Text
|
|
108
|
+
|
|
109
|
+
Use helper text to guide how many selections a user should make.
|
|
110
|
+
|
|
111
|
+
```jsx
|
|
112
|
+
function HelperTextExample() {
|
|
113
|
+
const { value, onChange } = useMultiSelect({ initialValue: [] });
|
|
114
|
+
|
|
115
|
+
const teamOptions = [
|
|
116
|
+
{ value: 'john', label: 'John Smith', description: 'Engineering' },
|
|
117
|
+
{ value: 'jane', label: 'Jane Doe', description: 'Design' },
|
|
118
|
+
{ value: 'bob', label: 'Bob Johnson', description: 'Product' },
|
|
119
|
+
{ value: 'alice', label: 'Alice Williams', description: 'Engineering' },
|
|
120
|
+
];
|
|
121
|
+
|
|
122
|
+
return (
|
|
123
|
+
<Combobox
|
|
124
|
+
helperText="Select up to 4 team members"
|
|
125
|
+
label="Team members"
|
|
126
|
+
onChange={onChange}
|
|
127
|
+
options={teamOptions}
|
|
128
|
+
placeholder="Search team members..."
|
|
129
|
+
type="multi"
|
|
130
|
+
value={value}
|
|
131
|
+
/>
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Props
|
|
137
|
+
|
|
138
|
+
| Prop | Type | Required | Default | Description |
|
|
139
|
+
| --- | --- | --- | --- | --- |
|
|
140
|
+
| `onChange` | `(value: Type extends multi ? SelectOptionValue \| SelectOptionValue[] \| null : SelectOptionValue \| null) => void` | Yes | `-` | - |
|
|
141
|
+
| `options` | `SelectOptionList<Type, SelectOptionValue>` | Yes | `-` | Array of options to display in the select dropdown. Can be individual options or groups with label and options |
|
|
142
|
+
| `value` | `string \| SelectOptionValue[] \| null` | Yes | `-` | - |
|
|
143
|
+
| `ComboboxControlComponent` | `ComboboxControlComponent` | No | `-` | - |
|
|
144
|
+
| `ComboboxDropdownComponent` | `SelectDropdownComponent` | No | `-` | - |
|
|
145
|
+
| `SelectAllOptionComponent` | `SelectOptionComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render the Select All option |
|
|
146
|
+
| `SelectControlComponent` | `SelectControlComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render the select control |
|
|
147
|
+
| `SelectDropdownComponent` | `SelectDropdownComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render the dropdown container |
|
|
148
|
+
| `SelectEmptyDropdownContentsComponent` | `SelectEmptyDropdownContentComponent` | No | `-` | Custom component to render when no options are available |
|
|
149
|
+
| `SelectOptionComponent` | `SelectOptionComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render individual options |
|
|
150
|
+
| `SelectOptionGroupComponent` | `SelectOptionGroupComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render group headers |
|
|
151
|
+
| `accessibilityRoles` | `{ option?: AccessibilityRole; } \| undefined` | No | `-` | Accessibility roles for dropdown elements |
|
|
152
|
+
| `accessory` | `ReactElement<CellAccessoryProps, string \| JSXElementConstructor<any>>` | No | `-` | - |
|
|
153
|
+
| `clearAllLabel` | `string` | No | `-` | Label for the Clear All option in multi-select mode |
|
|
154
|
+
| `closeButtonLabel` | `string` | No | `-` | Label for close button when combobox is open (mobile only) |
|
|
155
|
+
| `compact` | `boolean` | No | `-` | Whether to use compact styling for the select |
|
|
156
|
+
| `defaultOpen` | `boolean` | No | `-` | Initial open state when component mounts (uncontrolled mode) |
|
|
157
|
+
| `defaultSearchText` | `string` | No | `-` | Default search text value for uncontrolled mode |
|
|
158
|
+
| `disableClickOutsideClose` | `boolean` | No | `-` | Whether clicking outside the dropdown should close it |
|
|
159
|
+
| `disabled` | `boolean` | No | `false` | Toggles input interactability and opacity |
|
|
160
|
+
| `emptyOptionsLabel` | `string` | No | `-` | Label displayed when there are no options available |
|
|
161
|
+
| `end` | `null \| string \| number \| false \| true \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal` | No | `-` | End-aligned content (e.g., value, status). Replaces the deprecated detail prop. |
|
|
162
|
+
| `endNode` | `null \| string \| number \| false \| true \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal` | No | `-` | Adds content to the end of the inner input. Refer to diagram for location of endNode in InputStack component |
|
|
163
|
+
| `filterFunction` | `((options: SelectOptionList<Type, SelectOptionValue>, searchText: string) => SelectOption<SelectOptionValue>[])` | No | `-` | Custom filter function for searching options |
|
|
164
|
+
| `helperText` | `null \| string \| number \| false \| true \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal` | No | `-` | Helper text displayed below the select |
|
|
165
|
+
| `hiddenSelectedOptionsLabel` | `string` | No | `-` | Label to show for showcasing count of hidden selected options |
|
|
166
|
+
| `hideSearchInput` | `boolean` | No | `-` | Hide the search input |
|
|
167
|
+
| `hideSelectAll` | `boolean` | No | `-` | Whether to hide the Select All option in multi-select mode |
|
|
168
|
+
| `label` | `null \| string \| number \| false \| true \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal` | No | `-` | Label displayed above the control |
|
|
169
|
+
| `labelVariant` | `inside \| outside` | No | `'outside'` | The variant of the label. Only used when compact is not true. |
|
|
170
|
+
| `maxSelectedOptionsToShow` | `number` | No | `-` | Maximum number of selected options to show before truncating |
|
|
171
|
+
| `media` | `ReactElement` | No | `-` | Media rendered at the start of the cell (icon, avatar, image, etc). |
|
|
172
|
+
| `onSearch` | `((searchText: string) => void)` | No | `-` | Search text change handler |
|
|
173
|
+
| `open` | `boolean` | No | `-` | Controlled open state of the dropdown |
|
|
174
|
+
| `placeholder` | `null \| string \| number \| false \| true \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal` | No | `-` | Placeholder text displayed when no option is selected |
|
|
175
|
+
| `ref` | `null \| (instance: SelectRef \| null) => void \| RefObject<SelectRef>` | No | `-` | - |
|
|
176
|
+
| `removeSelectedOptionAccessibilityLabel` | `string` | No | `-` | Accessibility label for each chip in a multi-select |
|
|
177
|
+
| `searchText` | `string` | No | `-` | Controlled search text value |
|
|
178
|
+
| `selectAllLabel` | `string` | No | `-` | Label for the Select All option in multi-select mode |
|
|
179
|
+
| `setOpen` | `((open: boolean \| ((open: boolean) => boolean)) => void)` | No | `-` | Callback to update the open state |
|
|
180
|
+
| `startNode` | `null \| string \| number \| false \| true \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal` | No | `-` | Adds content to the start of the inner input. Refer to diagram for location of startNode in InputStack component |
|
|
181
|
+
| `style` | `null \| false \| ViewStyle \| RegisteredStyle<ViewStyle> \| RecursiveArray<ViewStyle \| Falsy \| RegisteredStyle<ViewStyle>>` | No | `-` | Inline styles for the root element |
|
|
182
|
+
| `styles` | `{ root?: StyleProp<ViewStyle>; control?: StyleProp<ViewStyle>; controlStartNode?: StyleProp<ViewStyle>; controlInputNode?: StyleProp<ViewStyle>; controlValueNode?: StyleProp<ViewStyle>; controlLabelNode?: StyleProp<ViewStyle>; controlHelperTextNode?: StyleProp<ViewStyle>; controlEndNode?: StyleProp<ViewStyle>; controlBlendStyles?: InteractableBlendStyles; dropdown?: StyleProp<ViewStyle>; option?: StyleProp<ViewStyle>; optionCell?: StyleProp<ViewStyle>; optionContent?: StyleProp<ViewStyle>; optionLabel?: StyleProp<ViewStyle>; optionDescription?: StyleProp<ViewStyle>; optionBlendStyles?: InteractableBlendStyles \| undefined; selectAllDivider?: StyleProp<ViewStyle>; emptyContentsContainer?: StyleProp<ViewStyle>; emptyContentsText?: StyleProp<ViewStyle>; optionGroup?: StyleProp<ViewStyle>; } \| undefined` | No | `-` | Custom styles for different parts of the select |
|
|
183
|
+
| `testID` | `string` | No | `-` | Test ID for the root element |
|
|
184
|
+
| `type` | `multi \| single` | No | `-` | Whether the select allows single or multiple selections |
|
|
185
|
+
| `variant` | `primary \| secondary \| positive \| negative \| foregroundMuted \| foreground` | No | `-` | Determines the sentiment of the input. Because we allow startContent and endContent to be custom ReactNode, the content placed inside these slots will not change colors according to the variant. You will have to add that yourself |
|
|
186
|
+
|
|
187
|
+
|
|
@@ -23,9 +23,9 @@ function Example() {
|
|
|
23
23
|
{
|
|
24
24
|
title: '$4.15',
|
|
25
25
|
description: (
|
|
26
|
-
<
|
|
26
|
+
<Text as="p" font="label2" color="fgPositive" numberOfLines={2}>
|
|
27
27
|
↗73.37%
|
|
28
|
-
</
|
|
28
|
+
</Text>
|
|
29
29
|
),
|
|
30
30
|
subtitle: 'ETH',
|
|
31
31
|
onPress: NoopFn,
|
|
@@ -55,9 +55,9 @@ function Example() {
|
|
|
55
55
|
{
|
|
56
56
|
title: '$309.43',
|
|
57
57
|
description: (
|
|
58
|
-
<
|
|
58
|
+
<Text as="p" font="label2" color="fgPositive" numberOfLines={2}>
|
|
59
59
|
↗3.37%
|
|
60
|
-
</
|
|
60
|
+
</Text>
|
|
61
61
|
),
|
|
62
62
|
subtitle: 'Bitcoin',
|
|
63
63
|
onPress: NoopFn,
|
|
@@ -30,9 +30,9 @@ function Example() {
|
|
|
30
30
|
}
|
|
31
31
|
meta={
|
|
32
32
|
<Box marginLeft={-1}>
|
|
33
|
-
<
|
|
33
|
+
<Text as="span" font="label2" color="fgMuted" marginLeft={-1} numberOfLines={1}>
|
|
34
34
|
・News・5 hrs
|
|
35
|
-
</
|
|
35
|
+
</Text>
|
|
36
36
|
</Box>
|
|
37
37
|
}
|
|
38
38
|
title="Description"
|
|
@@ -41,12 +41,12 @@ function Example() {
|
|
|
41
41
|
body="Bitcoin Network Shatters Records With Hashrate Climbing to 464 EH/s"
|
|
42
42
|
label={
|
|
43
43
|
<HStack alignItems="flex-end" flexWrap="wrap" gap={0.5}>
|
|
44
|
-
<
|
|
44
|
+
<Text as="p" font="label2" color="fgMuted" numberOfLines={1}>
|
|
45
45
|
BTC
|
|
46
|
-
</
|
|
47
|
-
<
|
|
46
|
+
</Text>
|
|
47
|
+
<Text font="label2" accessibilityLabel="Up 5.12%" as="p" color="fgPositive">
|
|
48
48
|
↗ 5.12%
|
|
49
|
-
</
|
|
49
|
+
</Text>
|
|
50
50
|
</HStack>
|
|
51
51
|
}
|
|
52
52
|
/>
|
|
@@ -55,9 +55,9 @@ function Example() {
|
|
|
55
55
|
<ContentCardHeader
|
|
56
56
|
meta={
|
|
57
57
|
<Box marginLeft={-1}>
|
|
58
|
-
<
|
|
58
|
+
<Text as="span" font="label2" color="fgMuted" numberOfLines={1}>
|
|
59
59
|
・News・5 hrs
|
|
60
|
-
</
|
|
60
|
+
</Text>
|
|
61
61
|
</Box>
|
|
62
62
|
}
|
|
63
63
|
title="Brian Armstrong"
|
|
@@ -66,12 +66,12 @@ function Example() {
|
|
|
66
66
|
body="Bitcoin Network Shatters Records With Hashrate Climbing to 464 EH/s"
|
|
67
67
|
label={
|
|
68
68
|
<HStack alignItems="flex-end" flexWrap="wrap" gap={0.5}>
|
|
69
|
-
<
|
|
69
|
+
<Text as="p" font="label2" color="fgMuted" numberOfLines={1}>
|
|
70
70
|
BTC
|
|
71
|
-
</
|
|
72
|
-
<
|
|
71
|
+
</Text>
|
|
72
|
+
<Text font="label2" accessibilityLabel="Up 5.12%" as="p" color="fgPositive">
|
|
73
73
|
↗ 5.12%
|
|
74
|
-
</
|
|
74
|
+
</Text>
|
|
75
75
|
</HStack>
|
|
76
76
|
}
|
|
77
77
|
media={
|
|
@@ -130,18 +130,18 @@ function Example() {
|
|
|
130
130
|
<ContentCard gap={3}>
|
|
131
131
|
<ContentCardBody
|
|
132
132
|
body={
|
|
133
|
-
<
|
|
133
|
+
<Text as="p" font="body" paddingTop={0.5}>
|
|
134
134
|
Bitcoin Network Shatters Records With Hashrate Climbing to 464 EH/s
|
|
135
|
-
</
|
|
135
|
+
</Text>
|
|
136
136
|
}
|
|
137
137
|
label={
|
|
138
138
|
<HStack alignItems="flex-end" flexWrap="wrap" gap={0.5}>
|
|
139
|
-
<
|
|
139
|
+
<Text as="p" font="label2" color="fgMuted" numberOfLines={1}>
|
|
140
140
|
BTC
|
|
141
|
-
</
|
|
142
|
-
<
|
|
141
|
+
</Text>
|
|
142
|
+
<Text font="label2" accessibilityLabel="Up 5.12%" as="p" color="fgPositive">
|
|
143
143
|
↗ 5.12%
|
|
144
|
-
</
|
|
144
|
+
</Text>
|
|
145
145
|
</HStack>
|
|
146
146
|
}
|
|
147
147
|
media={
|
|
@@ -165,7 +165,9 @@ function Example() {
|
|
|
165
165
|
<TextLegal as="span" color="fgMuted">
|
|
166
166
|
Reward
|
|
167
167
|
</TextLegal>
|
|
168
|
-
<
|
|
168
|
+
<Text as="span" font="headline">
|
|
169
|
+
+$15 ACS
|
|
170
|
+
</Text>
|
|
169
171
|
</VStack>
|
|
170
172
|
</HStack>
|
|
171
173
|
<Button compact accessibilityLabel="Claim now" variant="secondary">
|
|
@@ -203,9 +205,9 @@ function Example() {
|
|
|
203
205
|
}
|
|
204
206
|
meta={
|
|
205
207
|
<Box marginLeft={-1}>
|
|
206
|
-
<
|
|
208
|
+
<Text as="span" font="label2" color="fgMuted" numberOfLines={1}>
|
|
207
209
|
@matdryhurst・7 mo
|
|
208
|
-
</
|
|
210
|
+
</Text>
|
|
209
211
|
</Box>
|
|
210
212
|
}
|
|
211
213
|
title="Mat Dryhurst"
|
|
@@ -220,9 +222,9 @@ function Example() {
|
|
|
220
222
|
avatar="/img/card/content_card_custom_avatar_1.png"
|
|
221
223
|
meta={
|
|
222
224
|
<Box marginLeft={-1}>
|
|
223
|
-
<
|
|
225
|
+
<Text as="span" font="label2" color="fgMuted" numberOfLines={1}>
|
|
224
226
|
・News・5 hrs
|
|
225
|
-
</
|
|
227
|
+
</Text>
|
|
226
228
|
</Box>
|
|
227
229
|
}
|
|
228
230
|
title="Description"
|
|
@@ -240,12 +242,12 @@ function Example() {
|
|
|
240
242
|
gap={1.5}
|
|
241
243
|
label={
|
|
242
244
|
<HStack alignItems="flex-end" flexWrap="wrap" gap={0.5}>
|
|
243
|
-
<
|
|
245
|
+
<Text as="p" font="label2" color="fgMuted" numberOfLines={1}>
|
|
244
246
|
BTC
|
|
245
|
-
</
|
|
246
|
-
<
|
|
247
|
+
</Text>
|
|
248
|
+
<Text font="label2" accessibilityLabel="Up 5.12%" as="p" color="fgPositive">
|
|
247
249
|
↗ 5.12%
|
|
248
|
-
</
|
|
250
|
+
</Text>
|
|
249
251
|
</HStack>
|
|
250
252
|
}
|
|
251
253
|
paddingBottom={3}
|
|
@@ -18,12 +18,12 @@ import { ContentCardBody } from '@coinbase/cds-mobile/cards/ContentCard'
|
|
|
18
18
|
body="Bitcoin Network Shatters Records With Hashrate Climbing to 464 EH/s"
|
|
19
19
|
label={
|
|
20
20
|
<HStack alignItems="flex-end" flexWrap="wrap" gap={0.5}>
|
|
21
|
-
<
|
|
21
|
+
<Text as="p" font="label2" color="fgMuted" numberOfLines={1}>
|
|
22
22
|
BTC
|
|
23
|
-
</
|
|
24
|
-
<
|
|
23
|
+
</Text>
|
|
24
|
+
<Text font="label2" accessibilityLabel="Up 5.12%" as="p" color="fgPositive">
|
|
25
25
|
↗ 5.12%
|
|
26
|
-
</
|
|
26
|
+
</Text>
|
|
27
27
|
</HStack>
|
|
28
28
|
}
|
|
29
29
|
/>
|
|
@@ -20,9 +20,9 @@ function Example() {
|
|
|
20
20
|
avatar="/img/card/content_card_custom_avatar_1.png"
|
|
21
21
|
meta={
|
|
22
22
|
<Box marginLeft={-1}>
|
|
23
|
-
<
|
|
23
|
+
<Text as="span" font="label2" color="fgMuted" numberOfLines={1}>
|
|
24
24
|
・News・5 hrs
|
|
25
|
-
</
|
|
25
|
+
</Text>
|
|
26
26
|
</Box>
|
|
27
27
|
}
|
|
28
28
|
title="Description"
|