Calendar API
Use the package's date, interval, validation, lane, and event-change exports by their current signatures.
Import
Import core functions and types from @ghost-ui/core/calendar-core. This entry has no React or CSS dependency. CalendarDataOptions describes the core input. Import the React Calendar component and its CalendarProps type from @ghost-ui/core/components/calendar; see the component API.
Date and interval functions
| Export | Signature | Result and failure behavior |
|---|---|---|
parseCalendarDate | (value: string) => number | UTC-midnight millisecond value for a valid YYYY-MM-DD; throws for malformed or impossible dates. |
addCalendarDays | (value: string, days: number) => string | Adds an integer number of calendar days; throws for invalid date or non-integer increment. |
parseCalendarTimestamp | (value: string) => number | Parses ISO date-time with explicit offset to milliseconds; throws without offset or for invalid date, time, or offset. |
calendarDateInZone | (ms: number, timeZone: string) => string | Local date for an instant; invalid IANA zone throws. |
getCalendarDay | (date: string, timeZone: string) => CalendarDay | Local day bounds, actual duration in minutes, and hourly ticks; throws for invalid zone/date or a skipped local date. |
todayCalendarDate | (timeZone: string, now?: number) => string | Local date for now, defaulting to Date.now(). |
formatCalendarTime | (ms: number, timeZone: string, withOffset?: boolean) => string | HH:mm, optionally with UTC offset. |
getCalendarDates | (date: string, view: CalendarView) => string[] | Dates covered by a view; week starts Monday, month returns a 42-date grid; unknown view throws. |
navigateCalendarDate | (date: string, view: CalendarView, direction: -1 | 1) => string | Moves by view; month navigation clamps to the target month's last day and supported date bounds. Invalid direction/date throws. |
resolveCalendarLocalDateTime | (date, hour, minute, second, millisecond, timeZone) => number | Resolves only a unique local wall time; throws for nonexistent or ambiguous time. |
CalendarDay contains date, startMs, endMs, minutes, and ticks. CalendarInterval contains its event, instant bounds, point, and allDay. An event without an end is a point only when timed; an all-day event ends at the next local midnight.
Event and layout functions
| Export | Signature | Result and failure behavior |
|---|---|---|
normalizeCalendarEvent | (event: CalendarEvent) => CalendarEvent | Converts legacy status/scheduling fields into current metadata where needed; otherwise returns the input. |
toCalendarInterval | (event: CalendarEvent, timeZone: string) => CalendarInterval | Converts dates to instant bounds; invalid dates or zone throw. |
validateCalendarData | ({ events, date, timeZone, view?, resources? }) => CalendarValidation | Returns { valid, errors }; default view is agenda. Does not throw for normal invalid input. |
splitCalendarInterval | (interval: CalendarInterval, days: readonly CalendarDay[]) => CalendarSegment[] | Intersects interval with local days and marks continuation. |
assignCalendarLanes | (segments, minimumTargetMinutes?: number, byResource?: boolean) => CalendarSegment[] | Stable overlap lanes; defaults to 30-minute hit targets and resource-separated groups. Invalid minimum throws. |
limitCalendarLanes | (segments, maximum?: number) => { visible, overflow } | Defaults to 3 visible lanes; overflow maps date to unique events. Non-positive/non-integer maximum throws. |
getCalendarLaneLimit | (width, view, maximum?: "auto" | number, coarse?: boolean) => number | Width-constrained lane maximum; auto caps Day at 3, other views at 2, and coarse pointers at 2. Invalid width, view or maximum throws. |
getCalendarOverlapLayout | (segments, maximum, byResource?: boolean) => { visible, groups } | Packs semantic intervals, reserving a disclosure lane in crowded connected clusters. Each group retains its ordered events and hidden segments. Points do not inflate concurrency. |
getCalendarMonthBudget | (cellHeight: number | undefined, count: number, maximum?: "auto" | number) => { visible, hidden, slots } | Fits 22px rows with 2px gaps and an overflow row. Unbounded auto allows 3 events plus count; zero maximum keeps all events in the count. Invalid inputs throw. |
calendarResourceFor | (event: CalendarEvent, resources?: readonly CalendarResource[]) => CalendarResource | undefined | Finds the matching resource, if supplied. |
validateCalendarInteractionSettings | (slotDuration?: number, snapDuration?: number) => CalendarValidation | Defaults to 30 and 15 minutes; returns errors for non-finite, non-positive, or over-1440 values. |
Event changes
changeCalendarEvent(event, options) returns a new proposal. options requires action: "move" | "resize-start" | "resize-end" and timeZone; optional values are deltaMinutes (0), deltaDays (0), dateResize (false), and snapDuration (15). All-day edits use calendar dates. Timed edits return ISO timestamps. It throws when input deltas are non-finite, snapping is invalid, event.editable is false, a point is resized, the result is too short, or a timed resize leaves its original local day without dateResize.
The public types are CalendarOverlapGroup, CalendarView, CalendarResource, CalendarParticipant, CalendarEventStatus, CalendarActor, CalendarResponse, CalendarParticipation, CalendarAttendance, CalendarProposal, CalendarEventAction, CalendarConflict, CalendarEvent, CalendarTimeZoneChoice, CalendarSlot, CalendarChangeAction, CalendarTick, CalendarDay, CalendarInterval, CalendarSegment, CalendarValidation, CalendarDataOptions. Their event identity, date, and interval semantics are described in Calendar data; controlled callbacks and persistence ownership are in Calendar state.