Skip to content

Commit 08732eb

Browse files
authored
Merge pull request #8572 from jb-0/refactor/migrate_expandable_card
refactor: migrate expandable card to chakra
2 parents 605c566 + 3df272f commit 08732eb

File tree

1 file changed

+105
-176
lines changed

1 file changed

+105
-176
lines changed

src/components/ExpandableCard.tsx

Lines changed: 105 additions & 176 deletions
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,20 @@
11
// Libraries
22
import React, { ComponentType, ReactNode, SVGProps, useState } from "react"
3-
import styled from "@emotion/styled"
4-
import { motion } from "framer-motion"
53

64
// Components
75
import Translation from "./Translation"
86

97
// Utils
108
import { trackCustomEvent } from "../utils/matomo"
11-
12-
const Card = styled.div`
13-
border: 1px solid ${(props) => props.theme.colors.border};
14-
border-radius: 2px;
15-
padding: 1.5rem;
16-
display: flex;
17-
flex-direction: column;
18-
margin-bottom: 1rem;
19-
cursor: pointer;
20-
&:hover {
21-
background-color: ${(props) => props.theme.colors.ednBackground};
22-
}
23-
`
24-
25-
const Content = styled.div`
26-
display: flex;
27-
align-items: center;
28-
justify-content: space-between;
29-
30-
@media (max-width: ${(props) => props.theme.breakpoints.s}) {
31-
flex-direction: column;
32-
}
33-
`
34-
35-
const Title = styled.h3`
36-
margin-top: 0rem;
37-
font-size: 1.25rem;
38-
font-weight: 600;
39-
margin-bottom: 0.5rem;
40-
`
41-
42-
const TextPreview = styled.p`
43-
font-size: 0.875rem;
44-
font-weight: 400;
45-
color: ${(props) => props.theme.colors.text200};
46-
margin-bottom: 0rem;
47-
`
48-
49-
const Text = styled(motion.div)`
50-
font-size: 1rem;
51-
font-weight: 400;
52-
color: ${(props) => props.theme.colors.text};
53-
margin-top: 2rem;
54-
border-top: 1px solid ${(props) => props.theme.colors.border};
55-
padding-top: 1.5rem;
56-
`
57-
58-
const Question = styled.div`
59-
margin-right: 1rem;
60-
61-
@media (max-width: ${(props) => props.theme.breakpoints.s}) {
62-
margin-right: 0;
63-
margin-bottom: 0.5rem;
64-
}
65-
`
66-
67-
const Header = styled.div`
68-
display: flex;
69-
width: 100%;
70-
margin: 1rem 0;
71-
align-items: center;
72-
svg {
73-
margin-right: 1.5rem;
74-
}
75-
`
76-
77-
const ButtonContainer = styled.div`
78-
margin-left: 1rem;
79-
80-
@media (max-width: ${(props) => props.theme.breakpoints.s}) {
81-
margin-left: 0;
82-
}
83-
`
84-
85-
const ButtonLink = styled.button`
86-
border: 0;
87-
cursor: pointer;
88-
background-color: transparent;
89-
color: ${(props) => props.theme.colors.primary};
90-
`
9+
import {
10+
Accordion,
11+
AccordionButton,
12+
AccordionItem,
13+
AccordionPanel,
14+
Box,
15+
Heading,
16+
Text,
17+
} from "@chakra-ui/react"
9118

