Skip to content
Template Empire
Browse components

Booking Split

A free react booking section with local availability, native form fallbacks, and polished day and time selection.

Book a conversation

Make room for the work that matters.

Choose a quiet half hour with our product team and leave with a clear next step.

Pick a date, choose an available time, then confirm.

Prefer email? Write to the studio

Availability

Choose a time

Europe/London · BST

Customise

0.56
18px
0.035s
20px

Code

<ContactBookingSplit
  title="Make room for the work that matters."
  timezone="Europe/London · BST"
  days={bookingDays}
  onBook={(selection) => handleBooking(selection)}
/>

Booking Split is a free contact section for Next.js and React that presents local dates and time slots in a focused booking flow styled with Tailwind.

It renders a complete native form before JavaScript, then enhances desktop layouts with accessible manual tabs, controlled or uncontrolled selection, and Motion transitions that respect reduced-motion preferences.

Install

Add the @te registry to your components.json once:

{
  "registries": {
    "@te": "https://templateempire.io/r/{name}.json"
  }
}

Then install the component:

npx shadcn@latest add @te/contact-booking-split

Usage

import { ContactBookingSplit } from "@/components/contact-booking-split";

const days = [
  {
    id: "tue-29",
    label: "Tue 29",
    dateTime: "2026-09-29",
    slots: [
      {
        id: "tue-0930",
        label: "09:30",
        value: "2026-09-29T09:30:00+01:00",
      },
      {
        id: "tue-1100",
        label: "11:00",
        value: "2026-09-29T11:00:00+01:00",
        available: false,
      },
    ],
  },
  {
    id: "wed-30",
    label: "Wed 30",
    dateTime: "2026-09-30",
    slots: [
      {
        id: "wed-1000",
        label: "10:00",
        value: "2026-09-30T10:00:00+01:00",
      },
    ],
  },
];

export default function Page() {
  return (
    <ContactBookingSplit
      title="Choose a time to talk."
      timezone="Europe/London"
      days={days}
      onBook={(selection) => {
        console.log(selection);
      }}
    />
  );
}

Props

PropTypeDefaultDescription
eyebrowstring"Book a conversation"Introductory label above the section heading.
titlestringrequiredSection heading rendered as an h2.
descriptionstringundefinedSupporting copy beneath the title.
timezonestringrequiredVisible IANA or display timezone label supplied by the consumer.
days{ id; label; dateTime; slots[] }[]requiredTwo to seven stable-ID days with local slot labels, values, and optional availability.
activeDayIdstringundefinedControlled active day ID.
defaultActiveDayIdstringfirst available dayInitial active day in uncontrolled usage.
selectedSlotIdstringundefinedControlled selected slot ID.
defaultSelectedSlotIdstringundefinedInitial selected slot ID in uncontrolled usage.
onDayChange(dayId: string) => voidundefinedCalled after a valid day is selected.
onSlotChange(slotId: string) => voidundefinedCalled after an available time is selected.
onBook(selection) => voidrequiredConsumer-owned booking action receiving dayId, slotId, and value.
alternative{ label: string; href: string }undefinedOptional real-link alternative to the booking flow.
panelSide"left" | "right""right"Desktop scheduler placement.
panelRationumber0.56Desktop scheduler width fraction, clamped from 0.46 to 0.66.
panelOffsetnumber18Day-panel transition distance in pixels, clamped from 0 to 32.
slotStaggernumber0.035Available-slot stagger in seconds, clamped from 0 to 0.08.
radiusnumber20Scheduler radius in pixels, clamped from 8 to 32.
classNamestringundefinedAdditional classes merged onto the section root.

Customisation

Booking Split exposes four Tier 3 colour tokens for its scheduler surface, frame, active indicators, and selected slot. Geometry and motion remain available through the effect props:

.booking-section {
  --booking-surface: var(--background);
  --booking-frame: var(--ring);
  --booking-accent: var(--primary);
  --booking-selection: var(--ring);
}

Frequently asked questions

Is Booking Split free for commercial use?
Yes. Booking Split is MIT licensed, so you can use it in personal and commercial projects without attribution.
Does Booking Split work without JavaScript?
Yes. Server output contains every date and slot in native fieldsets with one radio group and a submit button. On desktop, JavaScript progressively adds manual tabs and Motion transitions. Reduced-motion users get synchronous selection with no translation or stagger.
Can I connect Booking Split to my own scheduling system?
Yes. Supply local availability through days and handle the selected day, slot, and value in onBook. The component does not fetch availability, convert timezones, or create meetings, so the consumer keeps control of those integrations.

Related components

Want the full page this belongs to?Template Empire builds complete Next.js templates with polished contact and conversion sections in the same motion system.Explore Template Empire templates