nb-image

This is an image component for Vue.js 3+. It allows you to create images with optional responsive behavior, optimized loading, layout shift prevention, magnifier glass effect, and preview modal functionality.

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 NbImage or nb-image.

Important: The image prop must be an object with url property and optionally alt, srcset, sizes, width, and height properties. The width and height properties help prevent layout shift (CLS) by reserving space before the image loads.

Mode 1
<template>
  <NbImage
    nb-id="image-1"
    :image="imageData"
  />
</template>

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

const imageData = ref({
  url: 'https://example.com/image.jpg',
  alt: 'Description',
  width: 1200,
  height: 800
})
</script>
Mode 2
<template>
  <nb-image
    nb-id="image-1"
    :image="imageData"
  />
</template>
Mode 3
<template>
  <nb-image
    nb-id="image-1"
    :image="imageData"
  ></nb-image>
</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
image (*)Object{ url: '', alt: '' }Image object. Must have url property and optionally alt, srcset, sizes, width, height properties
responsiveTypeString'full'Defines the responsive behavior. Accepts none (maintains original size), full (width: 100%, scales up and down), scale-down (max-width: 100%, never larger than original), restricted (width: 100% + max-width: value, restricts to maximum size)
maxWidthStringnullDefines the maximum width. Used when responsiveType is 'restricted' or 'scale-down', or to constrain size when responsiveType is 'none'
minWidthStringnullDefines the minimum width. Useful when responsiveType is 'none' to ensure a minimum size
maxHeightStringnullDefines the maximum height. Useful to constrain vertical size in any responsiveType
minHeightStringnullDefines the minimum height. Useful to ensure a minimum vertical size
objectFitString'cover'Defines how the image fits its container. Accepts cover, contain, fill, none, scale-down
loadingString'lazy'Defines the loading strategy. Accepts lazy (load when needed) and eager (load immediately)
decodingString'async'Defines the decoding strategy. 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)
sizesString'100vw'Defines the sizes attribute for responsive images. Used as fallback if image.sizes is not provided
borderRadiusNumber0.375Defines the border radius of the component in rem units
tabIndexNumber0Defines the tab order for keyboard navigation
ariaLabelString'Alternate Text Button'Defines the aria-label attribute for screen readers
ariaAttrsObject{}Allows passing custom aria attributes as an object. Keys will automatically receive the aria- prefix
displayString'ib'Defines the display type. Accepts b (block) and ib (inline-block)
hasPreviewBooleanfalseEnables the preview modal functionality. When true, clicking the image opens a full-screen modal with rotation and zoom controls
hasBackdropBlurBooleanfalseEnables backdrop blur effect for the preview modal
backdropBlurNumber5Defines the blur intensity for the backdrop (in pixels). Only applies when hasBackdropBlur is true
backdropRGBColorObject{ r: 0, g: 0, b: 0 }Defines the RGB color values for the modal backdrop
backdropAlphaNumber0.6Defines the alpha/opacity value for the modal backdrop (0 to 1)
controlsBgColorString'cyan'Defines the background color for the modal controls
controlsTextColorString'magenta'Defines the text color for the modal controls
controlsTextColorHoverString'brown'Defines the text color for the modal controls on hover
controlsBorderRadiusNumber20Defines the border radius for the modal controls
controlsPaddingXNumber4Defines the horizontal padding for the modal controls
controlsPaddingYNumber4Defines the vertical padding for the modal controls
controlsGapNumber5Defines the gap between modal control buttons
controlsFontSizeString'1.6em'Defines the font size for the modal controls
controlsFontWeightNumber800Defines the font weight for the modal controls
zIndexNumber2147483640Defines the z-index for the preview modal
hagnifierGlassBooleanfalseEnables the magnifier glass effect. When true, hovering over the image shows a magnifying glass that zooms into the image. Note: The magnifier may not work with cross-origin images in environments with strict Cross-Origin Embedder Policy (COEP), such as Stackblitz. In these cases, the magnifier will not display the magnified content.
hagnifierGlassZoomNumber3Defines the zoom level for the magnifier glass (must be greater than 0)
hagnifierGlassSizeNumber100Defines the size of the magnifier glass in pixels (must be greater than 0)
hagnifierGlassBorderRadiusNumber50Defines the border radius percentage for the magnifier glass (must be greater than 0)
hagnifierGlassBorderColorString'#000'Defines the border color for the magnifier glass
hagnifierGlassBorderWidthNumber3Defines the border width for the magnifier glass in pixels (must be greater than 0)

Events

nameReturn typeDescription
clicked-Fired when the image is clicked

Responsive Types

'none' - Fixed Size (Not Responsive)