9219
export interface IProps {
9320
children?: React.ReactNode
@@ -107,111 +34,113 @@ const ExpandableCard: React.FC<IProps> = ({
10734
eventName = "",
10835
}) => {
10936
const [isVisible, setIsVisible] = useState(false)
110-
111-
const expandCollapse = {
112-
collapsed: {
113-
height: 0,
114-
transition: {
115-
when: "afterChildren",
116-
},
117-
},
118-
expanded: {
119-
height: "100%",
120-
transition: {
121-
when: "beforeChildren",
122-
},
123-
},
124-
}
125-
126-
const showHide = {
127-
collapsed: {
128-
display: "none",
129-
},
130-
expanded: {
131-
display: "inline-block",
132-
},
133-
}
134-
135-
const fadeInOut = {
136-
collapsed: {
137-
opacity: 0,
138-
transition: {
139-
duration: 0.1,
140-
},
141-
},
142-
expanded: {
143-
opacity: 1,
144-
transition: {
145-
duration: 0.4,
146-
},
147-
},
148-
}
14937
const matomo = {
15038
eventAction: `Clicked`,
15139
eventCategory: `ExpandableCard${eventCategory}`,
15240
eventName,
15341
}
42+
const onClick = () => {
43+
// Card will not collapse if clicking on a link or selecting text
44+
if (
45+
window.getSelection()?.toString().length === 0 &&
46+
!(window.event?.target as HTMLDivElement)?.className.includes(
47+
"ExternalLink"
48+
)
49+
) {
50+
!isVisible && trackCustomEvent(matomo)
51+
setIsVisible(!isVisible)
52+
}
53+
}
54+
15455
return (
155-
<Card
156-
onClick={() => {
157-
// Card will not collapse if clicking on a link or selecting text
158-
if (
159-
window.getSelection()?.toString().length === 0 &&
160-
!(window.event?.target as HTMLDivElement)?.className.includes(
161-
"ExternalLink"
162-
)
163-
) {
164-
!isVisible && trackCustomEvent(matomo)
165-
setIsVisible(!isVisible)
166-
}
56+
<Accordion
57+
border="1px solid"
58+
borderColor="border"
59+
borderRadius="sm"
60+
h3
61+
display="flex"
62+
flex-direction="column"
63+
marginBottom="4"
64+
cursor="pointer"
65+
_hover={{
66+
backgroundColor: "ednBackground",
16767
}}
68+
borderBottomWidth="0"
69+
index={isVisible ? [0] : []}
16870
>
169-
<Content>
170-
<Question>
171-
<Header>
172-
{!!Svg && <Svg />}
173-
<Title>{title}</Title>
174-
</Header>
175-
<TextPreview>{contentPreview}</TextPreview>
176-
</Question>
177-
<ButtonContainer
178-
onClick={() => {
179-
trackCustomEvent(matomo)
180-
setIsVisible(!isVisible)
181-
}}
182-
>
183-
{!isVisible && (
184-
<ButtonLink onClick={() => setIsVisible(true)}>
185-
<Translation id="more" />
186-
</ButtonLink>
187-
)}
188-
{isVisible && (
189-
<ButtonLink onClick={() => setIsVisible(false)}>
190-
<Translation id="less" />
191-
</ButtonLink>
192-
)}
193-
</ButtonContainer>
194-
</Content>
195-
<motion.div
196-
variants={expandCollapse}
197-
animate={isVisible ? "expanded" : "collapsed"}
198-
initial={false}
199-
>
200-
<motion.div
201-
variants={showHide}
202-
animate={isVisible ? "expanded" : "collapsed"}
203-
initial={false}
71+
<AccordionItem borderTopWidth="0" flex="1">
72+
<Heading as="h3" m={0}>
73+
<AccordionButton
74+
width="100%"
75+
p={6}
76+
flex="1"
77+
onClick={onClick}
78+
_hover={{
79+
backgroundColor: "ednBackground",
80+
}}
81+
>
82+
<Box
83+
display="flex"
84+
width="100%"
85+
alignItems="center"
86+
flexDir={{ base: "column", sm: "row" }}
87+
>
88+
<Box
89+
marginBottom={{ base: 2, sm: 0 }}
90+
marginRight={{ base: 0, sm: 4 }}
91+
>
92+
<Box
93+
display="flex"
94+
alignItems="center"
95+
sx={{
96+
svg: { marginRight: "1.5rem" },
97+
}}
98+
my="4"
99+
>
100+
{!!Svg && <Svg />}
101+
<Text fontSize="xl" fontWeight="semibold" flex="1" m="0">
102+
{title}
103+
</Text>
104+
</Box>
105+
<Text
106+
fontSize="sm"
107+
color="text200"
108+
marginBottom="0"
109+
width="fit-content"
110+
>
111+
{contentPreview}
112+
</Text>
113+
</Box>
114+
<Text
115+
fontSize="md"
116+
color="primary"
117+
ml={{ base: undefined, sm: "auto" }}
118+
mt="auto"
119+
mb="auto"
120+
>
121+
<Translation id={isVisible ? "less" : "more"} />
122+
</Text>
123+
</Box>
124+
</AccordionButton>
125+
</Heading>
126+
<AccordionPanel
127+
paddingX="6"
128+
paddingBottom="6"
129+
paddingTop="0"
130+
onClick={onClick}
204131
>
205-
<Text
206-
variants={fadeInOut}
207-
animate={isVisible ? "expanded" : "collapsed"}
208-
initial={false}
132+
<Box
133+
fontSize="md"
134+
color="text"
135+
paddingTop="6"
136+
borderTop="1px solid"
137+
borderColor="border"
209138
>
210139
{children}
211-
</Text>
212-
</motion.div>
213-
</motion.div>
214-
</Card>
140+
</Box>
141+
</AccordionPanel>
142+
</AccordionItem>
143+
</Accordion>
215144
)
216145
}
217146

0 commit comments

Comments
 (0)