@coinbase/cds-mobile 9.9.0 → 9.10.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.
Files changed (103) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dts/alpha/combobox/Combobox.d.ts.map +1 -1
  3. package/dts/alpha/select/DefaultSelectControl.d.ts +1 -0
  4. package/dts/alpha/select/DefaultSelectControl.d.ts.map +1 -1
  5. package/dts/alpha/select/DefaultSelectDropdown.d.ts.map +1 -1
  6. package/dts/alpha/select/Select.d.ts +1 -0
  7. package/dts/alpha/select/Select.d.ts.map +1 -1
  8. package/dts/alpha/select/types.d.ts +27 -2
  9. package/dts/alpha/select/types.d.ts.map +1 -1
  10. package/dts/alpha/select-chip/SelectChip.d.ts +8 -2
  11. package/dts/alpha/select-chip/SelectChip.d.ts.map +1 -1
  12. package/dts/alpha/select-chip/SelectChipControl.d.ts +3 -4
  13. package/dts/alpha/select-chip/SelectChipControl.d.ts.map +1 -1
  14. package/dts/alpha/tabbed-chips/TabbedChips.d.ts +8 -1
  15. package/dts/alpha/tabbed-chips/TabbedChips.d.ts.map +1 -1
  16. package/dts/buttons/AvatarButton.d.ts +7 -3
  17. package/dts/buttons/AvatarButton.d.ts.map +1 -1
  18. package/dts/buttons/Button.d.ts +21 -2
  19. package/dts/buttons/Button.d.ts.map +1 -1
  20. package/dts/buttons/DefaultSlideButtonBackground.d.ts +2 -2
  21. package/dts/buttons/DefaultSlideButtonBackground.d.ts.map +1 -1
  22. package/dts/buttons/DefaultSlideButtonHandle.d.ts +20 -10
  23. package/dts/buttons/DefaultSlideButtonHandle.d.ts.map +1 -1
  24. package/dts/buttons/IconButton.d.ts +18 -5
  25. package/dts/buttons/IconButton.d.ts.map +1 -1
  26. package/dts/buttons/SlideButton.d.ts +47 -9
  27. package/dts/buttons/SlideButton.d.ts.map +1 -1
  28. package/dts/cards/CardBody.d.ts.map +1 -1
  29. package/dts/cards/FeedCard.d.ts.map +1 -1
  30. package/dts/cards/NudgeCard.d.ts +1 -1
  31. package/dts/cards/UpsellCard.d.ts +1 -1
  32. package/dts/carousel/DefaultCarouselNavigation.d.ts +8 -0
  33. package/dts/carousel/DefaultCarouselNavigation.d.ts.map +1 -1
  34. package/dts/chips/Chip.d.ts +3 -2
  35. package/dts/chips/Chip.d.ts.map +1 -1
  36. package/dts/chips/ChipProps.d.ts +11 -1
  37. package/dts/chips/ChipProps.d.ts.map +1 -1
  38. package/dts/chips/MediaChip.d.ts +1 -0
  39. package/dts/chips/MediaChip.d.ts.map +1 -1
  40. package/dts/controls/InputIcon.d.ts +6 -0
  41. package/dts/controls/InputIcon.d.ts.map +1 -1
  42. package/dts/controls/InputIconButton.d.ts +3 -1
  43. package/dts/controls/InputIconButton.d.ts.map +1 -1
  44. package/dts/controls/InputStack.d.ts.map +1 -1
  45. package/dts/controls/NativeInput.d.ts +7 -2
  46. package/dts/controls/NativeInput.d.ts.map +1 -1
  47. package/dts/controls/SearchInput.d.ts +4 -1
  48. package/dts/controls/SearchInput.d.ts.map +1 -1
  49. package/dts/controls/TextInput.d.ts +24 -2
  50. package/dts/controls/TextInput.d.ts.map +1 -1
  51. package/dts/dates/DateInput.d.ts +18 -3
  52. package/dts/dates/DateInput.d.ts.map +1 -1
  53. package/dts/dates/DatePicker.d.ts +13 -0
  54. package/dts/dates/DatePicker.d.ts.map +1 -1
  55. package/dts/gradients/LinearGradient.d.ts.map +1 -1
  56. package/dts/navigation/BrowserBarSearchInput.d.ts +1 -1
  57. package/dts/navigation/BrowserBarSearchInput.d.ts.map +1 -1
  58. package/esm/__stories__/SizeComposition.stories.js +237 -0
  59. package/esm/alpha/combobox/Combobox.js +1 -1
  60. package/esm/alpha/combobox/__stories__/Combobox.stories.js +34 -0
  61. package/esm/alpha/select/DefaultSelectControl.js +71 -22
  62. package/esm/alpha/select/DefaultSelectDropdown.js +5 -2
  63. package/esm/alpha/select/Select.js +9 -3
  64. package/esm/alpha/select/__stories__/AlphaSelect.stories.js +31 -0
  65. package/esm/alpha/select/types.js +8 -0
  66. package/esm/alpha/select-chip/SelectChip.js +14 -7
  67. package/esm/alpha/select-chip/SelectChipControl.js +2 -0
  68. package/esm/alpha/select-chip/__stories__/AlphaSelectChip.stories.js +31 -1
  69. package/esm/alpha/tabbed-chips/TabbedChips.js +8 -5
  70. package/esm/alpha/tabbed-chips/__stories__/AlphaTabbedChips.stories.js +23 -12
  71. package/esm/buttons/Button.js +52 -7
  72. package/esm/buttons/DefaultSlideButtonBackground.js +3 -2
  73. package/esm/buttons/DefaultSlideButtonHandle.js +13 -12
  74. package/esm/buttons/IconButton.js +38 -4
  75. package/esm/buttons/SlideButton.js +34 -6
  76. package/esm/buttons/__stories__/Button.stories.js +46 -16
  77. package/esm/buttons/__stories__/IconButton.stories.js +58 -11
  78. package/esm/buttons/__stories__/SlideButton.stories.js +18 -9
  79. package/esm/cards/CardBody.js +7 -2
  80. package/esm/cards/FeedCard.js +23 -8
  81. package/esm/cards/MessagingCard/MessagingCardLayout.js +2 -2
  82. package/esm/cards/NudgeCard.js +1 -1
  83. package/esm/cards/UpsellCard.js +2 -2
  84. package/esm/carousel/DefaultCarouselNavigation.js +11 -3
  85. package/esm/chips/Chip.js +24 -6
  86. package/esm/chips/MediaChip.js +7 -3
  87. package/esm/chips/__stories__/Chip.stories.js +9 -3
  88. package/esm/chips/__stories__/InputChip.stories.js +19 -1
  89. package/esm/controls/InputStack.js +6 -2
  90. package/esm/controls/NativeInput.js +7 -2
  91. package/esm/controls/SearchInput.js +2 -0
  92. package/esm/controls/TextInput.js +42 -16
  93. package/esm/controls/__stories__/SearchInput.stories.js +28 -1
  94. package/esm/controls/__stories__/TextInput.stories.js +82 -0
  95. package/esm/dates/DateInput.js +2 -1
  96. package/esm/dates/DatePicker.js +4 -2
  97. package/esm/dates/__stories__/DateInput.stories.js +28 -0
  98. package/esm/dates/__stories__/DatePicker.stories.js +23 -0
  99. package/esm/gradients/LinearGradient.js +32 -7
  100. package/esm/navigation/BrowserBarSearchInput.js +8 -4
  101. package/esm/overlays/Toast.js +1 -1
  102. package/esm/visualizations/ProgressContainerWithButtons.js +2 -2
  103. package/package.json +2 -2
