nb-image-gallery

This is an image gallery component for Vue.js 3+. It displays a main image with thumbnails below, allowing users to navigate through an image collection. When clicking on the main image, it opens a full-screen modal preview with rotation, zoom, and navigation controls.

Loading component...

Installation

Yarn
yarn add @vlalg-nimbus/nb-images
NPM
npm install @vlalg-nimbus/nb-images

Usage

Vue 3
import { createApp } from 'vue'
import App from './App.vue'

import NbImagesComponents from '@vlalg-nimbus/nb-images'
import "@vlalg-nimbus/nb-images/dist/style.css";

const app = createApp(App)
app.use(NbImagesComponents)
app.mount('#app')
Nuxt 3
import NbImagesComponents from '@vlalg-nimbus/nb-images'
import "@vlalg-nimbus/nb-images/dist/style.css";

export default defineNuxtPlugin(context => {
  context.vueApp.use(NbImagesComponents)
})

To use, simply call the component, in this case it will be NbImageGallery or nb-image-gallery.

Important: The images prop must be an array of objects with url and optionally alt properties. Each image object can also include srcset, sizes, width, and height for optimized loading and layout shift prevention. The component automatically handles image loading states and provides a smooth user experience with thumbnail navigation and full-screen preview modal.

Mode 1
<template>
  <NbImageGallery
    nb-id="gallery-1"
    :images="imageList"
    :initial-image-index="0"
  />
</template>

<script setup>
import { ref } from 'vue'

const imageList = ref([
  { 
    url: 'https://example.com/image1.jpg', 
    alt: 'Image 1',
    srcset: 'image1-300.jpg 300w, image1-600.jpg 600w, image1-1200.jpg 1200w',
    sizes: '(max-width: 600px) 300px, (max-width: 1200px) 600px, 1200px',
    width: 1200,
    height: 800
  },
  { 
    url: 'https://example.com/image2.jpg', 
    alt: 'Image 2',
    width: 1200,
    height: 800
  }
])
</script>
Mode 2
<template>
  <nb-image-gallery
    nb-id="gallery-1"
    :images="imageList"
    :initial-image-index="0"
  />
</template>
Mode 3
<template>
  <nb-image-gallery
    nb-id="gallery-1"
    :images="imageList"
    :initial-image-index="0"
  ></nb-image-gallery>
</template>

Preview & Playground

Select the component you want to edit/test

Loading Sandbox...

Props

Items with an (*) mean they are required

