# Lightbox

An image viewer that grows out of the thumbnail and zooms into the detail.

Package: @reuse-sh/lightbox

## Principles

These are the rules to keep when you adapt this library. The code is one way to keep them. An adaptation on any framework must keep every one.

- Page with native scroll snap. Pages are a scroll-snap strip from the carousel, so touch and trackpads keep the system's momentum.

- Open from the thumbnail and return to it. The image grows out of its cropped preview and goes back to the same place on close.

- Load only what is near. Only the current and neighboring images load, and a long jump skips the pages in between.

- Zoom around the point you touch. Pinch, wheel and double-tap zoom around the pointer or fingers, and panning stops at the image's edges.

- Keep focus inside and give it back. The viewer is a native modal dialog, and closing it returns focus to the element that opened it.

- Leave the page as it was. Destroy restores the page scroll, the hidden thumbnail, and every style and listener the viewer touched.

## Install

```bash
npm install @reuse-sh/lightbox
```

## Integration notes

- A click on the image zooms by default. For a publishing gallery, set imageClick: "close" and doubleTapZoom: false.

- Paging runs on the carousel package. Only the current and neighboring images stay loaded. Next and previous scroll smoothly, and a jump from a distant thumbnail fades through the backdrop so unloaded pages never flash past.

- Images and captions are supported, with optional thumbnails. Video and iframes are not supported yet.

## API

- `createLightbox(options?)`: Creates a viewer. Options include thumbnails, imageClick, doubleTapZoom, maxZoom, padding, className and icons.

- `bindLightboxGallery(root, options?)`: Opens every image inside root in the viewer, in page order. Its destroy also removes the click listener.

- `open(items, index?)`: Opens at an index. Items carry src, alt, caption, the natural size and an optional origin.

- `close(), next(), prev(), goTo(index)`: Moves through the set from code. Close returns to the origin thumbnail.

- `zoomTo(scale, focus?), toggleZoom(focus?)`: Zooms to a scale around a point, or between fit and the tap zoom.

- `getState(), subscribe(listener)`: Reads and listens to the index, zoom and open state.

- `destroy()`: Removes listeners and restores the page.

## Browser JavaScript

```js
import { bindLightboxGallery } from "@reuse-sh/lightbox";
import "@reuse-sh/lightbox/styles.css";

const gallery = document.querySelector("[data-gallery]");
const lightbox = bindLightboxGallery(gallery, {
  thumbnails: true,
  imageClick: "zoom",
});

// Later, when the gallery leaves the page
lightbox.destroy();
```

## React

```tsx
import { useLightbox } from "@reuse-sh/lightbox/react";
import "@reuse-sh/lightbox/styles.css";
import { useRef } from "react";

export function Gallery({ photos }) {
  const lightbox = useLightbox({ thumbnails: true });
  const root = useRef(null);
  const open = (index) => {
    const images = root.current.querySelectorAll("img");
    lightbox.open(photos.map((photo, i) => ({ ...photo, origin: images[i] })), index);
  };
  return (
    <div ref={root}>
      {photos.map((photo, index) => (
        <button key={photo.src} onClick={() => open(index)}>
          <img src={photo.src} alt={photo.alt} />
        </button>
      ))}
    </div>
  );
}
```

## Agent workflow

1. Inspect the project and read the installed package's types and stylesheet.

2. Reuse the native controller. Use the React adapter only in a React surface.

3. Adapt styles and data connections to the project. Keep every principle above. Do not recreate the gesture or state engine.

4. Connect destroy and unsubscribe callbacks to the owner lifecycle.

5. Verify keyboard access, pointer/touch behavior, resize, empty/one-item states, errors, reduced motion, and teardown where applicable.

6. Report the actual checks and remaining browser/device limits.

## Source

https://github.com/reuse-sh/reuse/tree/main/packages/lightbox/src

License: MIT for original library code. Preserve dependency and asset license notices.
