@coinbase/cds-mcp-server 8.37.0 → 8.38.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 CHANGED
@@ -8,6 +8,14 @@ All notable changes to this project will be documented in this file.
8
8
 
9
9
  <!-- template-start -->
10
10
 
11
+ ## 8.38.0 ((1/14/2026, 01:30 PM PST))
12
+
13
+ This is an artificial version bump with no new change.
14
+
15
+ ## 8.37.1 ((1/14/2026, 12:37 PM PST))
16
+
17
+ This is an artificial version bump with no new change.
18
+
11
19
  ## 8.37.0 ((1/12/2026, 02:16 PM PST))
12
20
 
13
21
  This is an artificial version bump with no new change.
@@ -133,6 +133,57 @@ function HelperTextExample() {
133
133
  }
134
134
  ```
135
135
 
136
+ ### Borderless
137
+
138
+ You can remove the border from the combobox control by setting `bordered` to `false`.
139
+
140
+ ```jsx
141
+ function BorderlessExample() {
142
+ const singleSelectOptions = [
143
+ { value: null, label: 'Remove selection' },
144
+ { value: 'apple', label: 'Apple' },
145
+ { value: 'banana', label: 'Banana' },
146
+ { value: 'cherry', label: 'Cherry' },
147
+ { value: 'date', label: 'Date' },
148
+ ];
149
+
150
+ const fruitOptions = [
151
+ { value: 'apple', label: 'Apple' },
152
+ { value: 'banana', label: 'Banana' },
153
+ { value: 'cherry', label: 'Cherry' },
154
+ { value: 'date', label: 'Date' },
155
+ { value: 'elderberry', label: 'Elderberry' },
156
+ ];
157
+
158
+ const [singleValue, setSingleValue] = useState('apple');
159
+ const { value: multiValue, onChange: multiOnChange } = useMultiSelect({
160
+ initialValue: ['apple'],
161
+ });
162
+
163
+ return (
164
+ <VStack gap={4}>
165
+ <Combobox
166
+ bordered={false}
167
+ label="Borderless single select"
168
+ onChange={setSingleValue}
169
+ options={singleSelectOptions}
170
+ placeholder="Search fruits..."
171
+ value={singleValue}
172
+ />
173
+ <Combobox
174
+ bordered={false}
175
+ label="Borderless multi select"
176
+ onChange={multiOnChange}
177
+ options={fruitOptions}
178
+ placeholder="Search fruits..."
179
+ type="multi"
180
+ value={multiValue}
181
+ />
182
+ </VStack>
183
+ );
184
+ }
185
+ ```
186
+
136
187
  ## Props
137
188
 
138
189
  | Prop | Type | Required | Default | Description |
@@ -150,6 +201,7 @@ function HelperTextExample() {
150
201
  | `SelectOptionGroupComponent` | `SelectOptionGroupComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render group headers |
151
202
  | `accessibilityRoles` | `{ option?: AccessibilityRole; } \| undefined` | No | `-` | Accessibility roles for dropdown elements |
152
203
  | `accessory` | `ReactElement<CellAccessoryProps, string \| JSXElementConstructor<any>>` | No | `-` | - |
204
+ | `bordered` | `boolean` | No | `true` | Add a border around all sides of the box. Determines if the control should have a default border. |
153
205
  | `clearAllLabel` | `string` | No | `-` | Label for the Clear All option in multi-select mode |
154
206
  | `closeButtonLabel` | `string` | No | `-` | Label for close button when combobox is open (mobile only) |
155
207
  | `compact` | `boolean` | No | `-` | Whether to use compact styling for the select |
@@ -1206,6 +1206,49 @@ function StressTestExample() {
1206
1206
  }
