Back to library

carousels

Card Swipe Carousel

A stacked card carousel built on Swiper's cards effect, with grab-to-drag gestures, looping, optional autoplay, pagination and navigation arrows.

Inspired by Skiper UI · View source

Preview

Nature photograph
Nature photograph
Nature photograph
Nature photograph
Nature photograph
Nature photograph

Copy for AI

Copy for Lovable is the fastest way to move this component into another Lovable project — it copies the full prompt with dependencies, files, and a usage example. Copy all files gives you the raw source if you want to paste it manually.

Installation

npx shadcn@latest add @skiper-ui/skiper48

Paste into a terminal — or paste into a Lovable chat and I'll run it for you.

Source files

components/ui/card-swipe.tsx
"use client";

import { motion } from "framer-motion";
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";

export const CardSwipe = ({
  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;
}) => {
  const css = `
  .CardSwipe {
    padding-bottom: 50px !important;
  }
  `;

  return (
    <motion.div
      initial={{ opacity: 0, translateY: 20 }}
      animate={{ opacity: 1, translateY: 0 }}
      transition={{ duration: 0.3, delay: 0.5 }}
      className={cn("relative w-full max-w-3xl", className)}
    >
      <style>{css}</style>

      <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="CardSwipe h-[380px] w-[260px]"
        modules={[EffectCards, Autoplay, Pagination, Navigation]}
      >
        {images.map((image, index) => (
          <SwiperSlide key={index} className="overflow-hidden rounded-3xl">
            <img
              className="h-full w-full object-cover"
              src={image.src}
              alt={image.alt}
              loading="lazy"
            />
          </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>
    </motion.div>
  );
};

export default CardSwipe;

/**
 * Skiper 48 Carousel_002 — React + Swiper
 * Built with Swiper.js — https://swiperjs.com/
 * Author: @gurvinder-singh02 — https://gxuri.me
 */

Dependencies

swiperframer-motionlucide-react