Overlay
Lightbox
Full-screen image viewer rendered in a portal with focus trap and Escape/backdrop dismiss. Navigates with arrow keys, buttons or swipe, offers zoom controls and an optional thumbnail strip.
Import
import { Lightbox } from "@zephora/react";Examples
Gallery
Open a four-slide gallery from a button. Navigate with the arrow buttons, ArrowLeft/ArrowRight or a swipe; Escape or the backdrop closes it.
const slides = [
{ src: "/photos/indigo.jpg", alt: "Indigo abstract artwork", title: "Indigo study" },
{ src: "/photos/blue.jpg", alt: "Blue abstract artwork", title: "Blue study" },
{ src: "/photos/green.jpg", alt: "Green abstract artwork", title: "Green study" },
{ src: "/photos/red.jpg", alt: "Red abstract artwork", title: "Red study" },
];
const [open, setOpen] = React.useState(false);
<Button onClick={() => setOpen(true)}>Open gallery</Button>
<Lightbox slides={slides} open={open} onOpenChange={setOpen} />Thumbnail strip
`showThumbnails` renders a clickable strip below the image; the active thumbnail is highlighted. `defaultIndex` picks the starting slide.
<Lightbox
slides={slides}
open={open}
onOpenChange={setOpen}
showThumbnails
defaultIndex={1}
/>Zoom disabled
`zoomable={false}` hides the zoom in/out controls for fixed-size artwork.
<Lightbox
slides={slides.slice(0, 2)}
open={open}
onOpenChange={setOpen}
zoomable={false}
/>API
Lightbox props
| Prop | Type | Default | Description |
|---|---|---|---|
slides * | LightboxSlide[] | — | Images shown by the lightbox, in order. |
open | boolean | — | Controlled open state. |
defaultOpen | boolean | false | Initial open state (uncontrolled). |
onOpenChange | (open: boolean) => void | — | Called whenever the lightbox requests an open state change. |
index | number | — | Controlled active slide index. |
defaultIndex | number | 0 | Initial slide for uncontrolled usage. |
onIndexChange | (index: number) => void | — | Fires whenever the active slide changes. |
showThumbnails | boolean | false | Renders a thumbnail strip below the image. |
zoomable | boolean | true | Renders zoom in/out controls. |
classNames | Partial<Record<LightboxSlot, string>> | — | Per-slot class overrides: "overlay" | "figure" | "image" | "caption" | "nav" | "navButton" | "closeButton" | "zoomControls" | "thumbnails" | "thumbnail". Appended after the module classes and also applied in unstyled mode. |
unstyled | boolean | false | Headless mode — skips Zephora styling. |
…rest | Omit<HTMLAttributes<HTMLDivElement>, "children"> | — | Native div props are forwarded to the dialog panel. |
LightboxSlide props
| Prop | Type | Default | Description |
|---|---|---|---|
src * | string | — | Image source URL. |
alt | string | — | Alternative text for the image (also used by its thumbnail). |
title | ReactNode | — | Optional caption rendered below the image. |
Keyboard
| Key | Action |
|---|---|
ArrowRight / ArrowLeft | Go to the next / previous slide. |
Escape | Closes the lightbox (backdrop press also closes it). |
Tab / Shift+Tab | Cycles focus inside the viewer — focus is trapped while open. |