@coinbase/cds-mobile 9.1.0 → 9.1.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 CHANGED
@@ -8,6 +8,12 @@ All notable changes to this project will be documented in this file.
8
8
 
9
9
  <!-- template-start -->
10
10
 
11
+ ## 9.1.1 (5/27/2026 PST)
12
+
13
+ #### 🐞 Fixes
14
+
15
+ - Fix: support inside label variant on select. [[#726](https://github.com/coinbase/cds/pull/726)]
16
+
11
17
  ## 9.1.0 (5/26/2026 PST)
12
18
 
13
19
  #### 🚀 Updates
@@ -1,4 +1,4 @@
1
- import { TouchableOpacity } from 'react-native';
1
+ import { type StyleProp, TouchableOpacity, type ViewStyle } from 'react-native';
2
2
  import type { SelectControlProps, SelectType } from './Select';
3
3
  type DefaultSelectControlComponent = <
4
4
  Type extends SelectType,
@@ -44,14 +44,14 @@ export declare const DefaultSelectControlComponent: import('react').NamedExoticC
44
44
  removeSelectedOptionAccessibilityLabel?: string;
45
45
  blendStyles?: import('../../system').InteractableBlendStyles;
46
46
  compact?: boolean;
47
- style?: import('react-native').StyleProp<import('react-native').ViewStyle>;
47
+ style?: StyleProp<ViewStyle>;
48
48
  styles?: {
49
- controlStartNode?: import('react-native').StyleProp<import('react-native').ViewStyle>;
50
- controlInputNode?: import('react-native').StyleProp<import('react-native').ViewStyle>;
51
- controlValueNode?: import('react-native').StyleProp<import('react-native').ViewStyle>;
52
- controlLabelNode?: import('react-native').StyleProp<import('react-native').ViewStyle>;
53
- controlHelperTextNode?: import('react-native').StyleProp<import('react-native').ViewStyle>;
54
- controlEndNode?: import('react-native').StyleProp<import('react-native').ViewStyle>;
49
+ controlStartNode?: StyleProp<ViewStyle>;
50
+ controlInputNode?: StyleProp<ViewStyle>;
51
+ controlValueNode?: StyleProp<ViewStyle>;
52
+ controlLabelNode?: StyleProp<ViewStyle>;
53
+ controlHelperTextNode?: StyleProp<ViewStyle>;
54
+ controlEndNode?: StyleProp<ViewStyle>;
55
55
  };
56
56
  } & import('react').RefAttributes<import('react-native').View>
57
57
  >;
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultSelectControl.d.ts","sourceRoot":"","sources":["../../../src/alpha/select/DefaultSelectControl.tsx"],"names":[],"mappings":"AACA,OAAO,EAAa,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAe3D,OAAO,KAAK,EAAE,kBAAkB,EAAgB,UAAU,EAAE,MAAM,UAAU,CAAC;AAY7E,KAAK,6BAA6B,GAAG,CACnC,IAAI,SAAS,UAAU,EACvB,iBAAiB,SAAS,MAAM,GAAG,MAAM,EAEzC,KAAK,EAAE,kBAAkB,CAAC,IAAI,EAAE,iBAAiB,CAAC,GAAG;IACnD,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,gBAAgB,CAAC,CAAC,CAAC;CAC9D,KACE,KAAK,CAAC,YAAY,CAAC;AAExB,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;wBAsPlC,CAAH;wBAEU,CAAC;wBAIgC,CAAA;wBAC9B,CAAC;6BACK,CAAC;sBAIb,CAAX;;+DAgIA,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAoC,6BAA6B,CAAC"}
1
+ {"version":3,"file":"DefaultSelectControl.d.ts","sourceRoot":"","sources":["../../../src/alpha/select/DefaultSelectControl.tsx"],"names":[],"mappings":"AACA,OAAO,EAAa,KAAK,SAAS,EAAE,gBAAgB,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAe3F,OAAO,KAAK,EAAE,kBAAkB,EAAgB,UAAU,EAAE,MAAM,UAAU,CAAC;AAY7E,KAAK,6BAA6B,GAAG,CACnC,IAAI,SAAS,UAAU,EACvB,iBAAiB,SAAS,MAAM,GAAG,MAAM,EAEzC,KAAK,EAAE,kBAAkB,CAAC,IAAI,EAAE,iBAAiB,CAAC,GAAG;IACnD,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,gBAAgB,CAAC,CAAC,CAAC;CAC9D,KACE,KAAK,CAAC,YAAY,CAAC;AAExB,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;wBA8OZ,CAAC;wBACoB,CAAC;wBAE1C,CAAR;wBAIO,CAAA;6BAKD,CAAH;sBAGU,CAAC;;+DA6Jf,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAoC,6BAA6B,CAAC"}
@@ -37,7 +37,7 @@ export const DefaultSelectControlComponent = /*#__PURE__*/memo(/*#__PURE__*/forw
37
37
  variant,
38
38
  helperText,
39
39
  label,
40
- labelVariant,
40
+ labelVariant: labelVariantProp,
41
41
  contentNode,
42
42
  startNode,
43
43
  endNode: customEndNode,
@@ -57,8 +57,11 @@ export const DefaultSelectControlComponent = /*#__PURE__*/memo(/*#__PURE__*/forw
57
57
  } = _ref,
58
58
  props = _objectWithoutPropertiesLoose(_ref, _excluded);
59
59
  const theme = useTheme();
60
+ // When compact, labelVariant is ignored
61
+ const labelVariant = compact ? undefined : labelVariantProp;
60
62
  const isMultiSelect = type === 'multi';
61
63
  const shouldShowCompactLabel = compact && label && !isMultiSelect;
64
+ const shouldShowInsideLabel = labelVariant === 'inside' && !compact && label;
62
65
  const hasValue = value !== null && !(Array.isArray(value) && value.length === 0);
63
66
 
64
67
  // Map of options to their values
@@ -128,18 +131,30 @@ export const DefaultSelectControlComponent = /*#__PURE__*/memo(/*#__PURE__*/forw
128
131
  style: styles == null ? void 0 : styles.controlHelperTextNode,
129
132
  children: helperText
130
133
  }) : helperText, [helperText, variant, styles == null ? void 0 : styles.controlHelperTextNode]);
