Skip to content

Commit d7bc386

Browse files
committed
Add props to ItemCard
1 parent 6735b89 commit d7bc386

File tree

1 file changed

+99
-67
lines changed

1 file changed

+99
-67
lines changed

packages/client/src/components/ItemCard.tsx

Lines changed: 99 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -9,83 +9,115 @@ import {
99
Text,
1010
Heading,
1111
Box,
12-
IconButton,
1312
HStack,
1413
Tag,
15-
MenuButton,
16-
Menu,
17-
MenuList,
18-
MenuItem,
19-
Link
14+
Skeleton,
15+
SkeletonText
2016
} from '@chakra-ui/react';
21-
import { CollecticonEllipsisVertical } from '@devseed-ui/collecticons-chakra';
17+
import SmartLink from './SmartLink';
18+
19+
interface ItemCardProps {
20+
imageSrc?: string;
21+
imageAlt?: string;
22+
title?: string;
23+
subtitle?: string;
24+
description?: string;
25+
tags?: string[];
26+
to?: string;
27+
renderMenu?: () => React.ReactNode;
28+
}
29+
30+
export function ItemCard({
31+
imageSrc,
32+
imageAlt,
33+
title,
34+
subtitle,
35+
description,
36+
tags,
37+
to,
38+
renderMenu
39+
}: ItemCardProps) {
40+
const renderLink = (children: React.ReactNode) => {
41+
return to ? (
42+
<SmartLink to={to} color='inherit'>
43+
{children}
44+
</SmartLink>
45+
) : (
46+
<>{children}</>
47+
);
48+
};
2249

23-
export default function ItemCard() {
2450
return (
2551
<Card as='article' variant='filled'>
26-
<Link href='#'>
27-
<Image
28-
src='https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?q=80&w=3464&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D'
29-
alt='Abstract 3D render'
30-
height='16rem'
31-
width='100%'
32-
objectFit='cover'
33-
borderRadius='md'
34-
/>
35-
</Link>
52+
{imageSrc &&
53+
renderLink(
54+
<Image
55+
src={imageSrc}
56+
alt={imageAlt}
57+
height='16rem'
58+
width='100%'
59+
objectFit='cover'
60+
borderRadius='md'
61+
/>
62+
)}
3663
<CardHeader as='header'>
3764
<Flex direction='row' gap={4}>
38-
<Box flexBasis='100%'>
39-
<Heading size='sm' as='h3'>
40-
<Link href='#' color='inherit'>
41-
Card title
42-
</Link>
43-
</Heading>
44-
<Text as='p' fontSize='sm' color='base.400'>
45-
Card subtitle
46-
</Text>
47-
</Box>
48-
<Box>
49-
<Menu>
50-
<MenuButton
51-
as={IconButton}
52-
aria-label='Options'
53-
icon={<CollecticonEllipsisVertical />}
54-
variant='outline'
55-
size='sm'
56-
/>
57-
<MenuList>
58-
<MenuItem>View</MenuItem>
59-
<MenuItem>Edit</MenuItem>
60-
<MenuItem>Delete</MenuItem>
61-
</MenuList>
62-
</Menu>
63-
</Box>
65+
{(title || subtitle) && (
66+
<Box flexBasis='100%'>
67+
{title && (
68+
<Heading size='sm' as='h3' wordBreak='break-word'>
69+
{renderLink(title)}
70+
</Heading>
71+
)}
72+
{subtitle && (
73+
<Text as='p' fontSize='sm' color='base.400'>
74+
{subtitle}
75+
</Text>
76+
)}
77+
</Box>
78+
)}
79+
{renderMenu && <Box>{renderMenu()}</Box>}
6480
</Flex>
6581
</CardHeader>
66-
<CardBody>
67-
<Text size='md'>
68-
Card Summary. Lorem ipsum dolor sit, amet consectetur adipisicing
69-
elit. Non impedit vitae tempore repellat neque sunt aut, veniam
70-
facere, corporis nihil voluptas quis quia magni.
71-
</Text>
72-
</CardBody>
73-
<CardFooter as='footer'>
74-
<HStack spacing={2}>
75-
<Tag size='sm' colorScheme='primary' as='a' href='#'>
76-
Tag
77-
</Tag>
78-
<Tag size='sm' colorScheme='primary' as='a' href='#'>
79-
Tag
80-
</Tag>
81-
<Tag size='sm' colorScheme='primary' as='a' href='#'>
82-
Tag
83-
</Tag>
84-
<Tag size='sm' colorScheme='primary' as='a' href='#'>
85-
Tag
86-
</Tag>
87-
</HStack>
88-
</CardFooter>
82+
{description && (
83+
<CardBody>
84+
<Text size='md'>{description}</Text>
85+
</CardBody>
86+
)}
87+
{tags && tags.length > 0 && (
88+
<CardFooter as='footer'>
89+
<HStack spacing={2} wrap='wrap'>
90+
{tags.map((tag) => (
91+
// <Tag key={tag} size='sm' colorScheme='primary' as='a' href='#'>
92+
<Tag key={tag} size='sm' colorScheme='primary'>
93+
{tag}
94+
</Tag>
95+
))}
96+
</HStack>
97+
</CardFooter>
98+
)}
99+
</Card>
100+
);
101+
}
102+
103+
export function ItemCardLoading(props: { mini?: boolean }) {
104+
return (
105+
<Card as='article' variant='filled' p={8}>
106+
<Flex direction='column' gap={2}>
107+
<Skeleton h={6} width='40%' />
108+
<Skeleton h={4} width='30%' />
109+
</Flex>
110+
111+
{!props.mini && (
112+
<>
113+
<SkeletonText mt={8} noOfLines={4} spacing='4' skeletonHeight='2' />
114+
<Flex gap={2} mt={12}>
115+
<Skeleton h={4} width={12} />
116+
<Skeleton h={4} width={12} />
117+
<Skeleton h={4} width={12} />
118+
</Flex>
119+
</>
120+
)}
89121
</Card>
90122
);
91123
}

0 commit comments

Comments
 (0)