Skip to content

Commit feeb1a3

Browse files
fix: remote image group zIndex and trailing space issue (#170)
* fix: RemoteImageGroup trailing space and zIndex problem * release * update docs examples for SelectChip
1 parent f18a4b3 commit feeb1a3

File tree

18 files changed

+297
-107
lines changed

18 files changed

+297
-107
lines changed

apps/docs/docs/components/inputs/SelectChipAlpha/_mobileExamples.mdx

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,59 @@ function ExampleMultiGroups() {
178178
}
179179
```
180180

181+
### Multi-select with assets
182+
183+
```tsx
184+
function ExampleMultiAssets() {
185+
const assetImageMap: Record<string, string> = {
186+
btc: assets.btc.imageUrl,
187+
eth: assets.eth.imageUrl,
188+
dai: assets.dai.imageUrl,
189+
ltc: assets.ltc.imageUrl,
190+
xrp: assets.xrp.imageUrl,
191+
};
192+
const exampleOptions = [
193+
{ value: 'btc', label: assets.btc.name },
194+
{ value: 'eth', label: assets.eth.name },
195+
{ value: 'dai', label: assets.dai.name },
196+
{ value: 'ltc', label: assets.ltc.name },
197+
{ value: 'xrp', label: assets.xrp.name },
198+
];
199+
const { value, onChange } = useMultiSelect({
200+
initialValue: ['eth', 'btc'],
201+
});
202+
203+
// Get startNode based on selected assets
204+
const startNode = useMemo(() => {
205+
if (value.length === 0) return null;
206+
207+
// Multiple assets selected - use RemoteImageGroup
208+
return (
209+
<RemoteImageGroup shape="circle" size={24}>
210+
{value.map((assetValue) => {
211+
const imageUrl = assetImageMap[assetValue];
212+
if (!imageUrl) return null;
213+
return <RemoteImage key={assetValue} source={imageUrl} />;
214+
})}
215+
</RemoteImageGroup>
216+
);
217+
}, [value]);
218+
219+
return (
220+
<SelectChip
221+
accessibilityLabel="Select multiple assets"
222+
maxWidth={400}
223+
onChange={onChange}
224+
options={exampleOptions}
225+
placeholder="Choose assets"
226+
startNode={startNode}
227+
type="multi"
228+
value={value}
229+
/>
230+
);
231+
}
232+
```
233+
181234
### Compact
182235

183236
```tsx

apps/docs/docs/components/inputs/SelectChipAlpha/_webExamples.mdx

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,60 @@ function ExampleMultiGroups() {
173173
}
174174
```
175175

176+
### Multi-select with assets
177+
178+
```jsx live
179+
function ExampleMultiAssets() {
180+
const assetImageMap: Record<string, string> = {
181+
btc: assets.btc.imageUrl,
182+
eth: assets.eth.imageUrl,
183+
dai: assets.dai.imageUrl,
184+
ltc: assets.ltc.imageUrl,
185+
xrp: assets.xrp.imageUrl,
186+
};
187+
188+
const exampleOptions = [
189+
{ value: 'btc', label: assets.btc.name },
190+
{ value: 'eth', label: assets.eth.name },
191+
{ value: 'dai', label: assets.dai.name },
192+
{ value: 'ltc', label: assets.ltc.name },
193+
{ value: 'xrp', label: assets.xrp.name },
194+
];
195+
const { value, onChange } = useMultiSelect({
196+
initialValue: ['eth', 'btc'],
197+
});
198+
199+
// Get startNode based on selected assets
200+
const startNode = useMemo(() => {
201+
if (value.length === 0) return null;
202+
203+
// Multiple assets selected - use RemoteImageGroup
204+
return (
205+
<RemoteImageGroup shape="circle" size={24}>
206+
{value.map((assetValue) => {
207+
const imageUrl = assetImageMap[assetValue];
208+
if (!imageUrl) return null;
209+
return <RemoteImage key={assetValue} source={imageUrl} />;
210+
})}
211+
</RemoteImageGroup>
212+
);
213+
}, [value]);
214+
215+
return (
216+
<SelectChip
217+
controlAccessibilityLabel="Select multiple assets"
218+
maxWidth={400}
219+
onChange={onChange}
220+
options={exampleOptions}
221+
placeholder="Choose assets"
222+
startNode={startNode}
223+
type="multi"
224+
value={value}
225+
/>
226+
);
227+
}
228+
```
229+
176230
### Compact
177231

178232
```jsx live

packages/common/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ All notable changes to this project will be documented in this file.
88

99
<!-- template-start -->
1010

11+
## 8.33.1 ((12/19/2025, 08:09 AM PST))
12+
13+
This is an artificial version bump with no new change.
14+
1115
## 8.33.0 (12/18/2025 PST)
1216

1317
#### 🚀 Updates

packages/common/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@coinbase/cds-common",
3-
"version": "8.33.0",
3+
"version": "8.33.1",
44
"description": "Coinbase Design System - Common",
55
"repository": {
66
"type": "git",

packages/mcp-server/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ All notable changes to this project will be documented in this file.
88

99
<!-- template-start -->
1010

11+
## 8.33.1 ((12/19/2025, 08:09 AM PST))
12+
13+
This is an artificial version bump with no new change.
14+
1115
## 8.33.0 ((12/18/2025, 11:46 AM PST))
1216

1317
This is an artificial version bump with no new change.

packages/mcp-server/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@coinbase/cds-mcp-server",
3-
"version": "8.33.0",
3+
"version": "8.33.1",
44
"description": "Coinbase Design System - MCP Server",
55
"repository": {
66
"type": "git",

packages/mobile/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ All notable changes to this project will be documented in this file.
88

99
<!-- template-start -->
1010

11+
## 8.33.1 (12/19/2025 PST)
12+
13+
#### 🐞 Fixes
14+
15+
- Fix RemoteImageGroup zIndex and trailing space issue. [[#170](https://github.com/coinbase/cds/pull/170)]
16+
1117
## 8.33.0 (12/18/2025 PST)
1218

1319
#### 🚀 Updates

packages/mobile/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@coinbase/cds-mobile",
3-
"version": "8.33.0",
3+
"version": "8.33.1",
44
"description": "Coinbase Design System - Mobile",
55
"repository": {
66
"type": "git",

packages/mobile/src/alpha/select-chip/__stories__/AlphaSelectChip.stories.tsx

Lines changed: 44 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState } from 'react';
1+
import { useMemo, useState } from 'react';
22
import { assets } from '@coinbase/cds-common/internal/data/assets';
33
import { useMultiSelect } from '@coinbase/cds-common/select/useMultiSelect';
44

@@ -121,47 +121,47 @@ const assetImageMap: Record<string, string> = {
121121
xrp: assets.xrp.imageUrl,
122122
};
123123

124-
// TODO: Add multi-select with assets story when RemoteImageGroup is fixed
125-
// export const MultiSelectWithAssets = () => {
126-
// const exampleOptions = [
127-
// { value: 'btc', label: assets.btc.name },
128-
// { value: 'eth', label: assets.eth.name },
129-
// { value: 'dai', label: assets.dai.name },
130-
// { value: 'ltc', label: assets.ltc.name },
131-
// { value: 'xrp', label: assets.xrp.name },
132-
// ];
133-
// const { value, onChange } = useMultiSelect({
134-
// initialValue: ['eth', 'btc'],
135-
// });
136-
137-
// // Get startNode based on selected assets
138-
// const startNode = useMemo(() => {
139-
// if (value.length === 0) return null;
140-
141-
// // Multiple assets selected - use RemoteImageGroup
142-
// return (
143-
// <RemoteImageGroup shape="circle" size={24}>
144-
// {value.map((assetValue) => {
145-
// const imageUrl = assetImageMap[assetValue];
146-
// if (!imageUrl) return null;
147-
// return <RemoteImage key={assetValue} source={imageUrl} />;
148-
// })}
149-
// </RemoteImageGroup>
150-
// );
151-
// }, [value]);
152-
153-
// return (
154-
// <SelectChip
155-
// accessibilityLabel="Select multiple assets"
156-
// onChange={onChange}
157-
// options={exampleOptions}
158-
// placeholder="Choose assets"
159-
// startNode={startNode}
160-
// type="multi"
161-
// value={value}
162-
// />
163-
// );
164-
// };
124+
export const MultiSelectWithAssets = () => {
125+
const exampleOptions = [
126+
{ value: 'btc', label: assets.btc.name },
127+
{ value: 'eth', label: assets.eth.name },
128+
{ value: 'dai', label: assets.dai.name },
129+
{ value: 'ltc', label: assets.ltc.name },
130+
{ value: 'xrp', label: assets.xrp.name },
131+
];
132+
const { value, onChange } = useMultiSelect({
133+
initialValue: ['eth', 'btc'],
134+
});
135+
136+
// Get startNode based on selected assets
137+
const startNode = useMemo(() => {
138+
if (value.length === 0) return null;
139+
140+
// Multiple assets selected - use RemoteImageGroup
141+
return (
142+
<RemoteImageGroup shape="circle" size={24}>
143+
{value.map((assetValue) => {
144+
const imageUrl = assetImageMap[assetValue];
145+
if (!imageUrl) return null;
146+
return <RemoteImage key={assetValue} source={imageUrl} />;
147+
})}
148+
</RemoteImageGroup>
149+
);
150+
}, [value]);
151+
152+
return (
153+
<SelectChip
154+
accessibilityLabel="Select multiple assets"
155+
maxWidth={400}
156+
onChange={onChange}
157+
options={exampleOptions}
158+
placeholder="Choose assets"
159+
startNode={startNode}
160+
type="multi"
161+
value={value}
162+
/>
163+
);
164+
};
165165

166166
export const InvertColorScheme = () => {
167167
const exampleOptions = [
@@ -473,9 +473,9 @@ const SelectChipScreen = () => {
473473
<Example title="With Start End Nodes">
474474
<WithStartEndNodes />
475475
</Example>
476-
{/* <Example title="Multi-Select with Assets">
476+
<Example title="Multi-Select with Assets">
477477
<MultiSelectWithAssets />
478-
</Example> */}
478+
</Example>
479479
<Example title="Invert Color Scheme">
480480
<InvertColorScheme />
481481
</Example>

packages/mobile/src/media/RemoteImageGroup.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type { ViewStyle } from 'react-native';
44
import { shapeBorderRadius } from '@coinbase/cds-common/tokens/borderRadius';
55
import type {
66
AvatarSize,
7+
NegativeSpace,
78
Shape,
89
SharedAccessibilityProps,
910
SharedProps,
@@ -49,7 +50,7 @@ export const RemoteImageGroup = ({
4950

5051
const shapeStyle = shapeStyles[shape];
5152
const sizeAsNumber = typeof size === 'number' ? size : avatarSize[size];
52-
const overlapSpacing = sizeAsNumber <= 40 ? 8 : 16;
53+
const overlapSpacing: NegativeSpace = sizeAsNumber <= 40 ? -1 : -2;
5354

5455
const excess = Children.count(children) - max;
5556
const groupChildren = useMemo(() => {
@@ -98,7 +99,7 @@ export const RemoteImageGroup = ({
9899
return (
99100
<Box
100101
key={index}
101-
left={index === 0 ? 'initial' : overlapSpacing * zIndex}
102+
marginStart={index === 0 ? undefined : overlapSpacing}
102103
position="relative"
103104
testID={`${testID ? `${testID}-` : ''}inner-box-${index}`}
104105
zIndex={zIndex}
@@ -113,7 +114,7 @@ export const RemoteImageGroup = ({
113114
background="bgOverlay"
114115
height={sizeAsNumber}
115116
justifyContent="center"
116-
left={groupChildren.length * overlapSpacing * -1}
117+
marginStart={overlapSpacing}
117118
position="relative"
118119
style={shapeStyle}
119120
width={sizeAsNumber}

0 commit comments

Comments
 (0)