Hapio Calendar

Differences from your calendar

What the migration component does differently from the calendar you migrate from, and what it does not support.

What this page says about the calendar you migrate from ("the source library") describes its current release as its public documentation describes it, checked in October 2026. Later releases may differ.

Behaviour

Accepted changes stay where the user put them. The source library keeps a dropped or resized event where the user left it, in its own store, and so does the migration component (EventCalendar, which renders through useCompatProps): a change your eventDrop, eventResize or eventChange keeps is held over your events (and eventSources arrays) until your input for that event changes its start, end or allDay, or the event leaves your input. Your data then wins, whether it saved the change or not. A change you revert (revert(), false or a throw) is not held. Two kinds of change are not held either, so save them or they move back after the settle timeout (15 seconds): changes to an instance of a recurring event (save the plan in info.recurrence; see Recurrence) and changes to events an events function returned (refetch them). fromCompatOptions alone holds nothing. HapioCalendar itself is controlled: an accepted change shows until your data has it (saved changes settle on your data).

Background events never count as overlaps. In the source library, eventOverlap and selectOverlap consider background events; in Hapio they never block a move or a selection, and an overlap function is not called for them. To keep events inside or outside background ranges, use a constraint: eventConstraint: 'open' keeps events inside the background events of group open.

Day limits. dayMaxEvents: true (or dayMaxEventRows: true) shows as many events as fit in the day grids and caps a time grid's all-day row, as the source library does. A number counts events in the source library and rows, the "+N more" row included, in Hapio, so the migration component passes N + 1: with exactly N + 1 events on a day Hapio shows all of them, where the source library shows N and "+1 more". eventMaxStack converts the same way.

Week numbers show in the day grids, not in the time grids (that arrives in 1.1). They are ISO weeks: weekNumberCalculation: 'ISO' is accepted, other values are reported, and without it the source library numbers weeks by the locale, which differs from ISO weeks in the United States.

Event display info. isFuture is !isPast && !isToday (Hapio has no "future" of its own), isNarrow is always false, and timeClass and titleClass are the registry's classes for the time and the title. Give the time your eventContent renders dir="auto" (or wrap it in <bdi>), so a time range keeps its order in right-to-left calendars.

Native events and elements. eventClick has the clicked element (el) and its click (jsEvent). The change callbacks (eventDrop, eventResize, eventChange), drop and eventReceive have jsEvent too: the DOM event that ended the change or the drop, which is a pointer's release, the click, tap or key that placed it, a menu item's or the "Change time…" form's click, or the key that dropped a keyboard grab. It is typed MouseEvent | KeyboardEvent | null, since a change can come from the keyboard, and those callbacks have no el. dateClick's jsEvent is MouseEvent | KeyboardEvent for the same reason: Enter or Space on a day or a time is a date click too.

DayCellInfo.isDisabled is true for a day-grid cell outside validRange and for another month's day the grid leaves unnumbered (showNonCurrentDates: false); it is false for a time grid's all-day cells, headers, lanes and list days.

One recurring change at a time. While a change to a recurring event waits for your save, its other instances cannot be changed. See Recurrence.

Accessibility comes along. The migration component is Hapio's calendar: keyboard navigation, selection and editing from the keyboard, the actions menu, names, descriptions and announcements all work with your options unchanged.

Types

EventCalendarProps declares every option the migration component maps (and the resource options that arrive in 1.2–1.4), so a typed options object keeps compiling for them. What it reports is not declared: an option marked reported on Options, or a form a partly row's notes name (a function for validRange or now, a feed URL for events), is a type error in a typed app ("Object literal may only specify known properties"), not something that compiles and is then ignored. That is how a typed app finds what step 4 of the migration replaces; in JavaScript, or through an object TypeScript does not check against EventCalendarProps, the same options are listed once in the console during development and ignored (Typing).

Not supported

Each option marked reported on Options is listed once in the console during development, and ignored. The main ones:

  • the imperative API: getApi() and its mutations (addEvent, setProp, …), setOption, on/off/trigger, batchRendering, and a ref on the component;
  • *DidMount and *WillUnmount callbacks, { html } and { domNodes } content given directly, and class hooks other than those mapped;
  • the headerToolbar and footerToolbar string syntax and buttons: use the built-in toolbar or useCalendarController();
  • visibleRange, dateIncrement and dateAlignment: Hapio's views own their length, alignment and step;
  • locale objects (locales, or one passed as locale: pass its code as locale and its texts as strings) and the text options (moreLinkText, the hints, …): pass strings, which EventCalendar takes as HapioCalendar does;
  • JSON feed, Google Calendar and iCalendar sources, eventDataTransform, lazyFetching, progressiveEventRendering, rerenderDelay;
  • Moment and Luxon format strings, and the format flags omitTrailing and weekdayJustify;
  • the multiMonth views, dayGridYear and listYear; the resourceDayGrid views are not planned;
  • slotMaxTime past '24:00';
  • Draggable and ThirdPartyDraggable: use CalendarDraggable or useExternalDraggable, and a calendar's store.hitTest for other drag-and-drop libraries;
  • unselectCancel (a press outside always clears the selection; unselectAuto: false keeps it), selectMinDistance and eventDragMinDistance (drags start past 5 px), eventDragStart, eventDragStop, eventResizeStart, eventResizeStop, dragScroll: false (Hapio always scrolls), dragRevertDuration, allDayMaintainDuration: true, fixedMirrorParent;
  • eventLeave: events cannot be dragged out of a calendar in 1.0;
  • exrule, and recurring events without a recurrence engine;
  • older option names (slotLabelFormat, eventClassNames, dayCellContent, …): use the current names.

Resource and timeline views and their options (resources, resourceOrder, resourceColumns, resourceColumnHeaderContent, resourceColumnsWidth, resourceGroupField, eventResourceEditable) arrive in 1.2 to 1.4. They are typed, so an app that passes them keeps compiling, and until then a development error names the version.