Works hung two to a bay on staggered ruled cards, opening a viewer that can hold a second work beside the first: the frame splits, both pictures keep their own caption and the pair can be walked together.
Works hung two to a bay, each on its own rule with alternate columns dropped down the wall. The viewer can hold two at once: the next work slides in beside the open one and the pair share a caption row.
Upgrade to Pro
Pro blocks install through the shadcn CLI with your license key and ship their full source. Docs and live previews stay open to everyone, so you can read every block's details first.
Swap YOUR_EMAIL and YOUR_KEY for the email and license key on your account. Find your license key on your account page.
Radix flavor
npx shadcn add "https://ui.beste.co/r/gallery20?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://ui.beste.co/r-base/gallery20?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/gallery20.tsx plus the badge7 eyebrow it uses.
The installed file exports gallery20Demo alongside the block: the exact props behind the preview above. Spread it to get a working gallery in one line.
import { Gallery20, gallery20Demo } from "@/components/beste/block/gallery20";
export default function Page() {
return <Gallery20 {...gallery20Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Gallery20 } from "@/components/beste/block/gallery20";
export default function Page() {
return (
<Gallery20
badge={{ label: "Hung in pairs" }}
heading="Works that were made to be argued with each other."
description="Open any frame, then hold the next one beside it."
works={[
{
src: "/pairs/alphabet.jpg",
alt: "Letterpress work",
title: "Alphabet for a Quiet Room",
artist: "Hélène Marchal",
year: "2025",
medium: "Letterpress on rag paper",
},
{
src: "/pairs/sheets.jpg",
alt: "Specimen sheets",
title: "Sheets, Before Binding",
artist: "Hélène Marchal",
year: "2025",
medium: "Ink on uncoated stock",
},
]}
labels={{
openLabel: "Open this work",
closeLabel: "Close the pair",
previousLabel: "Previous work",
nextLabel: "Next work",
compareLabel: "Hold the next work beside it",
compareTitle: "Held beside",
counterSeparator: "of",
}}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
badge | { label: string } | – | Eyebrow label rendered as a Badge7 |
heading | string | – | Section heading in the left header column |
description | string | – | Supporting paragraph in the right header column |
works | Work[] | [] | Works on the wall, in hanging order |
labels | Gallery20Labels | {} | Fixed strings that are not content: viewer controls, the compare labels and the counter separator |
lightbox | boolean | true | Render the built-in viewer; set false to leave the frames static |
className | string | – | Extra classes for the outer <section> |
type Work = {
src: string;
alt: string;
title: string;
artist: string;
year: string;
medium: string;
};
type Gallery20Labels = {
openLabel?: string;
closeLabel?: string;
previousLabel?: string;
nextLabel?: string;
compareLabel?: string;
compareTitle?: string;
counterSeparator?: string;
};md:border-l md:pl-8 and titled with its own label, so the pair never reads as one long credit.border-t rule and alternate columns are dropped by md:mt-12, which is what gives the hang its two-height rhythm.flex-wrap items-baseline justify-between, so the title and the credit share a baseline and wrap cleanly rather than colliding.lightbox={false} disables every frame button and switches the cursor back to default, leaving the paired hang as a static wall.gallery7
Two full-bleed image tracks scrolling in opposite directions under a centered statement, pausing together on hover, where any frame opens a framed viewer: the picture sits in a mount on a scrim with its caption, position and controls beneath it.
gallery12
Works of different sizes hung on one centre line inside a matted wall panel, each with its own label, opening a viewer that shows the piece in a mount beside a museum wall label of medium, dimensions and year.
gallery13
Printed-catalogue layout pairing a numbered index of works with a sticky matted plate and its note, where an expand seal opens the plate alone on a dark ground with only its number and the arrows.
gallery22
Text-first archive index of reference, thumbnail, title and year, opening a record card with two sides: the work on the front and the registrar's acquisition, condition and storage notes on the back.