@coinbase/cds-mcp-server 8.19.1 → 8.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/mcp-docs/mobile/components/AvatarButton.txt +1 -1
- package/mcp-docs/mobile/components/Button.txt +1 -1
- package/mcp-docs/mobile/components/CheckboxCell.txt +1 -1
- package/mcp-docs/mobile/components/Chip.txt +2 -1
- package/mcp-docs/mobile/components/ContentCell.txt +1 -0
- package/mcp-docs/mobile/components/IconButton.txt +1 -1
- package/mcp-docs/mobile/components/InputChip.txt +7 -3
- package/mcp-docs/mobile/components/Interactable.txt +1 -1
- package/mcp-docs/mobile/components/ListCell.txt +1 -0
- package/mcp-docs/mobile/components/MediaChip.txt +2 -1
- package/mcp-docs/mobile/components/Pressable.txt +1 -1
- package/mcp-docs/mobile/components/RadioCell.txt +1 -1
- package/mcp-docs/mobile/components/Select.txt +12 -12
- package/mcp-docs/mobile/components/SelectAlpha.txt +1211 -0
- package/mcp-docs/mobile/components/SelectChip.txt +2 -1
- package/mcp-docs/mobile/components/SelectOption.txt +3 -2
- package/mcp-docs/mobile/components/SlideButton.txt +1 -1
- package/mcp-docs/mobile/routes.txt +1 -0
- package/mcp-docs/web/components/AvatarButton.txt +1 -1
- package/mcp-docs/web/components/Button.txt +1 -1
- package/mcp-docs/web/components/CheckboxCell.txt +1 -1
- package/mcp-docs/web/components/Chip.txt +2 -2
- package/mcp-docs/web/components/IconButton.txt +1 -1
- package/mcp-docs/web/components/InputChip.txt +7 -2
- package/mcp-docs/web/components/Interactable.txt +1 -1
- package/mcp-docs/web/components/Link.txt +1 -1
- package/mcp-docs/web/components/MediaChip.txt +2 -2
- package/mcp-docs/web/components/Pressable.txt +1 -1
- package/mcp-docs/web/components/RadioCell.txt +1 -1
- package/mcp-docs/web/components/Select.txt +16 -16
- package/mcp-docs/web/components/SelectAlpha.txt +1115 -0
- package/mcp-docs/web/components/SelectChip.txt +3 -2
- package/mcp-docs/web/components/SelectOption.txt +2 -2
- package/mcp-docs/web/components/SidebarItem.txt +1 -1
- package/mcp-docs/web/components/TileButton.txt +1 -1
- package/mcp-docs/web/routes.txt +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,1115 @@
|
|
|
1
|
+
# SelectAlpha
|
|
2
|
+
|
|
3
|
+
A flexible select component for both single and multi-selection, built for web applications with comprehensive accessibility support.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { Select } from '@coinbase/cds-web/alpha/select'
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Examples
|
|
12
|
+
|
|
13
|
+
### Single Select
|
|
14
|
+
|
|
15
|
+
Basic single selection with predefined options.
|
|
16
|
+
|
|
17
|
+
```jsx live
|
|
18
|
+
function SingleSelectExample() {
|
|
19
|
+
const [value, setValue] = useState('1');
|
|
20
|
+
|
|
21
|
+
const options = [
|
|
22
|
+
{ value: '1', label: 'Option 1' },
|
|
23
|
+
{ value: '2', label: 'Option 2' },
|
|
24
|
+
{ value: '3', label: 'Option 3' },
|
|
25
|
+
{ value: '4', label: 'Option 4' },
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<Select
|
|
30
|
+
label="Choose an option"
|
|
31
|
+
value={value}
|
|
32
|
+
onChange={setValue}
|
|
33
|
+
options={options}
|
|
34
|
+
placeholder="Select an option"
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Multi-Select
|
|
41
|
+
|
|
42
|
+
Multi-selection mode allows users to select multiple options from the list.
|
|
43
|
+
|
|
44
|
+
```jsx live
|
|
45
|
+
function MultiSelectExample() {
|
|
46
|
+
const { value, onChange } = useMultiSelect({
|
|
47
|
+
initialValue: ['1', '3', '7', '8', '9', '10'],
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const options = [
|
|
51
|
+
{ value: '1', label: 'Option 1' },
|
|
52
|
+
{ value: '2', label: 'Option 2' },
|
|
53
|
+
{ value: '3', label: 'Option 3' },
|
|
54
|
+
{ value: '4', label: 'Option 4' },
|
|
55
|
+
{ value: '5', label: 'Option 5' },
|
|
56
|
+
{ value: '6', label: 'Option 6' },
|
|
57
|
+
{ value: '7', label: 'Option 7' },
|
|
58
|
+
{ value: '8', label: 'Option 8' },
|
|
59
|
+
{ value: '9', label: 'Option 9' },
|
|
60
|
+
{ value: '10', label: 'Option 10' },
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<Select
|
|
65
|
+
type="multi"
|
|
66
|
+
label="Choose multiple options"
|
|
67
|
+
value={value}
|
|
68
|
+
onChange={onChange}
|
|
69
|
+
options={options}
|
|
70
|
+
placeholder="Select options"
|
|
71
|
+
selectAllLabel="Select all options"
|
|
72
|
+
clearAllLabel="Clear all selections"
|
|
73
|
+
maxSelectedOptionsToShow={4}
|
|
74
|
+
/>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Accessibility Props
|
|
80
|
+
|
|
81
|
+
The Select component supports comprehensive accessibility features including custom labels and roles.
|
|
82
|
+
|
|
83
|
+
```jsx live
|
|
84
|
+
function AccessibilityExample() {
|
|
85
|
+
const [value, setValue] = useState('2');
|
|
86
|
+
|
|
87
|
+
const options = [
|
|
88
|
+
{ value: '1', label: 'High Priority' },
|
|
89
|
+
{ value: '2', label: 'Medium Priority' },
|
|
90
|
+
{ value: '3', label: 'Low Priority' },
|
|
91
|
+
];
|
|
92
|
+
|
|
93
|
+
return (
|
|
94
|
+
<Select
|
|
95
|
+
label="Task Priority"
|
|
96
|
+
value={value}
|
|
97
|
+
onChange={setValue}
|
|
98
|
+
options={options}
|
|
99
|
+
accessibilityLabel="Select task priority level"
|
|
100
|
+
accessibilityRoles={{
|
|
101
|
+
dropdown: 'listbox',
|
|
102
|
+
option: 'option',
|
|
103
|
+
}}
|
|
104
|
+
placeholder="Choose priority level"
|
|
105
|
+
helperText="Select the appropriate priority for this task"
|
|
106
|
+
/>
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Variant Props
|
|
112
|
+
|
|
113
|
+
The Select component supports different visual variants for various states and contexts.
|
|
114
|
+
|
|
115
|
+
```jsx live
|
|
116
|
+
function VariantExample() {
|
|
117
|
+
const [positiveValue, setPositiveValue] = useState('success');
|
|
118
|
+
const [negativeValue, setNegativeValue] = useState('');
|
|
119
|
+
|
|
120
|
+
const positiveOptions = [
|
|
121
|
+
{ value: 'success', label: 'Success' },
|
|
122
|
+
{ value: 'completed', label: 'Completed' },
|
|
123
|
+
{ value: 'approved', label: 'Approved' },
|
|
124
|
+
];
|
|
125
|
+
|
|
126
|
+
const negativeOptions = [
|
|
127
|
+
{ value: 'error', label: 'Error' },
|
|
128
|
+
{ value: 'failed', label: 'Failed' },
|
|
129
|
+
{ value: 'rejected', label: 'Rejected' },
|
|
130
|
+
];
|
|
131
|
+
|
|
132
|
+
return (
|
|
133
|
+
<VStack gap={4}>
|
|
134
|
+
<Select
|
|
135
|
+
label="Positive Status"
|
|
136
|
+
value={positiveValue}
|
|
137
|
+
onChange={setPositiveValue}
|
|
138
|
+
options={positiveOptions}
|
|
139
|
+
variant="positive"
|
|
140
|
+
helperText="This shows a positive state"
|
|
141
|
+
placeholder="Select positive status"
|
|
142
|
+
/>
|
|
143
|
+
|
|
144
|
+
<Select
|
|
145
|
+
label="Negative Status"
|
|
146
|
+
value={negativeValue}
|
|
147
|
+
onChange={setNegativeValue}
|
|
148
|
+
options={negativeOptions}
|
|
149
|
+
variant="negative"
|
|
150
|
+
helperText="This shows an error state"
|
|
151
|
+
placeholder="Select negative status"
|
|
152
|
+
/>
|
|
153
|
+
</VStack>
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Compact Mode
|
|
159
|
+
|
|
160
|
+
The Select component can be rendered in a compact size for denser UIs.
|
|
161
|
+
|
|
162
|
+
```jsx live
|
|
163
|
+
function CompactExample() {
|
|
164
|
+
const [value, setValue] = useState('1');
|
|
165
|
+
|
|
166
|
+
const options = [
|
|
167
|
+
{ value: '1', label: 'Small Option 1' },
|
|
168
|
+
{ value: '2', label: 'Small Option 2' },
|
|
169
|
+
{ value: '3', label: 'Small Option 3' },
|
|
170
|
+
];
|
|
171
|
+
|
|
172
|
+
return (
|
|
173
|
+
<Select
|
|
174
|
+
compact
|
|
175
|
+
label="Compact Select"
|
|
176
|
+
value={value}
|
|
177
|
+
onChange={setValue}
|
|
178
|
+
options={options}
|
|
179
|
+
placeholder="Select an option"
|
|
180
|
+
helperText="This is a compact select component"
|
|
181
|
+
/>
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Disabled States
|
|
187
|
+
|
|
188
|
+
Components can be disabled entirely or have individual options disabled.
|
|
189
|
+
|
|
190
|
+
```jsx live
|
|
191
|
+
function DisabledExample() {
|
|
192
|
+
const [value1, setValue1] = useState('2');
|
|
193
|
+
const [value2, setValue2] = useState('2');
|
|
194
|
+
|
|
195
|
+
const optionsWithDisabled = [
|
|
196
|
+
{ value: '1', label: 'Option 1', disabled: true },
|
|
197
|
+
{ value: '2', label: 'Option 2' },
|
|
198
|
+
{ value: '3', label: 'Option 3' },
|
|
199
|
+
{ value: '4', label: 'Option 4', disabled: true },
|
|
200
|
+
];
|
|
201
|
+
|
|
202
|
+
return (
|
|
203
|
+
<VStack gap={4}>
|
|
204
|
+
<Select
|
|
205
|
+
label="Disabled Select"
|
|
206
|
+
value={value1}
|
|
207
|
+
onChange={setValue1}
|
|
208
|
+
options={optionsWithDisabled}
|
|
209
|
+
disabled
|
|
210
|
+
placeholder="This select is disabled"
|
|
211
|
+
/>
|
|
212
|
+
|
|
213
|
+
<Select
|
|
214
|
+
label="Select with Disabled Options"
|
|
215
|
+
value={value2}
|
|
216
|
+
onChange={setValue2}
|
|
217
|
+
options={optionsWithDisabled}
|
|
218
|
+
placeholder="Some options are disabled"
|
|
219
|
+
/>
|
|
220
|
+
</VStack>
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Options with Descriptions
|
|
226
|
+
|
|
227
|
+
Options can include descriptions for additional context.
|
|
228
|
+
|
|
229
|
+
```jsx live
|
|
230
|
+
function DescriptionExample() {
|
|
231
|
+
const [value, setValue] = useState('1');
|
|
232
|
+
|
|
233
|
+
const optionsWithDescriptions = [
|
|
234
|
+
{ value: '1', label: 'Bitcoin', description: 'The first cryptocurrency' },
|
|
235
|
+
{ value: '2', label: 'Ethereum', description: 'Smart contract platform' },
|
|
236
|
+
{ value: '3', label: 'USDC', description: 'USD-backed stablecoin' },
|
|
237
|
+
{ value: '4', label: 'Solana', description: 'High-performance blockchain' },
|
|
238
|
+
];
|
|
239
|
+
|
|
240
|
+
return (
|
|
241
|
+
<Select
|
|
242
|
+
label="Select Cryptocurrency"
|
|
243
|
+
value={value}
|
|
244
|
+
onChange={setValue}
|
|
245
|
+
options={optionsWithDescriptions}
|
|
246
|
+
placeholder="Choose a cryptocurrency"
|
|
247
|
+
/>
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Start Node
|
|
253
|
+
|
|
254
|
+
Add an icon or element at the start of the select control.
|
|
255
|
+
|
|
256
|
+
```jsx live
|
|
257
|
+
function StartNodeExample() {
|
|
258
|
+
const [value, setValue] = useState('1');
|
|
259
|
+
|
|
260
|
+
const options = [
|
|
261
|
+
{ value: '1', label: 'Search Result 1' },
|
|
262
|
+
{ value: '2', label: 'Search Result 2' },
|
|
263
|
+
{ value: '3', label: 'Search Result 3' },
|
|
264
|
+
];
|
|
265
|
+
|
|
266
|
+
return (
|
|
267
|
+
<Select
|
|
268
|
+
label="Search"
|
|
269
|
+
value={value}
|
|
270
|
+
onChange={setValue}
|
|
271
|
+
options={options}
|
|
272
|
+
startNode={<Icon color="fg" name="search" />}
|
|
273
|
+
placeholder="Search for options"
|
|
274
|
+
/>
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### End Node
|
|
280
|
+
|
|
281
|
+
Add an icon or element at the end of the select control.
|
|
282
|
+
|
|
283
|
+
```jsx live
|
|
284
|
+
function EndNodeExample() {
|
|
285
|
+
const [value, setValue] = useState('1');
|
|
286
|
+
|
|
287
|
+
const options = [
|
|
288
|
+
{ value: '1', label: 'Search Result 1' },
|
|
289
|
+
{ value: '2', label: 'Search Result 2' },
|
|
290
|
+
{ value: '3', label: 'Search Result 3' },
|
|
291
|
+
];
|
|
292
|
+
|
|
293
|
+
return (
|
|
294
|
+
<Select
|
|
295
|
+
endNode={<Icon alignItems="center" color="fg" name="search" />}
|
|
296
|
+
label="Single select - end node"
|
|
297
|
+
onChange={setValue}
|
|
298
|
+
options={options}
|
|
299
|
+
placeholder="Empty value"
|
|
300
|
+
value={value}
|
|
301
|
+
/>
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### Custom Icons
|
|
307
|
+
|
|
308
|
+
Add custom icons as accessories or media to options.
|
|
309
|
+
|
|
310
|
+
```jsx live
|
|
311
|
+
function CustomIconsExample() {
|
|
312
|
+
const [value, setValue] = useState('1');
|
|
313
|
+
|
|
314
|
+
const optionsWithIcons = [
|
|
315
|
+
{
|
|
316
|
+
value: '1',
|
|
317
|
+
label: 'Favorites',
|
|
318
|
+
accessory: <Icon color="fg" name="star" />,
|
|
319
|
+
media: <Icon color="fg" name="heart" />,
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
value: '2',
|
|
323
|
+
label: 'Verified',
|
|
324
|
+
accessory: <Icon color="fg" name="checkmark" />,
|
|
325
|
+
media: <Icon color="fg" name="shield" />,
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
value: '3',
|
|
329
|
+
label: 'Settings',
|
|
330
|
+
accessory: <Icon color="fg" name="caretRight" />,
|
|
331
|
+
media: <Icon color="fg" name="gear" />,
|
|
332
|
+
},
|
|
333
|
+
];
|
|
334
|
+
|
|
335
|
+
return (
|
|
336
|
+
<Select
|
|
337
|
+
label="Choose Action"
|
|
338
|
+
value={value}
|
|
339
|
+
onChange={setValue}
|
|
340
|
+
options={optionsWithIcons}
|
|
341
|
+
placeholder="Select an action"
|
|
342
|
+
/>
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### Empty State
|
|
348
|
+
|
|
349
|
+
Handle empty option lists with custom messages or components.
|
|
350
|
+
|
|
351
|
+
```jsx live
|
|
352
|
+
function EmptyStateExample() {
|
|
353
|
+
const [searchTerm, setSearchTerm] = useState('');
|
|
354
|
+
const [value, setValue] = useState(null);
|
|
355
|
+
|
|
356
|
+
const allOptions = [];
|
|
357
|
+
|
|
358
|
+
const filteredOptions = searchTerm
|
|
359
|
+
? allOptions.filter((opt) => opt.label.toLowerCase().includes(searchTerm.toLowerCase()))
|
|
360
|
+
: allOptions;
|
|
361
|
+
|
|
362
|
+
return (
|
|
363
|
+
<Select
|
|
364
|
+
label="Filtered Select"
|
|
365
|
+
value={value}
|
|
366
|
+
onChange={setValue}
|
|
367
|
+
options={filteredOptions}
|
|
368
|
+
emptyOptionsLabel="No matching options found"
|
|
369
|
+
placeholder="Select an option"
|
|
370
|
+
/>
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
### Controlled Open State
|
|
376
|
+
|
|
377
|
+
Control the open/closed state of the dropdown programmatically.
|
|
378
|
+
|
|
379
|
+
```jsx live
|
|
380
|
+
function ControlledOpenExample() {
|
|
381
|
+
const [value, setValue] = useState('1');
|
|
382
|
+
const [open, setOpen] = useState(false);
|
|
383
|
+
|
|
384
|
+
const options = [
|
|
385
|
+
{ value: '1', label: 'Option 1' },
|
|
386
|
+
{ value: '2', label: 'Option 2' },
|
|
387
|
+
{ value: '3', label: 'Option 3' },
|
|
388
|
+
];
|
|
389
|
+
|
|
390
|
+
return (
|
|
391
|
+
<VStack gap={4}>
|
|
392
|
+
<Button onClick={() => setOpen(!open)}>{open ? 'Close Dropdown' : 'Open Dropdown'}</Button>
|
|
393
|
+
|
|
394
|
+
<Select
|
|
395
|
+
label="Controlled Select"
|
|
396
|
+
value={value}
|
|
397
|
+
onChange={setValue}
|
|
398
|
+
options={options}
|
|
399
|
+
open={open}
|
|
400
|
+
setOpen={setOpen}
|
|
401
|
+
placeholder="Select an option"
|
|
402
|
+
disableClickOutsideClose
|
|
403
|
+
/>
|
|
404
|
+
</VStack>
|
|
405
|
+
);
|
|
406
|
+
}
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
### Multi-Select with Max Display
|
|
410
|
+
|
|
411
|
+
Limit the number of selected items shown when using multi-select.
|
|
412
|
+
|
|
413
|
+
```jsx live
|
|
414
|
+
function MaxDisplayExample() {
|
|
415
|
+
const { value, onChange } = useMultiSelect({
|
|
416
|
+
initialValue: ['1', '2', '3', '4', '5'],
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
const options = Array.from({ length: 20 }, (_, i) => ({
|
|
420
|
+
value: (i + 1).toString(),
|
|
421
|
+
label: `Option ${i + 1}`,
|
|
422
|
+
}));
|
|
423
|
+
|
|
424
|
+
return (
|
|
425
|
+
<Select
|
|
426
|
+
type="multi"
|
|
427
|
+
label="Select Multiple Items"
|
|
428
|
+
value={value}
|
|
429
|
+
onChange={onChange}
|
|
430
|
+
options={options}
|
|
431
|
+
maxSelectedOptionsToShow={3}
|
|
432
|
+
placeholder="Select options"
|
|
433
|
+
helperText="Only showing first 3 selected items"
|
|
434
|
+
/>
|
|
435
|
+
);
|
|
436
|
+
}
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
### Custom Select All labels
|
|
440
|
+
|
|
441
|
+
Customize the select all functionality in multi-select mode.
|
|
442
|
+
|
|
443
|
+
```jsx live
|
|
444
|
+
function CustomSelectAllExample() {
|
|
445
|
+
const { value, onChange } = useMultiSelect({
|
|
446
|
+
initialValue: ['1'],
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
const options = [
|
|
450
|
+
{ value: '1', label: 'Monday' },
|
|
451
|
+
{ value: '2', label: 'Tuesday' },
|
|
452
|
+
{ value: '3', label: 'Wednesday' },
|
|
453
|
+
{ value: '4', label: 'Thursday' },
|
|
454
|
+
{ value: '5', label: 'Friday' },
|
|
455
|
+
{ value: '6', label: 'Saturday' },
|
|
456
|
+
{ value: '7', label: 'Sunday' },
|
|
457
|
+
];
|
|
458
|
+
|
|
459
|
+
return (
|
|
460
|
+
<Select
|
|
461
|
+
type="multi"
|
|
462
|
+
label="Select Days"
|
|
463
|
+
value={value}
|
|
464
|
+
onChange={onChange}
|
|
465
|
+
options={options}
|
|
466
|
+
selectAllLabel="Select all days of the week"
|
|
467
|
+
clearAllLabel="Clear all days"
|
|
468
|
+
placeholder="Choose days"
|
|
469
|
+
/>
|
|
470
|
+
);
|
|
471
|
+
}
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
### Label Variants
|
|
475
|
+
|
|
476
|
+
Different label positioning options for the Select component.
|
|
477
|
+
|
|
478
|
+
```jsx live
|
|
479
|
+
function LabelVariantExample() {
|
|
480
|
+
const [value1, setValue1] = useState('');
|
|
481
|
+
const [value2, setValue2] = useState('');
|
|
482
|
+
|
|
483
|
+
const options = [
|
|
484
|
+
{ value: '1', label: 'Option 1' },
|
|
485
|
+
{ value: '2', label: 'Option 2' },
|
|
486
|
+
{ value: '3', label: 'Option 3' },
|
|
487
|
+
];
|
|
488
|
+
|
|
489
|
+
return (
|
|
490
|
+
<VStack gap={4}>
|
|
491
|
+
<Select
|
|
492
|
+
label="Default Label Position"
|
|
493
|
+
value={value1}
|
|
494
|
+
onChange={setValue1}
|
|
495
|
+
options={options}
|
|
496
|
+
placeholder="Select an option"
|
|
497
|
+
/>
|
|
498
|
+
|
|
499
|
+
<Select
|
|
500
|
+
label="Inside Label"
|
|
501
|
+
labelVariant="inside"
|
|
502
|
+
value={value2}
|
|
503
|
+
onChange={setValue2}
|
|
504
|
+
options={options}
|
|
505
|
+
placeholder="Select an option"
|
|
506
|
+
/>
|
|
507
|
+
</VStack>
|
|
508
|
+
);
|
|
509
|
+
}
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
### Very Long Labels
|
|
513
|
+
|
|
514
|
+
Handle extremely long option labels that may need special treatment.
|
|
515
|
+
|
|
516
|
+
```jsx live
|
|
517
|
+
function VeryLongLabelsExample() {
|
|
518
|
+
const [value, setValue] = useState('1');
|
|
519
|
+
|
|
520
|
+
const longOptions = [
|
|
521
|
+
{
|
|
522
|
+
value: '1',
|
|
523
|
+
label:
|
|
524
|
+
'This is an extremely long option label that should test how the component handles very long text content that might overflow or wrap',
|
|
525
|
+
},
|
|
526
|
+
{
|
|
527
|
+
value: '2',
|
|
528
|
+
label:
|
|
529
|
+
'Another super long option label with even more text to see how it wraps or truncates in the UI when space is limited',
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
value: '3',
|
|
533
|
+
label: 'Short',
|
|
534
|
+
},
|
|
535
|
+
{
|
|
536
|
+
value: '4',
|
|
537
|
+
label: 'A moderately long label that is somewhere between short and extremely long',
|
|
538
|
+
},
|
|
539
|
+
];
|
|
540
|
+
|
|
541
|
+
return (
|
|
542
|
+
<Select
|
|
543
|
+
label="Options with Very Long Labels"
|
|
544
|
+
value={value}
|
|
545
|
+
onChange={setValue}
|
|
546
|
+
options={longOptions}
|
|
547
|
+
placeholder="Select an option"
|
|
548
|
+
/>
|
|
549
|
+
);
|
|
550
|
+
}
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
### Custom Long Placeholder
|
|
554
|
+
|
|
555
|
+
Use extended placeholder text for more descriptive empty states.
|
|
556
|
+
|
|
557
|
+
```jsx live
|
|
558
|
+
function LongPlaceholderExample() {
|
|
559
|
+
const [value, setValue] = useState(null);
|
|
560
|
+
|
|
561
|
+
const options = [
|
|
562
|
+
{ value: '1', label: 'Option 1' },
|
|
563
|
+
{ value: '2', label: 'Option 2' },
|
|
564
|
+
{ value: '3', label: 'Option 3' },
|
|
565
|
+
];
|
|
566
|
+
|
|
567
|
+
return (
|
|
568
|
+
<Select
|
|
569
|
+
label="Select with Long Placeholder"
|
|
570
|
+
value={value}
|
|
571
|
+
onChange={setValue}
|
|
572
|
+
options={options}
|
|
573
|
+
placeholder="This is a very long placeholder text that provides detailed instructions about what the user should select"
|
|
574
|
+
/>
|
|
575
|
+
);
|
|
576
|
+
}
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
### Mixed Options
|
|
580
|
+
|
|
581
|
+
Options with and without descriptions in the same select.
|
|
582
|
+
|
|
583
|
+
```jsx live
|
|
584
|
+
function MixedOptionsExample() {
|
|
585
|
+
const [value, setValue] = useState('1');
|
|
586
|
+
|
|
587
|
+
const mixedOptions = [
|
|
588
|
+
{ value: '1', label: 'Bitcoin', description: 'The original cryptocurrency' },
|
|
589
|
+
{ value: '2', label: 'Ethereum' },
|
|
590
|
+
{ value: '3', label: 'USDC', description: 'USD-backed stablecoin' },
|
|
591
|
+
{ value: '4', label: 'Solana' },
|
|
592
|
+
{ value: '5', label: 'Polygon', description: 'Layer 2 scaling solution' },
|
|
593
|
+
];
|
|
594
|
+
|
|
595
|
+
return (
|
|
596
|
+
<Select
|
|
597
|
+
label="Mixed Option Types"
|
|
598
|
+
value={value}
|
|
599
|
+
onChange={setValue}
|
|
600
|
+
options={mixedOptions}
|
|
601
|
+
placeholder="Choose an asset"
|
|
602
|
+
/>
|
|
603
|
+
);
|
|
604
|
+
}
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
### Options with Only Accessory
|
|
608
|
+
|
|
609
|
+
Add accessories without media for cleaner layouts.
|
|
610
|
+
|
|
611
|
+
```jsx live
|
|
612
|
+
function OnlyAccessoryExample() {
|
|
613
|
+
const [value, setValue] = useState('1');
|
|
614
|
+
|
|
615
|
+
const optionsWithAccessory = [
|
|
616
|
+
{
|
|
617
|
+
value: '1',
|
|
618
|
+
label: 'Favorites',
|
|
619
|
+
accessory: <Icon color="fg" name="star" />,
|
|
620
|
+
},
|
|
621
|
+
{
|
|
622
|
+
value: '2',
|
|
623
|
+
label: 'Verified',
|
|
624
|
+
accessory: <Icon color="fg" name="checkmark" />,
|
|
625
|
+
},
|
|
626
|
+
{
|
|
627
|
+
value: '3',
|
|
628
|
+
label: 'Premium',
|
|
629
|
+
accessory: <Icon color="fg" name="search" />,
|
|
630
|
+
},
|
|
631
|
+
];
|
|
632
|
+
|
|
633
|
+
return (
|
|
634
|
+
<Select
|
|
635
|
+
label="Options with Accessories Only"
|
|
636
|
+
value={value}
|
|
637
|
+
onChange={setValue}
|
|
638
|
+
options={optionsWithAccessory}
|
|
639
|
+
placeholder="Select an option"
|
|
640
|
+
/>
|
|
641
|
+
);
|
|
642
|
+
}
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
### Options with Only Media
|
|
646
|
+
|
|
647
|
+
Add media icons without accessories for visual identification.
|
|
648
|
+
|
|
649
|
+
```jsx live
|
|
650
|
+
function OnlyMediaExample() {
|
|
651
|
+
const [value, setValue] = useState('1');
|
|
652
|
+
|
|
653
|
+
const optionsWithMedia = [
|
|
654
|
+
{
|
|
655
|
+
value: '1',
|
|
656
|
+
label: 'Home',
|
|
657
|
+
media: <Icon color="fg" name="home" />,
|
|
658
|
+
},
|
|
659
|
+
{
|
|
660
|
+
value: '2',
|
|
661
|
+
label: 'Profile',
|
|
662
|
+
media: <Icon color="fg" name="search" />,
|
|
663
|
+
},
|
|
664
|
+
{
|
|
665
|
+
value: '3',
|
|
666
|
+
label: 'Settings',
|
|
667
|
+
media: <Icon color="fg" name="gear" />,
|
|
668
|
+
},
|
|
669
|
+
];
|
|
670
|
+
|
|
671
|
+
return (
|
|
672
|
+
<Select
|
|
673
|
+
label="Options with Media Only"
|
|
674
|
+
value={value}
|
|
675
|
+
onChange={setValue}
|
|
676
|
+
options={optionsWithMedia}
|
|
677
|
+
placeholder="Navigate to..."
|
|
678
|
+
/>
|
|
679
|
+
);
|
|
680
|
+
}
|
|
681
|
+
```
|
|
682
|
+
|
|
683
|
+
### Variants with Additional Props
|
|
684
|
+
|
|
685
|
+
Combine variants with other properties for complex states.
|
|
686
|
+
|
|
687
|
+
```jsx live
|
|
688
|
+
function VariantCombinationsExample() {
|
|
689
|
+
const [value1, setValue1] = useState('1');
|
|
690
|
+
const [value2, setValue2] = useState('2');
|
|
691
|
+
|
|
692
|
+
const options = [
|
|
693
|
+
{ value: '1', label: 'Option 1' },
|
|
694
|
+
{ value: '2', label: 'Option 2' },
|
|
695
|
+
{ value: '3', label: 'Option 3' },
|
|
696
|
+
];
|
|
697
|
+
|
|
698
|
+
return (
|
|
699
|
+
<VStack gap={4}>
|
|
700
|
+
<Select
|
|
701
|
+
compact
|
|
702
|
+
variant="positive"
|
|
703
|
+
startNode={<Icon color="fg" name="checkmark" />}
|
|
704
|
+
label="Compact + Positive + Icon"
|
|
705
|
+
value={value1}
|
|
706
|
+
onChange={setValue1}
|
|
707
|
+
options={options}
|
|
708
|
+
helperText="Multiple props combined"
|
|
709
|
+
/>
|
|
710
|
+
|
|
711
|
+
<Select
|
|
712
|
+
disabled
|
|
713
|
+
variant="negative"
|
|
714
|
+
label="Disabled + Negative"
|
|
715
|
+
value={value2}
|
|
716
|
+
onChange={setValue2}
|
|
717
|
+
options={options}
|
|
718
|
+
helperText="Error state but disabled"
|
|
719
|
+
/>
|
|
720
|
+
</VStack>
|
|
721
|
+
);
|
|
722
|
+
}
|
|
723
|
+
```
|
|
724
|
+
|
|
725
|
+
### Long Helper Text
|
|
726
|
+
|
|
727
|
+
Extended helper text for detailed instructions.
|
|
728
|
+
|
|
729
|
+
```jsx live
|
|
730
|
+
function LongHelperTextExample() {
|
|
731
|
+
const [value, setValue] = useState('1');
|
|
732
|
+
|
|
733
|
+
const options = [
|
|
734
|
+
{ value: '1', label: 'Option 1' },
|
|
735
|
+
{ value: '2', label: 'Option 2' },
|
|
736
|
+
{ value: '3', label: 'Option 3' },
|
|
737
|
+
];
|
|
738
|
+
|
|
739
|
+
return (
|
|
740
|
+
<Select
|
|
741
|
+
label="Select with Extended Helper"
|
|
742
|
+
value={value}
|
|
743
|
+
onChange={setValue}
|
|
744
|
+
options={options}
|
|
745
|
+
helperText="This is a very long helper text that provides extensive guidance about what the user should select. It might wrap to multiple lines depending on the container width and should remain readable."
|
|
746
|
+
placeholder="Select an option"
|
|
747
|
+
/>
|
|
748
|
+
);
|
|
749
|
+
}
|
|
750
|
+
```
|
|
751
|
+
|
|
752
|
+
### No Label
|
|
753
|
+
|
|
754
|
+
Select without a visible label (accessibility label still required).
|
|
755
|
+
|
|
756
|
+
```jsx live
|
|
757
|
+
function NoLabelExample() {
|
|
758
|
+
const [value, setValue] = useState('1');
|
|
759
|
+
|
|
760
|
+
const options = [
|
|
761
|
+
{ value: '1', label: 'Option 1' },
|
|
762
|
+
{ value: '2', label: 'Option 2' },
|
|
763
|
+
{ value: '3', label: 'Option 3' },
|
|
764
|
+
];
|
|
765
|
+
|
|
766
|
+
return (
|
|
767
|
+
<Select
|
|
768
|
+
accessibilityLabel="Hidden label select"
|
|
769
|
+
value={value}
|
|
770
|
+
onChange={setValue}
|
|
771
|
+
options={options}
|
|
772
|
+
placeholder="Select without visible label"
|
|
773
|
+
/>
|
|
774
|
+
);
|
|
775
|
+
}
|
|
776
|
+
```
|
|
777
|
+
|
|
778
|
+
### Complex Nested Options
|
|
779
|
+
|
|
780
|
+
Options with special characters, emojis, and complex content.
|
|
781
|
+
|
|
782
|
+
```jsx live
|
|
783
|
+
function ComplexOptionsExample() {
|
|
784
|
+
const [value, setValue] = useState('1');
|
|
785
|
+
|
|
786
|
+
const complexOptions = [
|
|
787
|
+
{
|
|
788
|
+
value: '1',
|
|
789
|
+
label: 'USD $100.00',
|
|
790
|
+
description: 'United States Dollar',
|
|
791
|
+
accessory: '🇺🇸',
|
|
792
|
+
},
|
|
793
|
+
{
|
|
794
|
+
value: '2',
|
|
795
|
+
label: 'EUR €85.50',
|
|
796
|
+
description: 'Euro (€)',
|
|
797
|
+
accessory: '🇪🇺',
|
|
798
|
+
},
|
|
799
|
+
{
|
|
800
|
+
value: '3',
|
|
801
|
+
label: 'GBP £73.25',
|
|
802
|
+
description: 'British Pound Sterling',
|
|
803
|
+
accessory: '🇬🇧',
|
|
804
|
+
},
|
|
805
|
+
{
|
|
806
|
+
value: '4',
|
|
807
|
+
label: 'JPY ¥11,050',
|
|
808
|
+
description: '日本円 (Japanese Yen)',
|
|
809
|
+
accessory: '🇯🇵',
|
|
810
|
+
},
|
|
811
|
+
];
|
|
812
|
+
|
|
813
|
+
return (
|
|
814
|
+
<Select
|
|
815
|
+
label="Currency Selection"
|
|
816
|
+
value={value}
|
|
817
|
+
onChange={setValue}
|
|
818
|
+
options={complexOptions}
|
|
819
|
+
placeholder="Choose currency"
|
|
820
|
+
/>
|
|
821
|
+
);
|
|
822
|
+
}
|
|
823
|
+
```
|
|
824
|
+
|
|
825
|
+
### Stress Test
|
|
826
|
+
|
|
827
|
+
Many options with various configurations for performance testing.
|
|
828
|
+
|
|
829
|
+
```jsx live
|
|
830
|
+
function StressTestExample() {
|
|
831
|
+
const [value, setValue] = useState('1');
|
|
832
|
+
|
|
833
|
+
const stressOptions = Array.from({ length: 50 }, (_, i) => ({
|
|
834
|
+
value: (i + 1).toString(),
|
|
835
|
+
label: `Option ${i + 1}`,
|
|
836
|
+
description: i % 3 === 0 ? `Description for option ${i + 1}` : undefined,
|
|
837
|
+
disabled: i % 7 === 0,
|
|
838
|
+
accessory: i % 5 === 0 ? <Icon color="fg" name="star" /> : undefined,
|
|
839
|
+
media: i % 8 === 0 ? <Icon color="fg" name="heart" /> : undefined,
|
|
840
|
+
}));
|
|
841
|
+
|
|
842
|
+
return (
|
|
843
|
+
<Select
|
|
844
|
+
label="Stress Test - Many Options"
|
|
845
|
+
value={value}
|
|
846
|
+
onChange={setValue}
|
|
847
|
+
options={stressOptions}
|
|
848
|
+
placeholder="Choose from many options"
|
|
849
|
+
/>
|
|
850
|
+
);
|
|
851
|
+
}
|
|
852
|
+
```
|
|
853
|
+
|
|
854
|
+
### Value Display
|
|
855
|
+
|
|
856
|
+
Show the selected value in another component.
|
|
857
|
+
|
|
858
|
+
```jsx live
|
|
859
|
+
function ValueDisplayExample() {
|
|
860
|
+
const [value, setValue] = useState('btc');
|
|
861
|
+
|
|
862
|
+
const cryptoOptions = [
|
|
863
|
+
{ value: 'btc', label: 'Bitcoin', description: 'BTC' },
|
|
864
|
+
{ value: 'eth', label: 'Ethereum', description: 'ETH' },
|
|
865
|
+
{ value: 'usdc', label: 'USD Coin', description: 'USDC' },
|
|
866
|
+
];
|
|
867
|
+
|
|
868
|
+
const selectedOption = cryptoOptions.find((opt) => opt.value === value);
|
|
869
|
+
|
|
870
|
+
return (
|
|
871
|
+
<VStack gap={4}>
|
|
872
|
+
<div
|
|
873
|
+
style={{
|
|
874
|
+
padding: '16px',
|
|
875
|
+
borderRadius: '8px',
|
|
876
|
+
backgroundColor: '#f0f0f0',
|
|
877
|
+
}}
|
|
878
|
+
>
|
|
879
|
+
<Text font="headline">Selected Asset:</Text>
|
|
880
|
+
<Text font="title2">{selectedOption?.label || 'None'}</Text>
|
|
881
|
+
<Text font="body" color="fgSecondary">
|
|
882
|
+
{selectedOption?.description || 'No selection'}
|
|
883
|
+
</Text>
|
|
884
|
+
</div>
|
|
885
|
+
|
|
886
|
+
<Select
|
|
887
|
+
label="Choose Cryptocurrency"
|
|
888
|
+
value={value}
|
|
889
|
+
onChange={setValue}
|
|
890
|
+
options={cryptoOptions}
|
|
891
|
+
placeholder="Select an asset"
|
|
892
|
+
/>
|
|
893
|
+
</VStack>
|
|
894
|
+
);
|
|
895
|
+
}
|
|
896
|
+
```
|
|
897
|
+
|
|
898
|
+
### Options with Only Description
|
|
899
|
+
|
|
900
|
+
Options that only have descriptions without labels.
|
|
901
|
+
|
|
902
|
+
```jsx live
|
|
903
|
+
function OnlyDescriptionExample() {
|
|
904
|
+
const [value, setValue] = useState('1');
|
|
905
|
+
|
|
906
|
+
const descriptionOnlyOptions = [
|
|
907
|
+
{ value: '1', description: 'First description without a label' },
|
|
908
|
+
{ value: '2', description: 'Second description only' },
|
|
909
|
+
{ value: '3', description: 'Third item with just description' },
|
|
910
|
+
{ value: '4', description: 'Fourth description-only option' },
|
|
911
|
+
];
|
|
912
|
+
|
|
913
|
+
return (
|
|
914
|
+
<Select
|
|
915
|
+
label="Description-Only Options"
|
|
916
|
+
value={value}
|
|
917
|
+
onChange={setValue}
|
|
918
|
+
options={descriptionOnlyOptions}
|
|
919
|
+
placeholder="Select by description"
|
|
920
|
+
/>
|
|
921
|
+
);
|
|
922
|
+
}
|
|
923
|
+
```
|
|
924
|
+
|
|
925
|
+
### Custom styles
|
|
926
|
+
|
|
927
|
+
You can use custom styles on the various subcomponents in Select.
|
|
928
|
+
|
|
929
|
+
```jsx live
|
|
930
|
+
function CustomStylesExample() {
|
|
931
|
+
const exampleOptions = [
|
|
932
|
+
{ value: null, label: 'Remove selection' },
|
|
933
|
+
{ value: '1', label: 'Option 1' },
|
|
934
|
+
{ value: '2', label: 'Option 2' },
|
|
935
|
+
{ value: '3', label: 'Option 3' },
|
|
936
|
+
{ value: '4', label: 'Option 4' },
|
|
937
|
+
];
|
|
938
|
+
const [value, setValue] = useState('1');
|
|
939
|
+
|
|
940
|
+
return (
|
|
941
|
+
<Select
|
|
942
|
+
label="Single select - styles"
|
|
943
|
+
onChange={setValue}
|
|
944
|
+
options={exampleOptions}
|
|
945
|
+
placeholder="Empty value"
|
|
946
|
+
styles={{
|
|
947
|
+
control: {
|
|
948
|
+
padding: '20px',
|
|
949
|
+
backgroundColor: 'lightgray',
|
|
950
|
+
},
|
|
951
|
+
controlBlendStyles: {
|
|
952
|
+
background: 'coral',
|
|
953
|
+
hoveredBackground: 'crimson',
|
|
954
|
+
pressedBackground: 'red',
|
|
955
|
+
},
|
|
956
|
+
optionBlendStyles: {
|
|
957
|
+
background: 'lightblue',
|
|
958
|
+
hoveredBackground: 'blue',
|
|
959
|
+
},
|
|
960
|
+
dropdown: {
|
|
961
|
+
padding: '20px',
|
|
962
|
+
backgroundColor: 'pink',
|
|
963
|
+
},
|
|
964
|
+
}}
|
|
965
|
+
value={value}
|
|
966
|
+
/>
|
|
967
|
+
);
|
|
968
|
+
}
|
|
969
|
+
```
|
|
970
|
+
|
|
971
|
+
### Custom class names
|
|
972
|
+
|
|
973
|
+
You can use custom class names on the various subcomponents in Select.
|
|
974
|
+
|
|
975
|
+
```jsx
|
|
976
|
+
function CustomClassNamesExamples() {
|
|
977
|
+
const exampleOptions = [
|
|
978
|
+
{ value: null, label: 'Remove selection' },
|
|
979
|
+
{ value: '1', label: 'Option 1' },
|
|
980
|
+
{ value: '2', label: 'Option 2' },
|
|
981
|
+
{ value: '3', label: 'Option 3' },
|
|
982
|
+
{ value: '4', label: 'Option 4' },
|
|
983
|
+
];
|
|
984
|
+
const [value, setValue] = useState('1');
|
|
985
|
+
|
|
986
|
+
return (
|
|
987
|
+
<Select
|
|
988
|
+
classNames={{
|
|
989
|
+
control: customControlStyles,
|
|
990
|
+
option: customOptionStyles,
|
|
991
|
+
}}
|
|
992
|
+
label="Single select - class names"
|
|
993
|
+
onChange={setValue}
|
|
994
|
+
options={exampleOptions}
|
|
995
|
+
placeholder="Empty value"
|
|
996
|
+
value={value}
|
|
997
|
+
/>
|
|
998
|
+
);
|
|
999
|
+
}
|
|
1000
|
+
```
|
|
1001
|
+
|
|
1002
|
+
### Custom components
|
|
1003
|
+
|
|
1004
|
+
Select is highly customizable. Use the _Component_ props to customize the various subcomponents in Select.
|
|
1005
|
+
|
|
1006
|
+
#### Customizable subcomponents
|
|
1007
|
+
|
|
1008
|
+
- **SelectControlComponent**: Trigger component used to open and close the Select.
|
|
1009
|
+
- **SelectDropdownComponent**: Component which renders the dropdown menu and SelectOptionComponents.
|
|
1010
|
+
- **SelectOptionComponent**: Component which renders the content of an option in the select.
|
|
1011
|
+
- **SelectAllOptionComponent**: Component which renders the Select All option in a multi-select select menu.
|
|
1012
|
+
- **SelectEmptyDropdownContentsComponent**: Component which renders as the select menu's content when no options are passed in.
|
|
1013
|
+
|
|
1014
|
+
Below is a diagram to help visualize the Select anatomy.
|
|
1015
|
+
|
|
1016
|
+
```text
|
|
1017
|
+
Select
|
|
1018
|
+
├── SelectControlComponent (trigger to open/close)
|
|
1019
|
+
└── SelectDropdownComponent (dropdown menu)
|
|
1020
|
+
├── SelectAllOptionComponent
|
|
1021
|
+
├── SelectOptionComponent (option 1)
|
|
1022
|
+
├── SelectOptionComponent (option 2)
|
|
1023
|
+
├── SelectOptionComponent (option 3)
|
|
1024
|
+
└── SelectOptionComponent (option N...)
|
|
1025
|
+
```
|
|
1026
|
+
|
|
1027
|
+
#### Example
|
|
1028
|
+
|
|
1029
|
+
```jsx
|
|
1030
|
+
function CustomComponentExamples() {
|
|
1031
|
+
const exampleOptions = [
|
|
1032
|
+
{ value: null, label: 'Remove selection' },
|
|
1033
|
+
{ value: '1', label: 'Option 1' },
|
|
1034
|
+
{ value: '2', label: 'Option 2' },
|
|
1035
|
+
{ value: '3', label: 'Option 3' },
|
|
1036
|
+
{ value: '4', label: 'Option 4' },
|
|
1037
|
+
];
|
|
1038
|
+
const [value, setValue] = useState('1');
|
|
1039
|
+
|
|
1040
|
+
const CustomControlComponent = ({ value, setOpen }) => {
|
|
1041
|
+
return <Button onClick={() => setOpen(true)}>{value ?? 'Empty value'}</Button>;
|
|
1042
|
+
};
|
|
1043
|
+
|
|
1044
|
+
const CustomOptionComponent = ({ value, onClick }) => {
|
|
1045
|
+
return (
|
|
1046
|
+
<HStack justifyContent="center">
|
|
1047
|
+
<Spinner size={4} />
|
|
1048
|
+
<Button transparent onClick={() => onClick?.(value)} width="80%">
|
|
1049
|
+
{value ?? 'Empty value'}
|
|
1050
|
+
</Button>
|
|
1051
|
+
<Spinner size={4} />
|
|
1052
|
+
</HStack>
|
|
1053
|
+
);
|
|
1054
|
+
};
|
|
1055
|
+
|
|
1056
|
+
return (
|
|
1057
|
+
<Select
|
|
1058
|
+
SelectControlComponent={CustomControlComponent}
|
|
1059
|
+
SelectOptionComponent={CustomOptionComponent}
|
|
1060
|
+
label="Single select - custom components"
|
|
1061
|
+
onChange={setValue}
|
|
1062
|
+
options={exampleOptions}
|
|
1063
|
+
placeholder="Empty value"
|
|
1064
|
+
value={value}
|
|
1065
|
+
/>
|
|
1066
|
+
);
|
|
1067
|
+
}
|
|
1068
|
+
```
|
|
1069
|
+
|
|
1070
|
+
## Props
|
|
1071
|
+
|
|
1072
|
+
| Prop | Type | Required | Default | Description |
|
|
1073
|
+
| --- | --- | --- | --- | --- |
|
|
1074
|
+
| `onChange` | `(value: Type extends multi ? SelectOptionValue \| SelectOptionValue[] \| null : SelectOptionValue \| null) => void` | Yes | `-` | - |
|
|
1075
|
+
| `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 |
|
|
1076
|
+
| `value` | `string \| SelectOptionValue[] \| null` | Yes | `-` | - |
|
|
1077
|
+
| `SelectAllOptionComponent` | `SelectOptionComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render the Select All option |
|
|
1078
|
+
| `SelectControlComponent` | `SelectControlComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render the select control |
|
|
1079
|
+
| `SelectDropdownComponent` | `SelectDropdownComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render the dropdown container |
|
|
1080
|
+
| `SelectEmptyDropdownContentsComponent` | `SelectEmptyDropdownContentComponent` | No | `-` | Custom component to render when no options are available |
|
|
1081
|
+
| `SelectOptionComponent` | `SelectOptionComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render individual options |
|
|
1082
|
+
| `accessibilityRoles` | `{ dropdown?: AriaHasPopupType; option?: string \| undefined; } \| undefined` | No | `-` | Accessibility roles for dropdown and option elements |
|
|
1083
|
+
| `accessory` | `ReactElement<CellAccessoryProps, string \| JSXElementConstructor<any>>` | No | `-` | Accessory element rendered at the end of the cell (e.g., chevron). |
|
|
1084
|
+
| `className` | `string` | No | `-` | CSS class name for the root element |
|
|
1085
|
+
| `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 |
|
|
1086
|
+
| `clearAllLabel` | `string` | No | `-` | Label for the Clear All option in multi-select mode |
|
|
1087
|
+
| `compact` | `boolean` | No | `-` | Whether to use compact styling for the select |
|
|
1088
|
+
| `controlAccessibilityLabel` | `string` | No | `-` | Accessibility label for the control |
|
|
1089
|
+
| `defaultOpen` | `boolean` | No | `-` | Initial open state when component mounts (uncontrolled mode) |
|
|
1090
|
+
| `disableClickOutsideClose` | `boolean` | No | `-` | Whether clicking outside the dropdown should close it |
|
|
1091
|
+
| `disabled` | `boolean` | No | `false` | Toggles input interactability and opacity |
|
|
1092
|
+
| `emptyOptionsLabel` | `string` | No | `-` | Label displayed when there are no options available |
|
|
1093
|
+
| `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. |
|
|
1094
|
+
| `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 |
|
|
1095
|
+
| `helperText` | `null \| string \| number \| false \| true \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal` | No | `-` | Helper text displayed below the select |
|
|
1096
|
+
| `hiddenSelectedOptionsLabel` | `string` | No | `-` | Label to show for showcasing count of hidden selected options |
|
|
1097
|
+
| `hideSelectAll` | `boolean` | No | `-` | Whether to hide the Select All option in multi-select mode |
|
|
1098
|
+
| `label` | `null \| string \| number \| false \| true \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal` | No | `-` | Label displayed above the control |
|
|
1099
|
+
| `labelVariant` | `inside \| outside` | No | `'outside'` | The variant of the label. Only used when compact is not true. |
|
|
1100
|
+
| `maxSelectedOptionsToShow` | `number` | No | `-` | Maximum number of selected options to show before truncating |
|
|
1101
|
+
| `media` | `ReactElement` | No | `-` | Media rendered at the start of the cell (icon, avatar, image, etc). |
|
|
1102
|
+
| `open` | `boolean` | No | `-` | Controlled open state of the dropdown |
|
|
1103
|
+
| `placeholder` | `null \| string \| number \| false \| true \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal` | No | `-` | Placeholder text displayed when no option is selected |
|
|
1104
|
+
| `ref` | `null \| (instance: SelectRef \| null) => void \| RefObject<SelectRef>` | No | `-` | - |
|
|
1105
|
+
| `removeSelectedOptionAccessibilityLabel` | `string` | No | `-` | Accessibility label for each chip in a multi-select |
|
|
1106
|
+
| `selectAllLabel` | `string` | No | `-` | Label for the Select All option in multi-select mode |
|
|
1107
|
+
| `setOpen` | `((open: boolean \| ((open: boolean) => boolean)) => void)` | No | `-` | Callback to update the open state |
|
|
1108
|
+
| `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 |
|
|
1109
|
+
| `style` | `CSSProperties` | No | `-` | Inline styles for the root element |
|
|
1110
|
+
| `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 |
|
|
1111
|
+
| `testID` | `string` | No | `-` | Test ID for the root element |
|
|
1112
|
+
| `type` | `single \| multi` | No | `-` | Whether the select allows single or multiple selections |
|
|
1113
|
+
| `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 |
|
|
1114
|
+
|
|
1115
|
+
|