A horizontal, snap-scrolling strip of photographs that starts in line with the heading and runs off the right edge, each frame carrying a serif subject and a small-caps place and month; steered by round arrow buttons, and any frame opens a filmstrip lightbox on ink with film grain, a counter, arrow and keyboard navigation and a thumbnail rail along the foot.
A horizontal filmstrip that starts flush with the heading and runs off the right edge, with arrow controls, snap scrolling, and a full-screen lightbox carrying its own thumbnails, counter and keyboard controls.
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/gallery27?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://ui.beste.co/r-base/gallery27?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/gallery27.tsx plus the button22 sliding-marker pill and the text1 word stagger it uses.
The installed file exports gallery27Demo alongside the block: the exact props behind the preview above. Spread it to get a working gallery in one line.
import { Gallery27, gallery27Demo } from "@/components/beste/block/gallery27";
export default function Page() {
return <Gallery27 {...gallery27Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Gallery27 } from "@/components/beste/block/gallery27";
export default function Page() {
return (
<Gallery27
eyebrow="The walk"
heading="Fridays along the river, in six frames."
button={{ label: "Join a walking session", href: "/walking", tone: "outline" }}
frames={[
{
src: "/photos/mist.jpg",
alt: "Morning mist lifting off a still lake",
subject: "Mist on the water",
where: "Tagus estuary, March",
},
]}
labels={{ previous: "Previous frame", next: "Next frame", close: "Close", open: "Open frame" }}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
eyebrow | string | – | Small-caps line above the heading |
heading | string | – | Section heading, rendered as an h2 through Text1 |
button | ActionButton | – | Pill action beside the arrows, hidden below md |
frames | Frame[] | [] | The photographs, in the order given |
labels | Gallery27Labels | {} | Accessible names for the controls |
className | string | – | Extra classes for the outer <section> |
type Frame = {
src: string;
alt: string;
subject: string;
where: string;
};
type Gallery27Labels = {
previous?: string;
next?: string;
close?: string;
open?: string;
};
type ActionButton = {
label: string;
href: string;
tone?: "primary" | "light" | "dark" | "outline";
};scrollPaddingLeft is set to the same measurement, so a snapped frame lands on that line rather than against the viewport edge.70% of the visible width rather than by one card, which keeps a partial frame on screen as a hint that the strip continues; the scroll respects reduced motion by falling back to behavior: "auto".role="dialog" with aria-modal, Escape to close, arrow keys to step, and document.body.style.overflow locked while it is open and restored on unmount.(value + direction + frames.length) % frames.length, so the arrows cycle rather than dead-ending at either end.stopPropagation, so clicking a thumbnail changes the frame instead of dismissing the whole thing.aria-pressed and an empty alt, since the full-size image beside them already carries the description; the counter is set in tabular-nums so it does not jitter while stepping.0px -10% 0px 0px), which is the horizontal equivalent of the vertical margins used elsewhere in the set.gallery4
Single-frame image reel that slides on a transform, driven by round arrow buttons in the header and a row of bar indicators beside the caption, with no hover behaviour on the image itself.
gallery11
Edge-to-edge strip of tall frames opening a viewer where the picture fills the screen and the caption, note and thumbnails sit in a sheet that slides off the bottom when you want the frame uncovered.
gallery5
Cinematic stage frame with the caption and frame counter set on a gradient at its foot, round arrow controls on the picture itself, and a scrolling filmstrip below where the inactive thumbnails sit back at low opacity.
gallery29
An even three-column grid of photographic plates that open into an ink lightbox: every frame keeps the same ratio so the captions line up, arrows and keys turn the page, either half of the plate is clickable, and a plate that belongs to a page offers it as a link.