PhotoAlbum
Render responsive photo rows, columns, or masonry with an included lightbox.
PhotoAlbum lays out one photo collection. Selecting a thumbnail opens the
included lightbox unless the lightbox is disabled or owned by a parent group.
Minimal usage
<script setup lang="ts">
import type { PhotoItem } from '@lupinum/nuxt-photo/app'
const photos: PhotoItem[] = [
{ id: 'one', src: '/photos/one.jpg', width: 1200, height: 800, alt: 'Mountain valley' },
{ id: 'two', src: '/photos/two.jpg', width: 800, height: 1200, alt: 'Forest path' },
]
</script>
<template>
<PhotoAlbum :photos="photos" layout="rows" />
</template>Props
| Prop | Type | Default | Description |
|---|---|---|---|
photos | readonly PhotoItem[] | - | Required. Ordered photos to render. |
validation | 'throw' | 'drop' | 'throw' | Invalid collection policy. |
layout | 'rows' | 'columns' | 'masonry' | AlbumLayout | 'rows' | Layout type and its options. |
spacing | ResponsiveParameter<number> | 8 | Gap between items in pixels. |
padding | ResponsiveParameter<number> | 0 | Padding around each item in pixels. |
defaultContainerWidth | number | - | Assumed server-side container width. |
breakpoints | readonly number[] | derived | Width snap points; derived from responsive() when omitted. |
sizes | string | ResponsivePhotoSizes | - | Native or rows-layout-aware image sizes hint. |
imageAdapter | ImageAdapter | provided/module default | Override image delivery for this album. |
lightbox | boolean | Component | true | Enable, disable, or replace the lightbox. |
transition | LightboxTransitionOption | 'auto' | Lightbox transition configuration. |
itemClass | string | - | Classes for each item wrapper. |
imgClass | string | - | Classes for each image. |
Rows layout accepts targetRowHeight and defaults it to 300. Columns and
masonry accept columns and default it to 3. These values may use
ResponsiveParameter<number>.
Events
| Event | Payload | When it fires |
|---|---|---|
invalidPhotos | InvalidPhotosEvent | Invalid entries are found while validation="drop" is set. |
<script setup lang="ts">
import type { InvalidPhotosEvent, PhotoItem } from '@lupinum/nuxt-photo/app'
defineProps<{ photos: readonly PhotoItem[] }>()
function reportInvalidPhotos(event: InvalidPhotosEvent) {
console.warn('Invalid photos:', event.issues)
}
</script>
<template>
<PhotoAlbum :photos="photos" validation="drop" @invalid-photos="reportInvalidPhotos" />
</template>Slots
| Slot | Props | Purpose |
|---|---|---|
thumbnail | { photo, index, width, height, hidden } | Replace each thumbnail content. |
hidden becomes true while the selected thumbnail is represented by the
opening or closing animation. Use PhotoImage inside a custom thumbnail to keep
the configured image adapter.
Exposed template-ref API
The component exposes LightboxHandle:
interface LightboxHandle {
open(index?: number): Promise<void>
openById(id: string): Promise<void>
close(): Promise<void>
readonly isOpen: boolean
}Inside PhotoGroup, an album-local index is translated to stable photo ID before
the request is delegated to the group.
Important behavior
- Rows produce justified photo rows. Columns keep a fixed column count. Masonry places each next photo in the shortest column.
- Layout options, photos, transition configuration, and responsive values are reactive.
lightboxis setup-time. Remount with a newkeyto add, remove, or replace it.- A parent
PhotoGroupowns the lightbox and navigation collection. - Incorrect dimensions can produce incorrect layout and transition geometry.
Responsive columns
<PhotoAlbum
:photos="photos"
:layout="{
type: 'columns',
columns: responsive({ 0: 2, 640: 3, 1024: 4 }),
}"
:spacing="responsive({ 0: 4, 640: 8, 1024: 12 })"
/>Nuxt auto-imports responsive(). Plain Vue applications import it from
@lupinum/vue-photo.
Use Tune responsive layouts for layout
decisions and SSR and layout stability
for defaultContainerWidth and hydration behavior.