Mischief

08 / Blocks

Image Gallery

A responsive image collection with equal and masonry layouts, plus a lightbox that handles focus, keyboard navigation, and scroll locking.

Live previewSource

From the archive

6

Installation

Copy the source into your project, or keep it behind a package.

Copy the component into your project and make it yours.

Usage

const images = [
  {
    id: "studio",
    src: "/photos/studio.jpg",
    alt: "Sunlight across the studio table",
    width: 1600,
    height: 1200,
    caption: "The studio",
  },
]

export function WorkGallery() {
  return <ImageGallery images={images} title="Recent work" />
}

API

imagesImageGalleryItem[]Image sources, alt text, captions, and optional downloads.
titleReactNodeThe heading above the collection.
layout"grid" | "masonry"The layout when controlled.
defaultLayout"grid" | "masonry"The initial uncontrolled layout.
onLayoutChange(layout) => voidRuns when the layout changes.
selectedIdstring | nullThe open image when controlled.
onSelectedIdChange(id) => voidRuns when the lightbox opens, moves, or closes.
showLayoutTogglebooleanShows or hides the layout control.
emptyStateReactNodeContent shown when the collection is empty.

Accessibility

Every thumbnail is a named button. Base UI supplies the modal dialog, focus trap, scroll lock, Escape handling, and focus restoration. Left and Right Arrow move between images. Captions, position, and close controls remain available without hover.

Dependencies

@base-ui/react, lucide-react, clsx, tailwind-merge