Avara UI

Booking Card

A booking panel that goes inside any card: a strip of days paged a week at a time, time slots in groups, a button that reads the choice back before anyone confirms, and a confirmation that draws itself in over the form once the booking is made.
BookingCard is a compound component. It holds the chosen day and slot; BookingCard.Days, BookingCard.Slots, BookingCard.Submit and BookingCard.Confirmation go inside it in whatever layout the panel needs. It draws no surface of its own, so it sits as comfortably in a plain bordered card as in a glass slab from Glass Panel — the Book Appointment section is the same card on a full page.

In a card

Pick a day and a time, press Book — the button stays busy while your onBook promise runs, then the check draws itself and the details rise in.

BookingCard
holds the chosen day and slot. Put BookingCard.Days, BookingCard.Slots, BookingCard.Submit and BookingCard.Confirmation inside it in any layout; the confirmation covers the BookingCard it sits in — so give the BookingCard the panel's padding (heading included) and the cover reaches the panel's edges and corners.
Return a promise fromonBook
and the button stays busy until it settles — resolve to show the confirmation, throw to drop back to the form.
unavailable(day) => day.getDay() === 0
on BookingCard.Days strikes out days with nothing free. Sundays here; feed it your real availability.
The Book button, the check and every focus ring take--primary
so the card follows your theme — pick a colour above to see it. Selected days and slots stay a neutral ink that reads on glass or solid.
The arrows pageBookingCard.Days
a week at a time, up to horizon days out (90 by default). Days start today, so the previous arrow is disabled on the first page — nobody can book into the past.

Installation

New project? Follow the installation guide to set up Tailwind CSS, shadcn, the cn helper and lucide-react, register the @algorize-ui registry once, then copy your styles from the Themes page.

Install Booking Card

npx shadcn@latest add @algorize-ui/booking-card

components/custom/blocks/BookingCardBlock.tsx is written into your project. Copy any snippet from a Usage tab above and it runs.

Install dependencies

Step 1 installs this for you. Run it yourself only if you are adding Booking Card to an existing project by hand. The cn helper and lucide-react are not listed — the installation guide covers them once for every component.

glass-panel is a component, not a package — the shadcn CLI installs it as source files.

npx shadcn@latest add @algorize-ui/glass-panel

Examples

In a glass slab

The same card inside a GlassPanel from Glass Panel. Nothing inside the card changes — it is surface-neutral by design.

Wrap it in aGlassPanel
and the card takes the panel's corners: its root is rounded-[inherit], so the confirmation's cover matches whatever shape it sits in.

Liquid glass

The booking card rendered inside a liquid-glass refraction surface.

Set variant toliquid-glass
on GlassBackdrop to render realistic SVG fluid refraction with pure white glass elements.
Choosing a new day clears the slot, since availability changes with the day. The submit button is disabled until both are chosen, and once they are it reads the choice back — Book now, Wed 25 at 9:00 AM — so nobody confirms blind.

Features

One state, any layout

Days, slots and the button share one context. Stack them, put them side by side, split them across panels — the card does not care.

A confirmation that shows what happened

When onBook resolves, a check draws itself over the form and the day, time and place rise in beneath it. Book another clears it. It holds still under prefers-reduced-motion.

Keyboard and screen reader ready

Days and slots are radio groups with full date names; taken slots and closed days are disabled, not hidden; the busy button carries aria-busy and the confirmation is a status region.

Honest about today

The default days are built on the client, so a server render never guesses the visitor's date. They start today and page forward a week at a time — the previous arrow never reaches into the past. Pass your own days array to offer a different range.

Props Reference

BookingCard

PropTypeDefaultDescription
onBook(booking: { day: Date; slot: string }) => void | Promise<void>—Called on confirm. Return a promise to hold the busy state; a rejection returns to the form.
classNamestring—Layout of the parts inside. The confirmation is positioned against this element.

BookingCard.Days

PropTypeDefaultDescription
daysDate[]today → horizonDays on offer, in order, paged count at a time with the previous/next arrows. The default is built on the client so the server never guesses today, and it starts today — there is no paging back into the past.
countnumber7Days shown per page.
horizonnumber90How far ahead the default days run, in days from today. Ignored when days is given.
unavailable(day: Date) => boolean—Days with nothing free — shown struck through, not selectable.

BookingCard.Slots

PropTypeDefaultDescription
labelstring—Group title, e.g. "Morning".
slots{ label: string; taken?: boolean }[]—Times in the group. Disabled until a day is chosen; taken slots are shown struck through.

BookingCard.Submit

PropTypeDefaultDescription
childrenReactNode"Book now"Button text. Once a day and slot are chosen it reads back the choice, e.g. Book now, Wed 25 at 9:00 AM.

BookingCard.Confirmation

PropTypeDefaultDescription
withNamestring—Who the appointment is with.
placestring—Where, appended after the name.