@coinbase/cds-mobile 8.34.2 → 8.35.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,12 @@ All notable changes to this project will be documented in this file.
8
8
 
9
9
  <!-- template-start -->
10
10
 
11
+ ## 8.35.0 (1/5/2026 PST)
12
+
13
+ #### 🚀 Updates
14
+
15
+ - Add border props to RemoteImageGroup.
16
+
11
17
  ## 8.34.2 ((1/2/2026, 09:41 AM PST))
12
18
 
13
19
  This is an artificial version bump with no new change.
@@ -6,8 +6,10 @@ import type {
6
6
  SharedAccessibilityProps,
7
7
  SharedProps,
8
8
  } from '@coinbase/cds-common/types';
9
+ import { type BoxProps } from '../layout/Box';
9
10
  export type RemoteImageGroupBaseProps = SharedProps &
10
- SharedAccessibilityProps & {
11
+ SharedAccessibilityProps &
12
+ Pick<BoxProps, 'borderWidth' | 'borderColor'> & {
11
13
  /**
12
14
  * Indicates the number of remote image before it collapses
13
15
  * @default 4
@@ -33,6 +35,8 @@ export declare const RemoteImageGroup: ({
33
35
  max,
34
36
  shape,
35
37
  testID,
38
+ borderWidth,
39
+ borderColor,
36
40
  ...props
37
41
  }: RemoteImageGroupProps) => import('react/jsx-runtime').JSX.Element;
38
42
  export declare const shapeStyles: Record<Shape, ViewStyle>;
@@ -1 +1 @@
1
- {"version":3,"file":"RemoteImageGroup.d.ts","sourceRoot":"","sources":["../../src/media/RemoteImageGroup.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4C,MAAM,OAAO,CAAC;AAEjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EACV,UAAU,EAEV,KAAK,EACL,wBAAwB,EACxB,WAAW,EACZ,MAAM,4BAA4B,CAAC;AAOpC,MAAM,MAAM,yBAAyB,GAAG,WAAW,GACjD,wBAAwB,GAAG;IACzB;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,IAAI,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;IAC3B;;;OAGG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,uBAAuB;IACvB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B,CAAC;AAEJ,MAAM,MAAM,qBAAqB,GAAG,yBAAyB,CAAC;AAE9D,eAAO,MAAM,gBAAgB,GAAI,kDAO9B,qBAAqB,4CAqFvB,CAAC;AAQF,eAAO,MAAM,WAAW,0BAgBtB,CAAC"}
1
+ {"version":3,"file":"RemoteImageGroup.d.ts","sourceRoot":"","sources":["../../src/media/RemoteImageGroup.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4C,MAAM,OAAO,CAAC;AAEjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EACV,UAAU,EAEV,KAAK,EACL,wBAAwB,EACxB,WAAW,EACZ,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EAAO,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AAInD,MAAM,MAAM,yBAAyB,GAAG,WAAW,GACjD,wBAAwB,GACxB,IAAI,CAAC,QAAQ,EAAE,aAAa,GAAG,aAAa,CAAC,GAAG;IAC9C;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,IAAI,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;IAC3B;;;OAGG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,uBAAuB;IACvB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B,CAAC;AAEJ,MAAM,MAAM,qBAAqB,GAAG,yBAAyB,CAAC;AAE9D,eAAO,MAAM,gBAAgB,GAAI,4EAS9B,qBAAqB,4CAiGvB,CAAC;AAQF,eAAO,MAAM,WAAW,0BAgBtB,CAAC"}
@@ -1,4 +1,4 @@
1
- const _excluded = ["children", "size", "max", "shape", "testID"];
1
+ const _excluded = ["children", "size", "max", "shape", "testID", "borderWidth", "borderColor"];
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, { Children, isValidElement, useMemo } from 'react';
@@ -13,7 +13,9 @@ export const RemoteImageGroup = _ref => {
13
13
  size = 'm',
14
14
  max = 4,
15
15
  shape = 'circle',
16
- testID
16
+ testID,
17
+ borderWidth,
18
+ borderColor = borderWidth ? 'bg' : undefined
17
19
  } = _ref,
18
20
  props = _objectWithoutPropertiesLoose(_ref, _excluded);
19
21
  const {
@@ -50,39 +52,49 @@ export const RemoteImageGroup = _ref => {
50
52
  if (! /*#__PURE__*/isValidElement(child)) {
51
53
  return null;
52
54
  }
55
+ const childShape = child.props.shape;
53
56
 
54
57
  // dynamically apply uniform sizing and shape to all RemoteImage children elements
55
58
  const clonedChild = /*#__PURE__*/React.cloneElement(child, _extends({
56
59
  testID: (testID ? testID + "-" : '') + "image-" + index,
57
60
  width: sizeAsNumber,
58
61
  height: sizeAsNumber
59
- }, child.props.shape ? undefined : {
62
+ }, childShape ? undefined : {
60
63
  shape
61
64
  }));
62
65
 
63
66
  // zIndex is progressively lower so that each child is stacked below the previous one
64
67
  const zIndex = -index;
68
+ const childShapeStyle = borderWidth ? shapeStyles[childShape != null ? childShape : shape] : undefined;
65
69
  return /*#__PURE__*/_jsx(Box, {
70
+ borderColor: borderColor,
71
+ borderWidth: borderWidth,
66
72
  marginStart: index === 0 ? undefined : overlapSpacing,
67
73
  position: "relative",
74
+ style: childShapeStyle,
68
75
  testID: (testID ? testID + "-" : '') + "inner-box-" + index,
69
76
  zIndex: zIndex,
70
77
  children: clonedChild
71
78
  }, index);
72
79
  }), excess > 0 && /*#__PURE__*/_jsx(Box, {
73
- alignItems: "center",
74
80
  background: "bgOverlay",
75
- height: sizeAsNumber,
76
- justifyContent: "center",
81
+ borderColor: borderColor,
82
+ borderWidth: borderWidth,
77
83
  marginStart: overlapSpacing,
84
+ overflow: "hidden",
78
85
  position: "relative",
79
86
  style: shapeStyle,
80
- width: sizeAsNumber,
81
87
  zIndex: groupChildren.length * -1,
82
- children: /*#__PURE__*/_jsxs(Text, {
83
- style: [typographyStyles, styles.centerText],
84
- testID: (testID ? testID + "-" : '') + "excess-text",
85
- children: ["+", excess]
88
+ children: /*#__PURE__*/_jsx(Box, {
89
+ alignItems: "center",
90
+ height: sizeAsNumber,
91
+ justifyContent: "center",
92
+ width: sizeAsNumber,
93
+ children: /*#__PURE__*/_jsxs(Text, {
94
+ style: [typographyStyles, styles.centerText],
95
+ testID: (testID ? testID + "-" : '') + "excess-text",
96
+ children: ["+", excess]
97
+ })
86
98
  })
87
99
  })]
88
100
  }));
