Skip to content

Components / Sections

Booking Bar

The dates and the guests of a stay, handed to the place's own booking engine: a form that sends them to the engine's address as the parameters it reads (check-in, check-out, adults, children, and any fixed ones, such as the property's id), so a guest lands on the engine's page with the search filled in. Nothing is kept on the site: the engine holds the rooms, the prices and the payment. Without JavaScript it is a plain form that sends ISO dates. With it, the dates cannot start in the past, the check-out follows the check-in by the shortest stay, the nights are said as the dates change, and a date is rewritten for an engine that reads day first or month first.

Live demo

A demo: the search opens a page that is not there.

Live, from the library itself, at full size: scroll, hover, navigate away and back. The demo is never gated.

Measured

JavaScript of its own

934 B raw

575 B gzip.

Uses the shared runtime (1.9 kB raw, once per site). With those included: 2.6 kB raw.

CSS 5.6 kB raw including the base tokens. Measured from a production build, and again in CI for every change that can move it.

Browser support

Baseline · widely available

every browser. Elsewhere: nothing to fall back from.

Install Pro

The demo above is never gated; the source is. With a key in components.json (see account), the registry serves it like any other item:

terminal
npx shadcn@latest add @moonarc-pro/booking-bar
src/pages/index.astro
---
import BookingBar from '@/components/moonarc/pro/BookingBar.astro';
---
<BookingBar
  engine="https://book.example.com/sitename"
  fields={{ from: 'arrival', to: 'departure', adults: 'adults', children: 'kids' }}
  fixed={{ property: '1042', lang: 'en' }}
  minNights={2}
/>

Without a key the registry answers 401 with an upgrade message.

Props

PropTypeDefaultDescription
enginestringnoneThe booking engine's https address; the build stops on anything else.
fields{ from?; to?; adults?; children? }checkin, checkout, adults, childrenThe names the engine reads each value under.
fixedRecord<string, string>noneParameters sent as they are with every search.
format'iso' | 'dmy' | 'mdy''iso'How the engine reads a date; dmy and mdy are written by the script, so without it the engine gets ISO.
minNightsnumber1The shortest stay, in nights.
max{ adults?; children? }8 adults, 6 childrenThe most one search takes; 0 children removes the field.
newTabbooleanfalseOpen the engine in a new tab; the tab gets no handle back to this page (noopener).
words{ from?; to?; adults?; children?; submit?; nights?; night?; note? }noneThe labels, the button, the nights line ({n}) and a note under it.
labelstring'Check availability'The form's accessible name; a named form is a landmark, so two bars on one page take two names.

Theming and overrides

The section reads the theme contract (shadcn's variable names with the base tokens as fallback), so a pasted theme or one --ma-brand recolours it. Its class names are the override surface and stay stable; a named slot replaces the matching prop with your own markup.

Classes

.ma-book.ma-book__field.ma-book__input.ma-book__label.ma-book__note.ma-book__say.ma-book__submit

Slots

none

Reduced motion

Nothing in it moves; the button's hover fade is dropped.

With ClientRouter

Bound per form through the runtime; a fresh page binds again.

Why it is built this way

Replaces: Hotel booking widgets embedded as an iframe. See the migration table.

Contact · sample page

Write to the team.

Sample channels on the left. The form on the right is real and sends nothing here: fill it in and watch the button.

Email (sample)
hello@studio.example
Phone (sample)
+1 555 0100
Office (sample)
1 Sample Street, Springfield

Demo: nothing is sent.

A contact section in two columns: the ways to reach you (email, phone, office) on one side, a form that really sends on the other.

Chrome 135 · not Firefox · Safari 27click

A guesthouse by the sea, made up for this demo

A house by the sea, open all year

Seven rooms in an old captain's house, the beach six minutes down the lane. Sample prices.

rooms
7
to the beach
6 min
The place

The first screen of a place to stay: the headline and a line of what the place is, a few facts, and the place by day and by night in one frame: light falling over the day picture (LightRays), the windows lit in the night one, and a pair of radios under them that picks which shows, with no script.

every browserloadclick

The rooms of a place to stay as cards: each drawn by RoomArt on a colour block, with its name, how many it sleeps, its beds and its size, what it has (a terrace, a bath, a sea view), a sentence about it and its price from a night, the whole card a link to book it or to its page.

every browserscrollhover

Also: view transitions · how costs are measured · browser support · accessibility policy · five-minute setup · MCP for agents · this page as Markdown