Components
Loading preview...
Animated Image Showcase This component displays a title, subtitle, and a fanned-out stack of images. On hover, the images gracefully spread out and scale up, creating an engaging user experience. It's fully responsive and theme-adaptive.
@ravikatiyar
npx shadcn@latest add https://21st.dev/r/ravikatiyar162/image-showcase// demo.tsx
import * as React from "react";
import { PhotoStackCard } from "@/components/ui/image-showcase";
// --- DEMO DATA ---
const memoriesData = [
{
images: [
"https://images.unsplash.com/photo-1644264249078-f15241a75fc7?w=900&auto=format&fit=crop&q=60&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MjB8fDgwfGVufDB8fDB8fHww?q=80&w=1964&auto=format&fit=crop",
"https://plus.unsplash.com/premium_photo-1672116453000-c31b150f48ef?w=900&auto=format&fit=crop&q=60&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MXx8ODB8ZW58MHx8MHx8fDA%3D?q=80&w=1887&auto=format&fit=crop",
"https://images.unsplash.com/photo-1501785888041-af3ef285b470?q=80&w=2070&auto=format&fit=crop",
],
category: "TRAVEL",
title: "Black Sea",
subtitle: "June 2023",
},
{
images: [
"https://images.unsplash.com/photo-1519681393784-d120267933ba?q=80&w=2070&auto=format&fit=crop",
"https://images.unsplash.com/photo-1485160497022-3e09382fb310?q=80&w=2070&auto=format&fit=crop",
"https://images.unsplash.com/photo-1476820865390-c52aeebb9891?q=80&w=2070&auto=format&fit=crop",
],
category: "ADVENTURE",
title: "Alps",
subtitle: "January 2024",
},
{
images: [
"https://images.unsplash.com/photo-1473448912268-2022ce9509d8?q=80&w=1925&auto=format&fit=crop",
"https://images.unsplash.com/photo-1643506454451-8924ad6722f5?w=900&auto=format&fit=crop&q=60&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxzZWFyY2h8Mjh8fDgwfGVufDB8fDB8fHww?q=80&w=2070&auto=format&fit=crop",
"https://images.unsplash.com/photo-1519046904884-53103b34b206?q=80&w=2070&auto=format&fit=crop",
],
category: "RELAXATION",
title: "Maldives",
subtitle: "August 2022",
},
];
// --- DEMO COMPONENT ---
export default function PhotoStackCardDemo() {
const [activeIndex, setActiveIndex] = React.useState<number | null>(1); // Default to the middle card
return (
<div className="flex h-screen w-full items-center justify-center bg-background p-4">
<div className="relative flex h-72 w-full max-w-3xl items-center justify-center">
{memoriesData.map((mem, index) => (
<div
key={mem.title}
className="absolute"
style={{
// Position cards to overlap for a better visual effect
transform: `translateX(${(index - 1) * 200}px)`,
}}
>
<PhotoStackCard
{...mem}
isActive={index === activeIndex}
onClick={() => setActiveIndex(index)}
/>
</div>
))}
</div>
</div>
);
}