Skip to content

useCalendar

Composable for the whole calendar state: current month, days, time slots of the selected day, navigation and selection.

ts
import { useCalendar } from "@zaptime/core";

const calendar = useCalendar(calendarId?);

Init

Initializes the calendar: computes the localized weekday headers, fetches the days of the current month and preselects the first available day. When the current month has no availability it advances to the next month automatically. Requires setConfig and loadDateFnsConfig to have run first; see Getting started.

ts
const { init } = useCalendar();
await init();

Get days

Refetches the days of the currently displayed month. Call it after changing the timezone or after a SlotNoLongerAvailableError.

ts
const { getDays } = useCalendar();
await getDays();

Day clicked

Selects a day and loads its time slots into state.timeSlots. Clears the previously selected time slot.

ts
const { dayClicked } = useCalendar();
dayClicked(day);

Select time slot

Marks a time slot as selected. The selection is shared with useSelectedTimeSlot and used by book, reserve and reschedule.

ts
const { selectTimeSlot } = useCalendar();
selectTimeSlot(timeSlot);

Next / previous month

Move the calendar by one month and refetch its days. nextDisabled and prevDisabled are computed from min and max in the config (months backwards and forwards the visitor may navigate).

ts
const { next, prev, nextDisabled, prevDisabled } = useCalendar();

Day has time slot

Returns true when the given day has at least one available time slot.

ts
const { dayHasTimeSlot } = useCalendar();
dayHasTimeSlot(day);

Is selected / is selected day

ts
const { isSelected, isSelectedDay } = useCalendar();

isSelected(timeSlot); // true when the time slot is the selected one
isSelectedDay(day); // true when the day is the selected one

Month name and year

Localized month name and the year of the displayed month.

ts
const { monthName, currentYear } = useCalendar();

Config

The merged config for this calendar, same as useConfig().config.

State

state is a reactive object (not a ref). Read its properties directly in templates and do not destructure it, otherwise reactivity is lost.

ts
const { state } = useCalendar();

state.date; // Date of the displayed month
state.days; // Day[] for the month grid, including padding days
state.timeSlots; // TimeSlot[] of the selected day
state.selectedDay; // Day | null
state.loading; // true while days are being fetched
state.headers; // string[] localized weekday labels, in startDayOfWeek order
state.monthHasTimeSlots; // false when the whole month is empty
state.initLoaded; // true once init() finished

Day

ts
interface Day {
  label: string; // day number as text
  date?: Date; // undefined for padding days from the previous month
  isPast?: boolean;
  isToday?: boolean;
  isCurrentMonth?: boolean;
  timeSlots?: TimeSlot[]; // undefined when the day has no availability
}

Render a day as disabled when !day.date || day.isPast || !dayHasTimeSlot(day).

TimeSlot

ts
interface TimeSlot {
  start: string; // ISO 8601
  end: string; // ISO 8601
  seats: number; // remaining seats (group events)
  calendarId: number;
  title: string;
  readableType: string;
}

Format start and end with useDateFormatters; they are UTC strings and the formatter applies the selected timezone.

Empty month

When state.monthHasTimeSlots is false, show the locale.texts.noTimeSlotAvailable text and a button that calls next() labeled with locale.texts.showNextMonth.