131
- const labelNode = useMemo(() => typeof label === 'string' ? /*#__PURE__*/_jsx(Pressable, {
132
- disabled: disabled,
133
- onPress: () => setOpen(s => !s),
134
- style: styles == null ? void 0 : styles.controlLabelNode,
135
- children: /*#__PURE__*/_jsx(InputLabel, {
136
- color: "fg"
137
- // remove default vertical padding when label is the compact/inline version
138
- ,
139
- paddingY: shouldShowCompactLabel ? 0 : 0.5,
140
- children: label
141
- })
142
- }) : label, [disabled, label, setOpen, shouldShowCompactLabel, styles == null ? void 0 : styles.controlLabelNode]);
134
+ const labelNode = useMemo(() => {
135
+ if (shouldShowInsideLabel || shouldShowCompactLabel) return null;
136
+ if (typeof label === 'string') {
137
+ return /*#__PURE__*/_jsx(InputLabel, {
138
+ color: "fg",
139
+ paddingY: 0.5,
140
+ style: styles == null ? void 0 : styles.controlLabelNode,
141
+ children: label
142
+ });
143
+ }
144
+ return label;
145
+ }, [shouldShowInsideLabel, shouldShowCompactLabel, label, styles == null ? void 0 : styles.controlLabelNode]);
146
+ const inlineLabelNode = useMemo(() => {
147
+ if (!shouldShowInsideLabel && !shouldShowCompactLabel) return null;
148
+ if (typeof label === 'string') {
149
+ return /*#__PURE__*/_jsx(InputLabel, {
150
+ color: "fg",
151
+ paddingY: 0,
152
+ style: styles == null ? void 0 : styles.controlLabelNode,
153
+ children: label
154
+ });
155
+ }
156
+ return label;
157
+ }, [shouldShowInsideLabel, shouldShowCompactLabel, label, styles == null ? void 0 : styles.controlLabelNode]);
143
158
  const valueAlignment = useMemo(() => align === 'end' ? 'flex-end' : align === 'center' ? 'center' : 'flex-start', [align]);
