@coinbase/cds-mcp-server 8.25.1 → 8.26.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 +4 -0
- package/mcp-docs/mobile/components/LineChart.txt +1 -1
- package/mcp-docs/mobile/components/ReferenceLine.txt +1 -0
- package/mcp-docs/mobile/components/Scrubber.txt +1 -1
- package/mcp-docs/mobile/components/SelectAlpha.txt +144 -37
- package/mcp-docs/mobile/components/SelectChipAlpha.txt +367 -0
- package/mcp-docs/mobile/routes.txt +1 -0
- package/mcp-docs/web/components/ReferenceLine.txt +1 -1
- package/mcp-docs/web/components/Scrubber.txt +1 -1
- package/mcp-docs/web/components/SelectAlpha.txt +144 -40
- package/mcp-docs/web/components/SelectChip.txt +4 -4
- package/mcp-docs/web/components/SelectChipAlpha.txt +354 -0
- package/mcp-docs/web/routes.txt +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,10 @@ All notable changes to this project will be documented in this file.
|
|
|
8
8
|
|
|
9
9
|
<!-- template-start -->
|
|
10
10
|
|
|
11
|
+
## 8.26.0 ((12/1/2025, 12:25 PM PST))
|
|
12
|
+
|
|
13
|
+
This is an artificial version bump with no new change.
|
|
14
|
+
|
|
11
15
|
## 8.25.1 ((12/1/2025, 11:18 AM PST))
|
|
12
16
|
|
|
13
17
|
This is an artificial version bump with no new change.
|
|
@@ -2012,7 +2012,7 @@ function ForecastAssetPrice() {
|
|
|
2012
2012
|
| `showArea` | `boolean` | No | `-` | Whether to show area fill under the line. |
|
|
2013
2013
|
| `showXAxis` | `boolean` | No | `-` | Whether to show the X axis. |
|
|
2014
2014
|
| `showYAxis` | `boolean` | No | `-` | Whether to show the Y axis. |
|
|
2015
|
-
| `strokeOpacity` | `number` | No | `1` | Opacity of the line |
|
|
2015
|
+
| `strokeOpacity` | `number \| { value: number; }` | No | `1` | Opacity of the line |
|
|
2016
2016
|
| `strokeWidth` | `number` | No | `2` | Width of the line |
|
|
2017
2017
|
| `style` | `((false \| RegisteredStyle<ViewStyle> \| WithAnimatedObject<ViewStyle> \| Value \| AnimatedInterpolation<string \| number> \| WithAnimatedArray<ViewStyle \| Falsy \| RegisteredStyle<ViewStyle> \| RecursiveArray<ViewStyle \| Falsy \| RegisteredStyle<ViewStyle>> \| readonly (ViewStyle \| Falsy \| RegisteredStyle<ViewStyle>)[]>) & ((false \| RegisteredStyle<ViewStyle> \| WithAnimatedObject<ViewStyle> \| Value \| AnimatedInterpolation<string \| number> \| WithAnimatedArray<ViewStyle \| Falsy \| RegisteredStyle<ViewStyle> \| RecursiveArray<ViewStyle \| Falsy \| RegisteredStyle<ViewStyle>> \| readonly (ViewStyle \| Falsy \| RegisteredStyle<ViewStyle>)[]>) & (false \| ViewStyle \| RegisteredStyle<ViewStyle> \| RecursiveArray<ViewStyle \| Falsy \| RegisteredStyle<ViewStyle>>))) \| null` | No | `-` | Custom styles for the root element. |
|
|
2018
2018
|
| `styles` | `{ root?: StyleProp<ViewStyle>; chart?: StyleProp<ViewStyle>; }` | No | `-` | Custom styles for the component. |
|
|
@@ -289,6 +289,7 @@ function LabelStyleExample() {
|
|
|
289
289
|
| `labelHorizontalAlignment` | `left \| right \| center` | No | `-` | Horizontal alignment of the label text. |
|
|
290
290
|
| `labelPosition` | `TextHorizontalAlignment \| TextVerticalAlignment` | No | `'right' 'top'` | Position of the label along the horizontal line. Position of the label along the vertical line. |
|
|
291
291
|
| `labelVerticalAlignment` | `top \| bottom \| middle` | No | `-` | Vertical alignment of the label text. |
|
|
292
|
+
| `opacity` | `number \| { value: number; }` | No | `1` | Opacity applied to both the line and label. |
|
|
292
293
|
| `stroke` | `string` | No | `theme.color.bgLine` | The color of the line. |
|
|
293
294
|
| `yAxisId` | `string` | No | `-` | The ID of the y-axis to use for positioning. Defaults to defaultAxisId if not specified. |
|
|
294
295
|
|
|
@@ -705,7 +705,7 @@ By default, Scrubber will show an overlay to de-emphasize future data. You can h
|
|
|
705
705
|
| `beaconLabelHorizontalOffset` | `number` | No | `-` | Horizontal offset for beacon labels from their beacon position. Measured in pixels. |
|
|
706
706
|
| `beaconLabelMinGap` | `number` | No | `-` | Minimum gap between beacon labels to prevent overlap. Measured in pixels. |
|
|
707
707
|
| `beaconTransitions` | `{ update?: Transition; pulse?: Transition \| undefined; pulseRepeatDelay?: number \| undefined; } \| undefined` | No | `-` | Transition configuration for the scrubber beacon. |
|
|
708
|
-
| `hideLine` | `boolean` | No | `-` | Hides the scrubber line |
|
|
708
|
+
| `hideLine` | `boolean` | No | `-` | Hides the scrubber line. |
|
|
709
709
|
| `hideOverlay` | `boolean` | No | `-` | Hides the overlay rect which obscures data beyond the scrubber position. |
|
|
710
710
|
| `idlePulse` | `boolean` | No | `-` | Pulse the beacons while at rest. |
|
|
711
711
|
| `key` | `Key \| null` | No | `-` | - |
|
|
@@ -10,6 +10,10 @@ import { Select } from '@coinbase/cds-mobile/alpha/select'
|
|
|
10
10
|
|
|
11
11
|
## Examples
|
|
12
12
|
|
|
13
|
+
:::note Duplicate Values
|
|
14
|
+
Avoid using options with duplicate values. Each option's `value` should be unique within the options array to ensure proper selection behavior.
|
|
15
|
+
:::
|
|
16
|
+
|
|
13
17
|
### Single Select
|
|
14
18
|
|
|
15
19
|
Basic single selection with predefined options for mobile interfaces.
|
|
@@ -41,6 +45,10 @@ function SingleSelectExample() {
|
|
|
41
45
|
|
|
42
46
|
Multi-selection mode allows users to select multiple options from the list with touch-friendly controls.
|
|
43
47
|
|
|
48
|
+
:::note Disabled Options and Select All
|
|
49
|
+
Disabled options and options inside disabled groups will be skipped when "Select all" is pressed. Only enabled options will be selected.
|
|
50
|
+
:::
|
|
51
|
+
|
|
44
52
|
```jsx
|
|
45
53
|
function MultiSelectExample() {
|
|
46
54
|
const { value, onChange } = useMultiSelect({
|
|
@@ -70,6 +78,95 @@ function MultiSelectExample() {
|
|
|
70
78
|
}
|
|
71
79
|
```
|
|
72
80
|
|
|
81
|
+
### Single Select with Groups
|
|
82
|
+
|
|
83
|
+
Organize options into logical groups for better organization on mobile.
|
|
84
|
+
|
|
85
|
+
```jsx
|
|
86
|
+
function SingleSelectWithGroupsExample() {
|
|
87
|
+
const [value, setValue] = useState(null);
|
|
88
|
+
|
|
89
|
+
const groupedOptions = [
|
|
90
|
+
{
|
|
91
|
+
label: 'Group A',
|
|
92
|
+
options: [
|
|
93
|
+
{ value: '1', label: 'Option 1' },
|
|
94
|
+
{ value: '2', label: 'Option 2' },
|
|
95
|
+
{ value: '3', label: 'Option 3' },
|
|
96
|
+
],
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
label: 'Group B',
|
|
100
|
+
options: [
|
|
101
|
+
{ value: '4', label: 'Option 4' },
|
|
102
|
+
{ value: '5', label: 'Option 5' },
|
|
103
|
+
],
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
label: 'Group C',
|
|
107
|
+
options: [{ value: '6', label: 'Option 6' }],
|
|
108
|
+
},
|
|
109
|
+
];
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
<Select
|
|
113
|
+
label="Choose an option"
|
|
114
|
+
value={value}
|
|
115
|
+
onChange={setValue}
|
|
116
|
+
options={groupedOptions}
|
|
117
|
+
placeholder="Select an option"
|
|
118
|
+
/>
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Multi-Select with Groups
|
|
124
|
+
|
|
125
|
+
Use groups in multi-select mode to organize selections on mobile.
|
|
126
|
+
|
|
127
|
+
```jsx
|
|
128
|
+
function MultiSelectWithGroupsExample() {
|
|
129
|
+
const { value, onChange } = useMultiSelect({
|
|
130
|
+
initialValue: [],
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const groupedOptions = [
|
|
134
|
+
{
|
|
135
|
+
label: 'Group A',
|
|
136
|
+
options: [
|
|
137
|
+
{ value: '1', label: 'Option 1' },
|
|
138
|
+
{ value: '2', label: 'Option 2' },
|
|
139
|
+
{ value: '3', label: 'Option 3' },
|
|
140
|
+
],
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
label: 'Group B',
|
|
144
|
+
options: [
|
|
145
|
+
{ value: '4', label: 'Option 4' },
|
|
146
|
+
{ value: '5', label: 'Option 5' },
|
|
147
|
+
],
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
label: 'Group C',
|
|
151
|
+
options: [{ value: '6', label: 'Option 6' }],
|
|
152
|
+
},
|
|
153
|
+
];
|
|
154
|
+
|
|
155
|
+
return (
|
|
156
|
+
<Select
|
|
157
|
+
type="multi"
|
|
158
|
+
label="Choose multiple options"
|
|
159
|
+
value={value}
|
|
160
|
+
onChange={onChange}
|
|
161
|
+
options={groupedOptions}
|
|
162
|
+
placeholder="Select options"
|
|
163
|
+
selectAllLabel="Select all options"
|
|
164
|
+
clearAllLabel="Clear all selections"
|
|
165
|
+
/>
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
73
170
|
### Accessibility Props
|
|
74
171
|
|
|
75
172
|
The mobile Select component supports comprehensive accessibility features including custom labels, hints, and roles.
|
|
@@ -149,6 +246,53 @@ function VariantExample() {
|
|
|
149
246
|
}
|
|
150
247
|
```
|
|
151
248
|
|
|
249
|
+
### With Disabled Option Group
|
|
250
|
+
|
|
251
|
+
Disable entire groups to prevent selection of those options.
|
|
252
|
+
|
|
253
|
+
```jsx
|
|
254
|
+
function DisabledGroupExample() {
|
|
255
|
+
const [value, setValue] = useState(null);
|
|
256
|
+
|
|
257
|
+
const groupedOptions = [
|
|
258
|
+
{
|
|
259
|
+
label: 'Available Options',
|
|
260
|
+
options: [
|
|
261
|
+
{ value: '1', label: 'Option 1' },
|
|
262
|
+
{ value: '2', label: 'Option 2' },
|
|
263
|
+
{ value: '3', label: 'Option 3' },
|
|
264
|
+
],
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
label: 'Unavailable Options (Group Disabled)',
|
|
268
|
+
disabled: true,
|
|
269
|
+
options: [
|
|
270
|
+
{ value: '4', label: 'Option 4' },
|
|
271
|
+
{ value: '5', label: 'Option 5' },
|
|
272
|
+
{ value: '6', label: 'Option 6' },
|
|
273
|
+
],
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
label: 'More Available Options',
|
|
277
|
+
options: [
|
|
278
|
+
{ value: '7', label: 'Option 7' },
|
|
279
|
+
{ value: '8', label: 'Option 8' },
|
|
280
|
+
],
|
|
281
|
+
},
|
|
282
|
+
];
|
|
283
|
+
|
|
284
|
+
return (
|
|
285
|
+
<Select
|
|
286
|
+
label="Choose an option"
|
|
287
|
+
value={value}
|
|
288
|
+
onChange={setValue}
|
|
289
|
+
options={groupedOptions}
|
|
290
|
+
placeholder="Select an option"
|
|
291
|
+
/>
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
152
296
|
### Compact Mode
|
|
153
297
|
|
|
154
298
|
The Select component can be rendered in a compact size for denser mobile UIs.
|
|
@@ -1235,42 +1379,5 @@ function CustomComponentExamples() {
|
|
|
1235
1379
|
|
|
1236
1380
|
| Prop | Type | Required | Default | Description |
|
|
1237
1381
|
| --- | --- | --- | --- | --- |
|
|
1238
|
-
| `onChange` | `(value: Type extends multi ? SelectOptionValue \| SelectOptionValue[] \| null : SelectOptionValue \| null) => void` | Yes | `-` | - |
|
|
1239
|
-
| `options` | `(SelectOption<SelectOptionValue> & Pick<SelectOptionProps<Type, string>, media \| end \| accessory> & { Component?: SelectOptionComponent<Type, SelectOptionValue> \| undefined; })[]` | Yes | `-` | Array of options to display in the select dropdown |
|
|
1240
|
-
| `value` | `string \| SelectOptionValue[] \| null` | Yes | `-` | - |
|
|
1241
|
-
| `SelectAllOptionComponent` | `SelectOptionComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render the Select All option |
|
|
1242
|
-
| `SelectControlComponent` | `SelectControlComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render the select control |
|
|
1243
|
-
| `SelectDropdownComponent` | `SelectDropdownComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render the dropdown container |
|
|
1244
|
-
| `SelectEmptyDropdownContentsComponent` | `SelectEmptyDropdownContentComponent` | No | `-` | Custom component to render when no options are available |
|
|
1245
|
-
| `SelectOptionComponent` | `SelectOptionComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render individual options |
|
|
1246
|
-
| `accessibilityRoles` | `{ option?: AccessibilityRole; } \| undefined` | No | `-` | Accessibility roles for dropdown elements |
|
|
1247
|
-
| `accessory` | `ReactElement<CellAccessoryProps, string \| JSXElementConstructor<any>>` | No | `-` | - |
|
|
1248
|
-
| `clearAllLabel` | `string` | No | `-` | Label for the Clear All option in multi-select mode |
|
|
1249
|
-
| `compact` | `boolean` | No | `-` | Whether to use compact styling for the select |
|
|
1250
|
-
| `defaultOpen` | `boolean` | No | `-` | Initial open state when component mounts (uncontrolled mode) |
|
|
1251
|
-
| `disableClickOutsideClose` | `boolean` | No | `-` | Whether clicking outside the dropdown should close it |
|
|
1252
|
-
| `disabled` | `boolean` | No | `false` | Toggles input interactability and opacity |
|
|
1253
|
-
| `emptyOptionsLabel` | `string` | No | `-` | Label displayed when there are no options available |
|
|
1254
|
-
| `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. |
|
|
1255
|
-
| `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 |
|
|
1256
|
-
| `helperText` | `null \| string \| number \| false \| true \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal` | No | `-` | Helper text displayed below the select |
|
|
1257
|
-
| `hiddenSelectedOptionsLabel` | `string` | No | `-` | Label to show for showcasing count of hidden selected options |
|
|
1258
|
-
| `hideSelectAll` | `boolean` | No | `-` | Whether to hide the Select All option in multi-select mode |
|
|
1259
|
-
| `label` | `null \| string \| number \| false \| true \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal` | No | `-` | Label displayed above the control |
|
|
1260
|
-
| `labelVariant` | `inside \| outside` | No | `'outside'` | The variant of the label. Only used when compact is not true. |
|
|
1261
|
-
| `maxSelectedOptionsToShow` | `number` | No | `-` | Maximum number of selected options to show before truncating |
|
|
1262
|
-
| `media` | `ReactElement` | No | `-` | Media rendered at the start of the cell (icon, avatar, image, etc). |
|
|
1263
|
-
| `open` | `boolean` | No | `-` | Controlled open state of the dropdown |
|
|
1264
|
-
| `placeholder` | `null \| string \| number \| false \| true \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal` | No | `-` | Placeholder text displayed when no option is selected |
|
|
1265
|
-
| `ref` | `null \| (instance: SelectRef \| null) => void \| RefObject<SelectRef>` | No | `-` | - |
|
|
1266
|
-
| `removeSelectedOptionAccessibilityLabel` | `string` | No | `-` | Accessibility label for each chip in a multi-select |
|
|
1267
|
-
| `selectAllLabel` | `string` | No | `-` | Label for the Select All option in multi-select mode |
|
|
1268
|
-
| `setOpen` | `((open: boolean \| ((open: boolean) => boolean)) => void)` | No | `-` | Callback to update the open state |
|
|
1269
|
-
| `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 |
|
|
1270
|
-
| `style` | `null \| false \| ViewStyle \| RegisteredStyle<ViewStyle> \| RecursiveArray<ViewStyle \| Falsy \| RegisteredStyle<ViewStyle>>` | No | `-` | Inline styles for the root element |
|
|
1271
|
-
| `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>; } \| undefined` | No | `-` | Custom styles for different parts of the select |
|
|
1272
|
-
| `testID` | `string` | No | `-` | Test ID for the root element |
|
|
1273
|
-
| `type` | `single \| multi` | No | `-` | Whether the select allows single or multiple selections |
|
|
1274
|
-
| `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 |
|
|
1275
1382
|
|
|
1276
1383
|
|
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
# SelectChipAlpha
|
|
2
|
+
|
|
3
|
+
A chip-styled Select control built on top of the Alpha Select component. Supports both single and multi selection.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { SelectChip } from '@coinbase/cds-mobile/alpha/select-chip/SelectChip'
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Examples
|
|
12
|
+
|
|
13
|
+
SelectChip is built on top of the [Alpha Select](/components/inputs/SelectAlpha/) component. It provides a chip-styled interface while maintaining all the functionality of Select, including support for single and multi-selection, option groups, and custom components.
|
|
14
|
+
|
|
15
|
+
:::note Duplicate Values
|
|
16
|
+
Avoid using options with duplicate values. Each option's `value` should be unique within the options array to ensure proper selection behavior.
|
|
17
|
+
:::
|
|
18
|
+
|
|
19
|
+
### Basic usage
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
function ExampleDefault() {
|
|
23
|
+
const exampleOptions = [
|
|
24
|
+
{ value: null, label: 'Clear selection' },
|
|
25
|
+
{ value: '1', label: 'Option 1' },
|
|
26
|
+
{ value: '2', label: 'Option 2' },
|
|
27
|
+
{ value: '3', label: 'Option 3' },
|
|
28
|
+
{ value: '4', label: 'Option 4' },
|
|
29
|
+
];
|
|
30
|
+
const [value, setValue] = useState<string | null>(null);
|
|
31
|
+
return (
|
|
32
|
+
<SelectChip
|
|
33
|
+
label="Select a value"
|
|
34
|
+
accessibilityLabel="Select a value"
|
|
35
|
+
onChange={setValue}
|
|
36
|
+
options={exampleOptions}
|
|
37
|
+
placeholder="Choose an option"
|
|
38
|
+
value={value}
|
|
39
|
+
/>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Single select with groups
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
function ExampleSingleGroups() {
|
|
48
|
+
const exampleOptions: Array<SelectOption | SelectOptionGroup> = [
|
|
49
|
+
{
|
|
50
|
+
label: 'Group A',
|
|
51
|
+
options: [
|
|
52
|
+
{ value: '1', label: 'Option 1' },
|
|
53
|
+
{ value: '2', label: 'Option 2' },
|
|
54
|
+
{ value: '3', label: 'Option 3' },
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
label: 'Group B',
|
|
59
|
+
options: [
|
|
60
|
+
{ value: '4', label: 'Option 4' },
|
|
61
|
+
{ value: '5', label: 'Option 5' },
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
label: 'Group C',
|
|
66
|
+
options: [{ value: '6', label: 'Option 6' }],
|
|
67
|
+
},
|
|
68
|
+
];
|
|
69
|
+
const [value, setValue] = useState<string | null>(null);
|
|
70
|
+
return (
|
|
71
|
+
<SelectChip
|
|
72
|
+
accessibilityLabel="Select a value"
|
|
73
|
+
label="Select a value"
|
|
74
|
+
onChange={setValue}
|
|
75
|
+
options={exampleOptions}
|
|
76
|
+
placeholder="Choose an option"
|
|
77
|
+
value={value}
|
|
78
|
+
/>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### With disabled option group
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
function ExampleDisabledGroup() {
|
|
87
|
+
const exampleOptions: Array<SelectOption | SelectOptionGroup> = [
|
|
88
|
+
{
|
|
89
|
+
label: 'Group A',
|
|
90
|
+
options: [
|
|
91
|
+
{ value: '1', label: 'Option 1' },
|
|
92
|
+
{ value: '2', label: 'Option 2' },
|
|
93
|
+
{ value: '3', label: 'Option 3' },
|
|
94
|
+
],
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
label: 'Group B',
|
|
98
|
+
disabled: true,
|
|
99
|
+
options: [
|
|
100
|
+
{ value: '4', label: 'Option 4' },
|
|
101
|
+
{ value: '5', label: 'Option 5' },
|
|
102
|
+
],
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
label: 'Group C',
|
|
106
|
+
options: [{ value: '6', label: 'Option 6' }],
|
|
107
|
+
},
|
|
108
|
+
];
|
|
109
|
+
const [value, setValue] = useState<string | null>(null);
|
|
110
|
+
return (
|
|
111
|
+
<SelectChip
|
|
112
|
+
accessibilityLabel="Select a value"
|
|
113
|
+
label="Select a value"
|
|
114
|
+
onChange={setValue}
|
|
115
|
+
options={exampleOptions}
|
|
116
|
+
placeholder="Choose an option"
|
|
117
|
+
value={value}
|
|
118
|
+
/>
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Multi-select
|
|
124
|
+
|
|
125
|
+
:::note Disabled Options and Select All
|
|
126
|
+
Disabled options and options inside disabled groups will be skipped when "Select all" is pressed. Only enabled options will be selected.
|
|
127
|
+
:::
|
|
128
|
+
|
|
129
|
+
```tsx
|
|
130
|
+
function ExampleMulti() {
|
|
131
|
+
const exampleOptions = [
|
|
132
|
+
{ value: '1', label: 'Option 1' },
|
|
133
|
+
{ value: '2', label: 'Option 2', disabled: true },
|
|
134
|
+
{ value: '3', label: 'Option 3' },
|
|
135
|
+
{ value: '4', label: 'Option 4' },
|
|
136
|
+
{ value: '5', label: 'Option 5' },
|
|
137
|
+
];
|
|
138
|
+
const { value, onChange } = useMultiSelect({ initialValue: [] });
|
|
139
|
+
return (
|
|
140
|
+
<SelectChip
|
|
141
|
+
accessibilityLabel="Select multiple values"
|
|
142
|
+
label="Select multiple values"
|
|
143
|
+
onChange={onChange}
|
|
144
|
+
options={exampleOptions}
|
|
145
|
+
placeholder="Choose options"
|
|
146
|
+
type="multi"
|
|
147
|
+
value={value}
|
|
148
|
+
/>
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Multi-select with groups
|
|
154
|
+
|
|
155
|
+
```tsx
|
|
156
|
+
function ExampleMultiGroups() {
|
|
157
|
+
const exampleOptions: Array<SelectOption | SelectOptionGroup> = [
|
|
158
|
+
{
|
|
159
|
+
label: 'Group A',
|
|
160
|
+
options: [
|
|
161
|
+
{ value: '1', label: 'Option 1' },
|
|
162
|
+
{ value: '2', label: 'Option 2' },
|
|
163
|
+
{ value: '3', label: 'Option 3' },
|
|
164
|
+
],
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
label: 'Group B',
|
|
168
|
+
options: [
|
|
169
|
+
{ value: '4', label: 'Option 4' },
|
|
170
|
+
{ value: '5', label: 'Option 5' },
|
|
171
|
+
],
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
label: 'Group C',
|
|
175
|
+
options: [{ value: '6', label: 'Option 6' }],
|
|
176
|
+
},
|
|
177
|
+
];
|
|
178
|
+
const { value, onChange } = useMultiSelect({ initialValue: [] });
|
|
179
|
+
return (
|
|
180
|
+
<SelectChip
|
|
181
|
+
accessibilityLabel="Select multiple values"
|
|
182
|
+
label="Select multiple values"
|
|
183
|
+
onChange={onChange}
|
|
184
|
+
options={exampleOptions}
|
|
185
|
+
placeholder="Choose options"
|
|
186
|
+
type="multi"
|
|
187
|
+
value={value}
|
|
188
|
+
/>
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Compact
|
|
194
|
+
|
|
195
|
+
```tsx
|
|
196
|
+
function ExampleCompact() {
|
|
197
|
+
const exampleOptions = [
|
|
198
|
+
{ value: '1', label: 'Option 1' },
|
|
199
|
+
{ value: '2', label: 'Option 2' },
|
|
200
|
+
{ value: '3', label: 'Option 3' },
|
|
201
|
+
{ value: '4', label: 'Option 4' },
|
|
202
|
+
];
|
|
203
|
+
const [value, setValue] = useState<string | null>('1');
|
|
204
|
+
return (
|
|
205
|
+
<SelectChip
|
|
206
|
+
compact
|
|
207
|
+
label="Choose an option"
|
|
208
|
+
onChange={setValue}
|
|
209
|
+
options={exampleOptions}
|
|
210
|
+
placeholder="Choose an option"
|
|
211
|
+
value={value}
|
|
212
|
+
/>
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### With start and end nodes
|
|
218
|
+
|
|
219
|
+
```tsx
|
|
220
|
+
function ExampleWithNodes() {
|
|
221
|
+
const exampleOptions = [
|
|
222
|
+
{ value: 'btc', label: assets.btc.name },
|
|
223
|
+
{ value: 'eth', label: assets.eth.name },
|
|
224
|
+
{ value: 'dai', label: assets.dai.name },
|
|
225
|
+
];
|
|
226
|
+
const [value, setValue] = useState<string | null>('eth');
|
|
227
|
+
const getStartNode = (selectedValue: string | null) => {
|
|
228
|
+
if (!selectedValue) return null;
|
|
229
|
+
const assetMap: Record<string, string> = {
|
|
230
|
+
btc: assets.btc.imageUrl,
|
|
231
|
+
eth: assets.eth.imageUrl,
|
|
232
|
+
dai: assets.dai.imageUrl,
|
|
233
|
+
};
|
|
234
|
+
const imageUrl = assetMap[selectedValue];
|
|
235
|
+
if (!imageUrl) return null;
|
|
236
|
+
return <RemoteImage height={24} shape="circle" source={imageUrl} width={24} />;
|
|
237
|
+
};
|
|
238
|
+
return (
|
|
239
|
+
<SelectChip
|
|
240
|
+
label="Choose an asset"
|
|
241
|
+
onChange={setValue}
|
|
242
|
+
options={exampleOptions}
|
|
243
|
+
placeholder="Choose an asset"
|
|
244
|
+
startNode={getStartNode(value)}
|
|
245
|
+
value={value}
|
|
246
|
+
/>
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Empty options
|
|
252
|
+
|
|
253
|
+
```tsx
|
|
254
|
+
function ExampleEmptyOptions() {
|
|
255
|
+
const [value, setValue] = useState<string | null>(null);
|
|
256
|
+
return (
|
|
257
|
+
<SelectChip
|
|
258
|
+
label="Select ..."
|
|
259
|
+
onChange={setValue}
|
|
260
|
+
options={[]}
|
|
261
|
+
placeholder="Select ..."
|
|
262
|
+
value={value}
|
|
263
|
+
/>
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Options with descriptions
|
|
269
|
+
|
|
270
|
+
```tsx
|
|
271
|
+
function ExampleDescriptions() {
|
|
272
|
+
const exampleOptions = [
|
|
273
|
+
{ value: '1', label: 'Option 1', description: 'First option description' },
|
|
274
|
+
{ value: '2', label: 'Option 2', description: 'Second option description' },
|
|
275
|
+
{ value: '3', label: 'Option 3', description: 'Third option description' },
|
|
276
|
+
{ value: '4', label: 'Option 4', description: 'Fourth option description' },
|
|
277
|
+
];
|
|
278
|
+
const [value, setValue] = useState<string | null>(null);
|
|
279
|
+
return (
|
|
280
|
+
<SelectChip
|
|
281
|
+
accessibilityLabel="Select a value"
|
|
282
|
+
label="Select a value"
|
|
283
|
+
onChange={setValue}
|
|
284
|
+
options={exampleOptions}
|
|
285
|
+
placeholder="Choose an option"
|
|
286
|
+
value={value}
|
|
287
|
+
/>
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Disabled
|
|
293
|
+
|
|
294
|
+
```tsx
|
|
295
|
+
function ExampleDisabled() {
|
|
296
|
+
const exampleOptions = [
|
|
297
|
+
{ value: '1', label: 'Option 1' },
|
|
298
|
+
{ value: '2', label: 'Option 2' },
|
|
299
|
+
{ value: '3', label: 'Option 3' },
|
|
300
|
+
{ value: '4', label: 'Option 4' },
|
|
301
|
+
];
|
|
302
|
+
const [value, setValue] = useState<string | null>('1');
|
|
303
|
+
return (
|
|
304
|
+
<VStack gap={2}>
|
|
305
|
+
<SelectChip
|
|
306
|
+
disabled
|
|
307
|
+
accessibilityLabel="Select a value"
|
|
308
|
+
onChange={setValue}
|
|
309
|
+
options={exampleOptions}
|
|
310
|
+
placeholder="Choose an option"
|
|
311
|
+
value={null}
|
|
312
|
+
/>
|
|
313
|
+
<SelectChip
|
|
314
|
+
disabled
|
|
315
|
+
accessibilityLabel="Select a value"
|
|
316
|
+
onChange={setValue}
|
|
317
|
+
options={exampleOptions}
|
|
318
|
+
placeholder="Choose an option"
|
|
319
|
+
value={value}
|
|
320
|
+
/>
|
|
321
|
+
</VStack>
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
## Props
|
|
327
|
+
|
|
328
|
+
| Prop | Type | Required | Default | Description |
|
|
329
|
+
| --- | --- | --- | --- | --- |
|
|
330
|
+
| `onChange` | `(value: Type extends multi ? SelectOptionValue \| SelectOptionValue[] \| null : SelectOptionValue \| null) => void` | Yes | `-` | - |
|
|
331
|
+
| `options` | `SelectOptionList<Type, SelectOptionValue>` | Yes | `-` | Array of options to display in the select dropdown. Can be individual options or groups with label and options |
|
|
332
|
+
| `value` | `string \| SelectOptionValue[] \| null` | Yes | `-` | - |
|
|
333
|
+
| `SelectAllOptionComponent` | `SelectOptionComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render the Select All option |
|
|
334
|
+
| `SelectDropdownComponent` | `SelectDropdownComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render the dropdown container |
|
|
335
|
+
| `SelectEmptyDropdownContentsComponent` | `SelectEmptyDropdownContentComponent` | No | `-` | Custom component to render when no options are available |
|
|
336
|
+
| `SelectOptionComponent` | `SelectOptionComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render individual options |
|
|
337
|
+
| `SelectOptionGroupComponent` | `SelectOptionGroupComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render group headers |
|
|
338
|
+
| `accessibilityRoles` | `{ option?: AccessibilityRole; } \| undefined` | No | `-` | Accessibility roles for dropdown elements |
|
|
339
|
+
| `accessory` | `ReactElement<CellAccessoryProps, string \| JSXElementConstructor<any>>` | No | `-` | - |
|
|
340
|
+
| `clearAllLabel` | `string` | No | `-` | Label for the Clear All option in multi-select mode |
|
|
341
|
+
| `compact` | `boolean` | No | `-` | Whether to use compact styling for the select |
|
|
342
|
+
| `defaultOpen` | `boolean` | No | `-` | Initial open state when component mounts (uncontrolled mode) |
|
|
343
|
+
| `disableClickOutsideClose` | `boolean` | No | `-` | Whether clicking outside the dropdown should close it |
|
|
344
|
+
| `disabled` | `boolean` | No | `false` | Toggles input interactability and opacity |
|
|
345
|
+
| `emptyOptionsLabel` | `string` | No | `-` | Label displayed when there are no options available |
|
|
346
|
+
| `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. |
|
|
347
|
+
| `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 |
|
|
348
|
+
| `hiddenSelectedOptionsLabel` | `string` | No | `-` | Label to show for showcasing count of hidden selected options |
|
|
349
|
+
| `hideSelectAll` | `boolean` | No | `-` | Whether to hide the Select All option in multi-select mode |
|
|
350
|
+
| `invertColorScheme` | `boolean` | No | `false` | Invert the foreground and background colors to emphasize the Chip. Depending on your theme, it may be dangerous to use this prop in conjunction with transparentWhileInactive. |
|
|
351
|
+
| `label` | `null \| string \| number \| false \| true \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal` | No | `-` | Label displayed above the control |
|
|
352
|
+
| `maxSelectedOptionsToShow` | `number` | No | `-` | Maximum number of selected options to show before truncating |
|
|
353
|
+
| `media` | `ReactElement` | No | `-` | Media rendered at the start of the cell (icon, avatar, image, etc). |
|
|
354
|
+
| `numberOfLines` | `number` | No | `1` | How many lines the text in the chip will be broken into. |
|
|
355
|
+
| `open` | `boolean` | No | `-` | Controlled open state of the dropdown |
|
|
356
|
+
| `placeholder` | `null \| string \| number \| false \| true \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal` | No | `-` | Placeholder text displayed when no option is selected |
|
|
357
|
+
| `ref` | `null \| (instance: SelectRef \| null) => void \| RefObject<SelectRef>` | No | `-` | - |
|
|
358
|
+
| `removeSelectedOptionAccessibilityLabel` | `string` | No | `-` | Accessibility label for each chip in a multi-select |
|
|
359
|
+
| `selectAllLabel` | `string` | No | `-` | Label for the Select All option in multi-select mode |
|
|
360
|
+
| `setOpen` | `((open: boolean \| ((open: boolean) => boolean)) => void)` | No | `-` | Callback to update the open state |
|
|
361
|
+
| `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 |
|
|
362
|
+
| `style` | `null \| false \| ViewStyle \| RegisteredStyle<ViewStyle> \| RecursiveArray<ViewStyle \| Falsy \| RegisteredStyle<ViewStyle>>` | No | `-` | Inline styles for the root element |
|
|
363
|
+
| `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 |
|
|
364
|
+
| `testID` | `string` | No | `-` | Test ID for the root element |
|
|
365
|
+
| `type` | `single \| multi` | No | `-` | Whether the select allows single or multiple selections |
|
|
366
|
+
|
|
367
|
+
|
|
@@ -77,6 +77,7 @@
|
|
|
77
77
|
- [Switch](mobile/components/Switch.txt): A control for toggling between on and off.
|
|
78
78
|
- [SlideButton](mobile/components/SlideButton.txt): A button that slides to confirm an action.
|
|
79
79
|
- [SelectOption](mobile/components/SelectOption.txt): A single option of a Select component.
|
|
80
|
+
- [SelectChipAlpha](mobile/components/SelectChipAlpha.txt): A chip-styled Select control built on top of the Alpha Select component. Supports both single and multi selection.
|
|
80
81
|
- [SelectChip](mobile/components/SelectChip.txt): A Chip and Select control for selecting from a list of options
|
|
81
82
|
- [SelectAlpha](mobile/components/SelectAlpha.txt): A flexible select component for both single and multi-selection, built for mobile applications with comprehensive accessibility support.
|
|
82
83
|
- [Select](mobile/components/Select.txt): A control for selecting from a list of options.
|
|
@@ -581,7 +581,7 @@ function DraggablePriceTarget() {
|
|
|
581
581
|
| `beaconLabelMinGap` | `number` | No | `-` | Minimum gap between beacon labels to prevent overlap. Measured in pixels. |
|
|
582
582
|
| `beaconTransitions` | `{ update?: Transition$1; pulse?: Transition$1 \| undefined; pulseRepeatDelay?: number \| undefined; } \| undefined` | No | `-` | Transition configuration for the scrubber beacon. |
|
|
583
583
|
| `classNames` | `{ overlay?: string; beacon?: string \| undefined; line?: string \| undefined; beaconLabel?: string \| undefined; } \| undefined` | No | `-` | Custom class names for scrubber elements. |
|
|
584
|
-
| `hideLine` | `boolean` | No | `-` | Hides the scrubber line |
|
|
584
|
+
| `hideLine` | `boolean` | No | `-` | Hides the scrubber line. |
|
|
585
585
|
| `hideOverlay` | `boolean` | No | `-` | Hides the overlay rect which obscures data beyond the scrubber position. |
|
|
586
586
|
| `idlePulse` | `boolean` | No | `-` | Pulse the beacons while at rest. |
|
|
587
587
|
| `key` | `Key \| null` | No | `-` | - |
|
|
@@ -608,7 +608,7 @@ By default, Scrubber will show an overlay to de-emphasize future data. You can h
|
|
|
608
608
|
| `beaconLabelMinGap` | `number` | No | `-` | Minimum gap between beacon labels to prevent overlap. Measured in pixels. |
|
|
609
609
|
| `beaconTransitions` | `{ update?: Transition$1; pulse?: Transition$1 \| undefined; pulseRepeatDelay?: number \| undefined; } \| undefined` | No | `-` | Transition configuration for the scrubber beacon. |
|
|
610
610
|
| `classNames` | `{ overlay?: string; beacon?: string \| undefined; line?: string \| undefined; beaconLabel?: string \| undefined; } \| undefined` | No | `-` | Custom class names for scrubber elements. |
|
|
611
|
-
| `hideLine` | `boolean` | No | `-` | Hides the scrubber line |
|
|
611
|
+
| `hideLine` | `boolean` | No | `-` | Hides the scrubber line. |
|
|
612
612
|
| `hideOverlay` | `boolean` | No | `-` | Hides the overlay rect which obscures data beyond the scrubber position. |
|
|
613
613
|
| `idlePulse` | `boolean` | No | `-` | Pulse the beacons while at rest. |
|
|
614
614
|
| `key` | `Key \| null` | No | `-` | - |
|
|
@@ -10,6 +10,10 @@ import { Select } from '@coinbase/cds-web/alpha/select'
|
|
|
10
10
|
|
|
11
11
|
## Examples
|
|
12
12
|
|
|
13
|
+
:::note Duplicate Values
|
|
14
|
+
Avoid using options with duplicate values. Each option's `value` should be unique within the options array to ensure proper selection behavior.
|
|
15
|
+
:::
|
|
16
|
+
|
|
13
17
|
### Single Select
|
|
14
18
|
|
|
15
19
|
Basic single selection with predefined options.
|
|
@@ -41,6 +45,10 @@ function SingleSelectExample() {
|
|
|
41
45
|
|
|
42
46
|
Multi-selection mode allows users to select multiple options from the list.
|
|
43
47
|
|
|
48
|
+
:::note Disabled Options and Select All
|
|
49
|
+
Disabled options and options inside disabled groups will be skipped when "Select all" is pressed. Only enabled options will be selected.
|
|
50
|
+
:::
|
|
51
|
+
|
|
44
52
|
```jsx live
|
|
45
53
|
function MultiSelectExample() {
|
|
46
54
|
const { value, onChange } = useMultiSelect({
|
|
@@ -76,6 +84,95 @@ function MultiSelectExample() {
|
|
|
76
84
|
}
|
|
77
85
|
```
|
|
78
86
|
|
|
87
|
+
### Single Select with Groups
|
|
88
|
+
|
|
89
|
+
Organize options into logical groups for better organization.
|
|
90
|
+
|
|
91
|
+
```jsx live
|
|
92
|
+
function SingleSelectWithGroupsExample() {
|
|
93
|
+
const [value, setValue] = useState(null);
|
|
94
|
+
|
|
95
|
+
const groupedOptions = [
|
|
96
|
+
{
|
|
97
|
+
label: 'Group A',
|
|
98
|
+
options: [
|
|
99
|
+
{ value: '1', label: 'Option 1' },
|
|
100
|
+
{ value: '2', label: 'Option 2' },
|
|
101
|
+
{ value: '3', label: 'Option 3' },
|
|
102
|
+
],
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
label: 'Group B',
|
|
106
|
+
options: [
|
|
107
|
+
{ value: '4', label: 'Option 4' },
|
|
108
|
+
{ value: '5', label: 'Option 5' },
|
|
109
|
+
],
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
label: 'Group C',
|
|
113
|
+
options: [{ value: '6', label: 'Option 6' }],
|
|
114
|
+
},
|
|
115
|
+
];
|
|
116
|
+
|
|
117
|
+
return (
|
|
118
|
+
<Select
|
|
119
|
+
label="Choose an option"
|
|
120
|
+
value={value}
|
|
121
|
+
onChange={setValue}
|
|
122
|
+
options={groupedOptions}
|
|
123
|
+
placeholder="Select an option"
|
|
124
|
+
/>
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Multi-Select with Groups
|
|
130
|
+
|
|
131
|
+
Use groups in multi-select mode to organize selections.
|
|
132
|
+
|
|
133
|
+
```jsx live
|
|
134
|
+
function MultiSelectWithGroupsExample() {
|
|
135
|
+
const { value, onChange } = useMultiSelect({
|
|
136
|
+
initialValue: [],
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
const groupedOptions = [
|
|
140
|
+
{
|
|
141
|
+
label: 'Group A',
|
|
142
|
+
options: [
|
|
143
|
+
{ value: '1', label: 'Option 1' },
|
|
144
|
+
{ value: '2', label: 'Option 2' },
|
|
145
|
+
{ value: '3', label: 'Option 3' },
|
|
146
|
+
],
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
label: 'Group B',
|
|
150
|
+
options: [
|
|
151
|
+
{ value: '4', label: 'Option 4' },
|
|
152
|
+
{ value: '5', label: 'Option 5' },
|
|
153
|
+
],
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
label: 'Group C',
|
|
157
|
+
options: [{ value: '6', label: 'Option 6' }],
|
|
158
|
+
},
|
|
159
|
+
];
|
|
160
|
+
|
|
161
|
+
return (
|
|
162
|
+
<Select
|
|
163
|
+
type="multi"
|
|
164
|
+
label="Choose multiple options"
|
|
165
|
+
value={value}
|
|
166
|
+
onChange={onChange}
|
|
167
|
+
options={groupedOptions}
|
|
168
|
+
placeholder="Select options"
|
|
169
|
+
selectAllLabel="Select all options"
|
|
170
|
+
clearAllLabel="Clear all selections"
|
|
171
|
+
/>
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
79
176
|
### Accessibility Props
|
|
80
177
|
|
|
81
178
|
The Select component supports comprehensive accessibility features including custom labels and roles.
|
|
@@ -155,6 +252,53 @@ function VariantExample() {
|
|
|
155
252
|
}
|
|
156
253
|
```
|
|
157
254
|
|
|
255
|
+
### With Disabled Option Group
|
|
256
|
+
|
|
257
|
+
Disable entire groups to prevent selection of those options.
|
|
258
|
+
|
|
259
|
+
```jsx live
|
|
260
|
+
function DisabledGroupExample() {
|
|
261
|
+
const [value, setValue] = useState(null);
|
|
262
|
+
|
|
263
|
+
const groupedOptions = [
|
|
264
|
+
{
|
|
265
|
+
label: 'Available Options',
|
|
266
|
+
options: [
|
|
267
|
+
{ value: '1', label: 'Option 1' },
|
|
268
|
+
{ value: '2', label: 'Option 2' },
|
|
269
|
+
{ value: '3', label: 'Option 3' },
|
|
270
|
+
],
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
label: 'Unavailable Options (Group Disabled)',
|
|
274
|
+
disabled: true,
|
|
275
|
+
options: [
|
|
276
|
+
{ value: '4', label: 'Option 4' },
|
|
277
|
+
{ value: '5', label: 'Option 5' },
|
|
278
|
+
{ value: '6', label: 'Option 6' },
|
|
279
|
+
],
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
label: 'More Available Options',
|
|
283
|
+
options: [
|
|
284
|
+
{ value: '7', label: 'Option 7' },
|
|
285
|
+
{ value: '8', label: 'Option 8' },
|
|
286
|
+
],
|
|
287
|
+
},
|
|
288
|
+
];
|
|
289
|
+
|
|
290
|
+
return (
|
|
291
|
+
<Select
|
|
292
|
+
label="Choose an option"
|
|
293
|
+
value={value}
|
|
294
|
+
onChange={setValue}
|
|
295
|
+
options={groupedOptions}
|
|
296
|
+
placeholder="Select an option"
|
|
297
|
+
/>
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
158
302
|
### Compact Mode
|
|
159
303
|
|
|
160
304
|
The Select component can be rendered in a compact size for denser UIs.
|
|
@@ -1142,45 +1286,5 @@ function CustomComponentExamples() {
|
|
|
1142
1286
|
|
|
1143
1287
|
| Prop | Type | Required | Default | Description |
|
|
1144
1288
|
| --- | --- | --- | --- | --- |
|
|
1145
|
-
| `onChange` | `(value: Type extends multi ? SelectOptionValue \| SelectOptionValue[] \| null : SelectOptionValue \| null) => void` | Yes | `-` | - |
|
|
1146
|
-
| `options` | `(SelectOption<SelectOptionValue> & Pick<SelectOptionProps<Type, string>, media \| end \| accessory> & { Component?: SelectOptionComponent<Type, SelectOptionValue> \| undefined; })[]` | Yes | `-` | Array of options to display in the select dropdown |
|
|
1147
|
-
| `value` | `string \| SelectOptionValue[] \| null` | Yes | `-` | - |
|
|
1148
|
-
| `SelectAllOptionComponent` | `SelectOptionComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render the Select All option |
|
|
1149
|
-
| `SelectControlComponent` | `SelectControlComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render the select control |
|
|
1150
|
-
| `SelectDropdownComponent` | `SelectDropdownComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render the dropdown container |
|
|
1151
|
-
| `SelectEmptyDropdownContentsComponent` | `SelectEmptyDropdownContentComponent` | No | `-` | Custom component to render when no options are available |
|
|
1152
|
-
| `SelectOptionComponent` | `SelectOptionComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render individual options |
|
|
1153
|
-
| `accessibilityRoles` | `{ dropdown?: AriaHasPopupType; option?: string \| undefined; } \| undefined` | No | `-` | Accessibility roles for dropdown and option elements |
|
|
1154
|
-
| `accessory` | `ReactElement<CellAccessoryProps, string \| JSXElementConstructor<any>>` | No | `-` | Accessory element rendered at the end of the cell (e.g., chevron). |
|
|
1155
|
-
| `className` | `string` | No | `-` | CSS class name for the root element |
|
|
1156
|
-
| `classNames` | `{ root?: string; control?: string \| undefined; controlStartNode?: string \| undefined; controlInputNode?: string \| undefined; controlValueNode?: string \| undefined; controlLabelNode?: string \| undefined; controlHelperTextNode?: string \| undefined; controlEndNode?: string \| undefined; dropdown?: string \| undefined; option?: string \| undefined; optionCell?: string \| undefined; optionContent?: string \| undefined; optionLabel?: string \| undefined; optionDescription?: string \| undefined; selectAllDivider?: string \| undefined; emptyContentsContainer?: string \| undefined; emptyContentsText?: string \| undefined; } \| undefined` | No | `-` | Custom class names for different parts of the select |
|
|
1157
|
-
| `clearAllLabel` | `string` | No | `-` | Label for the Clear All option in multi-select mode |
|
|
1158
|
-
| `compact` | `boolean` | No | `-` | Whether to use compact styling for the select |
|
|
1159
|
-
| `controlAccessibilityLabel` | `string` | No | `-` | Accessibility label for the control |
|
|
1160
|
-
| `defaultOpen` | `boolean` | No | `-` | Initial open state when component mounts (uncontrolled mode) |
|
|
1161
|
-
| `disableClickOutsideClose` | `boolean` | No | `-` | Whether clicking outside the dropdown should close it |
|
|
1162
|
-
| `disabled` | `boolean` | No | `false` | Toggles input interactability and opacity |
|
|
1163
|
-
| `emptyOptionsLabel` | `string` | No | `-` | Label displayed when there are no options available |
|
|
1164
|
-
| `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. |
|
|
1165
|
-
| `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 |
|
|
1166
|
-
| `helperText` | `null \| string \| number \| false \| true \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal` | No | `-` | Helper text displayed below the select |
|
|
1167
|
-
| `hiddenSelectedOptionsLabel` | `string` | No | `-` | Label to show for showcasing count of hidden selected options |
|
|
1168
|
-
| `hideSelectAll` | `boolean` | No | `-` | Whether to hide the Select All option in multi-select mode |
|
|
1169
|
-
| `label` | `null \| string \| number \| false \| true \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal` | No | `-` | Label displayed above the control |
|
|
1170
|
-
| `labelVariant` | `inside \| outside` | No | `'outside'` | The variant of the label. Only used when compact is not true. |
|
|
1171
|
-
| `maxSelectedOptionsToShow` | `number` | No | `-` | Maximum number of selected options to show before truncating |
|
|
1172
|
-
| `media` | `ReactElement` | No | `-` | Media rendered at the start of the cell (icon, avatar, image, etc). |
|
|
1173
|
-
| `open` | `boolean` | No | `-` | Controlled open state of the dropdown |
|
|
1174
|
-
| `placeholder` | `null \| string \| number \| false \| true \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal` | No | `-` | Placeholder text displayed when no option is selected |
|
|
1175
|
-
| `ref` | `null \| (instance: SelectRef \| null) => void \| RefObject<SelectRef>` | No | `-` | - |
|
|
1176
|
-
| `removeSelectedOptionAccessibilityLabel` | `string` | No | `-` | Accessibility label for each chip in a multi-select |
|
|
1177
|
-
| `selectAllLabel` | `string` | No | `-` | Label for the Select All option in multi-select mode |
|
|
1178
|
-
| `setOpen` | `((open: boolean \| ((open: boolean) => boolean)) => void)` | No | `-` | Callback to update the open state |
|
|
1179
|
-
| `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 |
|
|
1180
|
-
| `style` | `CSSProperties` | No | `-` | Inline styles for the root element |
|
|
1181
|
-
| `styles` | `{ root?: CSSProperties; control?: CSSProperties \| undefined; controlStartNode?: CSSProperties \| undefined; controlInputNode?: CSSProperties \| undefined; controlValueNode?: CSSProperties \| undefined; controlLabelNode?: CSSProperties \| undefined; controlHelperTextNode?: CSSProperties \| undefined; controlEndNode?: CSSProperties \| undefined; controlBlendStyles?: InteractableBlendStyles \| undefined; dropdown?: CSSProperties \| undefined; option?: CSSProperties \| undefined; optionCell?: CSSProperties \| undefined; optionContent?: CSSProperties \| undefined; optionLabel?: CSSProperties \| undefined; optionDescription?: CSSProperties \| undefined; optionBlendStyles?: InteractableBlendStyles \| undefined; selectAllDivider?: CSSProperties \| undefined; emptyContentsContainer?: CSSProperties \| undefined; emptyContentsText?: CSSProperties \| undefined; } \| undefined` | No | `-` | Custom styles for different parts of the select |
|
|
1182
|
-
| `testID` | `string` | No | `-` | Test ID for the root element |
|
|
1183
|
-
| `type` | `single \| multi` | No | `-` | Whether the select allows single or multiple selections |
|
|
1184
|
-
| `variant` | `primary \| secondary \| positive \| negative \| foregroundMuted \| foreground` | No | `foregroundMuted` | 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 |
|
|
1185
1289
|
|
|
1186
1290
|
|
|
@@ -37,7 +37,7 @@ function SelectChipExample() {
|
|
|
37
37
|
);
|
|
38
38
|
return (
|
|
39
39
|
<HStack>
|
|
40
|
-
<
|
|
40
|
+
<OldSelectChip value={value} onChange={setValue} content={content} minWidth={367} />
|
|
41
41
|
</HStack>
|
|
42
42
|
);
|
|
43
43
|
}
|
|
@@ -60,7 +60,7 @@ function SelectChipExample() {
|
|
|
60
60
|
);
|
|
61
61
|
return (
|
|
62
62
|
<HStack>
|
|
63
|
-
<
|
|
63
|
+
<OldSelectChip value={value} onChange={setValue} content={content} minWidth={150} />
|
|
64
64
|
</HStack>
|
|
65
65
|
);
|
|
66
66
|
}
|
|
@@ -107,7 +107,7 @@ function SelectChipExample() {
|
|
|
107
107
|
);
|
|
108
108
|
return (
|
|
109
109
|
<HStack>
|
|
110
|
-
<
|
|
110
|
+
<OldSelectChip
|
|
111
111
|
placeholder="Networks"
|
|
112
112
|
value={value ? value.value : undefined}
|
|
113
113
|
valueLabel={value ? value.title : undefined}
|
|
@@ -166,7 +166,7 @@ function SelectChipExample() {
|
|
|
166
166
|
);
|
|
167
167
|
return (
|
|
168
168
|
<HStack>
|
|
169
|
-
<
|
|
169
|
+
<OldSelectChip
|
|
170
170
|
value={value.value}
|
|
171
171
|
valueLabel={value.label}
|
|
172
172
|
end={<Icon size="s" color="fg" name={value.iconName} />}
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
# SelectChipAlpha
|
|
2
|
+
|
|
3
|
+
A chip-styled Select control built on top of the Alpha Select component. Supports both single and multi selection.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { SelectChip } from '@coinbase/cds-web/alpha/select-chip/SelectChip'
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Examples
|
|
12
|
+
|
|
13
|
+
SelectChip is built on top of the [Alpha Select](/components/inputs/SelectAlpha/) component. It provides a chip-styled interface while maintaining all the functionality of Select, including support for single and multi-selection, option groups, and custom components.
|
|
14
|
+
|
|
15
|
+
:::note Duplicate Values
|
|
16
|
+
Avoid using options with duplicate values. Each option's `value` should be unique within the options array to ensure proper selection behavior.
|
|
17
|
+
:::
|
|
18
|
+
|
|
19
|
+
### Basic usage
|
|
20
|
+
|
|
21
|
+
```jsx live
|
|
22
|
+
function ExampleDefault() {
|
|
23
|
+
const exampleOptions = [
|
|
24
|
+
{ value: null, label: 'Clear selection' },
|
|
25
|
+
{ value: '1', label: 'Option 1' },
|
|
26
|
+
{ value: '2', label: 'Option 2' },
|
|
27
|
+
{ value: '3', label: 'Option 3' },
|
|
28
|
+
{ value: '4', label: 'Option 4' },
|
|
29
|
+
];
|
|
30
|
+
const [value, setValue] = useState(null);
|
|
31
|
+
return (
|
|
32
|
+
<SelectChip
|
|
33
|
+
accessibilityLabel="Select a value"
|
|
34
|
+
onChange={setValue}
|
|
35
|
+
options={exampleOptions}
|
|
36
|
+
placeholder="Choose an option"
|
|
37
|
+
value={value}
|
|
38
|
+
/>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Single select with groups
|
|
44
|
+
|
|
45
|
+
```jsx live
|
|
46
|
+
function ExampleSingleGroups() {
|
|
47
|
+
const exampleOptions = [
|
|
48
|
+
{
|
|
49
|
+
label: 'Group A',
|
|
50
|
+
options: [
|
|
51
|
+
{ value: '1', label: 'Option 1' },
|
|
52
|
+
{ value: '2', label: 'Option 2' },
|
|
53
|
+
{ value: '3', label: 'Option 3' },
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
label: 'Group B',
|
|
58
|
+
options: [
|
|
59
|
+
{ value: '4', label: 'Option 4' },
|
|
60
|
+
{ value: '5', label: 'Option 5' },
|
|
61
|
+
],
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
label: 'Group C',
|
|
65
|
+
options: [{ value: '6', label: 'Option 6' }],
|
|
66
|
+
},
|
|
67
|
+
];
|
|
68
|
+
const [value, setValue] = useState(null);
|
|
69
|
+
return (
|
|
70
|
+
<SelectChip
|
|
71
|
+
accessibilityLabel="Select a value"
|
|
72
|
+
onChange={setValue}
|
|
73
|
+
options={exampleOptions}
|
|
74
|
+
placeholder="Choose an option"
|
|
75
|
+
value={value}
|
|
76
|
+
/>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### With disabled option group
|
|
82
|
+
|
|
83
|
+
```jsx live
|
|
84
|
+
function ExampleDisabledGroup() {
|
|
85
|
+
const exampleOptions = [
|
|
86
|
+
{
|
|
87
|
+
label: 'Group A',
|
|
88
|
+
options: [
|
|
89
|
+
{ value: '1', label: 'Option 1' },
|
|
90
|
+
{ value: '2', label: 'Option 2' },
|
|
91
|
+
{ value: '3', label: 'Option 3' },
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
label: 'Group B',
|
|
96
|
+
disabled: true,
|
|
97
|
+
options: [
|
|
98
|
+
{ value: '4', label: 'Option 4' },
|
|
99
|
+
{ value: '5', label: 'Option 5' },
|
|
100
|
+
],
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
label: 'Group C',
|
|
104
|
+
options: [{ value: '6', label: 'Option 6' }],
|
|
105
|
+
},
|
|
106
|
+
];
|
|
107
|
+
const [value, setValue] = useState(null);
|
|
108
|
+
return (
|
|
109
|
+
<SelectChip
|
|
110
|
+
accessibilityLabel="Select a value"
|
|
111
|
+
onChange={setValue}
|
|
112
|
+
options={exampleOptions}
|
|
113
|
+
placeholder="Choose an option"
|
|
114
|
+
value={value}
|
|
115
|
+
/>
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Multi-select
|
|
121
|
+
|
|
122
|
+
:::note Disabled Options and Select All
|
|
123
|
+
Disabled options and options inside disabled groups will be skipped when "Select all" is pressed. Only enabled options will be selected.
|
|
124
|
+
:::
|
|
125
|
+
|
|
126
|
+
```jsx live
|
|
127
|
+
function ExampleMulti() {
|
|
128
|
+
const exampleOptions = [
|
|
129
|
+
{ value: '1', label: 'Option 1' },
|
|
130
|
+
{ value: '2', label: 'Option 2', disabled: true },
|
|
131
|
+
{ value: '3', label: 'Option 3' },
|
|
132
|
+
{ value: '4', label: 'Option 4' },
|
|
133
|
+
{ value: '5', label: 'Option 5' },
|
|
134
|
+
];
|
|
135
|
+
const { value, onChange } = useMultiSelect({ initialValue: [] });
|
|
136
|
+
return (
|
|
137
|
+
<SelectChip
|
|
138
|
+
controlAccessibilityLabel="Select multiple values"
|
|
139
|
+
onChange={onChange}
|
|
140
|
+
options={exampleOptions}
|
|
141
|
+
placeholder="Choose options"
|
|
142
|
+
type="multi"
|
|
143
|
+
value={value}
|
|
144
|
+
/>
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Multi-select with groups
|
|
150
|
+
|
|
151
|
+
```jsx live
|
|
152
|
+
function ExampleMultiGroups() {
|
|
153
|
+
const exampleOptions = [
|
|
154
|
+
{
|
|
155
|
+
label: 'Group A',
|
|
156
|
+
options: [
|
|
157
|
+
{ value: '1', label: 'Option 1' },
|
|
158
|
+
{ value: '2', label: 'Option 2' },
|
|
159
|
+
{ value: '3', label: 'Option 3' },
|
|
160
|
+
],
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
label: 'Group B',
|
|
164
|
+
options: [
|
|
165
|
+
{ value: '4', label: 'Option 4' },
|
|
166
|
+
{ value: '5', label: 'Option 5' },
|
|
167
|
+
],
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
label: 'Group C',
|
|
171
|
+
options: [{ value: '6', label: 'Option 6' }],
|
|
172
|
+
},
|
|
173
|
+
];
|
|
174
|
+
const { value, onChange } = useMultiSelect({ initialValue: [] });
|
|
175
|
+
return (
|
|
176
|
+
<SelectChip
|
|
177
|
+
controlAccessibilityLabel="Select multiple values"
|
|
178
|
+
onChange={onChange}
|
|
179
|
+
options={exampleOptions}
|
|
180
|
+
placeholder="Choose options"
|
|
181
|
+
type="multi"
|
|
182
|
+
value={value}
|
|
183
|
+
/>
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Compact
|
|
189
|
+
|
|
190
|
+
```jsx live
|
|
191
|
+
function ExampleCompact() {
|
|
192
|
+
const exampleOptions = [
|
|
193
|
+
{ value: '1', label: 'Option 1' },
|
|
194
|
+
{ value: '2', label: 'Option 2' },
|
|
195
|
+
{ value: '3', label: 'Option 3' },
|
|
196
|
+
{ value: '4', label: 'Option 4' },
|
|
197
|
+
];
|
|
198
|
+
const [value, setValue] = useState('1');
|
|
199
|
+
return (
|
|
200
|
+
<SelectChip
|
|
201
|
+
compact
|
|
202
|
+
onChange={setValue}
|
|
203
|
+
options={exampleOptions}
|
|
204
|
+
placeholder="Choose an option"
|
|
205
|
+
value={value}
|
|
206
|
+
/>
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### With start and end nodes
|
|
212
|
+
|
|
213
|
+
```jsx live
|
|
214
|
+
function ExampleWithNodes() {
|
|
215
|
+
const exampleOptions = [
|
|
216
|
+
{ value: 'btc', label: assets.btc.name },
|
|
217
|
+
{ value: 'eth', label: assets.eth.name },
|
|
218
|
+
{ value: 'dai', label: assets.dai.name },
|
|
219
|
+
];
|
|
220
|
+
const [value, setValue] = useState('eth');
|
|
221
|
+
const getStartNode = (selectedValue) => {
|
|
222
|
+
if (!selectedValue) return null;
|
|
223
|
+
const assetMap = {
|
|
224
|
+
btc: assets.btc.imageUrl,
|
|
225
|
+
eth: assets.eth.imageUrl,
|
|
226
|
+
dai: assets.dai.imageUrl,
|
|
227
|
+
};
|
|
228
|
+
const imageUrl = assetMap[selectedValue];
|
|
229
|
+
if (!imageUrl) return null;
|
|
230
|
+
return <RemoteImage height={24} shape="circle" source={imageUrl} width={24} />;
|
|
231
|
+
};
|
|
232
|
+
return (
|
|
233
|
+
<SelectChip
|
|
234
|
+
onChange={setValue}
|
|
235
|
+
options={exampleOptions}
|
|
236
|
+
placeholder="Choose an asset"
|
|
237
|
+
startNode={getStartNode(value)}
|
|
238
|
+
value={value}
|
|
239
|
+
/>
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Empty options
|
|
245
|
+
|
|
246
|
+
```jsx live
|
|
247
|
+
function ExampleEmptyOptions() {
|
|
248
|
+
const [value, setValue] = useState(null);
|
|
249
|
+
return <SelectChip onChange={setValue} options={[]} placeholder="Select ..." value={value} />;
|
|
250
|
+
}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Options with descriptions
|
|
254
|
+
|
|
255
|
+
```jsx live
|
|
256
|
+
function ExampleDescriptions() {
|
|
257
|
+
const exampleOptions = [
|
|
258
|
+
{ value: '1', label: 'Option 1', description: 'First option description' },
|
|
259
|
+
{ value: '2', label: 'Option 2', description: 'Second option description' },
|
|
260
|
+
{ value: '3', label: 'Option 3', description: 'Third option description' },
|
|
261
|
+
{ value: '4', label: 'Option 4', description: 'Fourth option description' },
|
|
262
|
+
];
|
|
263
|
+
const [value, setValue] = useState(null);
|
|
264
|
+
return (
|
|
265
|
+
<SelectChip
|
|
266
|
+
accessibilityLabel="Select a value"
|
|
267
|
+
onChange={setValue}
|
|
268
|
+
options={exampleOptions}
|
|
269
|
+
placeholder="Choose an option"
|
|
270
|
+
value={value}
|
|
271
|
+
/>
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Disabled
|
|
277
|
+
|
|
278
|
+
```jsx live
|
|
279
|
+
function ExampleDisabled() {
|
|
280
|
+
const exampleOptions = [
|
|
281
|
+
{ value: '1', label: 'Option 1' },
|
|
282
|
+
{ value: '2', label: 'Option 2' },
|
|
283
|
+
{ value: '3', label: 'Option 3' },
|
|
284
|
+
{ value: '4', label: 'Option 4' },
|
|
285
|
+
];
|
|
286
|
+
const [value, setValue] = useState('1');
|
|
287
|
+
return (
|
|
288
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
|
|
289
|
+
<SelectChip
|
|
290
|
+
disabled
|
|
291
|
+
accessibilityLabel="Select a value"
|
|
292
|
+
onChange={setValue}
|
|
293
|
+
options={exampleOptions}
|
|
294
|
+
placeholder="Choose an option"
|
|
295
|
+
value={null}
|
|
296
|
+
/>
|
|
297
|
+
<SelectChip
|
|
298
|
+
disabled
|
|
299
|
+
accessibilityLabel="Select a value"
|
|
300
|
+
onChange={setValue}
|
|
301
|
+
options={exampleOptions}
|
|
302
|
+
placeholder="Choose an option"
|
|
303
|
+
value={value}
|
|
304
|
+
/>
|
|
305
|
+
</div>
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
## Props
|
|
311
|
+
|
|
312
|
+
| Prop | Type | Required | Default | Description |
|
|
313
|
+
| --- | --- | --- | --- | --- |
|
|
314
|
+
| `onChange` | `(value: Type extends multi ? SelectOptionValue \| SelectOptionValue[] \| null : SelectOptionValue \| null) => void` | Yes | `-` | - |
|
|
315
|
+
| `options` | `SelectOptionList<Type, SelectOptionValue>` | Yes | `-` | Array of options to display in the select dropdown. Can be individual options or groups with label and options |
|
|
316
|
+
| `value` | `string \| SelectOptionValue[] \| null` | Yes | `-` | - |
|
|
317
|
+
| `SelectAllOptionComponent` | `SelectOptionComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render the Select All option |
|
|
318
|
+
| `SelectDropdownComponent` | `SelectDropdownComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render the dropdown container |
|
|
319
|
+
| `SelectEmptyDropdownContentsComponent` | `SelectEmptyDropdownContentComponent` | No | `-` | Custom component to render when no options are available |
|
|
320
|
+
| `SelectOptionComponent` | `SelectOptionComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render individual options |
|
|
321
|
+
| `SelectOptionGroupComponent` | `SelectOptionGroupComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render group headers |
|
|
322
|
+
| `accessibilityRoles` | `{ dropdown?: AriaHasPopupType; option?: string \| undefined; } \| undefined` | No | `-` | Accessibility roles for dropdown and option elements |
|
|
323
|
+
| `accessory` | `ReactElement<CellAccessoryProps, string \| JSXElementConstructor<any>>` | No | `-` | Accessory element rendered at the end of the cell (e.g., chevron). |
|
|
324
|
+
| `className` | `string` | No | `-` | CSS class name for the root element |
|
|
325
|
+
| `classNames` | `{ root?: string; control?: string \| undefined; controlStartNode?: string \| undefined; controlInputNode?: string \| undefined; controlValueNode?: string \| undefined; controlLabelNode?: string \| undefined; controlHelperTextNode?: string \| undefined; controlEndNode?: string \| undefined; dropdown?: string \| undefined; option?: string \| undefined; optionCell?: string \| undefined; optionContent?: string \| undefined; optionLabel?: string \| undefined; optionDescription?: string \| undefined; selectAllDivider?: string \| undefined; emptyContentsContainer?: string \| undefined; emptyContentsText?: string \| undefined; optionGroup?: string \| undefined; } \| undefined` | No | `-` | Custom class names for different parts of the select |
|
|
326
|
+
| `clearAllLabel` | `string` | No | `-` | Label for the Clear All option in multi-select mode |
|
|
327
|
+
| `compact` | `boolean` | No | `-` | Whether to use compact styling for the select |
|
|
328
|
+
| `controlAccessibilityLabel` | `string` | No | `-` | Accessibility label for the control |
|
|
329
|
+
| `defaultOpen` | `boolean` | No | `-` | Initial open state when component mounts (uncontrolled mode) |
|
|
330
|
+
| `disableClickOutsideClose` | `boolean` | No | `-` | Whether clicking outside the dropdown should close it |
|
|
331
|
+
| `disabled` | `boolean` | No | `false` | Toggles input interactability and opacity |
|
|
332
|
+
| `emptyOptionsLabel` | `string` | No | `-` | Label displayed when there are no options available |
|
|
333
|
+
| `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. |
|
|
334
|
+
| `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 |
|
|
335
|
+
| `hiddenSelectedOptionsLabel` | `string` | No | `-` | Label to show for showcasing count of hidden selected options |
|
|
336
|
+
| `hideSelectAll` | `boolean` | No | `-` | Whether to hide the Select All option in multi-select mode |
|
|
337
|
+
| `invertColorScheme` | `boolean` | No | `false` | Invert the foreground and background colors to emphasize the Chip. Depending on your theme, it may be dangerous to use this prop in conjunction with transparentWhileInactive. |
|
|
338
|
+
| `label` | `null \| string \| number \| false \| true \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal` | No | `-` | Label displayed above the control |
|
|
339
|
+
| `maxSelectedOptionsToShow` | `number` | No | `-` | Maximum number of selected options to show before truncating |
|
|
340
|
+
| `media` | `ReactElement` | No | `-` | Media rendered at the start of the cell (icon, avatar, image, etc). |
|
|
341
|
+
| `numberOfLines` | `number` | No | `1` | How many lines the text in the chip will be broken into. |
|
|
342
|
+
| `open` | `boolean` | No | `-` | Controlled open state of the dropdown |
|
|
343
|
+
| `placeholder` | `null \| string \| number \| false \| true \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal` | No | `-` | Placeholder text displayed when no option is selected |
|
|
344
|
+
| `ref` | `null \| (instance: SelectRef \| null) => void \| RefObject<SelectRef>` | No | `-` | - |
|
|
345
|
+
| `removeSelectedOptionAccessibilityLabel` | `string` | No | `-` | Accessibility label for each chip in a multi-select |
|
|
346
|
+
| `selectAllLabel` | `string` | No | `-` | Label for the Select All option in multi-select mode |
|
|
347
|
+
| `setOpen` | `((open: boolean \| ((open: boolean) => boolean)) => void)` | No | `-` | Callback to update the open state |
|
|
348
|
+
| `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 |
|
|
349
|
+
| `style` | `CSSProperties` | No | `-` | Inline styles for the root element |
|
|
350
|
+
| `styles` | `{ root?: CSSProperties; control?: CSSProperties \| undefined; controlStartNode?: CSSProperties \| undefined; controlInputNode?: CSSProperties \| undefined; controlValueNode?: CSSProperties \| undefined; controlLabelNode?: CSSProperties \| undefined; controlHelperTextNode?: CSSProperties \| undefined; controlEndNode?: CSSProperties \| undefined; controlBlendStyles?: InteractableBlendStyles \| undefined; dropdown?: CSSProperties \| undefined; option?: CSSProperties \| undefined; optionCell?: CSSProperties \| undefined; optionContent?: CSSProperties \| undefined; optionLabel?: CSSProperties \| undefined; optionDescription?: CSSProperties \| undefined; optionBlendStyles?: InteractableBlendStyles \| undefined; selectAllDivider?: CSSProperties \| undefined; emptyContentsContainer?: CSSProperties \| undefined; emptyContentsText?: CSSProperties \| undefined; optionGroup?: CSSProperties \| undefined; } \| undefined` | No | `-` | Custom styles for different parts of the select |
|
|
351
|
+
| `testID` | `string` | No | `-` | Test ID for the root element |
|
|
352
|
+
| `type` | `single \| multi` | No | `-` | Whether the select allows single or multiple selections |
|
|
353
|
+
|
|
354
|
+
|
package/mcp-docs/web/routes.txt
CHANGED
|
@@ -89,6 +89,7 @@
|
|
|
89
89
|
- [TextInput](web/components/TextInput.txt): A control for entering text.
|
|
90
90
|
- [Switch](web/components/Switch.txt): A control for toggling between on and off.
|
|
91
91
|
- [SelectOption](web/components/SelectOption.txt): A single option of a Select component.
|
|
92
|
+
- [SelectChipAlpha](web/components/SelectChipAlpha.txt): A chip-styled Select control built on top of the Alpha Select component. Supports both single and multi selection.
|
|
92
93
|
- [SelectChip](web/components/SelectChip.txt): A Chip and Select control for selecting from a list of options.
|
|
93
94
|
- [SelectAlpha](web/components/SelectAlpha.txt): A flexible select component for both single and multi-selection, built for web applications with comprehensive accessibility support.
|
|
94
95
|
- [Select](web/components/Select.txt): A Dropdown control for selecting from a list of options.
|