Media Gallery

A grid that opens into a lightbox. `alt` is required by the type rather than optional, because a gallery is exactly where missing alt text accumulates.

src/components/ui/media-gallery.tsx

About

From the component's own source, where it was written.

A thumbnail grid with a lightbox.

The lightbox traps focus and restores it to the thumbnail that opened it. Returning focus to the top of the document is the standard failure and it loses a keyboard user's place in a grid of fifty images.

Arrow keys move between items while open, and Escape closes. These are the bindings people try first; a lightbox that only responds to on-screen arrows is one they will call broken.

Every item needs alt. It is a required field rather than an optional one, because a gallery is exactly where empty alt text accumulates.

Install

npx astralyx-ui add media-gallery

Usage

import { MediaGallery } from '@/components/ui/media-gallery'

<MediaGallery items={items} columns={3} />

Composer

Change the props and the source below follows.

Props
tsx
<MediaGallery items={items} columns={3} />

API

Generated from the source, so it cannot fall behind the code. One table per exported component, then hooks, functions and types.

MediaGallery

Extends Omit<ComponentProps<'div'>, 'children'>.

PropTypeDefaultDescription
itemsMediaItem[]required{ id, src, alt, thumbnail?, caption? }. alt is not optional.
columns2 | 3 | 4 | 53The count at full width; the grid steps down on narrow screens on its own.
rationumber1Tile aspect ratio. Tiles are uniform so the grid stays a grid; the full image is shown uncropped in the lightbox.
closeLabelstring'Close'Accessible names for the lightbox controls.
previousLabelstring'Previous'—
nextLabelstring'Next'—
emptyLabelReactNode'Nothing to show'—

Types

MediaItem

A thumbnail grid with a lightbox.

FieldTypeDescription
idstring—
srcstring—
altstringRequired — a gallery is where missing alt text accumulates.
thumbnail?string—
caption?ReactNode—

Behaviour

TopicDetailDescription
lightboxnative dialogOpens in a <dialog> with showModal(), which gives focus trapping, Escape and inertness for free rather than reimplemented.
navigationarrows, EscapeArrow keys move between images while the lightbox is open, and focus returns to the tile you opened.