Rooms Gallery with Filmstrip Lightbox

Gallery

Therooms,beforeyouunpack.

Six of the twelve, photographed in the light they get at the hour we like them best.

About this block

Rooms Gallery with Filmstrip LightboxPRO

A six-photo rooms gallery on an editorial grid of one large and five smaller frames that lean in and reveal a caption on hover; any photo opens a full-screen ink lightbox with a counter, sliding transitions, arrow keys, swipe, a serif caption and a thumbnail filmstrip.

Six room photographs rise into an editorial grid of one large frame and five smaller ones that zoom slightly and slide up a caption on hover, and any of them opens a full-screen dark lightbox with a counter, sliding transitions, arrow keys, swipe, a serif caption and a thumbnail filmstrip.

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/hotel39?email=YOUR_EMAIL&license_key=YOUR_KEY"

Base UI flavor

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

This installs the block to components/beste/block/hotel39.tsx plus the text1 word stagger used for the heading.

Quick start

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

tsx
import { Hotel39, hotel39Demo } from "@/components/beste/block/hotel39";

export default function Page() {
  return <Hotel39 {...hotel39Demo} />;
}

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

tsx
import { Hotel39 } from "@/components/beste/block/hotel39";

export default function Page() {
  return (
    <Hotel39
      eyebrow="Gallery"
      heading="The rooms, before you unpack."
      description="Six of the twelve rooms on Paros, in the light we like them best."
      photos={[
        { src: "https://oud.pics/b/hotel/ostria-sea-suite.webp", alt: "A linen bed facing an arched window onto the sea", caption: "Sea Suite, eight in the morning" },
        { src: "https://oud.pics/b/hotel/ostria-garden-room.webp", alt: "A bedroom opening onto a garden terrace", caption: "Garden Room, doors open to the olive" },
        { src: "https://oud.pics/b/hotel/ostria-stone-room.webp", alt: "A plaster bed under a whitewashed stone vault", caption: "Vaulted Room, cool at noon" },
        { src: "https://oud.pics/b/hotel/ostria-bedside-niche.webp", alt: "A plaster bedside niche with a brass lamp", caption: "A niche beside every pillow" },
        { src: "https://oud.pics/b/hotel/ostria-stone-bath.webp", alt: "A bathtub carved from pale stone", caption: "The stone bath in room nine" },
        { src: "https://oud.pics/b/hotel/ostria-rooftop-suite.webp", alt: "A rooftop plunge pool facing the sunset", caption: "Rooftop Suite, just before dinner" },
      ]}
      labels={{ open: "Open photo", close: "Close", previous: "Previous photo", next: "Next photo", of: "of" }}
    />
  );
}

Props

PropTypeDefaultDescription
eyebrowstring–Small uppercase line above the heading
headingstring–Serif <h2>, revealed word by word through Text1
descriptionstring–Paragraph to the right of the heading
photosPhoto[][]Gallery photographs; the grid shows the first six
labelsLabels{}Accessible names for the lightbox controls and the word in the counter
classNamestring–Extra classes for the outer <section>
ts
type Photo = {
  src: string;
  alt: string;
  caption: string;
};

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

Behavior notes

  • Grid slots are fixed by position: from md the first photo spans four of six columns and two rows, and the other five are squares; on a phone the first and last are full width at 4:3 and the middle four pair up two by two.
  • Frames rise in once with a 0.08 second stagger, and each photo stays blurred until its file has loaded. Hover zooms the photo to 105% and slides up its caption over a dark gradient.
  • Clicking a frame opens a role="dialog" lightbox and locks the page scroll. Esc closes it, the left and right arrow keys step through the photos, and stepping wraps at both ends.
  • Photos slide 80px in the direction of travel. Dragging the photo more than 80px left or right moves to the next or previous one.
  • The round previous and next buttons are hidden below md, where swipe and the filmstrip take over. The counter reads like 3 of 6, using labels.of.
  • The lightbox and its filmstrip use the whole photos array, so photos past the sixth are reachable there even though the grid does not show them.
  • With reduced motion the entrances and load blur are skipped, lightbox photos only crossfade, and dragging is turned off.

More Hotel blocks

View all Hotel
PRO

hotel40

Kitchen Gallery with Story Lightbox

PRO

hotel41

Outdoors Gallery with Morph Lightbox

PRO

hotel3

Room Collection List

Get Pro