# Booking cards

> Stay, flight and restaurant booking cards — live price breakdowns with a counting total, a plane that flies a drawn route and time slots that update with party size.

- Collection: Examples
- Tier: pro
- Docs: https://geturui.com/docs/booking-cards
- Install: `npx shadcn@latest add @geturui-pro/booking-cards`
- Dependencies: motion, lucide-react

## Variants

### Stay

Drawn cover, check-in and checkout that follow a nights stepper, a breakdown that unlocks a weekly discount and a counting total.

Install: `npx shadcn@latest add @geturui-pro/booking-cards-stay`

```tsx
import { StayBookingCard } from "@/components/examples/booking-cards/stay";

export function Booking() {
  return <StayBookingCard checkIn="2026-10-16" nightly={148} currency="EUR" onReserve={(b) => checkout(b)} />;
}
```

| Prop | Type | Default | Description |
|---|---|---|---|
| name / place | `string` | — | Listing title and subtitle. |
| rating / reviews | `number` | — | Badge on the cover. |
| checkIn | `string` | "2026-10-16" | ISO date; checkout is derived from nights. |
| defaultNights / defaultGuests / maxGuests | `number` | 3 / 2 / 4 | Stepper values. |
| nightly / cleaningFee / serviceRate / weeklyDiscount | `number` | — | Pricing inputs. |
| currency | `string` | "EUR" | ISO currency code. |
| onReserve | `({ nights, guests, total }) => void` | — | Reserve handler. |

### Flight

Flight option with an on-time status, a plane that flies the drawn route on mount and fare tabs that crossfade perks and count the price.

Install: `npx shadcn@latest add @geturui-pro/booking-cards-flight`

```tsx
import { FlightCard } from "@/components/examples/booking-cards/flight";

export function Option() {
  return <FlightCard from={{ code: "SFO", city: "San Francisco", time: "18:40" }} to={{ code: "LIS", city: "Lisbon", time: "14:45" }} onSelect={choose} />;
}
```

| Prop | Type | Default | Description |
|---|---|---|---|
| airline / flight / date | `string` | — | Header details. |
| from / to | `{ code; city; time }` | — | Route ends. |
| duration / stops | `string` | — | Shown under the route. |
| fares | `{ id; label; price; perks }[]` | — | Fare tabs. |
| defaultFare | `string` | "premium" | Initially selected fare. |
| onSelect | `(fareId: string) => void` | — | Select handler. |

### Restaurant

Party stepper, day chips and a time-slot grid whose availability updates live, ending in a confirmation with a booking code.

Install: `npx shadcn@latest add @geturui-pro/booking-cards-restaurant`

```tsx
import { RestaurantReservation } from "@/components/examples/booking-cards/restaurant";

export function Reserve() {
  return <RestaurantReservation name="Osteria Lumen" isAvailable={(day, slot, party) => availability[day][slot] >= party} onReserve={book} />;
}
```

| Prop | Type | Default | Description |
|---|---|---|---|
| name / meta / rating | `string / number` | — | Restaurant header. |
| days | `{ id; weekday; date }[]` | — | Selectable days. |
| slots | `string[]` | — | 24h times, e.g. "19:30". |
| isAvailable | `(day, slot, party) => boolean` | — | Availability; defaults to a fixed pattern. |
| defaultParty / maxParty / defaultSlot | `number / string` | 4 / 8 / "19:30" | Initial state. |
| onReserve | `({ day, slot, party }) => void` | — | Reserve handler. |

## Accessibility

- Steppers are labelled button pairs with a polite live value; days, fares and slots are radiogroups.
- Fully booked slots are disabled and say so in their accessible name, not only with a strike-through.
- Totals keep a static screen-reader value while the visible number counts; reduced motion parks the plane mid-route.

## Source

Pro item — send `Authorization: Bearer <registry token>` to include the source.
