@super-calendar/core is the render-agnostic engine both renderers are built on:
date math, the selection model, event layout, recurrence, time-zone conversion,
and the neutral theme tokens. Reach for it directly only when you want entirely
custom UI. Most apps use the native or
react-dom components, which already wrap all of this.
react is a peer dependency too, for the hooks; the pure functions work without it.
Month grid
When you want your own day-cell markup but not the date maths,useMonthGrid
gives you the grid as data: the weeks, the weekday headers, and per-day state
(today, selected, in-range, disabled, current-month). You render whatever you
like.
Per-day state
Eachday in weeks[].days carries:
useMonthGrid(month, options) accepts weekStartsOn, showSixWeeks, isRTL,
locale, selectedDates, selectedRange, and the minDate / maxDate /
isDateDisabled constraints.
layoutMonthWeek(days, events) lays one week row’s events out as spanning bars:
each event becomes a single segment carrying the startCol / endCol it covers,
a lane for stacking overlapping events, and continuesBefore / continuesAfter
flags for bars that run past the row’s edges. It’s the same layout the built-in
month grid uses, so a custom month cell can draw identical multi-day bars.
Laying out timed events
layoutDayEvents(events, day) resolves overlaps into side-by-side columns for a
day/week grid — the same math the TimeGrid uses, with no rendering opinion. Each
PositionedEvent gives you placement:
groupEventsByDay(events) — a Map keyed by startOfDay(date).toISOString()
that indexes multi-day events under every day they span. eventDayKeys(event)
returns those keys for a single event.
More in core
Every helper below is pure (safe in tests, on a server, or in a worker). See the TypeScript types for exact signatures.- Drag math —
cellRangeFromDrag(a sweep to start/end),resolveDraggedBounds(a move/resize to snapped bounds),snapDeltaMinutes,shiftMinutes. - Event display —
eventTimeLabel,eventAccessibilityLabel,titleNumberOfLines/titleEllipsizeMode,isTimeVisibleAtHeight,formatHour(the shared time-grid hour-axis label both renderers default to). - Month overflow —
monthEventCapacity+monthVisibleCountdecide how many chips fit before a “+N more” row. - Business hours —
closedHourBands(day, businessHours, minHour?, maxHour?)returns the hour spans to shade. - Presentation —
rangeBandKind,bandRounding,dayBadgeKindmap a day’s selection state to pill/badge intent (exactly what both renderers consume). - Selection — the
useDateRangehook, plus purenextDateRange,daySelectionState,isDateSelectable,isRangeEndpoint,isWithinDateRange. - Dates —
getViewDays,getWeekDays,getIsToday,isWeekend,isSameCalendarDay,minutesIntoDay,isAllDayEvent. - Theme tokens —
lightColors/darkColors(the neutralCalendarColorspalette) to build a theme from scratch.
expandRecurringEvents) and time zones (eventsInTimeZone,
toZonedTime) are pure core helpers too; see the
Recurring events and Time zones
guides.