1207
1207
  ```
1208
1208
 
1209
+ ### Borderless
1210
+
1211
+ You can remove the border from the select control by setting `bordered` to `false`. Now Select will only show a border when focused.
1212
+
1213
+ ```jsx
1214
+ function BorderlessExample() {
1215
+ const [singleValue, setSingleValue] = useState('1');
1216
+ const { value: multiValue, onChange: multiOnChange } = useMultiSelect({
1217
+ initialValue: ['1', '2'],
1218
+ });
1219
+
1220
+ const options = [
1221
+ { value: '1', label: 'Option 1' },
1222
+ { value: '2', label: 'Option 2' },
1223
+ { value: '3', label: 'Option 3' },
1224
+ { value: '4', label: 'Option 4' },
1225
+ ];
1226
+
1227
+ return (
1228
+ <VStack gap={4}>
1229
+ <Select
1230
+ bordered={false}
1231
+ label="Borderless single select"
1232
+ value={singleValue}
1233
+ onChange={setSingleValue}
1234
+ options={options}
1235
+ placeholder="Select an option"
1236
+ />
1237
+
1238
+ <Select
1239
+ bordered={false}
1240
+ type="multi"
1241
+ label="Borderless multi select"
1242
+ value={multiValue}
1243
+ onChange={multiOnChange}
1244
+ options={options}
1245
+ placeholder="Select options"
1246
+ />
1247
+ </VStack>
1248
+ );
1249
+ }
1250
+ ```
1251
+
1209
1252
  ### Custom styles
1210
1253
 
1211
1254
  You can use custom styles on the various subcomponents in Select.
@@ -1390,6 +1433,7 @@ function CustomComponentExamples() {
1390
1433
  | `SelectOptionGroupComponent` | `SelectOptionGroupComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render group headers |
1391
1434
  | `accessibilityRoles` | `{ option?: AccessibilityRole; } \| undefined` | No | `-` | Accessibility roles for dropdown elements |
1392
1435
  | `accessory` | `ReactElement<CellAccessoryProps, string \| JSXElementConstructor<any>>` | No | `-` | - |
1436
+ | `bordered` | `boolean` | No | `true` | Add a border around all sides of the box. Determines if the control should have a default border. |
1393
1437
  | `clearAllLabel` | `string` | No | `-` | Label for the Clear All option in multi-select mode |
1394
1438
  | `compact` | `boolean` | No | `-` | Whether to use compact styling for the select |
1395
1439
  | `defaultOpen` | `boolean` | No | `-` | Initial open state when component mounts (uncontrolled mode) |