nameValue typeDefaultDescription
nbId (*)StringSets the id attribute to differentiate from other components
images (*)ArrayArray of image objects. Each object must have url property and optionally alt, srcset, sizes, width, height properties
initialImageIndexNumber0Defines the initial selected image index (0-based)
loadingString'lazy'Defines the loading strategy for images. Accepts lazy (load when needed) and eager (load immediately)
decodingString'async'Defines the decoding strategy for images. Accepts async, sync, and auto
crossoriginStringnullnull
referrerpolicyString'no-referrer'Defines which referrer information to send when fetching the image. Accepts no-referrer, no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, and unsafe-url
integrityString''Defines a cryptographic hash of the image resource for Subresource Integrity (SRI) verification. Only applied when a non-empty value is provided
fetchpriorityString'auto'Defines the priority for fetching the image resource. Accepts high (high priority), low (low priority), and auto (browser decides)
tabIndexNumber0Defines the tab order for keyboard navigation
hasTabIndexEnterBooleantrueEnables Enter key to trigger image preview
hasTabIndexSpaceBooleantrueEnables Space key to trigger image preview
ariaLabelString'Image Gallery'Defines the aria-label attribute for screen readers
ariaAttrsObject{}Allows passing custom aria attributes as an object. Keys will automatically receive the aria- prefix
imageBackgroundString'transparent'Defines the background color of the main image container
hasThumbnailBorderBooleantrueDefines if thumbnails should have a border
thumbnailBorderColorString'#ffe54c'Defines the border color for active thumbnail
thumbnailBorderWidthNumber1Defines the border width for thumbnails in pixels
thumbnailGapNumber8Defines the gap between thumbnails in pixels
thumbnailSizeNumber80Defines the size of thumbnails in pixels
thumbnailButtonBgColorString'rgba(0, 0, 0, 0.5)'Defines the background color of thumbnail navigation buttons
thumbnailButtonBgColorHoverString'rgba(0, 0, 0, 0.7)'Defines the hover background color of thumbnail navigation buttons
thumbnailButtonBgColorActiveString'rgba(0, 0, 0, 0.9)'Defines the active background color of thumbnail navigation buttons
thumbnailButtonTextColorString'#ffffff'Defines the text color of thumbnail navigation buttons
thumbnailButtonBorderRadiusNumber0Defines the border radius of thumbnail navigation buttons
borderRadiusNumber0Defines the border radius of the component in rem units
disabledBooleanfalseDefines if the component is disabled
fontFamilyString'Lato, sans-serif'Defines the font family for the component
fontSizeString'1.6em'Defines the font size for the component
fontWeightNumber200Defines the font weight for the component
maxWidthString'auto'Defines the maximum width of the component
hasZoomBooleantrueDefines if the zoom button should be displayed on hover
zoomButtonTypeString'eye'Defines the zoom button icon type. Accepts eye and zoom
zoomButtonColorString'#ffffff'Defines the color of the zoom button icon
zoomButtonBgTypeString'solid'Defines the background type of the zoom button. Accepts solid and blur
zoomButtonBgColorString'#151515'Defines the background color of the zoom button (when bgType is 'solid')
zoomButtonSizeString'2em'Defines the size of the zoom button icon
zoomButtonOpacityNumber0.8Defines the opacity of the zoom button (0-1)
zoomButtonBgBlurNumber4Defines the blur intensity for the zoom button background (when bgType is 'blur')
backdropRGBColorObject{ r: 0, g: 0, b: 0 }Defines the RGB color of the preview modal backdrop. Must be an object with r, g, b properties (0-255)
backdropAlphaNumber0.6Defines the alpha/opacity of the preview modal backdrop (0-1)
hasBackdropBlurBooleanfalseDefines if the preview modal backdrop should have a blur effect
backdropBlurNumber5Defines the blur intensity in pixels for the preview modal backdrop
controlsBgColorString'cyan'Defines the background color of the preview modal controls
controlsTextColorString'yellow'Defines the text color of the preview modal controls
controlsTextColorHoverString'brown'Defines the hover text color of the preview modal controls
controlsBorderRadiusNumber20Defines the border radius of the preview modal controls in pixels
controlsPaddingXNumber4Defines the horizontal padding of the preview modal controls in pixels
controlsPaddingYNumber4Defines the vertical padding of the preview modal controls in pixels
controlsGapNumber5Defines the gap between preview modal control buttons in pixels
controlsFontSizeString'1.6em'Defines the font size of the preview modal controls
controlsFontWeightNumber100Defines the font weight of the preview modal controls
zIndexNumber2147483640Defines the base z-index for the component. Navigation arrows use zIndex, preview image uses zIndex + 1, modal uses zIndex + 1, and modal controls use zIndex + 2. Important: The maximum value is 2147483640 because controls add +2 to this value

Slots

nameDescription
preview-controlsCustom controls for the preview modal. Receives slot props: previewRotateLeft, previewRotateRight, previewZoomIn, previewZoomOut, previewClose, previewFirst, previewPrevious, previewNext, previewLast, previewInfos (object with currentIndex and totalImages)
preview-rotate-left-iconCustom icon for rotate left button. Receives previewRotateLeft function as slot prop
preview-rotate-right-iconCustom icon for rotate right button. Receives previewRotateRight function as slot prop
preview-zoom-in-iconCustom icon for zoom in button. Receives previewZoomIn function as slot prop
preview-zoom-out-iconCustom icon for zoom out button. Receives previewZoomOut function as slot prop
preview-close-iconCustom icon for close button. Receives previewClose function as slot prop
preview-first-iconCustom icon for first image button
preview-previous-iconCustom icon for previous image button
preview-next-iconCustom icon for next image button
preview-last-iconCustom icon for last image button
preview-infosCustom display for image information (current index / total images). Receives previewInfos object as slot prop

Events

