Skip to content

Lightbox

A click-to-enlarge media viewer: a thumbnail strip whose items open in an accessible, focus-trapped dialog. Multiple images and videos page through an embedded Carousel.

Import

import { Lightbox } from "@hyzer-labs/ui"

Demo

Image + Lightbox

Image renders media; Lightbox handles viewing. Compose an Image as a trigger face (see the "Image triggers" tab), or reach for the lightboxGroup attachment on the "Group attachment" tab to add click-to-view over an Image grid you already render.

Click the thumbnail and note the zoom cursor. Esc, the backdrop, and the close button all dismiss the viewer.

Demo image
Hole 7, sunset round
<Lightbox
	src="/photos/hole-7.jpg"
	thumbSrc="/photos/hole-7-thumb.jpg"
	alt="Hole 7 fairway at sunset"
	caption="Hole 7, sunset round"
/>

Props

NameTypeDefaultNote
itemsLightboxItem[]Media entries (images and videos) — see LightboxItem below. Renders one thumbnail trigger per item; the viewer pages through them with a Carousel.
src / alt / thumbSrc / captionstringSingle-image sugar — equivalent to a one-item items array.
openboolean (bindable)false
dialogLabelstring'Media viewer'Dialog name in multi-item mode (single items are labeled by their own name).
triggerLabelstring'View larger: {name}'Single trigger only.
closeLabelstring'Close media viewer'
prevLabelstring'Previous item'
nextLabelstring'Next item'
onclose() => voidFires once per dismissal.
childrenSnippetCustom trigger content — replaces the thumbnail strip; opens the first item.
triggerSnippet<[LightboxItem, number]>Per-item trigger face, e.g. an Image — replaces the default thumb/badge for every item. Ignored (with a DEV warning) when children is also passed.
classstringMerged after the hz-lightbox-triggers class (the inline strip).

LightboxItem (image)

NameTypeDefaultNote
type'image''image'Optional — image is the default.
srcstringRequired. Full-size image.
altstringRequired.
thumbSrcstringStrip thumbnail; defaults to src.
captionstring

LightboxItem (video)

NameTypeDefaultNote
type'video'Required for videos.
srcstringRequired. Native file or YouTube/Vimeo URL — plays via the Video component.
labelstringRequired. Accessible name (the Video title).
posterstring
thumbSrcstringStrip thumbnail; defaults to poster.
captionstring

Theme hooks

What this component promises your CSS. The reference theme styles exactly these — from @layer hz-theme, so your unlayered rules win. See Styling Components for the how.

Root class: .hz-lightbox-triggers

Data attributes

HookValuesStyles
data-state'open' | 'closed'On the viewer dialog, mirroring the bindable open prop. Visibility itself runs off the native [open] attribute — this is the hook to animate against.
data-gallerypresent with more than one itemOn the viewer dialog. Drives the fixed gallery stage sizing that a single item skips (it hugs its media instead).
data-lightbox-triggerpresent on a grouped triggerSet by the lightboxGroup attachment rather than the component. Its only styling is a zoom-in cursor.

Part classes

HookValuesStyles
.hz-lightbox-triggerchild elementA thumbnail button. Also the root class when you supply your own children.
.hz-lightbox-thumbchild elementThe thumbnail image.
.hz-lightbox-thumb-labelchild elementFallback chip when no thumbnail resolves.
.hz-lightbox-badgechild elementThe play marker on video items.
.hz-lightboxthe viewer dialogThe overlay itself. It takes no class prop, so this name is unconditionally stable.
.hz-lightbox-closechild elementThe close control.
.hz-lightbox-carouselon the embedded CarouselMulti-item viewers only — see Carousel for its own parts underneath.
.hz-lightbox-figurechild elementThe figure wrapping each item.
.hz-lightbox-captionchild elementThe caption.
.hz-lightbox-imgon an Image's wrapperRides through Image’s class prop — so it names a div, not an img. Reach the picture itself through .hz-lightbox-img .hz-image__img.
.hz-lightbox-videochild elementThe wrapper around a video item’s Video.

Accessibility

Each thumbnail is a real <button> with aria-haspopup="dialog", named by its item.

The viewer is a native <dialog> opened with showModal(). Focus is trapped. Escape and the backdrop both close it, and focus returns to the thumbnail that opened it.

Multi-item viewers embed the Carousel (labeled slides, live announcements), and ArrowLeft/ArrowRight page through it from anywhere in the dialog. Body scroll is locked while open.

References: APG Dialog (Modal) pattern · APG Carousel pattern