Getting Started
IntroductionLayout Components
Expandable PanelSwipeable Cards
An interactive swipeable card stack component using Swiper.js with cards effect. Features smooth touch gestures, loop functionality, and customizable navigation controls.
React
Swiper
Cards
Touch
Animation
Using CLI
npx dimaac add SwipeableCards
Manual Installation
npm install react swiper lucide-react
lib/utils.ts
import { type ClassValue, clsx } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
components/ui/SwipeableCards.tsx
"use client";
import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react";
import React from "react";
import { Autoplay, EffectCards, Navigation, Pagination } from "swiper/modules";
import { Swiper, SwiperSlide } from "swiper/react";
import "swiper/css/effect-cards";
import "swiper/css/pagination";
import "swiper/css/navigation";
import "swiper/css";
import { cn } from "@/lib/utils";
const SwipeableCards = ({
images,
className,
showPagination = false,
showNavigation = false,
loop = true,
autoplay = false,
spaceBetween = 40,
}: {
images: { src: string; alt: string }[];
className?: string;
showPagination?: boolean;
showNavigation?: boolean;
loop?: boolean;
autoplay?: boolean;
spaceBetween?: number;
}) => {
return (
<div
className={cn("relative w-full max-w-3xl", className)}
>
<Swiper
spaceBetween={spaceBetween}
autoplay={
autoplay
? {
delay: 1000,
disableOnInteraction: false,
}
: false
}
effect="cards"
grabCursor={true}
loop={loop}
pagination={
showPagination
? {
clickable: true,
}
: false
}
navigation={
showNavigation
? {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev",
}
: false
}
className="h-[380px] w-[260px]"
modules={[EffectCards, Autoplay, Pagination, Navigation]}
>
{images.map((image, index) => (
<SwiperSlide key={index} className="rounded-3xl">
<img
className="h-full w-full object-cover"
src={image.src}
alt={image.alt}
/>
</SwiperSlide>
))}
{showNavigation && (
<div>
<div className="swiper-button-next after:hidden">
<ChevronRightIcon className="h-6 w-6 text-white" />
</div>
<div className="swiper-button-prev after:hidden">
<ChevronLeftIcon className="h-6 w-6 text-white" />
</div>
</div>
)}
</Swiper>
</div>
);
};
export default SwipeableCards;