Hapio Calendar

Your options in Hapio

Every option, callback, event field and payload of the calendar you migrate from, what the migration component does with it, and the Hapio option it becomes.

EventCalendar takes the options of the calendar you migrate from by their names and passes HapioCalendar the Hapio options on the right. Anything it cannot map is listed once in the console during development. The tables below are @hapio/calendar-compat's own coverage list, which calls the calendar you migrate from "the source library": the package's tests check them against its code both ways, so every option the mapping reads has a row and every row's status is what the mapping does. The types are in the Compat reference; what behaves differently is explained on Differences.

Coverage

Every documented option, callback and method of the source library's Standard API, and its resource options, with what compat does with it. The "Status" column:

StatusMeaning
mappedMapped onto a Hapio option with the same behaviour (the notes say how).
differsMapped, with a behaviour difference the notes describe.
partlySome values are mapped; the others (named in the notes) are reported like an unsupported option.
ignoredAccepted without effect and without a report entry.
reportedNot supported: listed in unsupported, with one development warning. The notes say what to use instead.
1.2, 1.3, 1.4Arrives in that release of Hapio Calendar (the timeline, resource timeline and resource time-grid views); until then reported, with a development error naming the release.

The options tables are checked against the code by the package's tests: every option the mapping reads has a row, and every row's status matches what the mapping does with the option.

Views and navigation

