A walk through
Scroll the strip or use the arrows. The warehouse homes come first, then the courtyard wing and the terrace at the top.
A horizontal filmstrip for a development's photographs: 4:3 and 3:4 frames of one shared height with a title and caption under each, scroll-snapping as you drag or swipe, previous and next pills that move the strip by exactly one frame, and a hairline under the strip whose filled share follows the scroll position through a spring.
A horizontal filmstrip for a development's sales page: a rule eyebrow, a heading and an intro, then a single scrollable row of 4:3 and 3:4 photographs cut to one shared height, each with a title and a caption under it. The strip snaps frame by frame as you drag, swipe or use the previous and next pills, and a hairline under it fills from the left in step with how far you have scrolled. Each frame opens from the top once its file has loaded and drifts slowly against the page scroll.
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://beste.dev/r/realestate62?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://beste.dev/r-base/realestate62?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/realestate62.tsx plus the badge24 rule eyebrow, the button25 quiet pill used for the previous and next controls, and the shadcn/ui button primitive behind them.
The installed file exports realestate62Demo alongside the block: the exact props behind the preview above. Spread it to get a working section in one line.
import { Realestate62, realestate62Demo } from "@/components/beste/block/realestate62";
export default function Page() {
return <Realestate62 {...realestate62Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Realestate62 } from "@/components/beste/block/realestate62";
export default function Page() {
return (
<Realestate62
eyebrow="A walk through"
heading="From the lobby to the roof."
description="Scroll the strip or use the arrows."
stills={[
{
src: "https://oud.pics/b/realestate/alder-lobby-stair.webp",
alt: "An entrance lobby with a cast iron column, an oak stair and an arched window",
ratio: "3:4",
title: "The lobby",
caption: "Cast iron, oak and the first arched window",
},
{
src: "https://oud.pics/b/realestate/alder-warehouse-living.webp",
alt: "A double-height living room with a brick wall and a tall oak window",
ratio: "4:3",
title: "A warehouse living room",
caption: "Double height, with the river wall of windows",
},
{
src: "https://oud.pics/b/realestate/alder-roof-terrace.webp",
alt: "A penthouse roof terrace with oak chairs and a view over the river",
ratio: "4:3",
title: "The roof terrace",
caption: "Sixty-two square metres above the river",
},
]}
labels={{ previous: "Previous", next: "Next", strip: "Photographs of Alder Row" }}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
eyebrow | string | – | Short line above the heading, rendered through badge24. |
heading | string | – | Section heading. |
description | string | – | Intro paragraph beside the heading, bottom-aligned on desktop. |
stills | Still[] | [] | The frames in the strip, in order; ratio picks the frame width so 4:3 and 3:4 photographs share one height. |
labels | Labels | {} | Labels for the previous and next pills and the accessible name of the strip. |
className | string | – | Extra classes merged onto the section. |
type Ratio = "4:3" | "3:4";
type Still = {
src: string;
alt: string;
ratio: Ratio;
title: string;
caption: string;
};
type Labels = {
previous?: string;
next?: string;
strip?: string;
};scroll-snap-type: x mandatory; every frame is a snap-start item and the scroll padding matches the page gutter, so a frame always comes to rest on the left edge of the content column. The scrollbar is hidden in every browser.scrollLeft and scroll to the first frame whose left edge lies beyond it (or before it), one frame per click, with smooth scrolling unless the reader prefers reduced motion; the pill at either end dims and stops taking clicks once the strip is fully scrolled that way.scroll event (scrollLeft over the scrollable distance) and smoothed through a spring (stiffness 90, damping 22); it is recomputed on resize and when the number of frames changes.md) and 3:4 frames 162 px (324 px from md), which gives both a height of 216 px (432 px from md) so the row reads as one line of photographs.load event and on being in view, opens with a top-to-bottom clip over 1.6 s while the image settles from 1.18 to 1.12 scale, and drifts from -6% to 6% against the page scroll; the title and caption under it rise 0.2 s later, and the hairline and pills come last.