Migrating from FullCalendar

Documentation index

z-cal is not a drop-in FullCalendar replacement. Keep a translation layer if your application already exposes its own calendar API. Check the installed version's declarations rather than forwarding all existing options or callback assumptions unchanged.

Check units and data ownership first

Numeric z-cal durations are seconds. Numeric date inputs are epoch milliseconds. These are different input types. Convert duration values coming from a millisecond-based API: 30 minutes is 1800 seconds, not 1800000. Prefer explicit duration strings or objects at the integration boundary:

import type { CalendarOptions } from 'z-cal'

export const options: CalendarOptions = {
  slotDuration: '00:30',
  snapDuration: '00:15',
  duration: { days: 3 },
}

Callback event dates are Temporal values; all-day ranges have exclusive ends. updateEvent replaces the event input and requires id and start. Choose whether React state, the calendar instance, or remote source results own event data. See event semantics and React data ownership.

Integration checklist

Existing requirementz-cal approach
Render a calendarcreateCalendar(host, { plugins, options }) or <Calendar> from z-cal/react
Choose a viewExplicit view plus its registered plugin
Control displayed datedate, gotoDate, changeView; observe datesSet or the controller
Own navigation controlsuseCalendarController or calendar.controller
Render event contentReact eventContent or core text/DOM content; your renderer owns that region
Open an editor after selectionRegister Interaction, enable selectable, and handle select
Persist drag/resizeeventDrop/eventResize, application persistence, and revert() on failure
Guard dateClick while a popover is openpointerDown fires before any gesture; info.consume() makes the dismissing press do nothing else; see the popover recipe
Tailwind stylesEstablish theme, base, z-cal, components, utilities before CSS imports; recipe
Keyboard accesskeyboardNavigation and keyboardShortcuts; FullCalendar has no grid-level equivalent
businessHoursSame option and rule shapes (daysOfWeek, startTime, endTime), plus a function form; see business hours
eventConstraintdragConstraint and resizeConstraint take 'businessHours', inline hours, or an event id; per-event constraint
eventAllow / selectAllowThe predicate forms of dragConstraint, resizeConstraint, and selectConstraint
eventOverlap / selectOverlapSame names; per-event overlap: false; background events block only with overlap: false
resources[].businessHoursSame field on ResourceInput; replaces the calendar hours for that column or row

Current public API gaps

These capabilities are not provided by the current public API; do not pass similarly named options and assume they work. This list describes compatibility limits, not committed future features.

RequirementCurrent limitation or alternative
Pin the current clock for previews/testsdate selects the displayed date; it does not pin “now.” There is no public per-instance now option.
Set an arbitrary visibleRangeNo visibleRange option. date plus a custom view/duration can approximate some ranges, subject to view alignment and hidden days.
isDragging, isResizing, isMirror in event contentEventContentInfo contains event, timeText, and view. Track interaction start/stop callbacks if your UI needs additional state; display alone does not distinguish drag from resize.
Re-anchor a popover using stop-callback elDrag/resize stop info has event, jsEvent, and view, without el. Call getEventElements(id) for the live elements instead; an event can have multiple rendered segments.
Custom React day header or dayHeaders toggleHeader format options are available; there is no day-header React slot or day-headers toggle. dayCellContent is a different content region.
scrollToTime or centering commandsNo public imperative scroll-to-time/center method. scrollTime configures time-grid scrolling behavior.

Recurring events

EventInput.recurrence.rrule accepts the RRULE text that rrule.js, FullCalendar's rrule plugin, and most backends store, including DTSTART and EXDATE lines. Add the Recurrence plugin. The event start and end replace dtstart and duration; see recurring events.

rrule / FullCalendarz-cal
dtstart, DTSTARTEvent start (the TZID of a DTSTART line sets recurrence.timeZone)
duration, DTENDEvent end
freq, interval, count, untilFREQ, INTERVAL, COUNT, UNTIL in rrule, or freq, interval, count, until
byweekday (RRule.MO, RRule.TU.nth(2))BYDAY=MO, BYDAY=2TU, or weekdays: [1], { weekday: 2, nth: 2 } (0 = Sunday)
bymonthday, bymonth, bysetpos, wkstBYMONTHDAY, BYMONTH, BYSETPOS, WKST, or monthDays, months, setPositions, weekStart
exdate, EXDATEexdates, or EXDATE lines inside rrule
tzidrecurrence.timeZone
rdate, byhour, byweekno, byyearday, sub-daily freqNot supported; parsing throws
groupId, exception eventsoverrides keyed by occurrence key; server-expanded feeds use recurringEventId and originalStart

Avoid treating lower-level state access as a stable substitute for an absent application-facing option. Report concrete integration requirements with a minimal reproduction so they can be evaluated against the public API.