OptionStatusHapioNotes
initialViewmappeddefaultViewSeeds the calendar once, as in the source library (re-create it with a React key to reset). An unsupported view id is reported as initialView.<id>.
initialDatemappeddefaultDateRead in the calendar's zone; seeds once.
availableViewsmappedviews, in orderThe source library's shadcn registry prop. Without it: week, day, month and list, opening on the month (the source library's default view). Unsupported ids are reported as availableViews.<id>.
viewsmappedeach view's factory optionsKeyed by type (timeGrid), unit (week) or name; the cascade is type, then unit, then name. A used view's options that do not map are reported as views.<key>.<option>; unused views' options are ignored.
duration, dayCountmappeda generic view's lengthinitialView: 'timeGrid', duration: { days: 4 }.
visibleRange, dateIncrement, dateAlignmentreported—Hapio views own their length, alignment and step (timeGrid({ days, align, step }) on HapioCalendar).
validRangepartlyvalidRangeThe object form; the function form is reported.
nowpartlynowA fixed date; the function form is reported.
nowIndicatormappednowIndicator
navLinks, navLinkDayClick, navLinkWeekClickpartlynavLinks: { day, week }View names (default timeGridDay and timeGridWeek, added to the views when supported); the function forms are reported.
navLinkClassreported—Style the registry's day links (calendar-day-grid.tsx, calendar-time-grid.tsx).
datesSetmappedonRangeChangeDatesSetInfo: instants, ISO strings with offsets, the zone and the view.
timeZonemappedtimeZoneChanges take effect without a remount.
localepartlylocaleA locale code: dates are formatted by Intl. A locale object (the source library's locale modules) is reported: pass its code, and the calendar's texts as strings (sv ships).
localesreported—strings (Hapio's option, which compat takes too; sv ships).
directionmappeddir
firstDaymappedweekStartsOn0–6 → ISO weekdays (Sunday 0 → 7).
weekendsmappedhiddenDays 6 and 7
hiddenDaysmappedhiddenDaysISO weekdays. Weekdays as numbers or their strings ('0'); other entries are reported.
fixedWeekCount, showNonCurrentDatesmappedday grids' fixedWeekCount, showOtherMonthDaysAlso per view in views.
weekNumbersdiffersday grids' weekNumbersNot shown in time grids (a later release); a time grid's views.<key>.weekNumbers is reported.
weekNumberCalculationpartly—'ISO' is what Hapio shows (ISO weeks); other values are reported. Without it the source library numbers weeks by the locale, which differs from ISO weeks in the United States.
weekNumberFormatmappedformats.weekNumber
weekTextLong, weekTextShortreported—strings on HapioCalendar.

Toolbar, sizing and the shell

OptionStatusHapioNotes
headerToolbar, footerToolbar, buttons, buttonDisplay, toolbarElementsreported—The block's toolbar, HapioCalendar's toolbar prop, or controller with your own toolbar.
controllermappedthe block's toolbarFrom useCalendarController(): today, prev, next, gotoDate, changeView, getDate, view and getButtonState(). prevYear, nextYear and incrementDate are not provided.
titleFormatmappedformats.title
classNamemappedthe root's className
height, contentHeightdiffersthe root's style.heightAny CSS length, or pixels; 'auto' sets none. Both size the root, which includes the toolbar.
aspectRatio, expandRows, tableHeaderSticky, footerScrollbarSticky, dayMinWidth, dayNarrowWidthreported—Size the root; header rows are sticky; narrow layouts come from the registry's CSS.
borderless, borderlessX, borderlessTop, borderlessBottommappedthe view's classesThe registry item's classes (CompatUi.borderlessClasses); reported when the caller gives none.
headingLevelmappedheadingLevel
colorSchemereported—Dark mode follows the app's theme (the .dark class and the tokens).
todayHint, prevHint, nextHint, viewHint, viewChangeHint, navLinkHint, moreLinkHint, closeHint, eventsHint, moreLinkText, listTextreported—strings on HapioCalendar.
pluginsignored—Every view and interaction is built in (selection and editing come from the registry's <CalendarSelection> and <CalendarEditing>).
schedulerLicenseKeyignored—One development notice: every view is free (MIT).

Time axis and days

OptionStatusHapioNotes
slotDuration, snapDurationmappedthe same
slotMinTimemappedslotMin
slotMaxTimepartlyslotMaxUp to '24:00'; later times are reported.
slotHeaderIntervalmappedslotLabelInterval
slotHeaderFormatmappedformats.slotLabelAn array gives tiers, top first.
slotMinHeight, slotHeaderAlign, slotHeaderSticky, eventMinHeight, eventShortHeightreported—The registry's tokens and CSS.
allDaySlotmappedallDaySlot
allDayTextmappedstrings.allDay
scrollTime, scrollTimeResetmappedscrollTime, resetScrollOnNavigate
businessHoursmappedbusinessHours{ daysOfWeek, startTime, endTime } → { days (ISO), start, end }; true and lists as well. Weekdays as numbers or their strings; other entries are reported.
dayHeadersreported—
dayHeaderFormatmappedformats.dayHeader
dayCellFormat, monthStartFormatreported—
listDayFormat, listDayAltFormatmappedformats.listDay, formats.listDayAltThe list's day headings; false leaves the text empty.

Events and sources

OptionStatusHapioNotes
eventspartlyevents, backgroundEvents, series, eventSourcesAn array (see "Event fields"), or a function (an event source whose info adds signal; success/failure or a returned value or promise). A feed URL is reported.
eventSourcespartlyevents or eventSourcesArrays and functions, with each source's color, className and editing fields; feed sources (url, format, googleCalendarId, …) are reported as eventSources.<key>.
initialEventsreported—Pass events (compat keeps kept changes over them, see "Behaviour").
eventSourceSuccess, eventSourceFailure, eventDataTransform, startParam, endParam, timeZoneParam, lazyFetching, progressiveEventRendering, rerenderDelayreported—Fetch in an events function (or TanStack Query) and pass the result.
loadingmappedonLoadingChange
defaultTimedEventDuration, defaultAllDayEventDurationmappeddefaultTimedDuration, defaultAllDayDuration
defaultAllDay, forceEventDurationreported—All-day is read from each event's allDay or the form of its start.
nextDayThresholdmappednextDayThreshold
eventColor, eventContrastColor, backgroundEventColorreported—Each event's or source's color; the default colors are the registry's tokens.
eventDisplay, displayEventTime, displayEventEnd, eventSlicing, eventInteractivereported—eventContent for the content; every event is focusable.
eventTimeFormatmappedformats.eventTime
eventOrder, eventOrderStrictmappedeventOrder, orderStrictString keys ('start,-duration,allDay,title', extended props included), arrays and functions of EventApi.
dayMaxEvents, dayMaxEventRowsdiffersmaxEvents per view kindDay grids: true → 'auto', a number N of events → N + 1 levels (Hapio counts the "+N more" row), rows as given. A time grid's all-day row: 5 rows under true, as the source library. At exactly N + 1 events a day shows them all, where the source library shows N and "+1 more".
eventMaxStackdiffersmaxStackN → N + 1 (Hapio counts the "+N" column); at exactly N + 1 overlapping events all show.
moreLinkClickpartly—'popover' (Hapio's "+N more" popover); other values are reported.
popoverFormatmappedformats.moreTitleDefault "Thu 22", as the source library's shadcn shell.
slotEventOverlapmappedoverlap: 'stack' | 'columns'
eventClickmappedonEventClickjsEvent.preventDefault() cancels the link navigation; modified clicks reach the browser; a middle click does not call it.
eventMouseEnter, eventMouseLeavereported—eventContent's own handlers.
eventsSet, eventAdd, eventRemovereported—The app owns its events: they change when it changes them.
eventChangediffersonEventChangeCalled after eventDrop or eventResize, for moves and resizes only (there are no mutation methods to call it for).

Rendering

OptionStatusHapioNotes
eventContentmappedrenderEventEventDisplayInfo; returning true or nothing renders the default content. { html } and { domNodes } render the default content (given directly instead of a function, they are reported).
backgroundEventContentmappedrenderBackgroundEventThe content names the background event (its role="img").
eventClass, backgroundEventClass, viewClass, dayHeaderClass, dayCellClass, dayLaneClass, moreLinkClass, nowIndicatorLineClass, listDayClass, noEventsClassmappedclassNames.<part>A string, a list or a function of the part's info.
noEventsTextmappedstrings.noEvents
stringsmappedstringsHapio's option, not the source library's: the calendar's texts, accessible names and announcements (sv from @hapio/calendar-core/locales/sv, or members of your own). noEventsText and allDayText win over the members they map to.
dayHeaderContent, dayCellTopContent, slotHeaderContent, allDayHeaderContent, weekNumberHeaderContent, inlineWeekNumberContent, nowIndicatorHeaderContent, nowIndicatorLineContent, moreLinkContent, popoverCloseContent, listDayHeaderContent, noEventsContent, rowEventBeforeContent, rowEventAfterContentreported—HapioCalendar's renderDayHeader and renderEmpty, or the registry's files (they are yours to edit).
eventInnerClass, eventTimeClass, eventTitleClass, blockEventClass, rowEventClass, columnEventClass, listItemEventClass, dayRowClass, dayCellInnerClass, slotLaneClass, slotHeaderClass, allDayHeaderClass, nowIndicatorHeaderClass, nowIndicatorDotClass, popoverClass, toolbarClass, buttonClass, tableClass, highlightClass, nonBusinessHoursClass, listDayHeaderClass, and every other *Class hookreported—The registry's files and classNames on HapioCalendar (timeClass/titleClass in eventContent style the default content's parts).
eventDidMount, eventWillUnmount, viewDidMount, dayCellDidMount, and every other *DidMount/*WillUnmount hookreported—Refs and effects in eventContent.

Selection, editing and drops

The interactions need their engine, which the registry's <CalendarSelection> or <CalendarEditing> (and <CalendarExternalDrops>) gives the compat component, as the source library's interaction plugin did; compat never imports it.

OptionStatusHapioNotes
selectablemappedselectable
selectMirrormappedselectionPreviewtrue → 'event', false → 'highlight'.
unselectAutomappedclearSelectionOnOutsidePointer
unselectCancel, selectMinDistancereported—A press outside always clears (unselectAuto: false keeps selections); drags start past 5 px.
selectConstraint, selectOverlap, selectAllowdiffersrules.selectA group id becomes { group }. Background events never block a selection.
dateClickmappedonDateClickAlso Enter (and Space where it does not select) on a day cell or the slot cursor; jsEvent is then the keydown (typed MouseEvent | KeyboardEvent).
select, unselectmappedonSelect, onSelectionChange(null)jsEvent is null for a keyboard selection; a replaced selection is unselected first, as in the source library.
editable, eventStartEditable, eventDurationEditable, eventResizableFromStartmappededitable flagsWith each event's and source's fields over them, field by field.
eventConstraint, eventOverlap, eventAllowdiffersrules.eventA group id becomes { group }. Background events never count as overlaps. An object constraint's weekdays as numbers or their strings; other entries are reported.
eventDrop, eventResizediffersonEventChangerevert() makes the result false; jsEvent is the DOM event that ended the change (a KeyboardEvent for the keyboard); no el. Kept changes are held (see "Behaviour").
eventDragStart, eventDragStop, eventResizeStart, eventResizeStop, eventLeavereported—No such callbacks; dragging out of a calendar is a later release.
eventDragMinDistance, dragRevertDuration, fixedMirrorParentreported—Drags start past 5 px; a revert animates for 200 ms.
dragScrollpartly—true is Hapio's behaviour; false is reported.
allDayMaintainDurationpartly—false is Hapio's behaviour (a move between the all-day row and the lanes takes the default duration); true is reported.
longPressDelay, eventLongPressDelay, selectLongPressDelaydifferslongPressMsOne delay: the most specific option given wins.
droppable, dropAcceptmappeddroppable, acceptExternaldroppable alone accepts every item; a selector matches the draggable element.
drop, eventReceivediffersonExternalDropdraggedEl is the draggable element (else the drop's data); jsEvent the release, click or key that placed it; eventReceive only for object data, which compat reads as an EventInput.

Recurrence

OptionStatusHapioNotes
recurrence, recurrenceScopemappedrecurrence, recurrenceScopeHapio's options (the source library needs a plugin instead): with recurrence: rrule() the simple recurrence fields and rrule become series; 'all' is the default scope, as the source library moves every instance.

Resources and timelines

OptionStatusHapioNotes
resources, resourceOrder, resourceColumnHeaderContent, resourceColumnsWidth, resourceColumns, resourceGroupField, eventResourceEditable1.3—Typed, so apps keep compiling. Every option whose name contains resource is treated so.

View ids

View idStatusHapioNotes
timeGridWeek, timeGridDaymappedtimeGrid({ days: 7 | 1 })Labelled "Week" and "Day" (radios "Week view", "Day view").
timeGridmappedtimeGrid({ days })With a duration or dayCount (1–31 days), in views or at the top level.
dayGridMonth, dayGridWeek, dayGridDaymappeddayGrid({ unit })"Month".
dayGridpartlydayGrid({ unit })A duration of one day, week or month; others are reported.
listDay, listWeek, listMonthmappedlist({ unit })"List".
listYear, dayGridYear, multiMonthYear, multiMonthreported—
timelineDay, timelineWeek, timelineMonth, timelineYear1.2—
resourceTimelineDay, resourceTimelineWeek, resourceTimelineMonth1.3—
resourceTimeGridDay, resourceTimeGridWeek1.4—
resourceDayGridDay, resourceDayGridWeek, resourceDayGridMonthreported—Not planned.

Custom views (views: { fourDay: { type: 'timeGrid', duration: { days: 4 } } }) are supported for these kinds, and their buttonText is the label.

Event fields (EventInput)

FieldStatusNotes
id, groupId, title, start, end, date, allDay, display, editable, startEditable, durationEditable, constraint, overlap, allowmappedAn event without id gets one from its position and start (a development warning asks for ids). display: 'background' and 'inverse-background' make background events.
urlmappedhref: a real link.
color, contrastColor, backgroundColor, textColormappedAny CSS color, as --event-color/--event-contrast and the --fc-event-color/--fc-event-contrast-color aliases (legacyEventVars).
className, classmappedOn the event's root element (a string or a list).
extendedProps, and any other fieldmappeddata.
interactiveignoredEvery event is focusable.
resourceId, resourceIds, resourceEditablemappedPassed on to the calendar; the resource views that use them arrive in 1.3.
daysOfWeek, startTime, endTime, startRecur, endRecur, rrule, exdate, durationpartlyWith recurrence: a series. Without it: reported as events.<field> (the event shows once if it has a start). Recurring background events and events from a function are not expanded. daysOfWeek takes weekdays as numbers or their strings ('4'); other entries are reported (events.daysOfWeek).
exrulereportedRFC 5545 deprecates it.
rdate, overridesmappedHapio's additions for series (extra dates; changed instances).

Payloads, facades and methods

Source libraryStatusNotes
EventApidiffersRead-only: id, groupId, title, start, end, startStr, endStr, allDay, url, display, extendedProps, and the colors and classes as backgroundColor, textColor, classNames. No source, editable flags, constraint, overlap, and no methods (setProp, remove, toPlainObject, …): change your events and pass them again.
ViewApidifferstype, title, activeStart, activeEnd, currentStart, currentEnd; no calendar or getOption.
DatesSetInfo, EventClickInfomapped
DateClickInfo, DateSelectInfo, DropInfodiffersNo resource until 1.3.
EventDropInfo, EventResizeDoneInfo, EventChangeInfodiffersNo el; jsEvent may be a KeyboardEvent or null; an instance of a recurring event has relatedEvents: [] and Hapio's recurrence.
EventDisplayInfodiffersisNarrow is always false; isFuture is !isPast && !isToday; no isFirst, isLast, isResizing, isDraggable, isStartResizable, isEndResizable, isInteractive or level.
DayCellInfo (day cells, headers, lanes, list days)differsdate, dateStr, dow, isOther, isToday, isPast, isFuture, isDisabled, view; no text parts.
getApi() and the calendar's methodsreportedThere is no imperative API: a ref is reported. Navigate with controller, change data by passing new events, select with HapioCalendar's selection.
Draggable, ThirdPartyDraggablereportedNot provided: useExternalDraggable (@hapio/calendar-react/interaction) or the registry's CalendarDraggable, whose data is what eventReceive reads; other drag-and-drop libraries reach the calendar through its store's hitTest.
Format strings (Moment, Luxon plugins)reportedIntl.DateTimeFormat options or a function; omitCommas, forceCommas, omitZeroMinute and meridiem are supported, omitTrailing and weekdayJustify are reported (eventTimeFormat.omitTrailing).
Older option names (slotLabelFormat, eventClassNames, dayCellContent, …)reportedUse the current names.

Behaviour

  • Kept changes stay. The source library keeps a dropped or resized event where it was left, in its own store. With useCompatProps (the event-calendar item), compat does the same: a change the callbacks keep is held over the app's events (and eventSources arrays) until the app's input for that event changes its start, end or allDay (saving the change, or any other value: the app's data wins) or leaves the input. A reverted change is not held. Changes to an instance of a recurring event, and to events an events function returned, are not held: save them (the plan in info.recurrence, or a refetch), or they return after the settle timeout (15 s). fromCompatOptions alone holds nothing.
  • Overlap ignores background events. In the source library a background event counts as an overlap; in Hapio it never does. Use constraint: '<groupId>' (a background event's group) to keep events inside, for example, open hours.
  • Day limits count events (the source library) or levels including the "+N more" row (Hapio): compat converts, and at exactly N + 1 events Hapio shows them all.
  • Week numbers show in day grids only; time grids show none yet.
  • isFuture is !isPast && !isToday.
  • jsEvent of a change or a drop is the DOM event that ended it: a pointer release, a click, or the key (Enter) that dropped a keyboard grab, typed MouseEvent | KeyboardEvent | null. There is no el for changes and drops.

Typing

EventCalendarProps declares every option the tables above map (mapped, differs, partly and ignored), so a typed options object keeps compiling (satisfies EventCalendarProps). The options marked reported, and those of 1.2–1.4 except the six below, are not declared: in a typed app passing one is a type error (TS2353, "Object literal may only specify known properties"), and step 4 of the migration ("Replace what has no counterpart") removes them. Options that reach compat untyped (from JavaScript, or spread from an object of the app's own type) are reported in unsupported, with a development warning. The resource options of 1.3 that apps commonly pass (resources, resourceOrder, resourceColumnHeaderContent, resourceColumnsWidth, resourceColumns, resourceGroupField) are declared, so they compile and are reported with the release that brings them.