nameReturn typeDescription
clickedObjectFired when a thumbnail is clicked. Returns { index: number, image: object }
image-changedObjectFired when the selected image changes. Returns { index: number, image: object }

Examples

Basic Usage

<template>
  <NbImageGallery
    nb-id="gallery-basic"
    :images="images"
  />
</template>

<script setup>
import { ref } from 'vue'

const images = ref([
  { 
    url: 'https://example.com/img1.jpg', 
    alt: 'Image 1',
    width: 1200,
    height: 800
  },
  { 
    url: 'https://example.com/img2.jpg', 
    alt: 'Image 2',
    width: 1200,
    height: 800
  },
  { 
    url: 'https://example.com/img3.jpg', 
    alt: 'Image 3',
    width: 1200,
    height: 800
  }
])
</script>

Custom Initial Image

<template>
  <NbImageGallery
    nb-id="gallery-custom"
    :images="images"
    :initial-image-index="2"
  />
</template>

Custom Styling

<template>
  <NbImageGallery
    nb-id="gallery-styled"
    :images="images"
    :thumbnail-size="100"
    :thumbnail-gap="12"
    thumbnail-border-color="#ff0000"
    :thumbnail-border-width="3"
    :border-radius="0.5"
  />
</template>

Custom Preview Controls

<template>
  <NbImageGallery
    nb-id="gallery-custom-controls"
    :images="images"
  >
    <template #preview-controls="{
      previewRotateLeft,
      previewRotateRight,
      previewZoomIn,
      previewZoomOut,
      previewClose,
      previewFirst,
      previewPrevious,
      previewNext,
      previewLast,
      previewInfos
    }">
      <div class="custom-controls">
        <button @click="previewRotateLeft()">↺ Rotate Left</button>
        <button @click="previewRotateRight()">↻ Rotate Right</button>
        <button @click="previewZoomIn()">+ Zoom In</button>
        <button @click="previewZoomOut()">- Zoom Out</button>
        <button @click="previewClose()">✕ Close</button>
        <button @click="previewFirst()">⏮ First</button>
        <button @click="previewPrevious()">◀ Previous</button>
        <span>{{ previewInfos.currentIndex }} / {{ previewInfos.totalImages }}</span>
        <button @click="previewNext()">Next ▶</button>
        <button @click="previewLast()">Last ⏭</button>
      </div>
    </template>
  </NbImageGallery>
</template>

With Backdrop Blur

<template>
  <NbImageGallery
    nb-id="gallery-blur"
    :images="images"
    :has-backdrop-blur="true"
    :backdrop-blur="10"
    :backdrop-rgb-color="{ r: 0, g: 0, b: 0 }"
    :backdrop-alpha="0.8"
  />
</template>

With Optimized Images (srcset, sizes, width, height)

<template>
  <NbImageGallery
    nb-id="gallery-optimized"
    :images="optimizedImages"
    loading="lazy"
    decoding="async"
  />
</template>

<script setup>
import { ref } from 'vue'

const optimizedImages = ref([
  {
    url: 'https://example.com/img1-1200.jpg',
    alt: 'Image 1',
    srcset: 'img1-300.jpg 300w, img1-600.jpg 600w, img1-1200.jpg 1200w',
    sizes: '(max-width: 600px) 300px, (max-width: 1200px) 600px, 1200px',
    width: 1200,
    height: 800
  },
  {
    url: 'https://example.com/img2-1200.jpg',
    alt: 'Image 2',
    srcset: 'img2-300.jpg 300w, img2-600.jpg 600w, img2-1200.jpg 1200w',
    sizes: '(max-width: 600px) 300px, (max-width: 1200px) 600px, 1200px',
    width: 1200,
    height: 800
  }
])
</script>

Handling Events

<template>
  <NbImageGallery
    nb-id="gallery-events"
    :images="images"
    @clicked="handleThumbnailClick"
    @image-changed="handleImageChange"
  />
</template>

<script setup>
const handleThumbnailClick = ({ index, image }) => {
  console.log('Thumbnail clicked:', index, image)
}

const handleImageChange = ({ index, image }) => {
  console.log('Image changed to:', index, image)
}
</script>