Gallery
Six of the twelve, photographed in the light they get at the hour we like them best.
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.
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/hotel39?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
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.
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.
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:
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" }}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
eyebrow | string | – | Small uppercase line above the heading |
heading | string | – | Serif <h2>, revealed word by word through Text1 |
description | string | – | Paragraph to the right of the heading |
photos | Photo[] | [] | Gallery photographs; the grid shows the first six |
labels | Labels | {} | Accessible names for the lightbox controls and the word in the counter |
className | string | – | Extra classes for the outer <section> |
type Photo = {
src: string;
alt: string;
caption: string;
};
type Labels = {
open?: string;
close?: string;
previous?: string;
next?: string;
of?: string;
};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.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.md, where swipe and the filmstrip take over. The counter reads like 3 of 6, using labels.of.photos array, so photos past the sixth are reachable there even though the grid does not show them.