Stacking Cards
fancy/stacking-cardsFreeComponent
A ui component.
Install it
npx shadcn@latest add https://www.fancycomponents.dev/r/stacking-cards.jsonSource
1// author: Khoa Phan <https://www.pldkhoa.dev>23"use client"45import {6 createContext,7 useContext,8 useRef,9 type HTMLAttributes,10 type PropsWithChildren,11} from "react"12import {13 motion,14 useScroll,15 useTransform,16 type MotionValue,17 type UseScrollOptions,18} from "motion/react"1920import { cn } from "@/lib/utils"2122interface StackingCardsProps23 extends PropsWithChildren,24 HTMLAttributes<HTMLDivElement> {25 scrollOptions?: UseScrollOptions26 scaleMultiplier?: number27 totalCards: number28}2930interface StackingCardItemProps31 extends HTMLAttributes<HTMLDivElement>,32 PropsWithChildren {33 index: number34 topPosition?: string35}3637export default function StackingCards({38 children,39 className,40 scrollOptions,41 scaleMultiplier,42 totalCards,43 ...props44}: StackingCardsProps) {45 const targetRef = useRef<HTMLDivElement>(null)46 const { scrollYProgress } = useScroll({47 offset: ["start start", "end end"],48 ...scrollOptions,49 target: targetRef,50 })5152 return (53 <StackingCardsContext.Provider54 value={{ progress: scrollYProgress, scaleMultiplier, totalCards }}55 >56 <div className={cn(className)} ref={targetRef} {...props}>57 {children}58 </div>59 </StackingCardsContext.Provider>60 )61}6263const StackingCardItem = ({64 index,65 topPosition,66 className,67 children,68 ...props69}: StackingCardItemProps) => {70 const {71 progress,72 scaleMultiplier,73 totalCards = 0,74 } = useStackingCardsContext() // Get from Context75 const scaleTo = 1 - (totalCards - index) * (scaleMultiplier ?? 0.03)76 const rangeScale = [index * (1 / totalCards), 1]77 const scale = useTransform(progress, rangeScale, [1, scaleTo])78 const top = topPosition ?? `${5 + index * 3}%`7980 return (81 <div className={cn("h-full sticky top-0", className)} {...props}>82 <motion.div83 className={"origin-top relative h-full"}84 style={{ top, scale }}85 >86 {children}87 </motion.div>88 </div>89 )90}9192const StackingCardsContext = createContext<{93 progress: MotionValue<number>94 scaleMultiplier?: number95 totalCards?: number96} | null>(null)9798export const useStackingCardsContext = () => {99 const context = useContext(StackingCardsContext)100 if (!context)101 throw new Error("StackingCardItem must be used within StackingCards")102 return context103}104105export { StackingCardItem }
What it pulls in
npm packages
Files it writes
More from fancy
All 158 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Animated Gradient With Svganimated-gradient-with-svg | fancy | Components | Free | no deps | |
| Basic Number Tickerbasic-number-ticker | fancy | Components | Free | 1 dep | |
| Box Carouselbox-carousel | fancy | Components | Free | 1 dep | |
| Breathing Textbreathing-text | fancy | Components | Free | 1 dep | |
| Circling Elementscircling-elements | fancy | Components | Free | 1 dep | |
| Css Boxcss-box | fancy | Components | Free | 1 dep | |
| Cursor Attractor And Gravitycursor-attractor-and-gravity | fancy | Components | Free | 5 deps | |
| Drag Elementsdrag-elements | fancy | Components | Free | 1 dep |
