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 add @vlalg-nimbus/nb-images
Usage
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')
To use, simply call the component, in this case it will be NbImageGallery or nb-image-gallery.
Important: The
imagesprop must be an array of objects withurland optionallyaltproperties. Each image object can also includesrcset,sizes,width, andheightfor 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.
<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>
Preview & Playground
Select the component you want to edit/test
Props
Items with an (*) mean they are required
| name | Value type | Default | Description |
|---|---|---|---|
| nbId (*) | String | Sets the id attribute to differentiate from other components | |
| images (*) | Array | Array of image objects. Each object must have url property and optionally alt, srcset, sizes, width, height properties | |
| initialImageIndex | Number | 0 | Defines the initial selected image index (0-based) |
| loading | String | 'lazy' | Defines the loading strategy for images. Accepts lazy (load when needed) and eager (load immediately) |
| decoding | String | 'async' | Defines the decoding strategy for images. Accepts async, sync, and auto |
| crossorigin | String | null | null |
| referrerpolicy | String | '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 |
| integrity | String | '' | Defines a cryptographic hash of the image resource for Subresource Integrity (SRI) verification. Only applied when a non-empty value is provided |
| fetchpriority | String | 'auto' | Defines the priority for fetching the image resource. Accepts high (high priority), low (low priority), and auto (browser decides) |
| tabIndex | Number | 0 | Defines the tab order for keyboard navigation |
| hasTabIndexEnter | Boolean | true | Enables Enter key to trigger image preview |
| hasTabIndexSpace | Boolean | true | Enables Space key to trigger image preview |
| ariaLabel | String | 'Image Gallery' | Defines the aria-label attribute for screen readers |
| ariaAttrs | Object | {} | Allows passing custom aria attributes as an object. Keys will automatically receive the aria- prefix |
| imageBackground | String | 'transparent' | Defines the background color of the main image container |
| hasThumbnailBorder | Boolean | true | Defines if thumbnails should have a border |
| thumbnailBorderColor | String | '#ffe54c' | Defines the border color for active thumbnail |
| thumbnailBorderWidth | Number | 1 | Defines the border width for thumbnails in pixels |
| thumbnailGap | Number | 8 | Defines the gap between thumbnails in pixels |
| thumbnailSize | Number | 80 | Defines the size of thumbnails in pixels |
| thumbnailButtonBgColor | String | 'rgba(0, 0, 0, 0.5)' | Defines the background color of thumbnail navigation buttons |
| thumbnailButtonBgColorHover | String | 'rgba(0, 0, 0, 0.7)' | Defines the hover background color of thumbnail navigation buttons |
| thumbnailButtonBgColorActive | String | 'rgba(0, 0, 0, 0.9)' | Defines the active background color of thumbnail navigation buttons |
| thumbnailButtonTextColor | String | '#ffffff' | Defines the text color of thumbnail navigation buttons |
| thumbnailButtonBorderRadius | Number | 0 | Defines the border radius of thumbnail navigation buttons |
| borderRadius | Number | 0 | Defines the border radius of the component in rem units |
| disabled | Boolean | false | Defines if the component is disabled |
| fontFamily | String | 'Lato, sans-serif' | Defines the font family for the component |
| fontSize | String | '1.6em' | Defines the font size for the component |
| fontWeight | Number | 200 | Defines the font weight for the component |
| maxWidth | String | 'auto' | Defines the maximum width of the component |
| hasZoom | Boolean | true | Defines if the zoom button should be displayed on hover |
| zoomButtonType | String | 'eye' | Defines the zoom button icon type. Accepts eye and zoom |
| zoomButtonColor | String | '#ffffff' | Defines the color of the zoom button icon |
| zoomButtonBgType | String | 'solid' | Defines the background type of the zoom button. Accepts solid and blur |
| zoomButtonBgColor | String | '#151515' | Defines the background color of the zoom button (when bgType is 'solid') |
| zoomButtonSize | String | '2em' | Defines the size of the zoom button icon |
| zoomButtonOpacity | Number | 0.8 | Defines the opacity of the zoom button (0-1) |
| zoomButtonBgBlur | Number | 4 | Defines the blur intensity for the zoom button background (when bgType is 'blur') |
| backdropRGBColor | Object | { 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) |
| backdropAlpha | Number | 0.6 | Defines the alpha/opacity of the preview modal backdrop (0-1) |
| hasBackdropBlur | Boolean | false | Defines if the preview modal backdrop should have a blur effect |
| backdropBlur | Number | 5 | Defines the blur intensity in pixels for the preview modal backdrop |
| controlsBgColor | String | 'cyan' | Defines the background color of the preview modal controls |
| controlsTextColor | String | 'yellow' | Defines the text color of the preview modal controls |
| controlsTextColorHover | String | 'brown' | Defines the hover text color of the preview modal controls |
| controlsBorderRadius | Number | 20 | Defines the border radius of the preview modal controls in pixels |
| controlsPaddingX | Number | 4 | Defines the horizontal padding of the preview modal controls in pixels |
| controlsPaddingY | Number | 4 | Defines the vertical padding of the preview modal controls in pixels |
| controlsGap | Number | 5 | Defines the gap between preview modal control buttons in pixels |
| controlsFontSize | String | '1.6em' | Defines the font size of the preview modal controls |
| controlsFontWeight | Number | 100 | Defines the font weight of the preview modal controls |
| zIndex | Number | 2147483640 | Defines 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
| name | Description |
|---|---|
| preview-controls | Custom 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-icon | Custom icon for rotate left button. Receives previewRotateLeft function as slot prop |
| preview-rotate-right-icon | Custom icon for rotate right button. Receives previewRotateRight function as slot prop |
| preview-zoom-in-icon | Custom icon for zoom in button. Receives previewZoomIn function as slot prop |
| preview-zoom-out-icon | Custom icon for zoom out button. Receives previewZoomOut function as slot prop |
| preview-close-icon | Custom icon for close button. Receives previewClose function as slot prop |
| preview-first-icon | Custom icon for first image button |
| preview-previous-icon | Custom icon for previous image button |
| preview-next-icon | Custom icon for next image button |
| preview-last-icon | Custom icon for last image button |
| preview-infos | Custom display for image information (current index / total images). Receives previewInfos object as slot prop |
Events
| name | Return type | Description |
|---|---|---|
| clicked | Object | Fired when a thumbnail is clicked. Returns { index: number, image: object } |
| image-changed | Object | Fired 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>
