({
items,
offset,
scaleFactor,
}: {
items: Card[]
offset?: number
scaleFactor?: number
})
| 7 | let interval: any |
| 8 | |
| 9 | export const CardStack = ({ |
| 10 | items, |
| 11 | offset, |
| 12 | scaleFactor, |
| 13 | }: { |
| 14 | items: Card[] |
| 15 | offset?: number |
| 16 | scaleFactor?: number |
| 17 | }) => { |
| 18 | const CARD_OFFSET = offset || 10 |
| 19 | const SCALE_FACTOR = scaleFactor || 0.06 |
| 20 | const [cards, setCards] = useState<Card[]>(items) |
| 21 | |
| 22 | useEffect(() => { |
| 23 | startFlipping() |
| 24 | |
| 25 | return () => clearInterval(interval) |
| 26 | }, []) |
| 27 | const startFlipping = () => { |
| 28 | interval = setInterval(() => { |
| 29 | setCards((prevCards: Card[]) => { |
| 30 | const newArray = [...prevCards] // create a copy of the array |
| 31 | newArray.unshift(newArray.pop()!) // move the last element to the front |
| 32 | return newArray |
| 33 | }) |
| 34 | }, 5000) |
| 35 | } |
| 36 | |
| 37 | return ( |
| 38 | <div className="relative flex justify-center h-60 w-full m-5 md:m-0 md:h-96 md:w-full"> |
| 39 | {cards.map((card, index) => { |
| 40 | return ( |
| 41 | <motion.div |
| 42 | key={card.id} |
| 43 | className="absolute bg-white h-60 w-full md:h-[30rem] md:w-1/2 rounded-3xl p-4 shadow-xl border shadow-black/[0.1] dark:shadow-white/[0.05] flex flex-col justify-between" |
| 44 | style={{ |
| 45 | transformOrigin: 'top center', |
| 46 | }} |
| 47 | animate={{ |
| 48 | top: index * -CARD_OFFSET, |
| 49 | scale: 1 - index * SCALE_FACTOR, // decrease scale for cards that are behind |
| 50 | zIndex: cards.length - index, // decrease z-index for the cards that are behind |
| 51 | }} |
| 52 | > |
| 53 | <div className="flex items-center gap-2"> |
| 54 | <p className="bg-[#006399] p-2 text-white rounded-xl"> |
| 55 | {card.iconImag} |
| 56 | </p> |
| 57 | <p className="text-neutral-500 font-bold text-xl">{card.title}</p> |
| 58 | </div> |
| 59 | <div className="relative flex justify-center items-center h-40 md:h-96"> |
| 60 | <Image |
| 61 | src={card.img} |
| 62 | alt="/" |
| 63 | className="h-full w-auto max-w-full object-cover" |
| 64 | /> |
| 65 | </div> |
| 66 | </motion.div> |
nothing calls this directly
no test coverage detected