Airbnb/Booking.com-style search bar with location autocomplete, date range picker, guest counter dropdown, and search CTA. Responsive — inline on desktop, stacked on mobile. The universal booking hero section.
A hotel-search hero built as a single card with four inline segments: a location field with a filterable destination dropdown, a date-range popover calendar, a guests popover that steps adults, children, and rooms with plus/minus buttons, and a search button, all above an optional heading, description, badge, and a row of popular-destination pills.
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/booking12?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://ui.beste.co/r-base/booking12?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/booking12.tsx, plus the badge, button, calendar, and popover shadcn/ui primitives it uses for the section eyebrow, the search and done buttons, the date-range picker, and the dates popover panel.
The installed file exports booking12Demo alongside the block: the exact props behind the preview above. Spread it to get a working search-bar hero in one line.
import { Booking12, booking12Demo } from "@/components/beste/block/booking12";
export default function Page() {
return <Booking12 {...booking12Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Booking12 } from "@/components/beste/block/booking12";
export default function Page() {
return (
<Booking12
badge={{ label: "Hotels", variant: "secondary" }}
heading="Find your <strong>next stay</strong>"
description="Search deals on hotels, apartments, and much more."
suggestions={[
{ name: "Paris", country: "France" },
{ name: "Tokyo", country: "Japan" },
{ name: "New York", country: "United States" },
]}
labels={{
whereLabel: "Where",
wherePlaceholder: "Search destinations",
datesLabel: "Check-in / Check-out",
datesPlaceholder: "Add dates",
guestsLabel: "Guests",
guestsSummaryTemplate: "{guests} guests · {rooms} {roomLabel}",
searchButton: "Search",
popularLabel: "Popular:",
}}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
badge | { label: string; variant?: "default" | "secondary" | "outline" } | – | Optional section eyebrow badge; variant defaults to "default" |
heading | string | – | Section heading, supports inline <strong> |
description | string | – | Subheading paragraph under the heading |
suggestions | LocationSuggestion[] | [] | Destinations for the location dropdown and popular pills |
labels | Booking12Labels | {} | All display strings for fields, guest rows, and buttons |
className | string | – | Extra classes for the outer <section> |
type LocationSuggestion = {
name: string;
country: string;
};
type Booking12Labels = {
whereLabel?: string;
wherePlaceholder?: string;
datesLabel?: string;
datesPlaceholder?: string;
guestsLabel?: string;
guestsSummaryTemplate?: string;
adultsLabel?: string;
adultsDescription?: string;
childrenLabel?: string;
childrenDescription?: string;
roomsLabel?: string;
doneButton?: string;
searchButton?: string;
popularLabel?: string;
};useState (location, dateRange, adults, children, rooms) and never surfaced through props; there is no onSearch or onChange callback, so handleSearch only calls console.log(...) with the current selection, leaving submission wiring to the integrator.heading is rendered via dangerouslySetInnerHTML, and its inline <strong> is styled bold and in the primary color through a [&>strong] selector.suggestions when the field is empty and case-insensitively name-filters them once the user types; the panel is hidden unless focused, and its blur handler waits 200ms before closing so a click can register.date < todayStart), and numberOfMonths switches between 1 and 2 based on a (min-width: 768px) media query set on mount.1 to 10, children 0 to 8, rooms 1 to 5; the summary line is derived from guestsSummaryTemplate by replacing {guests}, {rooms}, and {roomLabel} (which pluralizes to room/rooms).suggestions (suggestions.slice(0, 5)) and each pill just sets location; the eyebrow popularLabel is omitted when falsy.badge, heading, or description is provided, and on desktop the four segments split to fixed basis widths (32% / 32% / 24% plus the search button) with vertical dividers.Wiring the form up
This block ships the form markup only; state, validation, and submit are yours to add. Our guide wires the shadcn Field primitives to React Hook Form, TanStack Form, and Formisch on one field system.
booking14
Tours and experiences booking card with hero image overlay, rating, duration, difficulty badge, date picker, traveler counter, language selector, highlights list, and reserve CTA. Perfect for guided tours, classes, and local experiences.
booking7
Hotel room selection with room type cards showing images, amenity icons, guest capacity, price per night, check-in/check-out date picker, guest counter, and total price summary.
booking13
Booking.com-style social proof ticker with rotating messages: live viewers, recent bookings, scarcity alerts, and location-based activity. Animated transitions, urgency indicators, and trust signals that boost conversion.
booking6
Restaurant table reservation with guest count selector, date/time picker, seating preference (indoor/outdoor/bar), special requests textarea, and booking summary. Fine dining reservation flow.
booking8
Flight search results with airline logos, departure/arrival times, duration, stops, class selector (economy/business/first), baggage info, and price comparison. Airline ticket booking flow.
booking1
Split-panel booking interface with interactive monthly calendar on the left and time slot grid on the right. Features today highlight, disabled dates, selected state, morning/afternoon grouping, and booking summary footer.