github kcsujeet/ilamy-calendar v3.0.0

4 hours ago

12 September 2026

v3 aligns an event's end with RFC 5545 and the Google Calendar API: it is now exclusive. In practice this affects one shape of event — an end at exactly midnight — and most calendars upgrade without changes. Existing all-day events render exactly as they did. The release also brings a renderEvent that knows which slice of an event it is drawing, server-rendering that hydrates cleanly, and a run of timezone fixes.

⚠️ Breaking changes

v3 migration guide — it lists exactly who is affected. If nothing in your data ends at exactly midnight, there is nothing to do.

  • end is exclusive. An event runs up to, but not including, its end, so only an end at exactly midnight changes: an event from 2025-01-13T00:00 to 2025-01-14T00:00 covers 13 January only, where it used to paint 14 January as well. An end during the day, such as 2025-01-14T23:59, still covers that day, and timed events inside a day are unaffected. To keep a bar that reaches a given day, end it during that day or at the following midnight. This matches RFC 5545 §3.6.1 and the Google Calendar API (#250) — Closes #248
  • All-day events store an exclusive end, and display identically. A new all-day event is stored as the midnight after the last covered day rather than 23:59. Both forms cover the same days, so existing events render exactly as before and nothing needs migrating; the form still shows you the last covered day. This is visible only if you read event.end yourself or compare an iCal export, where a one-day event is now DTSTART;VALUE=DATE:20250804 / DTEND;VALUE=DATE:20250805, as the RFC requires (#250)
  • CellInfo.end is the next midnight. What onCellClick receives (and the data-end attribute plugins read) ends on the next boundary rather than at 23:59, matching the hour and 15-minute cells, which already did (#250)
Features
  • feat: renderEvent receives a second argument saying which slice of the event the current bar draws. An event longer than its row is drawn as one bar per row, and until now every call looked identical, so a custom renderer could not square a cut edge and round a real one. segment.isStart / segment.isEnd follow FullCalendar's event render hook (#264) — Closes #263 — Thanks @habovh!
Fixes
  • fix: a date carrying an explicit offset (Z or ±HH:MM) keeps the instant it names instead of being re-read as wall-clock time in the configured zone, and the timezone prop now applies on mount rather than only when it changes (#249) — Closes #247
  • fix: initialDate opens on the date you give it. A string without an offset is anchored in the calendar's zone, so '2025-03-10' opens on 10 March wherever it is read; a Date, a Dayjs or an offset-carrying string keeps its instant and only the clock it renders against changes (#266) — Closes #265 — Thanks @habovh!
  • fix: server-rendered calendars hydrate without a mismatch. The drag-and-drop context now takes a stable id from React's useId instead of a module-level counter that carried between requests (#262) — Closes #261 — Thanks @habovh!
  • fix: week and day views no longer disable days belonging to the neighbouring month, so the week of 31 March is interactive on both sides. The month grid keeps greying its own padding (#260) — Closes #259 — Thanks @habovh!
  • fix: slotDuration reaches the droppable cells, so a cell click on a 15- or 30-minute grid reports the slot you configured rather than a full hour (#256) — Closes #255 — Thanks @johanjq!
  • fix: a recurrence override that has been moved no longer renders twice, and an event dragged onto another resource actually moves there (#257)
  • fix: header labels animate only when their text changes. Navigating a month used to replay the fade over an unchanged weekday row; now a week column keeps its weekday and animates its number, and a month column does the reverse (#273)
Performance
  • perf: date comparisons answer by instant rather than by formatting, and the year view resolves its events in one pass instead of one query per day (#253) — Closes #245 — Thanks @mattanderson-io!
Internal
  • test: a deterministic browser (E2E) suite covering all 12 rendering surfaces, with the clock, zone, locale and viewport pinned so a calendar test cannot depend on the day it runs (#275)
  • chore: the docs site moved to Astro 7.2.10 for a critical AVIF decode advisory. The published package is unaffected (#276) — Closes #274

Don't miss a new ilamy-calendar release

NewReleases is sending notifications on new releases.