144
159
  const valueNode = useMemo(() => {
145
160
  if (hasValue && isMultiSelect) {
@@ -221,8 +236,20 @@ export const DefaultSelectControlComponent = /*#__PURE__*/memo(/*#__PURE__*/forw
221
236
  alignItems: "center",
222
237
  maxWidth: "40%",
223
238
  paddingEnd: 1,
224
- children: labelNode
225
- }) : null, /*#__PURE__*/_jsxs(VStack, {
239
+ children: inlineLabelNode
240
+ }) : null, shouldShowInsideLabel ? /*#__PURE__*/_jsxs(VStack, {
241
+ flexGrow: 1,
242
+ minWidth: 0,
243
+ width: "100%",
244
+ children: [inlineLabelNode, /*#__PURE__*/_jsxs(VStack, {
245
+ alignItems: valueAlignment,
246
+ flexGrow: 1,
247
+ flexShrink: 1,
248
+ minWidth: 0,
249
+ style: styles == null ? void 0 : styles.controlValueNode,
250
+ children: [valueNode, contentNode]
251
+ })]
252
+ }) : /*#__PURE__*/_jsxs(VStack, {
226
253
  alignItems: valueAlignment,
227
254
  flexGrow: 1,
228
255
  flexShrink: 1,
@@ -232,7 +259,7 @@ export const DefaultSelectControlComponent = /*#__PURE__*/memo(/*#__PURE__*/forw
232
259
  })]
233
260
  })
234
261
  })
235
- })), [ref, computedControlAccessibilityLabel, disabled, onBlur, onFocus, styles == null ? void 0 : styles.controlInputNode, styles == null ? void 0 : styles.controlStartNode, styles == null ? void 0 : styles.controlValueNode, props, startNode, shouldShowCompactLabel, labelNode, valueAlignment, valueNode, contentNode, setOpen]);
262
+ })), [ref, computedControlAccessibilityLabel, disabled, onBlur, onFocus, styles == null ? void 0 : styles.controlInputNode, styles == null ? void 0 : styles.controlStartNode, styles == null ? void 0 : styles.controlValueNode, props, startNode, shouldShowCompactLabel, shouldShowInsideLabel, inlineLabelNode, valueAlignment, valueNode, contentNode, setOpen]);
236
263
  const endNode = useMemo(() => /*#__PURE__*/_jsx(Pressable, {
237
264
  accessible: customEndNode ? true : false,
238
265
  disabled: disabled,
@@ -249,13 +276,11 @@ export const DefaultSelectControlComponent = /*#__PURE__*/memo(/*#__PURE__*/forw
249
276
  })
250
277
  }), [styles == null ? void 0 : styles.controlEndNode, disabled, customEndNode, open, variant, setOpen]);
251
278
  const inputStackStyles = useMemo(() => ({
252
- input: {
253
- paddingTop: compact || labelVariant === 'inside' ? theme.space[1] : theme.space[2],
254
- paddingBottom: compact ? theme.space[1] : theme.space[2],
255
- paddingLeft: theme.space[2],
256
- paddingRight: theme.space[2]
257
- }
258
- }), [compact, theme, labelVariant]);
279
+ paddingTop: compact || labelVariant === 'inside' ? theme.space[1] : theme.space[2],
280
+ paddingBottom: compact || labelVariant === 'inside' ? theme.space[1] : theme.space[2],
281
+ paddingLeft: theme.space[2],
282
+ paddingRight: theme.space[2]
283
+ }), [compact, labelVariant, theme.space]);
259
284
  return /*#__PURE__*/_jsx(InputStack, _extends({
260
285
  borderFocusedStyle: borderFocusedStyle,
261
286
  borderStyle: borderUnfocusedStyle,
@@ -266,11 +291,13 @@ export const DefaultSelectControlComponent = /*#__PURE__*/memo(/*#__PURE__*/forw
266
291
  focusedBorderWidth: focusedBorderWidth,
267
292
  helperTextNode: helperTextNode,
268
293
  inputNode: inputNode,
269
- labelNode: shouldShowCompactLabel ? null : labelNode,
294
+ labelNode: labelNode,
270
295
  labelVariant: labelVariant,
271
296
  onBlur: onBlur,
272
297
  onFocus: onFocus,
273
- styles: inputStackStyles,
298
+ styles: {
299
+ input: inputStackStyles
300
+ },
274
301
  variant: variant
275
302
  }, props));
276
303
  }));
@@ -1,24 +1,41 @@
1
- import React, { memo, useState } from 'react';
1
+ import { memo, useState } from 'react';
2
2
  import { Select } from '../../../../alpha/select/Select';
3
3
  import { VStack } from '../../../../layout/VStack';
