Command Palette

Search for a command to run...

2.4KGitHub stars
Components

Lightbox

Image viewer that morphs from the thumbnail, with swipe, zoom, and pull to close.

Loading…
Dependencies (2)
Registry (1)

Features

Built on top of ramka, unstyled lightbox primitives for React. ramka handles the behavior, gestures, and accessibility. This component adds the styles.

  • Morphs from the thumbnail on open and back on close.
  • Swipe between images, pull down to close.
  • Pinch or double-tap to zoom, then drag to pan.

Use cases

  • Photo galleries on a portfolio or travel page.
  • Product images on a store page.
  • Screenshots in a blog post or changelog.

Installation

pnpm dlx shadcn@latest add @ncdai/lightbox

Usage

import {
  Lightbox,
  LightboxCaption,
  LightboxClose,
  LightboxContent,
  LightboxCounter,
  LightboxFooter,
  LightboxHeader,
  LightboxItem,
  LightboxMedia,
  LightboxNext,
  LightboxPrevious,
  LightboxSlide,
  LightboxSlides,
  LightboxTrigger,
  LightboxZoom,
  LightboxZoomIn,
  LightboxZoomOut,
} from "@/components/lightbox"
<Lightbox>
  {photos.map((photo, index) => (
    <LightboxTrigger key={photo.src} index={index}>
      {({ imageRef }) => <img ref={imageRef} src={photo.src} alt={photo.alt} />}
    </LightboxTrigger>
  ))}
 
  <LightboxContent aria-label="Photos">
    <LightboxSlides aria-label="Photos" aria-roledescription="carousel">
      {photos.map((photo, index) => (
        <LightboxSlide key={photo.src}>
          <LightboxItem index={index} caption={photo.caption}>
            <LightboxZoom>
              <LightboxMedia width={photo.width} height={photo.height}>
                <img src={photo.src} alt={photo.alt} />
              </LightboxMedia>
            </LightboxZoom>
          </LightboxItem>
        </LightboxSlide>
      ))}
    </LightboxSlides>
 
    <LightboxHeader>
      <LightboxZoomOut />
      <LightboxZoomIn />
      <LightboxClose />
    </LightboxHeader>
 
    <LightboxPrevious />
    <LightboxNext />
 
    <LightboxFooter>
      <LightboxCaption />
      <LightboxCounter />
    </LightboxFooter>
  </LightboxContent>
</Lightbox>

Composition

Use the following composition to build a Lightbox

Lightbox
├── LightboxTrigger
└── LightboxContent
    ├── LightboxSlides
    │   └── LightboxSlide
    │       └── LightboxItem
    │           └── LightboxZoom
    │               └── LightboxMedia
    ├── LightboxHeader
    │   ├── LightboxZoomOut
    │   ├── LightboxZoomIn
    │   └── LightboxClose
    ├── LightboxPrevious
    ├── LightboxNext
    └── LightboxFooter
        ├── LightboxCaption
        ├── LightboxCounter
        └── LightboxThumbnailStrip
            └── LightboxThumbnailStripTrack
                └── LightboxThumbnail

API reference

Props pass through to ramka. See the ramka API reference.

PartNotes
LightboxContentIncludes the portal and backdrop. Needs aria-label.
LightboxHeader, LightboxFooterHide while pulling to close. The footer also hides while zoomed.
LightboxClose, LightboxZoomIn, LightboxZoomOut, LightboxPrevious, LightboxNextRender a Button with variant="secondary" and size="icon", both overridable.
createLightboxHandleReturns a handle with open(index), close(), and goTo(index). Pass it to Lightbox as handle.

Spacing

Set on LightboxContent, for example md:[--lb-inset-x:2rem].

VariableDefault
--lb-inset-top4rem, 4.5rem from md
--lb-inset-bottom4rem, 4.5rem from md, 8rem with thumbnails
--lb-inset-x0, 4.5rem from md

Data attributes

LightboxContent is a group/lightbox, so children can use group-data-zoomed/lightbox:hidden and the like.

AttributeElement
data-pulling, data-pull-dismissing, data-zoomedLightboxContent
data-activeLightboxItem, LightboxThumbnail

Examples

Thumbnails

Loading…

Single image

scrollToZoom lets the mouse wheel zoom, and maxZoom caps it.

Loading…

Open from code

Without a trigger, the lightbox fades in instead of morphing.

Loading…

Next.js Image

Use sizes="100vw" on the full image and skip fill.

Loading…

Accessibility

  • Escape closes and returns focus to the trigger.
  • Arrow keys move between images, or pan when zoomed. Home and End jump to the ends.
  • +, -, and 0 zoom in, out, and reset.
  • The caption and counter are announced on change.
  • Button labels are in English. Pass children to translate them.
  • With prefers-reduced-motion, the morph becomes a fade and the thumbnail strip jumps.

Credits

References

License and usage

  • Free to use and modify in both personal and commercial projects.
  • Attribution is appreciated but not required.
  • Released under the MIT License.

Was this helpful?

Command Palette

Search for a command to run...