0.17.0

ImageGallery

Source code

A reusable image gallery component with hover-based image switching. When multiple images are provided, the component divides the image area into invisible vertical zones - hovering over each zone displays the corresponding image, similar to Instagram or Tinder photo galleries.

Basic Usage

Single Image

When a single image is provided, the component renders it without gallery functionality.

Single image
---
import { ImageGallery } from '@yatoday/astro-ui/astro';
---

<div class="w-64 h-48 overflow-hidden">
  <ImageGallery
    image={{src: '/images/photo.jpg', alt: 'Single image'}}
  />
</div>

When an array of images is provided, the component enables gallery mode with hover zones and indicator dots.

Multi-image gallery (hover to switch)
---
import { ImageGallery } from '@yatoday/astro-ui/astro';
---

<div class="w-64 h-48 overflow-hidden">
  <ImageGallery
    image={[
      {src: '/images/photo-1.jpg', alt: 'View 1'},
      {src: '/images/photo-2.jpg', alt: 'View 2'},
      {src: '/images/photo-3.jpg', alt: 'View 3'},
    ]}
  />
</div>

With Hover Effect

Enable the hoverEffect prop to add a scale animation on hover (useful when wrapped in a link).

With hover scale effect
<a href="/product" class="block w-64 h-48 overflow-hidden group">
  <ImageGallery
    image={[
      {src: '/images/photo-1.jpg', alt: 'View 1'},
      {src: '/images/photo-2.jpg', alt: 'View 2'},
    ]}
    hoverEffect={true}
  />
</a>

With Badge Slots

The component supports badge slots for overlaying content on the image.

With badges
<ImageGallery
  image={[
    {src: '/images/photo-1.jpg', alt: 'View 1'},
    {src: '/images/photo-2.jpg', alt: 'View 2'},
  ]}
>
  <Fragment slot="badgeBottomRight">
    <span class="bg-red-500 text-white text-xs px-2 py-1 rounded">Sale</span>
  </Fragment>
  <Fragment slot="badgeBottomLeft">
    <span class="bg-black/50 text-white text-xs px-2 py-1 rounded">New</span>
  </Fragment>
</ImageGallery>

Svelte Usage

<script>
  import { ImageGallery } from '@yatoday/astro-ui/svelte';
</script>

<div class="w-64 h-48 overflow-hidden">
  <ImageGallery
    image={[
      {src: '/images/photo-1.jpg', alt: 'View 1'},
      {src: '/images/photo-2.jpg', alt: 'View 2'},
      {src: '/images/photo-3.jpg', alt: 'View 3'},
    ]}
    hoverEffect={true}
  >
    {#snippet badgeBottomRight()}
      <span class="bg-red-500 text-white text-xs px-2 py-1 rounded">Sale</span>
    {/snippet}
  </ImageGallery>
</div>

Props

PropTypeDefaultDescription
imageImage | Image[] | string-Single image, array of images for gallery, or HTML string
imageClassstring''CSS classes for the image element
imageLayoutstring'cover'Image layout mode: fixed, constrained, fullWidth, cover, responsive, contained
widthsnumber[][400, 900]Image widths for srcset
widthnumber400Image width
heightnumber400Image height
sizesstring'(max-width: 900px) 400px, 900px'Image sizes attribute
hoverEffectbooleanfalseWhether to add hover scale effect (requires parent with group class)
classstring''Additional class for the container

Slots

SlotDescription
badgeBottomRightContent to display at the bottom right of the image
badgeBottomLeftContent to display at the bottom left of the image

How It Works

  1. Single Image: Renders a standard image without any gallery functionality
  2. Multiple Images:
    • All images are stacked absolutely positioned, with opacity controlling visibility
    • The image area is divided into equal vertical zones (one per image)
    • Hovering over a zone shows the corresponding image with a 200ms opacity transition
    • Indicator dots at the bottom show the active image
    • When the mouse leaves, it resets to the first image
  3. Performance: First image loads eagerly, subsequent images lazy-load

Integration with Card Components

This component is used internally by Card1, Card2, Card3, and Card6 components. You can use it directly for custom layouts or when you need more control over the image gallery behavior.

---
import { Card2 } from '@yatoday/astro-ui/astro';
---

<!-- Card2 uses ImageGallery internally -->
<Card2
  title="Product"
  image={[
    {src: '/images/front.jpg', alt: 'Front'},
    {src: '/images/back.jpg', alt: 'Back'},
  ]}
  url="/product"
/>