@@ -104,7 +104,7 @@ const CircleMax = () => {
104
104
  };
105
105
  const CircleMaxDefaultCustomSize = () => /*#__PURE__*/_jsxs(VStack, {
106
106
  children: [/*#__PURE__*/_jsx(Text, {
107
- font: "body",
107
+ font: "label1",
108
108
  children: "RemoteImageGroup excess element defaults to m of AvatarSize when size is not specified"
109
109
  }), /*#__PURE__*/_jsxs(RemoteImageGroup, {
110
110
  max: 2,
@@ -122,7 +122,7 @@ const CircleMaxDefaultCustomSize = () => /*#__PURE__*/_jsxs(VStack, {
122
122
  });
123
123
  const MixAndMatchShapes = () => /*#__PURE__*/_jsxs(VStack, {
124
124
  children: [/*#__PURE__*/_jsx(Text, {
125
- font: "body",
125
+ font: "label1",
126
126
  children: "RemoteImage child shape takes precedence over RemoteImageGroup shape"
127
127
  }), /*#__PURE__*/_jsxs(RemoteImageGroup, {
128
128
  shape: "circle",
@@ -218,7 +218,7 @@ const SquircleMax = () => {
218
218
  };
219
219
  const SquircleMaxDefaultCustomSize = () => /*#__PURE__*/_jsxs(VStack, {
220
220
  children: [/*#__PURE__*/_jsx(Text, {
221
- font: "body",
221
+ font: "label1",
222
222
  children: "RemoteImageGroup excess element defaults to m of AvatarSize when size is not specified"
223
223
  }), /*#__PURE__*/_jsxs(RemoteImageGroup, {
224
224
  max: 2,
@@ -236,7 +236,7 @@ const SquircleMaxDefaultCustomSize = () => /*#__PURE__*/_jsxs(VStack, {
236
236
  });
237
237
  const SquircleMaxSetCustomMaxSize = () => /*#__PURE__*/_jsxs(VStack, {
238
238
  children: [/*#__PURE__*/_jsx(Text, {
239
- font: "body",
239
+ font: "label1",
240
240
  children: "Set a custom size of 36 for RemoteImageGroup excess component"
241
241
  }), /*#__PURE__*/_jsxs(RemoteImageGroup, {
242
242
  max: 2,
@@ -255,7 +255,7 @@ const SquircleMaxSetCustomMaxSize = () => /*#__PURE__*/_jsxs(VStack, {
255
255
  });
256
256
  const HideExcessWhenExceedThreshold = () => /*#__PURE__*/_jsxs(VStack, {
257
257
  children: [/*#__PURE__*/_jsx(Text, {
258
- font: "body",
258
+ font: "label1",
259
259
  children: "Excess component when size is smaller than a certain size looks funky"
260
260
  }), /*#__PURE__*/_jsxs(RemoteImageGroup, {
261
261
  max: 2,
@@ -272,9 +272,85 @@ const HideExcessWhenExceedThreshold = () => /*#__PURE__*/_jsxs(VStack, {
272
272
  })]
273
273
  })]
274
274
  });
275
+ const ShapeWithBorderWidth = () => /*#__PURE__*/_jsxs(VStack, {
276
+ children: [/*#__PURE__*/_jsx(Text, {
277
+ font: "label1",
278
+ children: "Circle with border width"
279
+ }), /*#__PURE__*/_jsxs(RemoteImageGroup, {
280
+ borderWidth: 300,
281
+ shape: "circle",
282
+ size: 32,
283
+ children: [/*#__PURE__*/_jsx(RemoteImage, {
284
+ source: assets.eth.imageUrl
285
+ }), /*#__PURE__*/_jsx(RemoteImage, {
286
+ source: assets.btc.imageUrl
287
+ }), /*#__PURE__*/_jsx(RemoteImage, {
288
+ source: assets.dai.imageUrl
289
+ }), /*#__PURE__*/_jsx(RemoteImage, {
290
+ source: assets.hbar.imageUrl
291
+ }), /*#__PURE__*/_jsx(RemoteImage, {
292
+ source: assets.ltc.imageUrl
293
+ }), /*#__PURE__*/_jsx(RemoteImage, {
294
+ source: assets.uni.imageUrl
295
+ })]
296
+ }), /*#__PURE__*/_jsx(Text, {
297
+ font: "label1",
298
+ children: "Circle with border color and border width"
299
+ }), /*#__PURE__*/_jsxs(RemoteImageGroup, {
300
+ borderColor: "bgPositive",
301
+ borderWidth: 300,
302
+ shape: "circle",
303
+ size: 32,
304
+ children: [/*#__PURE__*/_jsx(RemoteImage, {
305
+ source: assets.eth.imageUrl
306
+ }), /*#__PURE__*/_jsx(RemoteImage, {
307
+ source: assets.btc.imageUrl
308
+ }), /*#__PURE__*/_jsx(RemoteImage, {
309
+ source: assets.dai.imageUrl
310
+ }), /*#__PURE__*/_jsx(RemoteImage, {
311
+ source: assets.hbar.imageUrl
312
+ }), /*#__PURE__*/_jsx(RemoteImage, {
313
+ source: assets.ltc.imageUrl
314
+ }), /*#__PURE__*/_jsx(RemoteImage, {
315
+ source: assets.uni.imageUrl
316
+ })]
317
+ }), /*#__PURE__*/_jsx(Text, {
318
+ font: "label1",
319
+ children: "Squircle with border width"
320
+ }), /*#__PURE__*/_jsxs(RemoteImageGroup, {
321
+ borderWidth: 300,
322
+ shape: "squircle",
323
+ size: 32,
324
+ children: [/*#__PURE__*/_jsx(RemoteImage, {
325
+ source: squareAssets.human1
326
+ }), /*#__PURE__*/_jsx(RemoteImage, {
327
+ source: squareAssets.human2
328
+ }), /*#__PURE__*/_jsx(RemoteImage, {
329
+ source: squareAssets.human1
330
+ })]
331
+ }), /*#__PURE__*/_jsx(Text, {
332
+ font: "label1",
333
+ children: "Mixed shape with border width"
334
+ }), /*#__PURE__*/_jsxs(RemoteImageGroup, {
335
+ borderWidth: 300,
336
+ shape: "circle",
337
+ size: "xxl",
338
+ children: [/*#__PURE__*/_jsx(RemoteImage, {
339
+ shape: "squircle",
340
+ source: squareAssets.human1
341
+ }), /*#__PURE__*/_jsx(RemoteImage, {
342
+ source: assets.sushi.imageUrl
343
+ }), /*#__PURE__*/_jsx(RemoteImage, {
344
+ shape: "squircle",
345
+ source: squareAssets.human2
346
+ }), /*#__PURE__*/_jsx(RemoteImage, {
347
+ source: assets.ltc.imageUrl
348
+ })]
349
+ })]
350
+ });
275
351
  const All = () => /*#__PURE__*/_jsxs(VStack, {
276
352
  gap: 7,
277
- children: [/*#__PURE__*/_jsx(Circle, {}), /*#__PURE__*/_jsx(CircleCustomSize, {}), /*#__PURE__*/_jsx(CircleAvatarSize, {}), /*#__PURE__*/_jsx(CircleMax, {}), /*#__PURE__*/_jsx(CircleMaxDefaultCustomSize, {}), /*#__PURE__*/_jsx(Squircle, {}), /*#__PURE__*/_jsx(SquircleCustomSize, {}), /*#__PURE__*/_jsx(SquircleAvatarSize, {}), /*#__PURE__*/_jsx(SquircleMax, {}), /*#__PURE__*/_jsx(SquircleMaxDefaultCustomSize, {}), /*#__PURE__*/_jsx(SquircleMaxSetCustomMaxSize, {}), /*#__PURE__*/_jsx(HideExcessWhenExceedThreshold, {}), /*#__PURE__*/_jsx(MixAndMatchShapes, {})]
353
+ children: [/*#__PURE__*/_jsx(Circle, {}), /*#__PURE__*/_jsx(CircleCustomSize, {}), /*#__PURE__*/_jsx(CircleAvatarSize, {}), /*#__PURE__*/_jsx(CircleMax, {}), /*#__PURE__*/_jsx(CircleMaxDefaultCustomSize, {}), /*#__PURE__*/_jsx(Squircle, {}), /*#__PURE__*/_jsx(SquircleCustomSize, {}), /*#__PURE__*/_jsx(SquircleAvatarSize, {}), /*#__PURE__*/_jsx(SquircleMax, {}), /*#__PURE__*/_jsx(SquircleMaxDefaultCustomSize, {}), /*#__PURE__*/_jsx(SquircleMaxSetCustomMaxSize, {}), /*#__PURE__*/_jsx(HideExcessWhenExceedThreshold, {}), /*#__PURE__*/_jsx(MixAndMatchShapes, {}), /*#__PURE__*/_jsx(ShapeWithBorderWidth, {})]
278
354
  });
279
355
  export { All };
280
356
  const RemoteImageGroupScreen = () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coinbase/cds-mobile",
3
- "version": "8.34.2",
3
+ "version": "8.35.0",
4
4
  "description": "Coinbase Design System - Mobile",
5
5
  "repository": {
6
6
  "type": "git",
@@ -198,7 +198,7 @@
198
198
  "react-native-svg": "^14.1.0"
199
199
  },
200
200
  "dependencies": {
201
- "@coinbase/cds-common": "^8.34.2",
201
+ "@coinbase/cds-common": "^8.35.0",
202
202
  "@coinbase/cds-icons": "^5.9.0",
203
203
  "@coinbase/cds-illustrations": "^4.29.0",
204
204
  "@coinbase/cds-lottie-files": "^3.3.4",