I'm trying to make this card in such a way that when you click on view details, the card's blue footer should expand in height and shows the lorem text, and then clicking on another card the previous card will get collapsed. The issue is when I click on view details
the card's blue bottom is not expanding with the lorem. Here is my sandbox: https://codesandbox.io/s/wonderful-bohr-by01z?file=/src/App.js
App.js:
import { Card, Footer, Header } from "./styles";
import { useState } from "react";
export default function App() {
const [expanded, setExpanded] = useState(false);
return (
<>
<Card>
<Header>last viewed: {null}</Header>
<Footer>
<span onClick={() => setExpanded(!expanded)}>View Details</span>
{expanded && (
<div className="accodion">
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Eos,
facilis. Lorem, ipsum dolor sit amet consectetur adipisicing elit.
Eos, facilis. Lorem, ipsum dolor sit amet consectetur adipisicing
elit. Eos, facilis. Lorem, ipsum dolor sit amet consectetur
adipisicing elit. Eos, facilis.
</div>
)}
</Footer>
</Card>
</>
);
}
styles.js:
import styled from "styled-components";
const Card = styled.div`
background-color: ${({ isEmpty }) => (isEmpty ? "#FAFAFA" : "white")};
height: 100%;
border-radius: 20px;
box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.5);
overflow: hidden;
margin: 8px;
`;
const DropDown = styled.div`
background-color: lightblue;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
`;
const Header = styled.div`
display: flex;
justify-content: space-between;
margin-top: -40;
font-size: 10px;
color: #7894b0;
margin: 16px;
`;
const Footer = styled.div`
background-color: rgb(242, 247, 251);
width: 100%;
height: 50px;
font-size: 12px;
line-height: 12px;
color: #4f4f4f;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
cursor: pointer;
.accodion {
padding: 30px;
}
`;
export { Card, Header, Footer, DropDown };
For solution need additional switch class .show and get the height for the current footer with useRef. Also adding second useState where will keep the whole footer height. sandbox example
Styled-components
const Card = styled.div`
background-color: ${({ isEmpty }) => (isEmpty ? '#FAFAFA' : 'white')};
height: 100%;
border-radius: 20px;
box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.5);
overflow: hidden;
margin: 8px;
`;
const DropDown = styled.div`
background-color: lightblue;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
`;
const Header = styled.div`
display: flex;
justify-content: space-between;
margin-top: -40;
font-size: 10px;
color: #7894b0;
margin: 16px;
`;
const Footer = styled.div`
background-color: rgb(242, 247, 251);
width: 100%;
height: 35px; /* changed */
font-size: 12px;
line-height: 12px;
color: #4f4f4f;
display: flex;
/* justify-content: center; */
flex-direction: column;
align-items: center;
cursor: pointer;
transition: all 0.3s ease-in-out; /* added */
overflow: hidden; /* added */
span {
padding: 12px 0;
}
.accodion {
padding: 10px 15px 15px; /* changed */
}
&.show {
height: ${({ setHeight }) => setHeight}px;
}
`;
App.js
import { Card, Footer, Header } from "./styles";
import { useState, useEffect, useRef } from "react";
export default function App() {
const [expanded, setExpanded] = useState(false);
const [accodionHeight, setAccodionHeight] = useState(0);
const ref = useRef(null);
const open = () => setExpanded(!expanded);
useEffect(() => {
const getHeight = ref.current.scrollHeight;
setAccodionHeight(getHeight);
}, [expanded]);
return (
<>
<Card>
<Header>last viewed: {null}</Header>
<Footer
onClick={open}
className={expanded ? "show" : ""}
setHeight={accodionHeight}
ref={ref}
>
<span>View Details</span>
<div className="accodion" ref={ref}>
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Eos,
facilis. Lorem, ipsum dolor sit amet consectetur adipisicing elit.
Eos, facilis. Lorem, ipsum dolor sit amet consectetur adipisicing
elit. Eos, facilis. Lorem, ipsum dolor sit amet consectetur
adipisicing elit. Eos, facilis.
</div>
</Footer>
</Card>
</>
);
}