Skip to main content

Create a custom thumbnail layout

Compose explicit primitives for any thumbnail layout.

<PhotoAlbum> owns rows, columns, and masonry. A bespoke layout owns its explicit photo collection and composes three primitives:

  • <LightboxProvider> owns state;
  • <PhotoTrigger> owns accessible activation and the FLIP source ref;
  • <Lightbox> renders the included viewer.
vue
<script setup lang="ts">
import { Lightbox, LightboxProvider, PhotoImage, PhotoTrigger } from '@lupinum/nuxt-photo/app'
import type { PhotoItem } from '@lupinum/nuxt-photo/app'

const photos: PhotoItem[] = [
  /* … */
]
</script>

<template>
  <LightboxProvider :photos="photos">
    <div class="hex-grid">
      <PhotoTrigger
        v-for="(photo, index) in photos"
        :key="photo.id"
        :photo="photo"
        :index="index"
        v-slot="{ hidden }"
      >
        <PhotoImage :photo="photo" context="thumb" :style="{ opacity: hidden ? 0 : 1 }" />
      </PhotoTrigger>
    </div>
    <Lightbox />
  </LightboxProvider>
</template>

PhotoTrigger supplies keyboard handling, ARIA labeling, activation, and the transition ref. Its hidden slot prop prevents the source thumbnail and ghost image from appearing at the same time.

Programmatic buttons inside the provider

Call useLightbox() from a descendant component:

vue
<script setup lang="ts">
import { useLightbox } from '@lupinum/nuxt-photo/app'

const lightbox = useLightbox()
</script>

<template>
  <button @click="lightbox.openById('desert-01')">Open desert</button>
</template>

Why PhotoGroup is not used here

PhotoGroup gives descendant <Photo> and <PhotoAlbum> components one explicit canonical collection, but it does not return generic trigger attribute bags. Use LightboxProvider when a bespoke layout needs direct control over every trigger and lower-level component rather than ready-made components.

Use the PhotoGroup reference when ready-made descendants should share one collection. Continue with Build a lightbox from primitives when the viewer structure also needs to change.