@coinbase/cds-mobile 9.0.2 → 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,22 @@ 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
+
17
+ ## 9.1.0 (5/26/2026 PST)
18
+
19
+ #### 🚀 Updates
20
+
21
+ - Feat: support DotCount theming. [[#723](https://github.com/coinbase/cds/pull/723)]
22
+
23
+ #### 🐞 Fixes
24
+
25
+ - Fix: DotCount border mixing with background color. [[#723](https://github.com/coinbase/cds/pull/723)]
26
+
11
27
  ## 9.0.2 ((5/22/2026, 09:54 AM PST))
12
28
 
13
29
  This is an artificial version bump with no new change.
@@ -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"}
@@ -7,13 +7,18 @@ import type {
7
7
  SharedAccessibilityProps,
8
8
  SharedProps,
9
9
  } from '@coinbase/cds-common/types';
10
- export declare const MAX_OVERFLOW_COUNT = 99;
11
- export declare const parseDotCountMaxOverflow: (count: number, max?: number) => string | number;
10
+ import {
11
+ MAX_OVERFLOW_COUNT,
12
+ parseDotCountMaxOverflow,
13
+ } from '@coinbase/cds-common/utils/parseDotCountMaxOverflow';
14
+ import { type BoxBaseProps } from '../layout/Box';
15
+ export { MAX_OVERFLOW_COUNT, parseDotCountMaxOverflow };
12
16
  export type DotCountBaseProps = SharedProps &
13
17
  Pick<
14
18
  SharedAccessibilityProps,
15
19
  'accessibilityLabel' | 'accessibilityLabelledBy' | 'accessibilityHint'
16
- > & {
20
+ > &
21
+ Omit<BoxBaseProps, 'children' | 'background' | 'pin' | 'style' | 'height'> & {
17
22
  /**
18
23
  * The number value to be shown in the dot. If count is <= 0, dot will not show up.
19
24
  * */
@@ -35,17 +40,10 @@ export type DotCountBaseProps = SharedProps &
35
40
  /** Indicates what shape Dot is overlapping */
36
41
  overlap?: DotOverlap;
37
42
  /**
38
- * An optional fixed height of the DotCount component.
39
- * Width grows based on content length.
43
+ * Fixed height of the DotCount badge container. Width grows based on content length.
40
44
  * @default 24
41
- * */
42
- height?: number;
43
- /**
44
- * An optional fixed width of the DotCount component.
45
- * By default, width grows based on content length.
46
- * @default auto
47
- * */
48
- width?: number;
45
+ */
46
+ height?: BoxBaseProps['height'];
49
47
  };
50
48
  export type DotCountProps = DotCountBaseProps & {
51
49
  style?: StyleProp<ViewStyle>;
@@ -1 +1 @@
1
- {"version":3,"file":"DotCount.d.ts","sourceRoot":"","sources":["../../src/dots/DotCount.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6C,MAAM,OAAO,CAAC;AAClE,OAAO,EAEL,KAAK,SAAS,EAEd,KAAK,SAAS,EAEd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAgBtB,OAAO,KAAK,EACV,oBAAoB,EACpB,gBAAgB,EAChB,UAAU,EACV,wBAAwB,EACxB,WAAW,EACZ,MAAM,4BAA4B,CAAC;AAepC,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAErC,eAAO,MAAM,wBAAwB,GAAI,OAAO,MAAM,EAAE,MAAK,MAA2B,oBAEvF,CAAC;AAaF,MAAM,MAAM,iBAAiB,GAAG,WAAW,GACzC,IAAI,CACF,wBAAwB,EACxB,oBAAoB,GAAG,yBAAyB,GAAG,mBAAmB,CACvE,GAAG;IACF;;UAEM;IACN,KAAK,EAAE,MAAM,CAAC;IACd;;;UAGM;IACN,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;SAGK;IACL,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,6CAA6C;IAC7C,GAAG,CAAC,EAAE,oBAAoB,CAAC;IAC3B,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,8CAA8C;IAC9C,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB;;;;SAIK;IACL,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;SAIK;IACL,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEJ,MAAM,MAAM,aAAa,GAAG,iBAAiB,GAAG;IAC9C,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,sEAAsE;IACtE,MAAM,CAAC,EAAE;QACP,mBAAmB;QACnB,IAAI,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;QAC5B,wBAAwB;QACxB,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;QACjC,mBAAmB;QACnB,IAAI,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;KAC7B,CAAC;CACH,CAAC;AAEF,eAAO,MAAM,QAAQ,qCAAiB,aAAa,6CAsHjD,CAAC"}
1
+ {"version":3,"file":"DotCount.d.ts","sourceRoot":"","sources":["../../src/dots/DotCount.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6C,MAAM,OAAO,CAAC;AAClE,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,SAAS,EAEd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAgBtB,OAAO,KAAK,EACV,oBAAoB,EACpB,gBAAgB,EAChB,UAAU,EACV,wBAAwB,EACxB,WAAW,EACZ,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACzB,MAAM,qDAAqD,CAAC;AAK7D,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AASvD,OAAO,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,CAAC;AAexD,MAAM,MAAM,iBAAiB,GAAG,WAAW,GACzC,IAAI,CACF,wBAAwB,EACxB,oBAAoB,GAAG,yBAAyB,GAAG,mBAAmB,CACvE,GACD,IAAI,CAAC,YAAY,EAAE,UAAU,GAAG,YAAY,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC,GAAG;IAC3E;;UAEM;IACN,KAAK,EAAE,MAAM,CAAC;IACd;;;UAGM;IACN,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;SAGK;IACL,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,6CAA6C;IAC7C,GAAG,CAAC,EAAE,oBAAoB,CAAC;IAC3B,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,8CAA8C;IAC9C,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB;;;OAGG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;CACjC,CAAC;AAEJ,MAAM,MAAM,aAAa,GAAG,iBAAiB,GAAG;IAC9C,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,sEAAsE;IACtE,MAAM,CAAC,EAAE;QACP,mBAAmB;QACnB,IAAI,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;QAC5B,wBAAwB;QACxB,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;QACjC,mBAAmB;QACnB,IAAI,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;KAC7B,CAAC;CACH,CAAC;AAEF,eAAO,MAAM,QAAQ,qCAAiB,aAAa,6CAyJjD,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,31 +1,26 @@
1
- const _excluded = ["children", "pin", "variant", "count", "max", "height", "width", "overlap", "style", "styles"];
1
+ const _excluded = ["children", "pin", "variant", "count", "max", "height", "width", "testID", "accessibilityLabel", "accessibilityLabelledBy", "accessibilityHint", "overlap", "style", "styles", "alignItems", "justifyContent", "paddingX", "borderWidth", "borderRadius", "borderColor", "font", "color", "fontFamily", "fontSize", "fontWeight", "lineHeight", "overflow"];
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 React, { memo, useEffect, useMemo, useState } from 'react';
5
- import { StyleSheet, View } from 'react-native';
5
+ import { View } from 'react-native';
6
6
  import Animated, { runOnJS, useAnimatedReaction, useAnimatedStyle, useSharedValue } from 'react-native-reanimated';
7
7
  import { usePreviousValue } from '@coinbase/cds-common/hooks/usePreviousValue';
8
8
  import { dotOpacityEnterConfig, dotOpacityExitConfig, dotScaleEnterConfig, dotScaleExitConfig } from '@coinbase/cds-common/motion/dot';
9
9
  import { dotCountSize } from '@coinbase/cds-common/tokens/dot';
10
+ import { MAX_OVERFLOW_COUNT, parseDotCountMaxOverflow } from '@coinbase/cds-common/utils/parseDotCountMaxOverflow';
10
11
  import { useComponentConfig } from '../hooks/useComponentConfig';
11
12
  import { useDotPinStyles } from '../hooks/useDotPinStyles';
12
- import { useTheme } from '../hooks/useTheme';
13
+ import { Box } from '../layout/Box';
13
14
  import { convertMotionConfigs } from '../motion/convertMotionConfig';
14
15
  import { withMotionTiming } from '../motion/withMotionTiming';
15
16
  import { Text } from '../typography/Text';
16
17
  import { getTransform } from './dotStyles';
17
18
  import { useDotsLayout } from './useDotsLayout';
18
19
 
19
- // If a badge count is greater than max (optional, defaults at 99), it should
20
- // truncate the numbers so its x+.
20
+ // Re-exporting for backwards compatibility
21
21
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
22
- export const MAX_OVERFLOW_COUNT = 99;
23
- export const parseDotCountMaxOverflow = function (count, max) {
24
- if (max === void 0) {
25
- max = MAX_OVERFLOW_COUNT;
26
- }
27
- return count <= max ? count : max + "+";
28
- };
22
+ export { MAX_OVERFLOW_COUNT, parseDotCountMaxOverflow };
23
+ const AnimatedBox = Animated.createAnimatedComponent(Box);
29
24
  const [opacityEnter, opacityExit, scaleEnter, scaleExit] = convertMotionConfigs([dotOpacityEnterConfig, dotOpacityExitConfig, dotScaleEnterConfig, dotScaleExitConfig]);
30
25
  const variantColorMap = {
31
26
  negative: 'bgNegative'
@@ -40,12 +35,28 @@ export const DotCount = /*#__PURE__*/memo(_props => {
40
35
  max,
41
36
  height = dotCountSize,
42
37
  width,
38
+ testID = 'dot-count',
39
+ accessibilityLabel,
40
+ accessibilityLabelledBy,
41
+ accessibilityHint,
43
42
  overlap,
44
43
  style,
45
- styles
44
+ styles,
45
+ alignItems = 'center',
46
+ justifyContent = 'center',
47
+ paddingX = 0.75,
48
+ borderWidth = 100,
49
+ borderRadius = 400,
50
+ borderColor = 'bgSecondary',
51
+ font = 'caption',
52
+ color = 'fgInverse',
53
+ fontFamily,
54
+ fontSize,
55
+ fontWeight,
56
+ lineHeight,
57
+ overflow = 'hidden'
46
58
  } = mergedProps,
47
59
  props = _objectWithoutPropertiesLoose(mergedProps, _excluded);
48
- const theme = useTheme();
49
60
  const [childrenSize, onChildrenLayout] = useDotsLayout();
50
61
  const transforms = useDotPinStyles(childrenSize, {
51
62
  width: width != null ? width : height,
@@ -63,18 +74,6 @@ export const DotCount = /*#__PURE__*/memo(_props => {
63
74
  }
64
75
  return {};
65
76
  }, [pin, transforms]);
66
- const containerStyles = useMemo(() => {
67
- return [styleSheet.container, {
68
- height,
69
- minWidth: height,
70
- width,
71
- paddingHorizontal: theme.space[0.75],
72
- borderWidth: theme.borderWidth[100],
73
- borderRadius: theme.borderRadius[400],
74
- borderColor: theme.color.bgSecondary,
75
- backgroundColor: theme.color[variantColorMap[variant]]
76
- }];
77
- }, [height, width, theme.space, theme.borderWidth, theme.borderRadius, theme.color, variant]);
78
77
 
79
78
  // avoid displaying 0 during animations and preserve exit animation
80
79
  useEffect(() => {
@@ -106,37 +105,51 @@ export const DotCount = /*#__PURE__*/memo(_props => {
106
105
  }]
107
106
  };
108
107
  });
109
- const dotCountContainerStyle = useMemo(() => [containerStyles, animatedStyles, styles == null ? void 0 : styles.container], [containerStyles, animatedStyles, styles == null ? void 0 : styles.container]);
108
+ const dotCountContainerStyle = useMemo(() => [animatedStyles, styles == null ? void 0 : styles.container], [animatedStyles, styles == null ? void 0 : styles.container]);
110
109
  const rootStyles = useMemo(() => [style, styles == null ? void 0 : styles.root], [styles == null ? void 0 : styles.root, style]);
110
+ const displayCount = useMemo(() => parseDotCountMaxOverflow(countInternal, max), [countInternal, max]);
111
111
 
112
112
  // only check childrenSize when children is defined
113
113
  const shouldShow = children !== undefined ? childrenSize !== null : true;
114
- return /*#__PURE__*/_jsxs(View, _extends({
115
- style: rootStyles
116
- }, props, {
114
+ return /*#__PURE__*/_jsxs(View, {
115
+ accessibilityHint: accessibilityHint,
116
+ accessibilityLabel: accessibilityLabel,
117
+ accessibilityLabelledBy: accessibilityLabelledBy,
118
+ style: rootStyles,
119
+ testID: testID,
117
120
  children: [/*#__PURE__*/_jsx(View, {
118
121
  onLayout: onChildrenLayout,
119
- testID: props.testID + "-children",
122
+ testID: testID + "-children",
120
123
  children: children
121
124
  }), !shouldUnmount && shouldShow && /*#__PURE__*/_jsx(View, {
122
125
  style: pinStyles,
123
- children: /*#__PURE__*/_jsx(Animated.View, {
126
+ children: /*#__PURE__*/_jsx(AnimatedBox, _extends({
127
+ animated: true,
128
+ alignItems: alignItems,
129
+ background: variantColorMap[variant],
130
+ borderColor: borderColor,
131
+ borderRadius: borderRadius,
132
+ borderWidth: borderWidth,
133
+ height: height,
134
+ justifyContent: justifyContent,
135
+ minWidth: height,
136
+ overflow: overflow,
137
+ paddingX: paddingX,
124
138
  style: dotCountContainerStyle,
125
139
  testID: "dotcount-container",
140
+ width: width
141
+ }, props, {
126
142
  children: /*#__PURE__*/_jsx(Text, {
127
- color: "fgInverse",
128
- font: "caption",
143
+ color: color,
144
+ font: font,
145
+ fontFamily: fontFamily,
146
+ fontSize: fontSize,
147
+ fontWeight: fontWeight,
148
+ lineHeight: lineHeight,
129
149
  style: styles == null ? void 0 : styles.text,
130
- children: parseDotCountMaxOverflow(countInternal, max)
150
+ children: displayCount
131
151
  })
132
- })
152
+ }))
133
153
  })]
134
- }));
135
- });
136
- const styleSheet = StyleSheet.create({
137
- container: {
138
- alignItems: 'center',
139
- justifyContent: 'center',
140
- display: 'flex'
141
- }
154
+ });
142
155
  });
@@ -126,5 +126,11 @@ export const customComponentConfig = {
126
126
  paddingX: 1,
127
127
  font: 'caption',
128
128
  emphasis: 'low'
129
+ },
130
+ DotCount: {
131
+ height: 16,
132
+ // Design is 1.5 but this causes the badge to be too wide for some single-digit counts
133
+ paddingX: 1,
134
+ paddingY: 0
129
135
  }
130
136
  };
@@ -1,28 +1,21 @@
1
1
  import React, { memo } from 'react';
2
+ import { IconButton } from '../../../../buttons/IconButton';
2
3
  import { DotCount } from '../../../../dots/DotCount';
3
- import { Icon } from '../../../../icons/Icon';
4
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
4
+ import { HStack } from '../../../../layout/HStack';
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ const dotCounts = [3, 12, 100];
5
7
  export const DotCountExample = /*#__PURE__*/memo(() => {
6
- return /*#__PURE__*/_jsxs(_Fragment, {
7
- children: [/*#__PURE__*/_jsx(DotCount, {
8
- count: 3,
9
- children: /*#__PURE__*/_jsx(Icon, {
10
- name: "bell",
11
- size: "m"
8
+ return /*#__PURE__*/_jsx(HStack, {
9
+ gap: 2,
10
+ children: dotCounts.map(count => /*#__PURE__*/_jsx(DotCount, {
11
+ count: count,
12
+ pin: "top-end",
13
+ children: /*#__PURE__*/_jsx(IconButton, {
14
+ transparent: true,
15
+ accessibilityLabel: "Notifications",
16
+ iconSize: "m",
17
+ name: "bell"
12
18
  })
13
- }), /*#__PURE__*/_jsx(DotCount, {
14
- count: 12,
15
- children: /*#__PURE__*/_jsx(Icon, {
16
- name: "bell",
17
- size: "m"
18
- })
19
- }), /*#__PURE__*/_jsx(DotCount, {
20
- count: 100,
21
- max: 99,
22
- children: /*#__PURE__*/_jsx(Icon, {
23
- name: "bell",
24
- size: "m"
25
- })
26
- })]
19
+ }, count))
27
20
  });
28
21
  });
@@ -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.0.2",
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.0.2",
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",