ZaptimeCalendar component
import { ZaptimeCalendar, useCalendarViewState, book, reserve, confirm, cancel } from "@zaptime/vue3";
import type { ZaptimeConfig } from "@zaptime/vue3";Props
| Prop | Type | Description |
|---|---|---|
config | ZaptimeConfig | Required. See the config reference. The prop is watched: replacing it or mutating a ref merges the new values into the calendar without a remount. |
calendar-id | string | Optional. Isolates the state of this instance. Required when several calendars share a page. Pass the same id to book, reserve, confirm, cancel and to every composable. |
class | string | Forwarded to the calendar, form and success containers. |
Events
| Event | Payload | When |
|---|---|---|
booking-confirmed | ReservationResponse | The built-in form booked or rescheduled successfully. Not emitted with externalBooking: true. |
time-slot-changed | TimeSlot | undefined | The selected time slot changed. undefined on deselect. |
calendar-loaded | none | Initialization finished: remote configuration fetched and the first month loaded. Also fires for a disabled event type. |
<ZaptimeCalendar
:config="config"
@booking-confirmed="(r) => track('booked', r.data.uuid)"
@time-slot-changed="(slot) => (selected = slot)"
@calendar-loaded="loading = false"
/>ReservationResponse is { success: boolean; data: { uuid: string; userId: number; userName: string; userEmail: string } }. TimeSlot carries start and end as ISO strings. See Types.
TIP
The component shows its own success screen after a booking. Use booking-confirmed for analytics, closing a modal, or navigation. When redirectAfterBookingUrl is set the browser navigates away right after the booking, before your handler can do much.
Rendering states
- A spinner (min height 360px) until the remote configuration is loaded.
- The calendar.
- A "calendar disabled" panel when the event type is disabled in the dashboard.
Updating the config at runtime
Keep the config in a ref or computed and change it; the component merges the new value into its state.
<script setup lang="ts">
import { computed, ref } from "vue";
import { ZaptimeCalendar } from "@zaptime/vue3";
import type { ZaptimeConfig } from "@zaptime/vue3";
const locale = ref("en");
const dark = ref(false);
const config = computed<ZaptimeConfig>(() => ({
token: "<API_TOKEN>",
locale: { preset: locale.value },
theme: { mode: dark.value ? "dark" : "light" },
}));
</script>
<template>
<select v-model="locale">
<option value="en">English</option>
<option value="de">Deutsch</option>
</select>
<label><input v-model="dark" type="checkbox" /> Dark</label>
<ZaptimeCalendar :config="config" />
</template>Multiple calendars on one page
Give every instance a unique calendar-id and pass it to any API call.
<template>
<ZaptimeCalendar calendar-id="sales" :config="{ token: SALES_TOKEN }" />
<ZaptimeCalendar calendar-id="support" :config="{ token: SUPPORT_TOKEN }" />
</template>
<script setup lang="ts">
import { ZaptimeCalendar, book } from "@zaptime/vue3";
await book({ email: "john@doe.test", calendarId: "sales" });
</script>Calendar state lives at module level. Two calendars without distinct ids (or two pages that mount a calendar with the same id) share selection and config.
Using in a modal
Mount the calendar only when the modal is open (v-if, not v-show). Initialization runs in onMounted and needs real viewport widths for the compact layout switch.
<Dialog v-model:open="open">
<ZaptimeCalendar v-if="open" :config="config" @booking-confirmed="open = false" />
</Dialog>useCalendarViewState
Read or set which screen the component shows.
import { useCalendarViewState } from "@zaptime/vue3";
const { view, calendarView, setView, setCalendarView } = useCalendarViewState(calendarId);
view.value; // "calendar" | "form" | "success"
calendarView.value; // "pickingDate" | "pickingTime" (compact mode only)
setView("calendar"); // reset the widget to the month grid after a host-side actionResponsive behaviour
The default layout is about 840px wide. Under a viewport width of 860px the component switches to the single-column compact layout (date first, then time) automatically. Set compact: true in the config to force it.
Re-exported API functions
book, reserve, confirm and cancel are re-exported from @zaptime/core for convenience. Everything else (composables, reschedule, error classes, types) is imported from @zaptime/core. See Working with Time Slots.
