Image Gallery
A photo gallery carousel with thumbnail navigation.
Use Case
Image galleries are perfect for:
- Product photo galleries
- Portfolio showcases
- Property listings
- Event photography
Features
- Full-width images - Each slide displays a single image
- Thumbnail navigation - Custom thumbnails using
useCarouselhook - Aspect ratio container - Consistent 4:3 aspect ratio
- Hover states - Visual feedback on thumbnail interaction
Implementation
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNavigation,
useCarousel,
} from "@/components/ui/carousel";
const images = [
{ src: "/photos/image-1.jpg", alt: "Photo 1" },
{ src: "/photos/image-2.jpg", alt: "Photo 2" },
// ... more images
];
function ThumbnailIndicator() {
const { index, setIndex, itemsCount } = useCarousel();
return (
<div className="flex justify-center gap-2 pt-4">
{images.slice(0, itemsCount).map((image, i) => (
<button
key={i}
onClick={() => setIndex(i)}
className={`h-12 w-16 overflow-hidden rounded-md border-2 transition-all ${
index === i
? "border-zinc-900 dark:border-zinc-100"
: "border-transparent opacity-60 hover:opacity-100"
}`}
>
<img
src={image.src}
alt={image.alt}
className="h-full w-full object-cover"
/>
</button>
))}
</div>
);
}
export function ImageGallery() {
return (
<div className="relative w-full max-w-xl">
<Carousel>
<CarouselContent>
{images.map((image, index) => (
<CarouselItem key={index}>
<div className="aspect-[4/3] overflow-hidden rounded-xl">
<img
src={image.src}
alt={image.alt}
className="h-full w-full object-cover"
/>
</div>
</CarouselItem>
))}
</CarouselContent>
<CarouselNavigation alwaysShow />
<ThumbnailIndicator />
</Carousel>
</div>
);
}Tips
- Use
aspect-[4/3]oraspect-videofor consistent image dimensions - The
useCarouselhook allows building fully custom indicators - Consider lazy loading images for performance with large galleries