4
4
  import { stickerSheetSelectOptions } from './constants';
5
5
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
6
6
  export const SelectExample = /*#__PURE__*/memo(() => {
7
- const [value, setValue] = useState('btc');
8
- const [secondaryValue, setSecondaryValue] = useState(null);
7
+ const [selectValue, setSelectValue] = useState(null);
9
8
  return /*#__PURE__*/_jsxs(VStack, {
10
9
  gap: 1,
11
10
  width: "100%",
12
11
  children: [/*#__PURE__*/_jsx(Select, {
13
- label: "Asset",
14
- onChange: setValue,
12
+ label: "Label",
13
+ onChange: setSelectValue,
15
14
  options: stickerSheetSelectOptions,
16
- value: value
15
+ placeholder: "Outside label",
16
+ value: selectValue
17
17
  }), /*#__PURE__*/_jsx(Select, {
18
- label: "Asset (empty)",
19
- onChange: setSecondaryValue,
18
+ label: "Label",
19
+ labelVariant: "inside",
20
+ onChange: setSelectValue,
20
21
  options: stickerSheetSelectOptions,
21
- value: secondaryValue
22
+ placeholder: "Inside label",
23
+ value: selectValue
24
+ }), /*#__PURE__*/_jsx(Select, {
25
+ compact: true,
26
+ label: "Label",
27
+ onChange: setSelectValue,
28
+ options: stickerSheetSelectOptions,
29
+ placeholder: "Compact input",
30
+ value: selectValue
31
+ }), /*#__PURE__*/_jsx(Select, {
32
+ compact: true,
33
+ align: "end",
34
+ label: "Label",
35
+ onChange: setSelectValue,
36
+ options: stickerSheetSelectOptions,
37
+ placeholder: "Compact end align",
38
+ value: selectValue
22
39
  })]
23
40
  });
24
41
  });
@@ -1,22 +1,26 @@
1
- import React, { memo, useState } from 'react';
2
- import { SelectChip } from '../../../../chips/SelectChip';
3
- import { SelectOption } from '../../../../controls/SelectOption';
4
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { memo, useState } from 'react';
2
+ import { SelectChip } from '../../../../alpha/select-chip/SelectChip';
3
+ import { jsx as _jsx } from "react/jsx-runtime";
4
+ const selectChipOptions = [{
5
+ value: 'USD',
6
+ label: 'USD'
7
+ }, {
8
+ value: 'CAD',
9
+ label: 'CAD'
10
+ }, {
11
+ value: 'GBP',
12
+ label: 'GBP'
13
+ }, {
14
+ value: 'JPY',
15
+ label: 'JPY'
16
+ }];
5
17
  export const SelectChipExample = /*#__PURE__*/memo(() => {
6
- const [value, setValue] = useState('Balance');
7
- return /*#__PURE__*/_jsxs(SelectChip, {
18
+ const [value, setValue] = useState(null);
19
+ return /*#__PURE__*/_jsx(SelectChip, {
20
+ accessibilityLabel: "Select a currency",
8
21
  onChange: setValue,
9
- placeholder: "Sort",
10
- value: value,
11
- children: [/*#__PURE__*/_jsx(SelectOption, {
12
- title: "Balance",
13
- value: "Balance"
14
- }), /*#__PURE__*/_jsx(SelectOption, {
15
- title: "Name",
16
- value: "Name"
17
- }), /*#__PURE__*/_jsx(SelectOption, {
18
- title: "Asset Value",
19
- value: "Asset Value"
20
- })]
22
+ options: selectChipOptions,
23
+ placeholder: "Currency",
24
+ value: value
21
25
  });
22
26
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coinbase/cds-mobile",
3
- "version": "9.1.0",
3
+ "version": "9.1.1",
4
4
  "description": "Coinbase Design System - Mobile",
5
5
  "repository": {
6
6
  "type": "git",
@@ -202,7 +202,7 @@
202
202
  "react-native-worklets": "0.5.2"
203
203
  },
204
204
  "dependencies": {
205
- "@coinbase/cds-common": "^9.1.0",
205
+ "@coinbase/cds-common": "^9.1.1",
206
206
  "@coinbase/cds-icons": "^5.17.0",
207
207
  "@coinbase/cds-illustrations": "^4.40.1",
208
208
  "@coinbase/cds-lottie-files": "^3.3.4",