Feature-Rich Card Slider Component
import React, { useState, useEffect } from "react"; import { FaChevronLeft, FaChevronRight } from "react-icons/fa"; const cardData = [ { id: 1, image: "images.unsplash.com/photo-1506744038136-46273834b3fb", name: "Mountain Lake", description: "Serene mountain lake surrounded by lush forests" }, { id: 2, image: "images.unsplash.com/photo-1501785888041-af3ef285b470", name: "Autumn Forest", description: "Vibrant autumn colors in a dense forest" }, { id: 3, image: "images.unsplash.com/photo-1470071459604-3b5ec3a7fe05", name: "Misty Valley", description: "A foggy morning in a picturesque valley" }, { id: 4, image: "images.unsplash.com/photo-1447752875215-b2761acb3c5d", name: "Forest River", description: "A tranquil river flowing through a lush forest" }, { id: 5, image: "images.unsplash.com/photo-1472214103451-9374bd1c798e", name: "Mountain Peak", description: "Majestic mountain peak piercing through the clouds" }, { id: 6, image: "images.unsplash.com/photo-1470071459604-3b5ec3a7fe05", name: "Golden Sunset", description: "A breathtaking golden sunset over rolling hills" } ]; const Card = ({ image, name, description, size }) => { return ( <div className={`relative overflow-hidden rounded-lg shadow-lg transition-all duration-300 ease-in-out ${size} transform hover:scale-105`} style={{ aspectRatio: "3/4" }} > <img src={image} alt={name} className="w-full h-full object-cover" loading="lazy" /> <div className="absolute inset-0 bg-black bg-opacity-50 opacity-0 hover:opacity-100 transition-opacity duration-300 flex flex-col justify-end p-4"> <h3 className="text-white text-lg font-semibold mb-1">{name}</h3> <p className="text-white text-sm">{description}</p> </div> </div> ); }; const FeatureRichCardSlider = () => { const [currentIndex, setCurrentIndex] = useState(0); const [isSmallScreen, setIsSmallScreen] = useState(false); useEffect(() => { const handleResize = () => { setIsSmallScreen(window.innerWidth < 768); }; handleResize(); window.addEventListener("resize", handleResize); return () => window.removeEventListener("resize", handleResize); }, []); const handlePrev = () => { setCurrentIndex((prevIndex) => prevIndex === 0 ? cardData.length - 1 : prevIndex - 1 ); }; const handleNext = () => { setCurrentIndex((prevIndex) => prevIndex === cardData.length - 1 ? 0 : prevIndex + 1 ); }; const getVisibleCards = () => { if (isSmallScreen) { return [cardData[currentIndex]]; } const visibleCards = []; for (let i = -2; i <= 2; i++) { const index = (currentIndex + i + cardData.length) % cardData.length; visibleCards.push(cardData[index]); } return visibleCards; }; const getCardSize = (index) => { if (isSmallScreen) return "w-full h-96"; const sizes = ["w-32 h-48", "w-48 h-64", "w-64 h-80", "w-48 h-64", "w-32 h-48"]; return sizes[index]; }; return ( <div className="relative w-full max-w-6xl mx-auto px-4 py-8"> <div className="flex items-center justify-center space-x-4 overflow-hidden"> {getVisibleCards().map((card, index) => ( <Card key={card.id} {...card} size={getCardSize(index)} /> ))} </div> <button onClick={handlePrev} className="absolute left-0 top-1/2 transform -translate-y-1/2 bg-white bg-opacity-50 hover:bg-opacity-75 rounded-full p-2 focus:outline-none focus:ring-2 focus:ring-blue-500 transition-all duration-300" aria-label="Previous card" > <FaChevronLeft className="text-gray-800 text-2xl" /> </button> <button onClick={handleNext} className="absolute right-0 top-1/2 transform -translate-y-1/2 bg-white bg-opacity-50 hover:bg-opacity-75 rounded-full p-2 focus:outline-none focus:ring-2 focus:ring-blue-500 transition-all duration-300" aria-label="Next card" > <FaChevronRight className="text-gray-800 text-2xl" /> </button> </div> ); }; export default FeatureRichCardSlider;