Skip to main content

PhotoCarousel

Render a horizontal photo carousel with controls, thumbnails, and optional autoplay or lightbox behavior.

PhotoCarousel provides one slide per snap. Its lightbox is off by default.

Minimal usage

app/pages/carousel.vue
<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: 'Rocky coast' },
  { id: 'two', src: '/photos/two.jpg', width: 1200, height: 800, alt: 'Calm sea' },
]
</script>

<template>
  <PhotoCarousel :photos="photos" />
</template>

Props

PropTypeDefaultDescription
photosreadonly PhotoItem[]-Required. Ordered slides.
validation'throw' | 'drop''throw'Invalid collection policy.
imageAdapterImageAdapterprovided/module defaultOverride image delivery for this carousel.
loopbooleanfalseContinue from the final slide to the first.
dragFreebooleanfalseAllow the track to stop between snap points.
direction'ltr' | 'rtl'inheritedSet carousel and thumbnail direction.
showArrowsbooleantrueRender previous and next buttons.
showThumbnailsbooleantrueRender the thumbnail rail.
showCounterbooleantrueRender the current slide counter.
showDotsbooleanfalseRender slide dots.
autoplayboolean | PhotoCarouselAutoplayOptionsfalseEnable autoplay.
slideSizestring-CSS flex-basis for each slide.
slideAspectstring-CSS aspect-ratio for each slide.
gapstring-CSS gap between slides.
thumbSizestring-Thumbnail width.
lightboxboolean | ComponentfalseEnable or replace the optional lightbox.
transitionLightboxTransitionOption'auto'Optional lightbox transition configuration.
slideClassstring-Classes for each slide.
imgClassstring-Classes for each main image.
thumbClassstring-Classes for each thumbnail.
captionClassstring-Classes for the caption.
controlsClassstring-Classes for the controls wrapper.

Events

EventPayloadWhen it fires
invalidPhotosInvalidPhotosEventInvalid entries are found while validation="drop" is set.
vue
<PhotoCarousel :photos="photos" validation="drop" @invalid-photos="reportInvalidPhotos" />

Slots

SlotPropsPurpose
slide{ photo, index, selected, open }Replace each main slide.
thumb{ photo, index, selected, goTo }Replace each thumbnail.
caption{ photo, index, count }Replace the caption.
controls{ goToPrev, goToNext, canGoToPrev, canGoToNext, selectedIndex, snapCount, goTo }Replace the complete control block.
prev-Replace the previous-button content.
next-Replace the next-button content.
dots{ snaps, selectedIndex, goTo }Replace the dot indicators.

Custom slide and thumb slots replace adapter-backed image content. Render PhotoImage inside the slot to keep the configured adapter.

Exposed template-ref API

PhotoCarousel exposes no public template-ref controller. Use the controls slot callbacks for custom carousel controls.

Important behavior

  • The carousel uses documented Embla behavior internally, with one slide per snap.
  • loop, dragFree, direction, visual options, and autoplay are reactive.
  • When direction is omitted, inherited direction is resolved at mount. Bind direction when locale direction can change while the component remains mounted.
  • Main and thumbnail rails use the same direction.
  • lightbox is setup-time. Remount with a new key to add, remove, or replace it.
  • Arrow, thumbnail, and dot buttons use the configured localization labels.

Autoplay options

ts
interface PhotoCarouselAutoplayOptions {
  delayMs?: number
  stopOnInteraction?: boolean
  stopOnMouseEnter?: boolean
}

delayMs defaults to 4000, stopOnInteraction to true, and stopOnMouseEnter to false. delayMs must be a positive finite number.

vue
<PhotoCarousel
  :photos="photos"
  loop
  :autoplay="{
    delayMs: 5000,
    stopOnInteraction: false,
    stopOnMouseEnter: true,
  }"
/>

Build a carousel covers practical setup. Lightbox, gestures, and accessibility lists keyboard and reduced-motion behavior.