Lightbox
Fullscreen photo viewer. Built on Dialog (focus trap, portal, Escape closes). Adds keyboard ←/→ between items and a counter overlay.
Default#
Loop#
Set loop to wrap the prev / next buttons and ←/→ keyboard navigation
past the boundaries. Pairs with Carousel's loop prop for marketplace
photo galleries — ListingDetail forwards a single loop prop to
both surfaces.
Props#
| Prop | Type | Default | Description |
|---|---|---|---|
| open | boolean | undefined | — | |
| defaultOpen | boolean | undefined | — | |
| onOpenChange | ((open: boolean) => void) | undefined | — | |
| items * | readonly unknown[] | — | Items to view — usually image URLs but anything renderable is fine. |
| renderItem * | (item: unknown, index: number) => ReactNode | — | Renderer for the active item. |
| index | number | undefined | — | Current index (controlled). |
| defaultIndex | number | undefined | — | Default index (uncontrolled). |
| onIndexChange | ((index: number) => void) | undefined | — | Fires when the index changes. |
| loop | boolean | undefined | false | Wrap prev / next (buttons and ←/→ keys) past the boundaries. Default `false`. When `true`, "next" on the last item goes to the first and vice versa, and the arrow buttons never disable while there's more than one item. |
| title | ReactNode | Photo viewer | Accessible title (visually hidden). |
Accessibility#
- The dialog has
role="dialog"and a visually hidden title (override via thetitleprop). - Keyboard: Escape closes; Left / Right move between items; Tab cycles through the focusable controls (prev, next, close).
- The active photo is the only one rendered in the viewport — there is no reflow when moving between items.
Composition#
Lightbox is the modal shell — pair it with Carousel for a listing
detail's photo gallery: thumbnails in Carousel, on-click open Lightbox.