Single Testimonial With Photo

The main bedroom of a warehouse home, an oak bed against the brick wall and birch branches in the window

What living here is like

The bedroom faces the birches, so the light in the morning is green and moving. I have not set an alarm since we moved in.

Joni MitchellType B, two bedroom with study
1 of 3
About this block

Single Testimonial With PhotoPRO

One large buyer quote beside a 4:3 photograph that opens from the top once it has loaded and drifts gently against the scroll, with the buyer's name and the home they bought on a hairline row and a counter with previous and next buttons that cycle through the quotes with a cross-fade.

Realestate50: Single Testimonial With Photo

One large buyer quote beside a 4:3 photograph for a development's sales page. The photograph opens from the top once it has loaded and drifts gently against the scroll; the quote sits large on the right with the buyer's name and the home they bought on a hairline row beneath it, and a counter with previous and next buttons cycles through the quotes with a short cross-fade.

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.

Upgrade Now

Installation

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

bash
npx shadcn add "https://beste.dev/r/realestate50?email=YOUR_EMAIL&license_key=YOUR_KEY"

Base UI flavor

bash
npx shadcn add "https://beste.dev/r-base/realestate50?email=YOUR_EMAIL&license_key=YOUR_KEY"

This installs the block to components/beste/block/realestate50.tsx plus the badge24 eyebrow above the quote; the previous and next controls are plain buttons, so no shadcn/ui primitives are needed.

Quick start

The installed file exports realestate50Demo alongside the block: the exact props behind the preview above. Spread it to get a working section in one line.

tsx
import { Realestate50, realestate50Demo } from "@/components/beste/block/realestate50";

export default function Page() {
  return <Realestate50 {...realestate50Demo} />;
}

Then replace the demo with your own props. Written out, a trimmed setup looks like this:

tsx
import { Realestate50 } from "@/components/beste/block/realestate50";

export default function Page() {
  return (
    <Realestate50
      eyebrow="What living here is like"
      image={{
        src: "https://oud.pics/b/realestate/alder-warehouse-bedroom.webp",
        alt: "The main bedroom of a warehouse home, an oak bed against the brick wall",
      }}
      quotes={[
        {
          quote: "The bedroom faces the birches, so the light in the morning is green and moving.",
          name: "Joni Mitchell",
          detail: "Type B, two bedroom with study",
        },
        {
          quote: "The children are at St Olave's in 8 minutes and I am at the station in 6.",
          name: "Bill Evans",
          detail: "Type D, four bedroom",
        },
      ]}
      labels={{ previous: "Previous quote", next: "Next quote", of: "of" }}
    />
  );
}

Props

PropTypeDefaultDescription
eyebrowstring–Short line above the quote, drawn with a rule in front of it.
image{ src: string; alt: string }–The 4:3 photograph beside the quote; without it the text spans eight columns.
quotesQuote[][]The testimonials to cycle through; the first one shows on load.
labelsLabels{}Accessible names for the two arrow buttons and the word between the counter's numbers.
classNamestring–Extra classes merged onto the section.
ts
type Quote = {
  quote: string;
  name: string;
  detail: string;
};

type Labels = {
  previous?: string;
  next?: string;
  of?: string;
};

Behavior notes

  • The photograph is gated on its own load event and on entering the viewport: only then does the frame open from the top over 1.6 seconds while the image settles from a 1.18 to a 1.12 scale, and a scroll-linked transform moves it from -6% to 6% as the section passes.
  • The quote, the attribution and the controls enter once in view at 0.1, 0.3 and 0.4 seconds, with the hairline above the attribution scaling in from the left at 0.25 seconds.
  • Previous and next wrap around the list in both directions. Each change swaps the quote and the attribution through AnimatePresence in wait mode: the old text fades out in 0.2 seconds and the new one rises in over 0.6 seconds.
  • The counter reads the current position as 1 of 3 using labels.of and is marked aria-live="polite", so screen readers hear the change; the controls only render when there is more than one quote.
  • With prefers-reduced-motion the frame and text render in place, the parallax is held at its start value and quote changes swap without an entrance.

More Real Estate blocks

View all Real Estate
PRO

realestate49

Buyer Quotes List

PRO

realestate41

Two Column Buyer FAQ

PRO

realestate80

Partner Agents Side by Side

Get Pro