Getting Started
image-gallery-kit is built for Vue 3.5+ and ships as a focused package: sixteen components, one plugin install path, one stylesheet, and no layout or styling props — the arrangement and the appearance are markup and classes you write.
npm install image-gallery-kitimport 'image-gallery-kit/style.css'Use It In A Component
Import the component directly when you only need it in one place.
<script setup lang="ts">
import { ImageGallery, ImageGalleryImage, ImageGalleryOverflowTrigger } from 'image-gallery-kit'
import 'image-gallery-kit/style.css'
const images = [
{
id: 'tasting-table',
src: 'https://images.unsplash.com/photo-1511300636408-a63a89df3482?auto=format&fit=crop&w=1400&q=80',
alt: 'Guests trading baked treats at a tasting table',
width: 1400,
height: 1800
},
{
id: 'plating',
src: 'https://images.unsplash.com/photo-1482049016688-2d3e1b311543?auto=format&fit=crop&w=1800&q=80',
alt: 'Baker plating pastries in a warm kitchen',
width: 1800,
height: 1200
}
]
</script>
<template>
<ImageGallery :images="images">
<div class="grid grid-cols-2 gap-4">
<ImageGalleryImage
v-for="image in images"
:key="image.id"
:image="image"
class="aspect-[4/5] rounded-xl"
/>
</div>
</ImageGallery>
</template>Register It As A Plugin
If you want <ImageGallery /> globally available, use the default export as a Vue plugin.
import { createApp } from 'vue'
import App from './App.vue'
import ImageGalleryPlugin from 'image-gallery-kit'
import 'image-gallery-kit/style.css'
// Registers all sixteen components under the names they are exported by.
createApp(App).use(ImageGalleryPlugin).mount('#app')What To Configure First
images: array of{ src, alt, id?, thumbnailSrc?, srcset?, sizes?, caption?, width?, height?, loading?, decoding? }. Give each a stableid— it is how a tile finds its place in the collection- the default slot: your preview markup. There are no layout props; arrangement and size are classes on your own elements
openandindex: optional controlled props forv-model:openandv-model:indexallowGridView: enable or disable every route into the all-images gridlabels: overrides for the built-in English strings andaria-labelsdialog-toolbaranddialog-caption: slots for custom dialog controls and captionsdialog: the whole dialog, if you want to recompose it. It defaults to the standard composition, so leaving it alone changes nothing — see Anatomy for the parts and Examples for worked compositions
Building The Preview
ImageGallery renders no preview of its own — you put the tiles in its default slot, and CSS decides the arrangement. A different layout per breakpoint is a class, not a prop:
<ImageGallery :images="images">
<div class="flex flex-col gap-3 md:flex-row">
<ImageGalleryImage :image="images[0]" class="h-56 shrink-0 rounded-2xl md:h-auto md:w-2/5" />
<div class="grid min-w-0 flex-1 grid-cols-2 gap-3 md:grid-cols-3">
<ImageGalleryImage
v-for="image in images.slice(1, 5)"
:key="image.id"
:image="image"
class="h-24 rounded-xl md:h-40"
/>
</div>
</div>
</ImageGallery>The dialog, carousel, all-images grid and transitions all render from images, so they work the same whatever your preview looks like. See Layout for sizing rules and the overflow trigger, and Examples for ready-made arrangements.
Styling
There are no design tokens. Every part is a component, every default is a class in @layer components, and no part leaves a utility of its own on the element -- so a class of yours wins, with or without Tailwind:
<ImageGalleryCloseButton class="rounded-lg bg-black text-white" />
<ImageGalleryGrid class="grid-cols-3 gap-6 lg:grid-cols-6" />Colour comes from CSS system colours (Canvas, CanvasText, ButtonFace, AccentColor), which follow the reader's platform light/dark setting on their own and collapse correctly under forced-colors. Your own dark mode is whatever your project already does -- class="bg-white dark:bg-zinc-900" on the parts.
See Styling for the whole surface, and Anatomy for the parts.
Animation
Opening a tile plays a shared-element flight: the tile's frame and corner radius tween onto the dialog image, and the all-images grid animates its tiles in and out the same way.
Those animations are driven by gsap, which is an optional peer dependency — install it to switch them on:
npm install gsapWithout it the gallery still works exactly as it does with it: the dialog opens, the index changes and the grid toggles, just without the tweens. The same is true under prefers-reduced-motion: reduce, which skips the animations even when gsap is installed.
Notes
- Import
image-gallery-kit/style.cssonce in your app. vueis a required peer dependency;gsapis an optional one that enables the animations.- The component is safe to render on the server; dialog and transition behavior activate on the client.
- The dialog traps focus, restores focus to the trigger, and locks body scroll while open.