cards-slider
pixel-perfect/cards-sliderFreeBlock
Cards Slider — an infinite deck of product cards. The active card sits
Install it
npx shadcn@latest add https://www.pixel-perfect.space/r/cards-slider.jsonSource
1"use client";23/**4 * Cards Slider — an infinite deck of product cards. The active card sits5 * front-and-centre while the rest fan out behind it, each one stepped back6 * with less scale, a touch of rotation and a soft blur. Drag, click a peeking7 * card, or let it auto-advance; the index wraps forever so the deck never ends.8 */910import { motion } from "framer-motion";11import { useEffect, useState } from "react";1213type Card = { title: string; image: string };1415const CARDS: Card[] = [16 {17 title: "ZV210",18 image:19 "https://images.unsplash.com/photo-1541701494587-cb58502866ab?q=80&w=800&auto=format&fit=crop",20 },21 {22 title: "AX90",23 image:24 "https://images.unsplash.com/photo-1604871000636-074fa5117945?q=80&w=800&auto=format&fit=crop",25 },26 {27 title: "NOVA",28 image:29 "https://images.unsplash.com/photo-1620421680010-0766ff230392?q=80&w=800&auto=format&fit=crop",30 },31 {32 title: "DRIFT",33 image:34 "https://images.unsplash.com/photo-1579546929518-9e396f3cc809?q=80&w=800&auto=format&fit=crop",35 },36 {37 title: "PULSE",38 image:39 "https://images.unsplash.com/photo-1557672172-298e090bd0f1?q=80&w=800&auto=format&fit=crop",40 },41];4243const VISIBLE = 2; // cards shown on each side of the active one44const SPACING = 56; // px each step fans sideways45const DRAG_THRESHOLD = 70; // px before a drag commits to a step4647const offsetFrom = (i: number, active: number, len: number) => {48 let d = (((i - active) % len) + len) % len;49 if (d > len / 2) d -= len;50 return d;51};5253const CardsSlider = () => {54 const [active, setActive] = useState(0);55 const [paused, setPaused] = useState(false);56 const len = CARDS.length;5758 useEffect(() => {59 if (paused) return;60 const id = setInterval(() => setActive((a) => a + 1), 2600);61 return () => clearInterval(id);62 }, [paused]);6364 return (65 <div66 className="relative flex h-[80vh] w-full select-none items-center justify-center overflow-hidden"67 onPointerEnter={() => setPaused(true)}68 onPointerLeave={() => setPaused(false)}69 >70 <div className="relative h-96 w-72">71 {CARDS.map((card, i) => {72 const offset = offsetFrom(i, active, len);73 const abs = Math.abs(offset);74 const hidden = abs > VISIBLE;75 const isActive = offset === 0;7677 return (78 <motion.div79 key={card.title}80 className={`absolute inset-0 overflow-hidden rounded-3xl shadow-2xl ${81// … truncated
What it pulls in
npm packages
Files it writes
More from pixel-perfect
All 60 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| 3d-button3d-button | pixel-perfect | Blocks | Unverified | 2 deps | |
| abhinav-bento-buttonabhinav-bento-button | pixel-perfect | Blocks | Unverified | no deps | |
| accordion-carouselaccordion-carousel | pixel-perfect | Blocks | Free | 1 dep | |
| accordion-foldaccordion-fold | pixel-perfect | Blocks | Free | 1 dep | |
| activity-wheel-motionactivity-wheel-motion | pixel-perfect | Blocks | Free | 2 deps | |
| animated-textureanimated-texture | pixel-perfect | Blocks | Free | 1 dep | |
| aperture-mask-revealaperture-mask-reveal | pixel-perfect | Blocks | Free | 1 dep | |
| aurora-curtainaurora-curtain | pixel-perfect | Blocks | Free | no deps |
