Nuka Carousel
Installation
npm i nuka-carousel@7.0.0
Basic usage
import { Carousel } from "nuka-carousel";
const App = () => {
return (
<Carousel autoplay showDots>
<div>Slide 1</div>
<div>Slide 2</div>
<div>Slide 3</div>
</Carousel>
);
};
Configure Nuka Component
"use client";
import { ChevronLeft, ChevronRight } from "lucide-react";
import Image from "next/image";
import Link from "next/link";
import Carousel from "nuka-carousel";
export default function HeroCarousel({ banners }) {
const config = {
nextButtonClassName: "rounded-full",
nextButtonText: <ChevronRight />,
pagingDotsClassName: "me-2 w-4 h-4",
prevButtonClassName: "rounded-full",
prevButtonText: <ChevronLeft />,
};
return (
<Carousel
defaultControlsConfig={config}
autoplay
className="rounded-md overflow-hidden"
wrapAround
>
{banners.map((banner, i) => {
return (
<Link key={i} href={banner.link} className="">
<Image
width={712}
height={384}
src={banner.imageUrl}
className="w-full"
alt={banner.title}
/>
</Link>
);
})}
</Carousel>
);
}
React Multi Carousel
Installation
npm i react-multi-carousel
The Ovaerall Component
import Link from "next/link";
import React from "react";
import CategoryCarousel from "./CategoryCarousel";
export default function CategoryList({ category, isMarketPage }) {
return (
<div className="bg-white border border-gray-300 rounded-lg dark:bg-gray-700 dark:border-gray-700 text-slate-800 overflow-hidden">
<div className="bg-slate-100 dark:bg-gray-800 py-3 px-6 font-semibold border-b border-gray-300 dark:border-gray-600 text-slate-800 dark:text-slate-100 flex justify-between items-center">
<h2>{category.title}</h2>
<Link
className="bg-lime-600 hover:bg-lime-800 duration-300 transition-all text-slate-50 rounded-md px-4 py-2"
href={`/category/${category.slug}`}
>
See All
</Link>
</div>
<div className="bg-white dark:bg-slate-700 p-4">
<CategoryCarousel
isMarketPage={isMarketPage}
products={category.products}
/>
</div>
</div>
);
}
The Carouse Component
"use client";
import { BaggageClaim } from "lucide-react";
import Image from "next/image";
import Link from "next/link";
import React from "react";
import Carousel from "react-multi-carousel";
import "react-multi-carousel/lib/styles.css";
import Product from "./Product";
export default function CategoryCarousel({ products, isMarketPage = false }) {
const responsive = {
desktop: {
breakpoint: { max: 3000, min: 1024 },
items: isMarketPage ? 3 : 4,
slidesToSlide: 3, // optional, default to 1.
},
tablet: {
breakpoint: { max: 1024, min: 464 },
items: isMarketPage ? 2 : 3,
slidesToSlide: 2, // optional, default to 1.
},
mobile: {
breakpoint: { max: 464, min: 0 },
items: 2,
slidesToSlide: 1, // optional, default to 1.
},
};
return (
<Carousel
swipeable={false}
draggable={false}
showDots={true}
responsive={responsive}
ssr={true} // means to render carousel on server-side.
infinite={true}
autoPlay={true}
autoPlaySpeed={5000}
keyBoardControl={true}
customTransition="all .5"
transitionDuration={1000}
containerClass="carousel-container"
removeArrowOnDeviceType={["tablet", "mobile"]}
// deviceType={}
dotListClass="custom-dot-list-style"
itemClass="px-4"
>
{products.map((product, i) => {
return <Product product={product} key={i} />;
})}
</Carousel>
);
}
The Product Component
"use client";
import { addToCart } from "@/redux/slices/cartSlice";
import { BaggageClaim } from "lucide-react";
import Image from "next/image";
import Link from "next/link";
import React from "react";
import toast from "react-hot-toast";
import { useDispatch } from "react-redux";
export default function Product({ product }) {
const dispatch = useDispatch();
function handleAddToCart() {
// Dispatch the reducer
dispatch(addToCart(product));
toast.success("Item added Successfully");
}
return (
<div className="rounded-lg mr-3 bg-white dark:bg-slate-900 overflow-hidden border shadow">
<Link href={`/products/${product.slug}`}>
<Image
src={product.imageUrl}
alt={product.title}
width={556}
height={556}
className="w-full h-48 object-cover"
/>
</Link>
<div className="px-4">
<Link href={`/products/${product.slug}`}>
<h2 className="text-center dark:text-slate-200 text-slate-800 my-2 font-semibold">
{product.title}
</h2>
</Link>
<div className="flex items-center justify-between gap-2 pb-3 dark:text-slate-200 text-slate-800">
<p>UGX {product.salePrice}</p>
<button
onClick={() => handleAddToCart()}
className="flex items-center space-x-2 bg-lime-600 px-4 py-2 rounded-md text-white"
>
<BaggageClaim />
<span>Add</span>
</button>
</div>
</div>
</div>
);
}