Skip to content

Commit 634007d

Browse files
feat: CardRoot
1 parent feeb1a3 commit 634007d

File tree

7 files changed

+87
-37
lines changed

7 files changed

+87
-37
lines changed

packages/mobile/src/cards/CardMedia.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { memo } from 'react';
1+
import { memo } from 'react';
22
import {
33
defaultMediaDimension,
44
defaultMediaSize,
@@ -11,8 +11,7 @@ import type {
1111
} from '@coinbase/cds-common/types';
1212

1313
import { Pictogram, SpotSquare } from '../illustrations';
14-
15-
import { CardRemoteImage } from './CardRemoteImage';
14+
import { getSource, RemoteImage } from '../media/RemoteImage';
1615

1716
export type CardMediaProps = CommonCardMediaProps;
1817

@@ -50,8 +49,10 @@ export const CardMedia = memo(function CardMedia({ placement = 'end', ...props }
5049
);
5150
case 'image':
5251
return (
53-
<CardRemoteImage
52+
<RemoteImage
5453
alt={props.alt ?? ''}
54+
resizeMode="cover"
55+
source={getSource(props.src)}
5556
src={props.src}
5657
testID={props.testID}
5758
{...imageProps[placement]}

packages/mobile/src/cards/CardRemoteImage.tsx

Lines changed: 0 additions & 16 deletions
This file was deleted.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import React, { forwardRef, memo } from 'react';
2+
import type { StyleProp, View, ViewStyle } from 'react-native';
3+
4+
import { HStack } from '../layout/HStack';
5+
import { Pressable, type PressableProps } from '../system/Pressable';
6+
7+
export type CardRootBaseProps = {
8+
children: React.ReactNode;
9+
/** If true, the CardRoot will be rendered as a Pressable component. */
10+
renderAsPressable?: boolean;
11+
};
12+
13+
export type CardRootProps = CardRootBaseProps &
14+
Omit<PressableProps, 'style'> & {
15+
style?: StyleProp<ViewStyle>;
16+
};
17+
18+
export const CardRoot = memo(
19+
forwardRef<View, CardRootProps>(({ children, style, renderAsPressable, ...props }, ref) => {
20+
const Component = renderAsPressable ? Pressable : HStack;
21+
return (
22+
<Component ref={ref} {...props}>
23+
{children}
24+
</Component>
25+
);
26+
}),
27+
);
28+
29+
CardRoot.displayName = 'CardRoot';

packages/mobile/src/cards/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export * from './CardFooter';
44
export * from './CardGroup';
55
export * from './CardHeader';
66
export * from './CardMedia';
7+
export * from './CardRoot';
78
// Card variants
89
export * from './AnnouncementCard';
910
export * from './FeatureEntryCard';

packages/web/src/cards/CardRemoteImage.tsx

Lines changed: 0 additions & 17 deletions
This file was deleted.
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import React, { forwardRef, memo } from 'react';
2+
3+
import type { Polymorphic } from '../core/polymorphism';
4+
import { HStack } from '../layout/HStack';
5+
import { Pressable, type PressableBaseProps } from '../system/Pressable';
6+
7+
export type CardRootBaseProps = Polymorphic.ExtendableProps<
8+
PressableBaseProps,
9+
{
10+
children?: React.ReactNode;
11+
/** If true, the CardRoot will be rendered as a Pressable component. */
12+
renderAsPressable?: boolean;
13+
}
14+
>;
15+
16+
export type CardRootProps<AsComponent extends React.ElementType = 'article'> = Polymorphic.Props<
17+
AsComponent,
18+
CardRootBaseProps
19+
>;
20+
21+
type CardRootComponent = (<AsComponent extends React.ElementType = 'article'>(
22+
props: Polymorphic.Props<AsComponent, CardRootBaseProps>,
23+
) => Polymorphic.ReactReturn) &
24+
Polymorphic.ReactNamed;
25+
26+
export const CardRoot: CardRootComponent = memo(
27+
forwardRef<React.ReactElement<CardRootBaseProps>, CardRootBaseProps>(
28+
<AsComponent extends React.ElementType>(
29+
{ renderAsPressable, children, ...props }: CardRootProps<AsComponent>,
30+
ref?: Polymorphic.Ref<AsComponent>,
31+
) => {
32+
if (renderAsPressable) {
33+
const { as, ...pressableRestProps } = props;
34+
return (
35+
<Pressable ref={ref} as={as ?? 'button'} {...(pressableRestProps as any)}>
36+
{children}
37+
</Pressable>
38+
);
39+
} else {
40+
const { as, ...hstackRestProps } = props;
41+
return (
42+
<HStack ref={ref} as={as ?? 'article'} {...(hstackRestProps as any)}>
43+
{children}
44+
</HStack>
45+
);
46+
}
47+
},
48+
),
49+
);
50+
51+
CardRoot.displayName = 'CardRoot';

packages/web/src/cards/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export * from './CardFooter';
44
export * from './CardGroup';
55
export * from './CardHeader';
66
export * from './CardMedia';
7+
export * from './CardRoot';
78
// Card variants
89
export * from './AnnouncementCard';
910
export * from './FeatureEntryCard';

0 commit comments

Comments
 (0)