/* No width or max-width applied by default */
height: auto;
/* But you can use minWidth, maxWidth, minHeight, maxHeight props */
  • Maintains the original image size by default
  • Does not scale with container automatically
  • Uses the width and height attributes from the image object
  • You can use minWidth, maxWidth, minHeight, and maxHeight props to constrain the size
  • Use when you want a fixed-size image that doesn't adapt to container, but still need size constraints

'full' - Full Responsive

width: 100%;
height: auto;
  • Scales both up and down to fill the container
  • Image can become larger than its original size
  • Use when you want the image to always fill the available space

'scale-down' - Scale Down Only

max-width: 100%;
height: auto;
  • Never becomes larger than its original size
  • Scales down when container is smaller
  • Maintains image quality by preventing upscaling
  • Use when you want to preserve image quality

'restricted' - Restricted Maximum

width: 100%;
max-width: [value];
height: auto;
  • Responsive up to a maximum width limit
  • Uses the maxWidth prop to set the limit
  • Use when you need responsive behavior with a size cap

Examples

Basic Usage (Not Responsive)

<template>
  <NbImage
    nb-id="image-fixed"
    :image="image"
    responsive-type="none"
  />
</template>

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

const image = ref({
  url: 'https://example.com/image.jpg',
  alt: 'Description',
  width: 1200,
  height: 800
})
</script>

Basic Usage (Responsive)

<template>
  <NbImage
    nb-id="image-basic"
    :image="image"
  />
</template>

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

const image = ref({
  url: 'https://example.com/image.jpg',
  alt: 'Description',
  width: 1200,
  height: 800
})
</script>

With Responsive Type: Scale Down

<template>
  <NbImage
    nb-id="image-scale-down"
    :image="image"
    responsive-type="scale-down"
  />
</template>

With Responsive Type: Restricted

<template>
  <NbImage
    nb-id="image-restricted"
    :image="image"
    responsive-type="restricted"
    max-width="400px"
  />
</template>

With Object Fit: Contain

<template>
  <NbImage
    nb-id="image-contain"
    :image="image"
    object-fit="contain"
  />
</template>

With Optimized Loading (srcset and sizes)

<template>
  <NbImage
    nb-id="image-optimized"
    :image="optimizedImage"
  />
</template>

<script setup>
const optimizedImage = ref({
  url: 'https://example.com/image-1200.jpg',
  alt: 'Optimized image',
  srcset: 'image-300.jpg 300w, image-600.jpg 600w, image-1200.jpg 1200w',
  sizes: '(max-width: 600px) 300px, (max-width: 1200px) 600px, 1200px',
  width: 1200,
  height: 800
})
</script>

With Custom Border Radius

<template>
  <NbImage
    nb-id="image-radius"
    :image="image"
    :border-radius="1"
  />
</template>

Handling Click Event

<template>
  <NbImage
    nb-id="image-clickable"
    :image="image"
    @clicked="handleImageClick"
  />
</template>

<script setup>
const handleImageClick = () => {
  console.log('Image clicked!')
  // Open modal, navigate, etc.
}
</script>

With Preview Modal

<template>
  <NbImage
    nb-id="image-preview"
    :image="image"
    :has-preview="true"
    :has-backdrop-blur="true"
    :backdrop-blur="10"
    :backdrop-r-g-b-color="{ r: 0, g: 0, b: 0 }"
    :backdrop-alpha="0.8"
    controls-bg-color="rgba(0, 0, 0, 0.7)"
    controls-text-color="#ffffff"
    controls-text-color-hover="#4CAF50"
    :controls-border-radius="8"
    :z-index="9999"
  />
</template>

With Magnifier Glass

<template>
  <NbImage
    nb-id="image-magnifier"
    :image="image"
    :hagnifier-glass="true"
    :hagnifier-glass-zoom="3"
    :hagnifier-glass-size="150"
    :hagnifier-glass-border-radius="50"
    hagnifier-glass-border-color="#000"
    :hagnifier-glass-border-width="3"
  />
</template>

Preventing Layout Shift

<template>
  <NbImage
    nb-id="image-no-shift"
    :image="imageWithDimensions"
  />
</template>

<script setup>
// Always provide width and height to prevent layout shift
const imageWithDimensions = ref({
  url: 'https://example.com/image.jpg',
  alt: 'Description',
  width: 1200,  // Original width in pixels
  height: 800   // Original height in pixels
})
</script>

With Size Constraints (Non-Responsive)

<template>
  <NbImage
    nb-id="image-constrained"
    :image="image"
    responsive-type="none"
    min-width="200px"
    max-width="600px"
    min-height="150px"
    max-height="400px"
  />
</template>

<script setup>
const image = ref({
  url: 'https://example.com/image.jpg',
  alt: 'Description',
  width: 1200,
  height: 800
})
</script>