@@ -475,6 +475,7 @@ function ExampleDisabled() {
475
475
  | `SelectOptionGroupComponent` | `SelectOptionGroupComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render group headers |
476
476
  | `accessibilityRoles` | `{ option?: AccessibilityRole; } \| undefined` | No | `-` | Accessibility roles for dropdown elements |
477
477
  | `accessory` | `ReactElement<CellAccessoryProps, string \| JSXElementConstructor<any>>` | No | `-` | - |
478
+ | `bordered` | `boolean` | No | `true` | Add a border around all sides of the box. Determines if the control should have a default border. |
478
479
  | `clearAllLabel` | `string` | No | `-` | Label for the Clear All option in multi-select mode |
479
480
  | `compact` | `boolean` | No | `-` | Whether to use compact styling for the select |
480
481
  | `defaultOpen` | `boolean` | No | `-` | Initial open state when component mounts (uncontrolled mode) |
@@ -121,6 +121,57 @@ const fruitOptions: SelectOption[] = [
121
121
  }
122
122
  ```
123
123
 
124
+ ### Borderless
125
+
126
+ You can remove the border from the combobox control by setting `bordered` to `false`.
127
+
128
+ ```jsx live
129
+ function BorderlessExample() {
130
+ const singleSelectOptions = [
131
+ { value: null, label: 'Remove selection' },
132
+ { value: 'apple', label: 'Apple' },
133
+ { value: 'banana', label: 'Banana' },
134
+ { value: 'cherry', label: 'Cherry' },
135
+ { value: 'date', label: 'Date' },
136
+ ];
137
+
138
+ const fruitOptions = [
139
+ { value: 'apple', label: 'Apple' },
140
+ { value: 'banana', label: 'Banana' },
141
+ { value: 'cherry', label: 'Cherry' },
142
+ { value: 'date', label: 'Date' },
143
+ { value: 'elderberry', label: 'Elderberry' },
144
+ ];
145
+
146
+ const [singleValue, setSingleValue] = useState('apple');
147
+ const { value: multiValue, onChange: multiOnChange } = useMultiSelect({
148
+ initialValue: ['apple'],
149
+ });
150
+
151
+ return (
152
+ <VStack gap={4}>
153
+ <Combobox
154
+ bordered={false}
155
+ label="Borderless single select"
156
+ onChange={setSingleValue}
157
+ options={singleSelectOptions}
158
+ placeholder="Search fruits..."
159
+ value={singleValue}
160
+ />
161
+ <Combobox
162
+ bordered={false}
163
+ label="Borderless multi select"
164
+ onChange={multiOnChange}
165
+ options={fruitOptions}
166
+ placeholder="Search fruits..."
167
+ type="multi"
168
+ value={multiValue}
169
+ />
170
+ </VStack>
171
+ );
172
+ }
173
+ ```
174
+
124
175
  ## Props
125
176
 
126
177
  | Prop | Type | Required | Default | Description |
@@ -137,6 +188,7 @@ const fruitOptions: SelectOption[] = [
137
188
  | `SelectOptionGroupComponent` | `SelectOptionGroupComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render group headers |
138
189
  | `accessibilityRoles` | `{ dropdown?: AriaHasPopupType; option?: string \| undefined; } \| undefined` | No | `-` | Accessibility roles for dropdown and option elements |
139
190
  | `accessory` | `ReactElement<CellAccessoryProps, string \| JSXElementConstructor<any>>` | No | `-` | Accessory element rendered at the end of the cell (e.g., chevron). |
191
+ | `bordered` | `boolean` | No | `true` | Add a border around all sides of the box. Determines if the control should have a default border. |
140
192
  | `className` | `string` | No | `-` | CSS class name for the root element |
141
193
  | `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 |
142
194
  | `clearAllLabel` | `string` | No | `-` | Label for the Clear All option in multi-select mode |
@@ -0,0 +1,150 @@
1
+ # FocusTrap
2
+
3
+ FocusTrap is a component that traps focus within its children.
4
+
5
+ ## Import
6
+
7
+ ```tsx
8
+ import { FocusTrap } from '@coinbase/cds-web/overlays/FocusTrap'
9
+ ```
10
+
11
+ ## Examples
12
+
13
+ :::note Before using FocusTrap
14
+ `<FocusTrap>` is intended to prevent keyboard users from interacting with elements on the page that a mouse user cannot interact with either. An example of this is `<Modal>` where the user cannot click the items behind the modal. If you want to shift focus based on UI events, consider using the [.focus()](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus) method instead.
15
+ :::
16
+
17
+ :::warning Accessibility
18
+ It is **required** that when using a `<FocusTrap>` there is logic using only key presses to escape the focus trap. Otherwise, keyboard users will be blocked after they enter a `<FocusTrap>`.
19
+ :::
20
+
21
+ ### Basic example
22
+
23
+ :::note
24
+ All the examples have controls to enable / disable the focus trap so that page keyboard navigation isn't blocked.
25
+ :::
26
+
27
+ When enabled, only the children of the `<FocusTrap>` will be able to receive focus. Otherwise, standard DOM focus order follows.
28
+
29
+ ```jsx live
30
+ function Example() {
31
+ const [focusTrapEnabled, setFocusTrapEnabled] = useState(false);
32
+
33
+ return (
34
+ <VStack gap={2}>
35
+ <Checkbox
36
+ checked={focusTrapEnabled}
37
+ onChange={() => setFocusTrapEnabled((prev) => !prev)}
38
+ label="Focus trap enabled"
39
+ />
40
+ {focusTrapEnabled && (
41
+ <FocusTrap>
42
+ <VStack gap={2} background="bgAlternate" padding={2}>
43
+ <Text>Inside FocusTrap</Text>
44
+ <HStack gap={1}>
45
+ <Button>1</Button>
46
+ <Button>2</Button>
47
+ <Button>3</Button>
48
+ </HStack>
49
+ <Checkbox
50
+ checked={focusTrapEnabled}
51
+ onChange={() => setFocusTrapEnabled((prev) => !prev)}
52
+ label="Focus trap enabled"
53
+ />
54
+ </VStack>
55
+ </FocusTrap>
56
+ )}
57
+ </VStack>
58
+ );
59
+ }
60
+ ```
61
+
62
+ ### Include trigger in FocusTrap
63
+
64
+ The `includeTriggerInFocusTrap` prop includes the triggering element causing the `<FocusTrap>` to render as part of the focus order.
65
+
66
+ ```jsx live
67
+ function Example() {
68
+ const [focusTrapEnabled, setFocusTrapEnabled] = useState(false);
69
+
70
+ return (
71
+ <VStack gap={2}>
72
+ <Checkbox
73
+ checked={focusTrapEnabled}
74
+ onChange={() => setFocusTrapEnabled((prev) => !prev)}
75
+ label="Focus trap enabled"
76
+ />
77
+ {focusTrapEnabled && (
78
+ <FocusTrap includeTriggerInFocusTrap>
79
+ <VStack gap={2} background="bgAlternate" padding={2}>
80
+ <Text>Inside FocusTrap</Text>
81
+ <HStack gap={1}>
82
+ <Button>1</Button>
83
+ <Button>2</Button>
84
+ <Button>3</Button>
85
+ </HStack>
86
+ <Checkbox
87
+ checked={focusTrapEnabled}
88
+ onChange={() => setFocusTrapEnabled((prev) => !prev)}
89
+ label="Focus trap enabled"
90
+ />
91
+ </VStack>
92
+ </FocusTrap>
93
+ )}
94
+ </VStack>
95
+ );
96
+ }
97
+ ```
98
+
99
+ ### Restore focus on unmount
100
+
101
+ The `restoreFocusOnUnmount` prop returns focus to the triggering element when the `<FocusTrap>` is unmounted.
102
+
103
+ ```jsx live
104
+ function Example() {
105
+ const [focusTrapEnabled, setFocusTrapEnabled] = useState(false);
106
+
107
+ return (
108
+ <VStack gap={2}>
109
+ <Checkbox
110
+ checked={focusTrapEnabled}
111
+ onChange={() => setFocusTrapEnabled((prev) => !prev)}
112
+ label="Focus trap enabled"
113
+ />
114
+ {focusTrapEnabled && (
115
+ <FocusTrap restoreFocusOnUnmount>
116
+ <VStack gap={2} background="bgAlternate" padding={2}>
117
+ <Text>Inside FocusTrap</Text>
118
+ <HStack gap={1}>
119
+ <Button>1</Button>
120
+ <Button>2</Button>
121
+ <Button>3</Button>
122
+ </HStack>
123
+ <Checkbox
124
+ checked={focusTrapEnabled}
125
+ onChange={() => setFocusTrapEnabled((prev) => !prev)}
126
+ label="Focus trap enabled"
127
+ />
128
+ </VStack>
129
+ </FocusTrap>
130
+ )}
131
+ </VStack>
132
+ );
133
+ }
134
+ ```
135
+
136
+ ## Props
137
+
138
+ | Prop | Type | Required | Default | Description |
139
+ | --- | --- | --- | --- | --- |
140
+ | `autoFocusDelay` | `number` | No | `undefined` | The amount of time in milliseconds to wait before auto-focusing the first focusable element. |
141
+ | `disableAutoFocus` | `boolean` | No | `false` | If true, the focus trap will not automatically shift focus to itself when it opens, and replace it to the last focused element when it closes. |
142
+ | `disableFocusTrap` | `boolean` | No | `-` | Disables the focus trap to allow normal keyboard navigation. |
143
+ | `disableTypeFocus` | `boolean` | No | `-` | Use for editable Search Input components to ensure focus is correctly applied |
144
+ | `focusTabIndexElements` | `boolean` | No | `false` | If true, the focus trap will include all elements with tabIndex values in the list of focusable elements. |
145
+ | `includeTriggerInFocusTrap` | `boolean` | No | `-` | If true, the focus trap will include the trigger in the focus trap. |
146
+ | `onEscPress` | `(() => void)` | No | `-` | - |
147
+ | `respectNegativeTabIndex` | `boolean` | No | `false` | If true, the focus trap will respect negative tabIndex values, removing them from the list of focusable elements. |
148
+ | `restoreFocusOnUnmount` | `boolean` | No | `false` | If true, the focus trap will restore focus to the previously focused element when it unmounts. |
149
+
150
+
@@ -1214,6 +1214,49 @@ function CustomLabelExample() {
1214
1214
  }
1215
1215
  ```
1216
1216
 
1217
+ ### Borderless
1218
+
1219
+ You can remove the border from the select control by setting `bordered` to `false`. Now Select will only show a border when focused.
1220
+
1221
+ ```jsx live
1222
+ function BorderlessExample() {
1223
+ const [singleValue, setSingleValue] = useState('1');
1224
+ const { value: multiValue, onChange: multiOnChange } = useMultiSelect({
1225
+ initialValue: ['1', '2'],
1226
+ });
1227
+
1228
+ const options = [
1229
+ { value: '1', label: 'Option 1' },
1230
+ { value: '2', label: 'Option 2' },
1231
+ { value: '3', label: 'Option 3' },
1232
+ { value: '4', label: 'Option 4' },
1233
+ ];
1234
+
1235
+ return (
1236
+ <VStack gap={4}>
1237
+ <Select
1238
+ bordered={false}
1239
+ label="Borderless single select"
1240
+ value={singleValue}
1241
+ onChange={setSingleValue}
1242
+ options={options}
1243
+ placeholder="Select an option"
1244
+ />
1245
+
1246
+ <Select
1247
+ bordered={false}
1248
+ type="multi"
1249
+ label="Borderless multi select"
1250
+ value={multiValue}
1251
+ onChange={multiOnChange}
1252
+ options={options}
1253
+ placeholder="Select options"
1254
+ />
1255
+ </VStack>
1256
+ );
1257
+ }
1258
+ ```
1259
+
1217
1260
  ### Custom components
1218
1261
 
1219
1262
  Select is highly customizable. Use the _Component_ props to customize the various subcomponents in Select.
@@ -1297,6 +1340,7 @@ function CustomComponentExamples() {
1297
1340
  | `SelectOptionGroupComponent` | `SelectOptionGroupComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render group headers |
1298
1341
  | `accessibilityRoles` | `{ dropdown?: AriaHasPopupType; option?: string \| undefined; } \| undefined` | No | `-` | Accessibility roles for dropdown and option elements |
1299
1342
  | `accessory` | `ReactElement<CellAccessoryProps, string \| JSXElementConstructor<any>>` | No | `-` | Accessory element rendered at the end of the cell (e.g., chevron). |
1343
+ | `bordered` | `boolean` | No | `true` | Add a border around all sides of the box. Determines if the control should have a default border. |
1300
1344
  | `className` | `string` | No | `-` | CSS class name for the root element |
1301
1345
  | `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 |
1302
1346
  | `clearAllLabel` | `string` | No | `-` | Label for the Clear All option in multi-select mode |
@@ -457,6 +457,7 @@ function ExampleDisabled() {
457
457
  | `SelectOptionGroupComponent` | `SelectOptionGroupComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render group headers |
458
458
  | `accessibilityRoles` | `{ dropdown?: AriaHasPopupType; option?: string \| undefined; } \| undefined` | No | `-` | Accessibility roles for dropdown and option elements |
459
459
  | `accessory` | `ReactElement<CellAccessoryProps, string \| JSXElementConstructor<any>>` | No | `-` | Accessory element rendered at the end of the cell (e.g., chevron). |
460
+ | `bordered` | `boolean` | No | `true` | Add a border around all sides of the box. Determines if the control should have a default border. |
460
461
  | `className` | `string` | No | `-` | CSS class name for the root element |
461
462
  | `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 |
462
463
  | `clearAllLabel` | `string` | No | `-` | Label for the Clear All option in multi-select mode |
@@ -28,6 +28,7 @@
28
28
  - [FullscreenModalLayout](web/components/FullscreenModalLayout.txt): Provides the layout structure, overlay, focus trapping, and animations for fullscreen modals. Intended for internal use within Modal component variants.
29
29
  - [FullscreenModal](web/components/FullscreenModal.txt): FullscreenModal is a component that displays content in a full-screen overlay, typically used for immersive experiences or complex interactions.
30
30
  - [FullscreenAlert](web/components/FullscreenAlert.txt): A fullscreen alert component for displaying important messages that require user attention.
31
+ - [FocusTrap](web/components/FocusTrap.txt): FocusTrap is a component that traps focus within its children.
31
32
  - [Alert](web/components/Alert.txt): A dialog that communicates critical information and blocks user interaction.
32
33
  - [ThemeProvider](web/components/ThemeProvider.txt): Provides the theme context to all child components, and automatically generates CSS Variables for dynamic theming.
33
34
  - [MediaQueryProvider](web/components/MediaQueryProvider.txt): Manages window.matchMedia subscriptions with SSR support.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coinbase/cds-mcp-server",
3
- "version": "8.37.0",
3
+ "version": "8.38.0",
4
4
  "description": "Coinbase Design System - MCP Server",
5
5
  "repository": {
6
6
  "type": "git",