@@ -36,7 +36,25 @@ const InputChipScreen = () => {
36
36
  children: "USD"
37
37
  })]
38
38
  }), /*#__PURE__*/_jsxs(Example, {
39
- title: "Compact",
39
+ title: "Size xs",
40
+ children: [/*#__PURE__*/_jsx(InputChip, {
41
+ onPress: NoopFn,
42
+ size: "xs",
43
+ children: "USD"
44
+ }), /*#__PURE__*/_jsx(InputChip, {
45
+ onPress: NoopFn,
46
+ size: "xs",
47
+ start: /*#__PURE__*/_jsx(RemoteImage, _extends({}, compactMediaProps)),
48
+ children: "USD"
49
+ }), /*#__PURE__*/_jsx(InputChip, {
50
+ disabled: true,
51
+ onPress: NoopFn,
52
+ size: "xs",
53
+ start: /*#__PURE__*/_jsx(RemoteImage, _extends({}, compactMediaProps)),
54
+ children: "USD"
55
+ })]
56
+ }), /*#__PURE__*/_jsxs(Example, {
57
+ title: "Compact (deprecated)",
40
58
  children: [/*#__PURE__*/_jsx(InputChip, {
41
59
  compact: true,
42
60
  onPress: NoopFn,
@@ -123,9 +123,13 @@ export const InputStack = /*#__PURE__*/memo(function InputStack(_props) {
123
123
  background: variant ? variantColorMap[variant] : undefined
124
124
  }), !!startNode && /*#__PURE__*/_jsx(_Fragment, {
125
125
  children: startNode
126
- }), !!labelNode && labelVariant === 'inside' ? /*#__PURE__*/_jsxs(VStack, {
126
+ }), !!labelNode && labelVariant === 'inside' ?
127
+ /*#__PURE__*/
128
+ // A stacked inside label tightens its top/bottom spacing so the label + input still
129
+ // fit the same natural field height an outside label produces.
130
+ _jsxs(VStack, {
127
131
  flexGrow: 1,
128
- paddingY: 1,
132
+ paddingY: 0.75,
129
133
  children: [labelNode, inputNode]
130
134
  }) : inputNode, !!endNode && /*#__PURE__*/_jsx(_Fragment, {
131
135
  children: endNode
@@ -23,7 +23,7 @@ export const NativeInput = /*#__PURE__*/memo(_ref => {
23
23
  editableInputAddonProps = _objectWithoutPropertiesLoose(_ref, _excluded);
24
24
  const theme = useTheme();
25
25
  const textAlignInputTransformed = useTextAlign(align).textAlign;
26
- const inputTextStyle = useMemo(() => ({
26
+ const inputTextStyle = useMemo(() => _extends({
27
27
  fontSize: theme.fontSize[font],
28
28
  fontFamily: theme.fontFamily[font],
29
29
  minHeight: theme.lineHeight[font],
@@ -31,8 +31,13 @@ export const NativeInput = /*#__PURE__*/memo(_ref => {
31
31
  padding: 0,
32
32
  margin: 0,
33
33
  color: theme.color.fg
34
- }), [theme.fontSize, theme.fontFamily, theme.lineHeight, theme.fontWeight, theme.color.fg, font]);
34
+ }, editableInputAddonProps.multiline ? null : {
35
+ textAlignVertical: 'center'
36
+ }), [theme.fontSize, theme.fontFamily, theme.lineHeight, theme.fontWeight, theme.color.fg, font, editableInputAddonProps.multiline]);
35
37
  const containerStyle = useMemo(() => {
38
+ // NativeInput has no `size` prop, so the deprecated `compact` still drives its own base
39
+ // padding here. When rendered inside TextInput, `containerSpacing` (size-derived) is
40
+ // spread after and overrides this fallback.
36
41
  return _extends({
37
42
  flex: 2,
38
43
  minWidth: 0,
@@ -8,6 +8,8 @@ import { useComponentConfig } from '../hooks/useComponentConfig';
8
8
  import { Box } from '../layout/Box';
9
9
  import { InputIconButton } from './InputIconButton';
10
10
  import { TextInput } from './TextInput';
11
+
12
+ /** T-shirt size for SearchInput. Aliases the TextInput size union. */
11
13
  import { jsx as _jsx } from "react/jsx-runtime";
12
14
  export const SearchInput = /*#__PURE__*/memo(_ref => {
13
15
  let {
@@ -1,5 +1,5 @@
1
1
  const _excluded = ["ref"],
2
- _excluded2 = ["label", "labelFont", "labelColor", "helperText", "variant", "testID", "testIDMap", "start", "end", "width", "disabled", "align", "font", "compact", "suffix", "accessibilityLabel", "borderRadius", "enableColorSurge", "helperTextErrorIconAccessibilityLabel", "bordered", "focusedBorderWidth", "labelVariant", "labelNode", "inputBackground"];
2
+ _excluded2 = ["label", "labelFont", "labelColor", "helperText", "variant", "testID", "testIDMap", "start", "end", "width", "disabled", "align", "font", "compact", "size", "suffix", "accessibilityLabel", "borderRadius", "enableColorSurge", "helperTextErrorIconAccessibilityLabel", "bordered", "focusedBorderWidth", "labelVariant", "labelNode", "inputBackground"];
3
3
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
4
4
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
5
5
  import React, { cloneElement, isValidElement, memo, useCallback, useMemo, useRef, useState } from 'react';
@@ -19,6 +19,7 @@ import { InputLabel } from './InputLabel';
19
19
  import { InputStack } from './InputStack';
20
20
  import { NativeInput } from './NativeInput';
21
21
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
22
+ const defaultTextInputSize = 'l';
22
23
  const variantColorMap = {
23
24
  primary: 'fgPrimary',
24
25
  positive: 'fgPositive',
@@ -48,7 +49,8 @@ export const TextInput = /*#__PURE__*/memo(_ref => {
48
49
  disabled = false,
49
50
  align = 'start',
50
51
  font = 'body',
51
- compact,
52
+ compact = false,
53
+ size,
52
54
  suffix = '',
53
55
  accessibilityLabel,
54
56
  borderRadius,
@@ -88,12 +90,36 @@ export const TextInput = /*#__PURE__*/memo(_ref => {
88
90
  }
89
91
  }, [setFocused, internalRef, editableInputAddonProps.readOnly]);
90
92
  const hasLabel = useMemo(() => !!label || !!labelNode, [label, labelNode]);
91
- const containerSpacing = useMemo(() => _extends({}, !!start && {
92
- paddingStart: theme.space[0.5]
93
- }, labelVariant === 'inside' && hasLabel && !compact && {
94
- paddingBottom: 0,
95
- paddingTop: 0
96
- }), [start, theme.space, labelVariant, hasLabel, compact]);
93
+
94
+ // Geometry is driven entirely by the resolved size. An explicit `size` always wins;
95
+ // the deprecated `compact` only maps to `s` as a fallback so legacy callers keep dense spacing.
96
+ const resolvedSize = size != null ? size : compact ? 's' : defaultTextInputSize;
97
+ // compact only forces label placement (inline start slot) when the caller did NOT set an
98
+ // explicit size. Once `size` is provided, label placement follows normal `labelVariant` rules.
99
+ const isCompactLabel = Boolean(compact) && size === undefined;
100
+
101
+ // Label placement is independent of size. `compact` (set alone) forces an inside label;
102
+ // otherwise placement follows `labelVariant`. An inside label sits horizontally in the start
103
+ // slot at every size EXCEPT `l`, where it stacks vertically above the input.
104
+ const wantsInsideLabel = hasLabel && (isCompactLabel || labelVariant === 'inside');
105
+ const insideVerticalLabel = wantsInsideLabel && !isCompactLabel && resolvedSize === 'l';
106
+ const insideHorizontalLabel = wantsInsideLabel && !insideVerticalLabel;
107
+ const containerSpacing = useMemo(() => {
108
+ const verticalPad = resolvedSize === 'l' ? 2 : resolvedSize === 'm' ? 1.5 : 1;
109
+ return _extends({
110
+ // Horizontal padding is size-invariant. A start node contributes 0.5 here and supplies the
111
+ // rest of the gap itself (e.g. InputIcon's own padding); an inline label needs a 1 gap to
112
+ // the input text. A start node wins when both are present, since it's the input's neighbor.
113
+ paddingStart: theme.space[start ? 0.5 : insideHorizontalLabel ? 1 : 2],
114
+ paddingEnd: theme.space[2],
115
+ // A vertical inside label (size `l`) gets its top/bottom spacing from the stacking wrapper;
116
+ // every other placement keeps the per-size padding here.
117
+ paddingTop: insideVerticalLabel ? 0 : theme.space[verticalPad],
118
+ paddingBottom: insideVerticalLabel ? 0 : theme.space[verticalPad]
119
+ }, insideVerticalLabel ? null : {
120
+ minHeight: theme.space[verticalPad] * 2 + theme.lineHeight[font]
121
+ });
122
+ }, [start, theme.space, theme.lineHeight, font, insideHorizontalLabel, insideVerticalLabel, resolvedSize]);
97
123
 
98
124
  // Get the accessability label from the start node child
99
125
  const startIconA11yLabel = useMemo(() => {
@@ -167,23 +193,23 @@ export const TextInput = /*#__PURE__*/memo(_ref => {
167
193
  accessibilityHint: typeof helperText === 'string' ? helperText : undefined,
168
194
  accessibilityLabel: accessibilityLabel != null ? accessibilityLabel : label,
169
195
  align: align,
170
- compact: compact,
196
+ compact: resolvedSize === 's',
171
197
  containerSpacing: containerSpacing,
172
198
  disabled: disabled,
173
199
  font: font,
174
200
  selectionColor: variantColorMap[focusedVariant],
175
201
  testID: testID
176
202
  }, editableInputAddonProps)),
177
- labelNode: !compact && (labelNode && labelVariant !== 'inside' ? labelNode : hasLabel && /*#__PURE__*/_jsx(Pressable, {
203
+ labelNode: !insideHorizontalLabel && (labelNode && !insideVerticalLabel ? labelNode : hasLabel && /*#__PURE__*/_jsx(Pressable, {
178
204
  accessibilityRole: "button",
179
205
  disabled: disabled,
180
206
  onPress: handleNodePress,
181
- children: labelVariant === 'inside' && labelNode ? /*#__PURE__*/_jsx(Box, {
207
+ children: insideVerticalLabel && labelNode ? /*#__PURE__*/_jsx(Box, {
182
208
  background: readOnlyInputBackground,
183
209
  paddingEnd: 2,
184
210
  paddingStart: start ? 0.5 : 2,
185
211
  children: labelNode
186
- }) : labelVariant === 'inside' ? /*#__PURE__*/_jsx(InputLabel, {
212
+ }) : insideVerticalLabel ? /*#__PURE__*/_jsx(InputLabel, {
187
213
  background: readOnlyInputBackground,
188
214
  color: labelColor,
189
215
  font: labelFont,
@@ -199,8 +225,8 @@ export const TextInput = /*#__PURE__*/memo(_ref => {
199
225
  children: label
200
226
  })
201
227
  })),
202
- labelVariant: labelVariant,
203
- startNode: (compact && hasLabel || !!start) && /*#__PURE__*/_jsx(Box, {
228
+ labelVariant: insideVerticalLabel ? 'inside' : 'outside',
229
+ startNode: (insideHorizontalLabel && hasLabel || !!start) && /*#__PURE__*/_jsx(Box, {
204
230
  alignItems: "center",
205
231
  background: readOnlyInputBackground,
206
232
  justifyContent: "center",
@@ -214,8 +240,8 @@ export const TextInput = /*#__PURE__*/memo(_ref => {
214
240
  importantForAccessibility: startIconA11yLabel ? 'auto' : 'no',
215
241
  onPress: handleNodePress,
216
242
  children: /*#__PURE__*/_jsxs(HStack, {
217
- paddingStart: compact && hasLabel ? 2 : undefined,
218
- children: [compact && (labelNode ? labelNode : !!label && /*#__PURE__*/_jsx(InputLabel, {
243
+ paddingStart: insideHorizontalLabel && hasLabel ? 2 : undefined,
244
+ children: [insideHorizontalLabel && (labelNode ? labelNode : !!label && /*#__PURE__*/_jsx(InputLabel, {
219
245
  color: labelColor,
220
246
  font: labelFont,
221
247
  children: label
@@ -13,6 +13,30 @@ const Basic = () => {
13
13
  value: text
14
14
  });
15
15
  };
16
+ const Sizes = () => {
17
+ const [text, setText] = useState('');
18
+ return /*#__PURE__*/_jsxs(VStack, {
19
+ gap: 2,
20
+ children: [/*#__PURE__*/_jsx(SearchInput, {
21
+ editable: __DEV__,
22
+ onChangeText: setText,
23
+ size: "s",
24
+ value: text
25
+ }), /*#__PURE__*/_jsx(SearchInput, {
26
+ editable: __DEV__,
27
+ onChangeText: setText,
28
+ size: "m",
29
+ value: text
30
+ }), /*#__PURE__*/_jsx(SearchInput, {
31
+ editable: __DEV__,
32
+ onChangeText: setText,
33
+ size: "l",
34
+ value: text
35
+ })]
36
+ });
37
+ };
38
+
39
+ /** `compact` is deprecated in favor of `size="s"`; kept here to verify legacy behavior. */
16
40
  const Compact = () => {
17
41
  const [text, setText] = useState('');
18
42
  return /*#__PURE__*/_jsx(SearchInput, {
@@ -196,7 +220,10 @@ const SearchInputScreen = () => {
196
220
  title: "Custom Ref",
197
221
  children: /*#__PURE__*/_jsx(CustomRef, {})
198
222
  }), /*#__PURE__*/_jsx(Example, {
199
- title: "Compact",
223
+ title: "Sizes",
224
+ children: /*#__PURE__*/_jsx(Sizes, {})
225
+ }), /*#__PURE__*/_jsx(Example, {
226
+ title: "Deprecated compact (renders as size s)",
200
227
  children: /*#__PURE__*/_jsx(Compact, {})
201
228
  }), /*#__PURE__*/_jsx(Example, {
202
229
  title: "Borderless variants",
@@ -34,6 +34,15 @@ const MockCompactTextInput = _ref2 => {
34
34
  value: text
35
35
  }, props));
36
36
  };
37
+ const MockSizeTextInput = _ref3 => {
38
+ let props = _extends({}, (_objectDestructuringEmpty(_ref3), _ref3));
39
+ const [text, onChangeText] = useState('');
40
+ return /*#__PURE__*/_jsx(TextInput, _extends({
41
+ editable: __DEV__,
42
+ onChangeText: onChangeText,
43
+ value: text
44
+ }, props));
45
+ };
37
46
  const MockComplexInput = () => {
38
47
  const [text, onChangeText] = useState('');
39
48
  return /*#__PURE__*/_jsxs(HStack, {
@@ -330,6 +339,79 @@ const InputScreen = () => {
330
339
  placeholder: "189-280-1111",
331
340
  variant: "foregroundMuted"
332
341
  })
342
+ }), /*#__PURE__*/_jsxs(Example, {
343
+ inline: true,
344
+ title: "TextInput Sizes",
345
+ children: [/*#__PURE__*/_jsx(MockSizeTextInput, {
346
+ label: "Small (s)",
347
+ placeholder: "Small",
348
+ size: "s"
349
+ }), /*#__PURE__*/_jsx(MockSizeTextInput, {
350
+ label: "Medium (m)",
351
+ placeholder: "Medium",
352
+ size: "m"
353
+ }), /*#__PURE__*/_jsx(MockSizeTextInput, {
354
+ label: "Large (l) - default",
355
+ placeholder: "Large",
356
+ size: "l"
357
+ })]
358
+ }), /*#__PURE__*/_jsx(Example, {
359
+ inline: true,
360
+ title: "TextInput Size S Inside Label",
361
+ children: /*#__PURE__*/_jsx(MockSizeTextInput, {
362
+ label: "Inside Label",
363
+ labelVariant: "inside",
364
+ placeholder: "Small",
365
+ size: "s"
366
+ })
367
+ }), /*#__PURE__*/_jsx(Example, {
368
+ inline: true,
369
+ title: "TextInput Size M Inside Label",
370
+ children: /*#__PURE__*/_jsx(MockSizeTextInput, {
371
+ label: "Inside Label",
372
+ labelVariant: "inside",
373
+ placeholder: "Medium",
374
+ size: "m"
375
+ })
376
+ }), /*#__PURE__*/_jsx(Example, {
377
+ inline: true,
378
+ title: "TextInput Size S with suffix",
379
+ children: /*#__PURE__*/_jsx(MockSizeTextInput, {
380
+ label: "Label",
381
+ placeholder: "0.00",
382
+ size: "s",
383
+ suffix: "USD"
384
+ })
385
+ }), /*#__PURE__*/_jsx(Example, {
386
+ inline: true,
387
+ title: "TextInput Size S with start node",
388
+ children: /*#__PURE__*/_jsx(MockSizeTextInput, {
389
+ label: "Label",
390
+ placeholder: "189-280-1111",
391
+ size: "s",
392
+ start: /*#__PURE__*/_jsx(HStack, {
393
+ accessibilityHint: "Start Node",
394
+ accessibilityLabel: "Start Node",
395
+ children: /*#__PURE__*/_jsx(Text, {
396
+ font: "body",
397
+ children: "Start"
398
+ })
399
+ })
400
+ })
401
+ }), /*#__PURE__*/_jsx(Example, {
402
+ inline: true,
403
+ title: "TextInput Size S with end node",
404
+ children: /*#__PURE__*/_jsx(MockSizeTextInput, {
405
+ end: /*#__PURE__*/_jsx(Text, {
406
+ accessibilityHint: "Cancel",
407
+ accessibilityLabel: "Cancel",
408
+ font: "body",
409
+ children: "End"
410
+ }),
411
+ label: "Label",
412
+ placeholder: "189-280-1111",
413
+ size: "s"
414
+ })
333
415
  }), /*#__PURE__*/_jsx(Example, {
334
416
  inline: true,
335
417
  title: "CompactTextInput",
@@ -11,6 +11,7 @@ import { useComponentConfig } from '../hooks/useComponentConfig';
11
11
  import { VStack } from '../layout/VStack';
12
12
  import { jsx as _jsx } from "react/jsx-runtime";
13
13
  export const DateInput = /*#__PURE__*/memo(_ref => {
14
+ var _ref2;
14
15
  let {
15
16
  ref
16
17
  } = _ref,
@@ -99,7 +100,7 @@ export const DateInput = /*#__PURE__*/memo(_ref => {
99
100
  children: /*#__PURE__*/_jsx(TextInput, _extends({
100
101
  ref: ref,
101
102
  end: end,
102
- helperText: helperText || (error == null ? void 0 : error.message) || intlDateFormat.dateStringFormat,
103
+ helperText: (_ref2 = helperText != null ? helperText : error == null ? void 0 : error.message) != null ? _ref2 : intlDateFormat.dateStringFormat,
103
104
  keyboardType: "number-pad",
104
105
  onBlur: handleBlur,
105
106
  onChange: handleChange,
@@ -1,5 +1,5 @@
1
1
  const _excluded = ["ref"],
2
- _excluded2 = ["date", "styles", "highlightedDates", "highlightedDateAccessibilityHint", "nextArrowAccessibilityLabel", "previousArrowAccessibilityLabel", "disabledDates", "onChangeDate", "error", "onErrorDate", "required", "disabled", "seedDate", "minDate", "maxDate", "requiredError", "invalidDateError", "disabledDateError", "label", "accessibilityHint", "accessibilityLabel", "accessibilityLabelledBy", "calendarIconButtonAccessibilityLabel", "openCalendarAccessibilityLabel", "closeCalendarAccessibilityLabel", "dateInputStyle", "compact", "variant", "confirmText", "confirmButtonAccessibilityHint", "helperText", "width", "onOpen", "onClose", "onConfirm", "onCancel", "onChange"];
2
+ _excluded2 = ["date", "styles", "highlightedDates", "highlightedDateAccessibilityHint", "nextArrowAccessibilityLabel", "previousArrowAccessibilityLabel", "disabledDates", "onChangeDate", "error", "onErrorDate", "required", "disabled", "seedDate", "minDate", "maxDate", "requiredError", "invalidDateError", "disabledDateError", "label", "accessibilityHint", "accessibilityLabel", "accessibilityLabelledBy", "calendarIconButtonAccessibilityLabel", "openCalendarAccessibilityLabel", "closeCalendarAccessibilityLabel", "dateInputStyle", "compact", "size", "variant", "confirmText", "confirmButtonAccessibilityHint", "helperText", "width", "onOpen", "onClose", "onConfirm", "onCancel", "onChange"];
3
3
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
4
4
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
5
5
  import { memo, useCallback, useMemo, useRef, useState } from 'react';
@@ -47,6 +47,7 @@ export const DatePicker = /*#__PURE__*/memo(_ref => {
47
47
  closeCalendarAccessibilityLabel = 'Close calendar without selecting a date',
48
48
  dateInputStyle,
49
49
  compact,
50
+ size,
50
51
  variant,
51
52
  confirmText = 'Confirm',
52
53
  confirmButtonAccessibilityHint,
@@ -143,6 +144,7 @@ export const DatePicker = /*#__PURE__*/memo(_ref => {
143
144
  onErrorDate: onErrorDate,
144
145
  required: required,
145
146
  requiredError: requiredError,
147
+ size: size,
146
148
  style: [dateInputStyle, styles == null ? void 0 : styles.dateInput],
147
149
  variant: variant
148
150
  }, props)), showPicker && /*#__PURE__*/_jsx(Tray, {
@@ -155,7 +157,6 @@ export const DatePicker = /*#__PURE__*/memo(_ref => {
155
157
  role: "none",
156
158
  children: /*#__PURE__*/_jsx(Button, {
157
159
  block: true,
158
- compact: true,
159
160
  accessibilityHint: confirmButtonAccessibilityHint,
160
161
  disabled: disabled || !calendarSelectedDate,
161
162
  onPress: () => {
@@ -164,6 +165,7 @@ export const DatePicker = /*#__PURE__*/memo(_ref => {
164
165
  handleClose();
165
166
  }
166
167
  },
168
+ size: "s",
167
169
  children: confirmText
168
170
  })
169
171
  });
@@ -92,6 +92,34 @@ export const Examples = () => {
92
92
  })
93
93
  });
94
94
  };
95
+ export const Sizes = () => {
96
+ const [date, setDate] = useState(null);
97
+ const [error, setError] = useState(null);
98
+ const props = {
99
+ date,
100
+ onChangeDate: setDate,
101
+ error,
102
+ onErrorDate: setError
103
+ };
104
+ return /*#__PURE__*/_jsx(ExampleScreen, {
105
+ children: /*#__PURE__*/_jsx(Example, {
106
+ title: "DateInput sizes",
107
+ children: /*#__PURE__*/_jsxs(Group, {
108
+ gap: 8,
109
+ paddingEnd: 8,
110
+ children: [/*#__PURE__*/_jsx(DateInput, _extends({
111
+ size: "s"
112
+ }, sharedProps, props)), /*#__PURE__*/_jsx(DateInput, _extends({
113
+ size: "m"
114
+ }, sharedProps, props)), /*#__PURE__*/_jsx(DateInput, _extends({
115
+ size: "l"
116
+ }, sharedProps, props)), /*#__PURE__*/_jsx(DateInput, _extends({
117
+ compact: true
118
+ }, sharedProps, props))]
119
+ })
120
+ })
121
+ });
122
+ };
95
123
  export const CustomLabel = () => {
96
124
  const [date, setDate] = useState(null);
97
125
  const [error, setError] = useState(null);
@@ -150,6 +150,29 @@ export const FullExample = () => {
150
150
  })]
151
151
  });
152
152
  };
153
+ export const Sizes = () => {
154
+ return /*#__PURE__*/_jsx(ExampleScreen, {
155
+ children: /*#__PURE__*/_jsx(Example, {
156
+ title: "DatePicker sizes",
157
+ children: /*#__PURE__*/_jsxs(VStack, {
158
+ gap: 2,
159
+ children: [/*#__PURE__*/_jsx(ExampleDatePicker, {
160
+ openCalendarAccessibilityLabel: "Small calendar",
161
+ size: "s"
162
+ }), /*#__PURE__*/_jsx(ExampleDatePicker, {
163
+ openCalendarAccessibilityLabel: "Medium calendar",
164
+ size: "m"
165
+ }), /*#__PURE__*/_jsx(ExampleDatePicker, {
166
+ openCalendarAccessibilityLabel: "Large calendar",
167
+ size: "l"
168
+ }), /*#__PURE__*/_jsx(ExampleDatePicker, {
169
+ compact: true,
170
+ openCalendarAccessibilityLabel: "Compact calendar"
171
+ })]
172
+ })
173
+ })
174
+ });
175
+ };
153
176
  export const CustomLabel = () => {
154
177
  return /*#__PURE__*/_jsx(ExampleScreen, {
155
178
  children: /*#__PURE__*/_jsx(Example, {
@@ -1,4 +1,4 @@
1
- import React, { useMemo } from 'react';
1
+ import React, { useCallback, useMemo, useState } from 'react';
2
2
  import { StyleSheet, View } from 'react-native';
3
3
  import { Defs, LinearGradient as Lg, Rect, Stop, Svg } from 'react-native-svg';
4
4
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
@@ -23,6 +23,30 @@ export function LinearGradient(_ref) {
23
23
  pointerEvents,
24
24
  testID
25
25
  } = _ref;
26
+ const [pixelSize, setPixelSize] = useState(() => {
27
+ const flat = StyleSheet.flatten(style);
28
+ return flat && typeof flat.width === 'number' && typeof flat.height === 'number' ? {
29
+ width: flat.width,
30
+ height: flat.height
31
+ } : null;
32
+ });
33
+ const handleLayout = useCallback(event => {
34
+ const width = Math.round(event.nativeEvent.layout.width);
35
+ const height = Math.round(event.nativeEvent.layout.height);
36
+ setPixelSize(prev => prev && prev.width === width && prev.height === height ? prev : {
37
+ width,
38
+ height
39
+ });
40
+ }, []);
41
+ const svgWidth = pixelSize ? pixelSize.width : 0;
42
+ const svgHeight = pixelSize ? pixelSize.height : 0;
43
+ const containerStyle = useMemo(() => ({
44
+ position: 'absolute',
45
+ top: 0,
46
+ left: 0,
47
+ width: svgWidth,
48
+ height: svgHeight
49
+ }), [svgWidth, svgHeight]);
26
50
  const svg = useMemo(() => {
27
51
  var _start$x, _start$y, _end$x, _end$y;
28
52
  const anglePI = -angle * Math.PI / 180;
@@ -31,10 +55,10 @@ export function LinearGradient(_ref) {
31
55
  const x2 = (_end$x = end == null ? void 0 : end.x) != null ? _end$x : Math.round(50 + Math.sin(anglePI + Math.PI) * 50) / 100;
32
56
  const y2 = (_end$y = end == null ? void 0 : end.y) != null ? _end$y : Math.round(50 + Math.cos(anglePI + Math.PI) * 50) / 100;
33
57
  return /*#__PURE__*/_jsx(View, {
34
- style: StyleSheet.absoluteFillObject,
58
+ style: containerStyle,
35
59
  children: /*#__PURE__*/_jsxs(Svg, {
36
- height: "100%",
37
- width: "100%",
60
+ height: svgHeight,
61
+ width: svgWidth,
38
62
  children: [/*#__PURE__*/_jsx(Defs, {
39
63
  children: /*#__PURE__*/_jsx(Lg, {
40
64
  id: "LinearGradient",
@@ -50,14 +74,15 @@ export function LinearGradient(_ref) {
50
74
  })
51
75
  }), /*#__PURE__*/_jsx(Rect, {
52
76
  fill: "url(#LinearGradient)",
53
- height: "100%",
54
- width: "100%"
77
+ height: svgHeight,
78
+ width: svgWidth
55
79
  })]
56
80
  })
57
81
  }, "GrandientSvgContainer");
58
- }, [colors, start, end, angle, stops]);
82
+ }, [colors, start, end, angle, stops, containerStyle, svgWidth, svgHeight]);
59
83
  const items = !elevated ? [svg, children] : [children, svg];
60
84
  return /*#__PURE__*/_jsx(View, {
85
+ onLayout: handleLayout,
61
86
  pointerEvents: pointerEvents,
62
87
  style: style,
63
88
  testID: testID,
@@ -1,4 +1,4 @@
1
- const _excluded = ["onFocus", "onBlur", "compact", "expandOnFocus"];
1
+ const _excluded = ["onFocus", "onBlur", "size", "expandOnFocus"];
2
2
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
3
3
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
4
4
  import { memo, useCallback } from 'react';
@@ -14,7 +14,7 @@ export const BrowserBarSearchInput = /*#__PURE__*/memo(_ref => {
14
14
  let {
15
15
  onFocus,
16
16
  onBlur,
17
- compact = true,
17
+ size = 's',
18
18
  expandOnFocus = true
19
19
  } = _ref,
20
20
  props = _objectWithoutPropertiesLoose(_ref, _excluded);
@@ -34,10 +34,14 @@ export const BrowserBarSearchInput = /*#__PURE__*/memo(_ref => {
34
34
  setHideStart(false);
35
35
  onBlur == null || onBlur(e);
36
36
  }, [onBlur, setHideEnd, setHideStart]);
37
+
38
+ // The browser bar always wants the dense input, so the density default moved from the deprecated
39
+ // `compact` onto `size`. A consumer-supplied `compact` still arrives via the spread but is inert,
40
+ // since `SearchInput` resolves `size` first.
37
41
  return /*#__PURE__*/_jsx(SearchInput, _extends({
38
- compact: compact,
39
42
  onBlur: handleBlur,
40
- onFocus: handleFocus
43
+ onFocus: handleFocus,
44
+ size: size
41
45
  }, props));
42
46
  });
43
47
  BrowserBarSearchInput.displayName = 'BrowserBarSearchInput';
@@ -125,9 +125,9 @@ export const Toast = /*#__PURE__*/memo(_ref => {
125
125
  children: text
126
126
  })
127
127
  }), !!action && /*#__PURE__*/_jsx(Button, {
128
- compact: true,
129
128
  transparent: true,
130
129
  onPress: handleActionPress,
130
+ size: "s",
131
131
  testID: (_action$testID = action.testID) != null ? _action$testID : 'toast-action',
132
132
  children: action.label
133
133
  })]
@@ -27,12 +27,12 @@ export const ProgressContainerWithButtons = _ref => {
27
27
  children: [children({
28
28
  calculateProgress
29
29
  }), /*#__PURE__*/_jsx(Button, {
30
- compact: true,
31
30
  onPress: reRender,
31
+ size: "s",
32
32
  children: "Re-render"
33
33
  }), !hideIncrease && /*#__PURE__*/_jsx(Button, {
34
- compact: true,
35
34
  onPress: increase,
35
+ size: "s",
36
36
  children: "Increase 20%"
37
37
  })]
38
38
  }, num);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coinbase/cds-mobile",
3
- "version": "9.9.0",
3
+ "version": "9.10.1",
4
4
  "description": "Coinbase Design System - Mobile",
5
5
  "repository": {
6
6
  "type": "git",
@@ -218,7 +218,7 @@
218
218
  "react-native-worklets": "0.5.2"
219
219
  },
220
220
  "dependencies": {
221
- "@coinbase/cds-common": "^9.9.0",
221
+ "@coinbase/cds-common": "^9.10.1",
222
222
  "@coinbase/cds-icons": "^5.21.0",
223
223
  "@coinbase/cds-illustrations": "^4.45.0",
224
224
  "@coinbase/cds-lottie-files": "^3.3.4",