Skip to main content
@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

Each day in weeks[].days carries: useMonthGrid(month, options) accepts weekStartsOn, showSixWeeks, isRTL, locale, selectedDates, selectedRange, and the minDate / maxDate / isDateDisabled constraints.
Need the grid outside React (tests, server, exports)? Call the pure buildMonthGrid(month, options); useMonthGrid is just a memoized wrapper around it. buildMonthWeeks(month, weekStartsOn) returns the raw Date[][].
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:
To bucket events by calendar day (for a month or agenda), use 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 mathcellRangeFromDrag (a sweep to start/end), resolveDraggedBounds (a move/resize to snapped bounds), snapDeltaMinutes, shiftMinutes.
  • Event displayeventTimeLabel, eventAccessibilityLabel, titleNumberOfLines / titleEllipsizeMode, isTimeVisibleAtHeight, formatHour (the shared time-grid hour-axis label both renderers default to).
  • Month overflowmonthEventCapacity + monthVisibleCount decide how many chips fit before a “+N more” row.
  • Business hoursclosedHourBands(day, businessHours, minHour?, maxHour?) returns the hour spans to shade.
  • PresentationrangeBandKind, bandRounding, dayBadgeKind map a day’s selection state to pill/badge intent (exactly what both renderers consume).
  • Selection — the useDateRange hook, plus pure nextDateRange, daySelectionState, isDateSelectable, isRangeEndpoint, isWithinDateRange.
  • DatesgetViewDays, getWeekDays, getIsToday, isWeekend, isSameCalendarDay, minutesIntoDay, isAllDayEvent.
  • Theme tokenslightColors / darkColors (the neutral CalendarColors palette) to build a theme from scratch.
Recurrence (expandRecurringEvents) and time zones (eventsInTimeZone, toZonedTime) are pure core helpers too; see the Recurring events and Time zones guides.