Skip to content

Commit bddb811

Browse files
authored
Merge pull request #8685 from TylerAPfledderer/refactor/products-card-chakra
Refactor: Migrate `ProductCard` to Chakra
2 parents 8f06f27 + 88f0daf commit bddb811

File tree

1 file changed

+117
-134
lines changed

1 file changed

+117
-134
lines changed

src/components/ProductCard.tsx

Lines changed: 117 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -1,123 +1,20 @@
11
import React, { ReactNode } from "react"
2-
import styled from "@emotion/styled"
32
import { GatsbyImage, IGatsbyImageData } from "gatsby-plugin-image"
43
import { useQuery, gql } from "@apollo/client"
4+
import {
5+
Box,
6+
Center,
7+
Flex,
8+
Heading,
9+
HStack,
10+
Img,
11+
Text,
12+
TextProps,
13+
} from "@chakra-ui/react"
514

615
import GitStars from "./GitStars"
716
import ButtonLink from "./ButtonLink"
817

9-
const ImageWrapper = styled.div<{
10-
background: string
11-
}>`
12-
display: flex;
13-
flex-direction: row;
14-
justify-content: center;
15-
align-items: center;
16-
background: ${(props) => props.background};
17-
box-shadow: inset 0px -1px 0px rgba(0, 0, 0, 0.1);
18-
min-height: 200px;
19-
`
20-
21-
const Image = styled(GatsbyImage)`
22-
width: 100%;
23-
align-self: center;
24-
max-width: 372px;
25-
max-height: 257px;
26-
@media (max-width: ${(props) => props.theme.breakpoints.s}) {
27-
max-width: 311px;
28-
}
29-
`
30-
31-
const Card = styled.div`
32-
color: ${(props) => props.theme.colors.text};
33-
box-shadow: 0px 14px 66px rgba(0, 0, 0, 0.07);
34-
display: flex;
35-
flex-direction: column;
36-
justify-content: space-between;
37-
background: ${(props) => props.theme.colors.searchBackground};
38-
border-radius: 4px;
39-
border: 1px solid ${(props) => props.theme.colors.lightBorder};
40-
text-decoration: none;
41-
&:hover {
42-
transition: transform 0.1s;
43-
transform: scale(1.02);
44-
}
45-
`
46-
47-
const Content = styled.div`
48-
padding: 1.5rem;
49-
text-align: left;
50-
height: 100%;
51-
display: flex;
52-
flex-direction: column;
53-
`
54-
55-
const Title = styled.h3<{
56-
gitHidden: boolean
57-
}>`
58-
margin-top: ${(props) => (props.gitHidden ? "2rem" : "3rem")};
59-
margin-bottom: 0.75rem;
60-
`
61-
62-
const Description = styled.p`
63-
opacity: 0.8;
64-
font-size: ${(props) => props.theme.fontSizes.s};
65-
margin-bottom: 0.5rem;
66-
line-height: 140%;
67-
`
68-
69-
const SubjectContainer = styled.div`
70-
margin-top: 1.25rem;
71-
padding: 0 1.5rem;
72-
`
73-
74-
const SubjectPill = styled.div<{
75-
subject: string
76-
}>`
77-
text-align: center;
78-
padding: 0 0.5rem;
79-
margin: 0 0.75rem 0.5rem 0;
80-
color: ${(props) => props.theme.colors.black300};
81-
float: left;
82-
background: ${({ theme, subject }) => {
83-
switch (subject) {
84-
case "Solidity":
85-
return theme.colors.tagYellow
86-
case "Vyper":
87-
return theme.colors.tagBlue
88-
case "web3":
89-
return theme.colors.tagTurquoise
90-
case "JavaScript":
91-
return theme.colors.tagRed
92-
case "TypeScript":
93-
return theme.colors.tagBlue
94-
case "Go":
95-
return theme.colors.tagTurquoise
96-
case "Python":
97-
return theme.colors.tagMint
98-
case "Rust":
99-
return theme.colors.tagOrange
100-
case "C#":
101-
return theme.colors.tagBlue
102-
case "Java":
103-
return theme.colors.tagPink
104-
default:
105-
return theme.colors.tagGray
106-
}
107-
}};
108-
font-size: ${(props) => props.theme.fontSizes.xs};
109-
border: 1px solid ${(props) => props.theme.colors.lightBorder};
110-
border-radius: 4px;
111-
`
112-
113-
const StyledButtonLink = styled(ButtonLink)`
114-
margin: 1rem;
115-
`
116-
117-
const Children = styled.div`
118-
margin-top: 1rem;
119-
`
120-
12118
const REPO_DATA = gql`
12219
query RepoData(
12320
$repoOwner: String!
@@ -139,6 +36,52 @@ const REPO_DATA = gql`
13936
}
14037
`
14138

39+
const SubjectPill: React.FC<{ subject: string; children: ReactNode }> = ({
40+
subject,
41+
children,
42+
}) => {
43+
const bgColor = () => {
44+
switch (subject) {
45+
case "Solidity":
46+
return "tagYellow"
47+
case "Vyper":
48+
return "tagBlue"
49+
case "web3":
50+
return "tagTurquoise"
51+
case "JavaScript":
52+
return "tagRed"
53+
case "TypeScript":
54+
return "tagBlue"
55+
case "Go":
56+
return "tagTurquoise"
57+
case "Python":
58+
return "tagMint"
59+
case "Rust":
60+
return "tagOrange"
61+
case "C#":
62+
return "tagBlue"
63+
case "Java":
64+
return "tagPink"
65+
default:
66+
return "tagGray"
67+
}
68+
}
69+
return (
70+
<Box
71+
background={bgColor()}
72+
border="1px"
73+
borderColor="lightBorder"
74+
borderRadius="base"
75+
color="black300"
76+
fontSize="xs"
77+
textAlign="center"
78+
px={2}
79+
>
80+
{children}
81+
</Box>
82+
)
83+
}
84+
14285
export interface IProps {
14386
children?: React.ReactNode
14487
url: string
@@ -156,7 +99,7 @@ export interface IProps {
15699

157100
const ProductCard: React.FC<IProps> = ({
158101
url,
159-
background,
102+
background: bgProp,
160103
image,
161104
name,
162105
description,
@@ -186,27 +129,67 @@ const ProductCard: React.FC<IProps> = ({
186129

187130
const isImgSrc = typeof image === "string"
188131

132+
const DESCRIPTION_STYLES: TextProps = {
133+
opacity: 0.8,
134+
fontSize: "sm",
135+
mb: 2,
136+
lineHeight: "140%",
137+
}
138+
189139
return (
190-
<Card>
191-
<ImageWrapper background={background}>
140+
<Flex
141+
flexDirection="column"
142+
justifyContent="space-between"
143+
color="text"
144+
background="searchBackground"
145+
boxShadow="0px 14px 66px rgba(0, 0, 0, 0.07)"
146+
borderRadius="base"
147+
border="1px"
148+
borderColor="lightBorder"
149+
textDecoration="none"
150+
_hover={{
151+
transition: "transform 0.1s",
152+
transform: "scale(1.02)",
153+
}}
154+
>
155+
<Center
156+
background={bgProp}
157+
boxShadow="inset 0px -1px 0px rgba(0, 0, 0, 0.1)"
158+
minH="200px"
159+
>
192160
{isImgSrc ? (
193161
<img src={image} alt={alt} />
194162
) : (
195-
<Image image={image} alt={alt} objectFit="contain" />
163+
<Img
164+
as={GatsbyImage}
165+
image={image}
166+
alt={alt}
167+
objectFit="contain"
168+
width="100%"
169+
alignSelf="center"
170+
maxW={{ base: "311px", sm: "372px" }}
171+
maxH="257px"
172+
/>
196173
)}
197-
</ImageWrapper>
198-
<Content className="hover">
199-
<div>
200-
{hasRepoData && (
201-
<GitStars gitHubRepo={data.repository} hideStars={hideStars} />
202-
)}
203-
<Title gitHidden={!hasRepoData}>{name}</Title>
204-
<Description>{description}</Description>
205-
{note.length > 0 && <Description>Note: {note}</Description>}
206-
</div>
207-
{children && <Children>{children}</Children>}
208-
</Content>
209-
<SubjectContainer>
174+
</Center>
175+
<Flex flexDirection="column" p={6} textAlign="left" height="100%">
176+
{hasRepoData && (
177+
<GitStars gitHubRepo={data.repository} hideStars={hideStars} />
178+
)}
179+
<Heading
180+
as="h3"
181+
fontSize="2xl"
182+
fontWeight={600}
183+
mt={!hasRepoData ? 8 : 12}
184+
mb={3}
185+
>
186+
{name}
187+
</Heading>
188+
{description && <Text {...DESCRIPTION_STYLES}>{description}</Text>}
189+
{note.length > 0 && <Text {...DESCRIPTION_STYLES}>Note: {note}</Text>}
190+
{children && <Box mt={4}>{children}</Box>}
191+
</Flex>
192+
<HStack mt={5} mb={2} px={6} spacing={3}>
210193
{subjects &&
211194
subjects.map((subject, idx) => (
212195
<SubjectPill key={idx} subject={subject}>
@@ -221,11 +204,11 @@ const ProductCard: React.FC<IProps> = ({
221204
</SubjectPill>
222205
)
223206
)}
224-
</SubjectContainer>
225-
<StyledButtonLink h={20} to={url}>
207+
</HStack>
208+
<ButtonLink to={url} m={4} height={20}>
226209
Open {name}
227-
</StyledButtonLink>
228-
</Card>
210+
</ButtonLink>
211+
</Flex>
229212
)
230213
}
231214

0 commit comments

Comments
 (0)