Gallery

Render a responsive grid of images that opens a full-screen, swipeable lightbox.

Gallery is a client component that lays images out in a Collection grid and opens a Headless UI dialog with a carousel when an image is clicked. Use it for photo sets and screenshots. It depends on next/image, next/navigation, @headlessui/react, react-swipeable, and motion, so it must run inside a Next.js App Router app wrapped in DesignSystemProvider.

image
image
image
image

Import#

typescript
import { Gallery } from "@reactberry/system/blocks";

Usage#

typescript
import { Gallery } from "@reactberry/system/blocks";
import { Box } from "@reactberry/system/elements";

const images = [
  { id: 1, url: "/photos/harbour.jpg" },
  { id: 2, url: "/photos/forest.jpg" },
  { id: 3, url: "/photos/city.jpg" },
];

export default function PhotosPage() {
  return (
    <Box p="l">
      <Gallery images={images} />
    </Box>
  );
}

Examples#

With a heading#

Gallery renders only the grid, so add a title or caption around it yourself.

Release screenshots

2 images attached to v2.1.0

image
image

API#

PropTypeDefaultDescription
images*
ImageType[]
—

Images to display. Each item is { id: number; url: string }.

No other props are accepted and nothing is spread. ImageType is exported from the package root:

typescript
import type { ImageType } from "@reactberry/system";

Keyboard#

KeyAction
ArrowRight

Shows the next image in the open lightbox. Stops at the last image.

ArrowLeft

Shows the previous image in the open lightbox. Stops at the first image.

Escape

Closes the lightbox.

Accessibility#

  • All grid images use the fixed alt="image", the lightbox image uses alt="Image", and thumbnails use alt="small photos on the bottom"; there is no way to provide per-image alternative text.
  • Grid tiles, arrow controls, thumbnails and the download control are clickable div elements without a button role or keyboard focus. The "Open fullsize version" control is an a element.
  • The lightbox is a Headless UI Dialog.

Notes#

  • The grid uses Collection with colsize="medium". Each tile is a 3 / 2 rounded box that scales to 1.04 on hover and renders a next/image with fill and objectFit: "cover".
  • Clicking a tile opens the lightbox at that image.
  • The lightbox shows the selected image with objectFit: "contain", previous and next arrow controls, a strip of thumbnails along the bottom of the viewport, an "Open fullsize version" link (opens url in a new tab), and a "Download fullsize version" control.
  • Navigation in the lightbox also works by clicking the arrows or thumbnails, or by swiping or mouse-dragging horizontally. It stops at the first and last image (no wraparound).
  • The download control fetches url with mode: "cors" and saves it as <index>.jpg, so cross-origin images need permissive CORS headers.
  • Clicking the blurred backdrop also closes the lightbox.
  • Because tiles use next/image, remote URLs must be allowed in images.remotePatterns in next.config.
  • The lightbox header renders the literal text "Title"; it is not derived from the image data.
  • Hover and slide animations use motion and do not check for reduced-motion preferences.