I'm trying to replicate the following design in react:
Here's what I've currently got:
Here's the code for it:
import React, { useState } from "react";
import "./DisplayCards.css";
type DisplayCardsProps = {
images: string[];
group: number;
};
const DisplayCards: React.FC<DisplayCardsProps> = ({ images, group }) => {
const [currentGroup, setCurrentGroup] = useState(0);
const startIndex = currentGroup * group;
const firstGroup = images.slice(0, startIndex);
const secondGroup = images.slice(startIndex, startIndex + group);
const thirdGroup = images.slice(startIndex + group);
return (
<div>
<div className="main-cards">
{secondGroup.map((name, index) => {
return (
<img
key={index}
src={name}
style={{
position: "absolute",
}}
/>
);
})}
</div>
<div>
<button
onClick={() =>
setCurrentGroup((prevGroup) =>
thirdGroup.length !== 0 ? prevGroup + 1 : prevGroup
)
}
>
Shift Group Forward
</button>
<button
onClick={() =>
setCurrentGroup((prevGroup) =>
firstGroup.length !== 0 ? prevGroup - 1 : prevGroup
)
}
>
Shift Group Backward
</button>
</div>
<div style={{ padding: "200px" }}></div>
<div className="grid-container">
<div className="first-group">
{firstGroup.map((name, index) => {
return (
<img
key={index}
src={name}
width={157}
height={219}
style={{
position: "absolute",
left: `${10 * index}px`,
}}
/>
);
})}
</div>
<div className="third-group">
{thirdGroup.map((name, index) => {
return (
<img
key={index}
src={name}
width={157}
height={219}
style={{
position: "absolute",
left: `${10 * index}px`,
marginLeft: "500px",
}}
/>
);
})}
</div>
</div>
</div>
);
};
export default DisplayCards;
And the CSS:
.main-cards {
display: flex;
justify-content: center;
}
.grid-container {
display: flex;
justify-content: space;
}
I can't figure out how to center the cards on the bottom. Also, the cards on top are three images on top of each other. I tried spreading them out with:
{secondGroup.map((name, index) => {
return (
<img
key={index}
src={name}
width={157}
height={219}
style={{
position: "absolute",
left: `${30 * index}px`,
}}
/>
);
})}
Which kind of worked, but it wasn't centered perfectly. It was off by like 50px or something. How can I center all the cards and display them like shown in the design I'm trying to replicate?
Last question, when I'm moving the cards forward (i.e., clicking the Shift Group Forward
button), how can I make the left stack of cards grow backward like in this video?
I finally got everything working. I don't know what I really changed (mostly because I did a lot of changes), but here's the final code:
import React, { useState } from "react";
import { FaArrowLeft, FaArrowRight } from "react-icons/fa";
import { BiChevronsLeft, BiChevronsRight } from "react-icons/bi";
import Button from "../Button";
import "./DisplayCards.css";
type DisplayCardsProps = {
images: string[];
group: number;
data: any;
};
const DisplayCards: React.FC<DisplayCardsProps> = ({ images, group, data }) => {
const [currentGroup, setCurrentGroup] = useState(0);
const startIndex = currentGroup * group;
const firstGroup = images.slice(0, startIndex);
const secondGroup = images.slice(startIndex, startIndex + group);
const thirdGroup = images.slice(startIndex + group);
let margin: string;
if (data["cardSpacing"] == "regular") margin = "-125px";
else margin = "-175px";
return (
<div>
<div className="first-section">
<div className="button">
<Button
icon={<FaArrowLeft />}
className="arrow"
onClick={() =>
setCurrentGroup((prevGroup) =>
firstGroup.length !== 0 ? prevGroup - 1 : prevGroup
)
}
/>
</div>
<div className="main-cards">
{secondGroup.map((name, index) => {
return (
<img
key={index}
src={name}
style={{
marginLeft: index == 0 ? "0px" : margin,
}}
/>
);
})}
</div>
<div className="button">
<Button
icon={<FaArrowRight />}
className="arrow"
onClick={() =>
setCurrentGroup((prevGroup) =>
thirdGroup.length !== 0 ? prevGroup + 1 : prevGroup
)
}
/>
</div>
</div>
<div className="second-section">
<div className="first-cards" style={{
marginLeft: firstGroup.length !== 0 ? "0px" : "110px",
}}>
{firstGroup.map((name, index) => {
return (
<img
key={index}
src={name}
width={157}
height={219}
style={{
marginLeft: index == 0 ? "0px" : "-145px",
}}
/>
);
})}
</div>
{thirdGroup.length !== 0 && (
<div className="third-cards">
{thirdGroup.map((name, index) => {
return (
<img
key={index}
src={name}
width={157}
height={219}
style={{
marginLeft: index == 0 ? "0px" : "-145px",
}}
/>
);
})}
</div>
)}
</div>
<div className="third-section"></div>
</div>
);
};
export default DisplayCards;
And here's the CSS:
.first-section {
display: flex;
justify-content: space-around;
align-items: center;
margin-bottom: 20px;
}
.second-section {
display: flex;
justify-content: center;
}
.third-cards {
margin-left: -110px;
}
.arrow {
padding: 0.78571429em 1.5em 0.78571429em;
padding-right: 10px;
border-radius: 0.28571429rem;
background-color: var(--button-ok-background-color);
color: var(--button-ok-text-color);
}