DEV Community

Amaresh Adak
Amaresh Adak

Posted on

Creating a Dynamic Product Showcase Carousel with React and Tailwind CSS

Creating a Dynamic Product Showcase Carousel with React and Tailwind CSS

In this tutorial, we'll walk through the process of building a beautiful, responsive product showcase carousel using React and Tailwind CSS. This carousel will feature smooth transitions, automatic and manual navigation, and a sleek design that adapts to various screen sizes.

Step 1: Set Up the Project

First, ensure you have a React project set up with Tailwind CSS. If you're starting from scratch, you can use a tool like Vite to quickly bootstrap a new project.

Step 2: Create the Product Data

Create a file named products.ts in your src/data directory to store the product information:

export const products = [
  {
    id: 1,
    name: "Premium Wireless Headphones",
    description: "Immerse yourself in crystal-clear sound with our latest noise-cancelling technology.",
    image: "https://images.unsplash.com/photo-1505740420928-5e560c06d30e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80"
  },
  // Add more products...
]
Enter fullscreen mode Exit fullscreen mode

Step 3: Create the ProductCarousel Component

Create a new file ProductCarousel.tsx in your src/components directory:

import React from 'react'
import { ChevronLeft, ChevronRight } from 'lucide-react'

interface Product {
  id: number
  name: string
  description: string
  image: string
}

interface ProductCarouselProps {
  products: Product[]
}

const ProductCarousel: React.FC<ProductCarouselProps> = ({ products }) => {
  // Implement carousel logic here
  return (
    <div className="relative">
      {/* Carousel content */}
    </div>
  )
}

export default ProductCarousel
Enter fullscreen mode Exit fullscreen mode

Step 4: Implement Carousel Logic

Inside the ProductCarousel component, implement the carousel logic:

  1. Add state to track the current slide:
   const [currentSlide, setCurrentSlide] = React.useState(0)
Enter fullscreen mode Exit fullscreen mode
  1. Create functions for navigation:
   const nextSlide = () => setCurrentSlide((prev) => (prev + 1) % products.length)
   const prevSlide = () => setCurrentSlide((prev) => (prev - 1 + products.length) % products.length)
Enter fullscreen mode Exit fullscreen mode
  1. Set up automatic sliding:
   React.useEffect(() => {
     const timer = setInterval(nextSlide, 5000)
     return () => clearInterval(timer)
   }, [])
Enter fullscreen mode Exit fullscreen mode

Step 5: Create the Carousel UI

Update the return statement of the ProductCarousel component:

return (
  <div className="relative overflow-hidden">
    <div
      className="flex transition-transform duration-500 ease-out"
      style={{ transform: `translateX(-${currentSlide * 100}%)` }}
    >
      {products.map((product) => (
        <div key={product.id} className="w-full flex-shrink-0">
          <div className="relative h-[60vh] md:h-[70vh] lg:h-[80vh]">
            <img
              src={product.image}
              alt={product.name}
              className="w-full h-full object-cover"
            />
            <div className="absolute inset-0 bg-black bg-opacity-40 flex items-center justify-center">
              <div className="text-center text-white p-4 md:p-8 max-w-2xl">
                <h2 className="text-3xl md:text-4xl font-bold mb-4">{product.name}</h2>
                <p className="text-lg md:text-xl mb-6">{product.description}</p>
                <button className="bg-white text-black font-bold py-2 px-6 rounded-full hover:bg-gray-200 transition duration-300">
                  Shop Now
                </button>
              </div>
            </div>
          </div>
        </div>
      ))}
    </div>
    {/* Navigation arrows */}
    <button
      onClick={prevSlide}
      className="absolute left-4 top-1/2 transform -translate-y-1/2 bg-white bg-opacity-50 rounded-full p-2 hover:bg-opacity-75 transition duration-300"
    >
      <ChevronLeft className="w-6 h-6 text-black" />
    </button>
    <button
      onClick={nextSlide}
      className="absolute right-4 top-1/2 transform -translate-y-1/2 bg-white bg-opacity-50 rounded-full p-2 hover:bg-opacity-75 transition duration-300"
    >
      <ChevronRight className="w-6 h-6 text-black" />
    </button>
    {/* Dots navigation */}
    <div className="absolute bottom-4 left-0 right-0">
      <div className="flex items-center justify-center gap-2">
        {products.map((_, i) => (
          <button
            key={i}
            className={`
              w-3 h-3 rounded-full transition-all duration-300
              ${currentSlide === i ? 'bg-white scale-110' : 'bg-white bg-opacity-50'}
            `}
            onClick={() => setCurrentSlide(i)}
          />
        ))}
      </div>
    </div>
  </div>
)
Enter fullscreen mode Exit fullscreen mode

Step 6: Use the ProductCarousel in Your App

Update your App.tsx to use the ProductCarousel component:

import React from 'react'
import ProductCarousel from './components/ProductCarousel'
import { products } from './data/products'

function App() {
  return (
    <div className="min-h-screen bg-gray-100">
      <header className="bg-white shadow-md py-4">
        <div className="container mx-auto px-4">
          <h1 className="text-3xl font-bold text-gray-800">Product Showcase</h1>
        </div>
      </header>
      <main className="container mx-auto px-4 py-8">
        <ProductCarousel products={products} />
      </main>
    </div>
  )
}

export default App
Enter fullscreen mode Exit fullscreen mode

Conclusion

You now have a beautiful, responsive product showcase carousel built with React and Tailwind CSS. This carousel features smooth transitions, automatic and manual navigation, and adapts well to different screen sizes.

You can further customize the design and add more interactive features to enhance the user experience.

Remember to optimize your images and test the carousel on various devices to ensure the best performance and user experience across all platforms.

Top comments (0)