calendar-tsx

Day grid view

Day ranges, calendar periods and resource groups with spanning event bars.

Days as columns with spanning event bars, for a day, an N-day range, whole weeks, or calendar months, quarters and years.

Loading the preview…

Live, with sample events. Click an event to see what it reports.
export const dayGridsFeatures = calendarFeatures({});
export const dayGrids = calendarViews({
  features: dayGridsFeatures,
  views: {
    day: dayGridView({ days: 1, maxEventsPerDay: 3 }),
    threeDays: dayGridView({ days: 3, maxEventsPerDay: 3 }),
    workweek: dayGridView({ weeks: 1, hiddenDays: [6, 7], maxEventsPerDay: 3 }),
    year: dayGridView({ period: 'year', maxEventsPerDay: 3 }),
    months: dayGridView({ period: 'year', groupBy: 'month', fixedWeekCount: true, maxEventsPerDay: 3 }),
    rooms: dayGridView({ days: 1, groupBy: 'resource', maxEventsPerDay: 3 }),
    monthsThenRooms: dayGridView({ period: 'quarter', groupBy: ['month', 'resource'], maxEventsPerDay: 3 }),
    roomsThenMonths: dayGridView({ months: 3, groupBy: ['resource', 'month'], maxEventsPerDay: 3 }),
  },
});

Duration

Every view factory takes exactly one of days, weeks, months or period. Counts are positive integers.

DurationRangenext() / prev()
days: NN dates from date; 7 keeps week alignment.N days.
weeks: NN whole weeks from firstDayOfWeek.N weeks, keeping the weekday.
months: NN calendar months from the first of the anchor month.N months, landing on the first day.
period'month', 'quarter' or 'year', aligned to its calendar boundary.One period, landing on its first day.

Day ranges use one row, week ranges one row per week. Month-based ranges are padded to whole weeks, and padding days have isOutside: true. A continuous year is one section of weeks.

Grouping

groupBy accepts 'month', 'resource', or an ordered tuple of those distinct keys. Month grouping requires a month-based duration.

groupByResult
omittedOne continuous grid.
'month' or ['month']One section per month.
'resource' or ['resource']Resource columns within the grid.
['month', 'resource']Month sections, each containing resource columns.
['resource', 'month']Each resource's month sections, in resource input order and then month order.

groupOrder: 'resource-first' keeps each resource's dates together in a row so bars can span them. 'date-first' groups columns by date and splits bars at resource boundaries. Neither changes the section order groupBy sets.

An event appears under every resource it names; unassigned events appear only in ungrouped grids. A background event without resource IDs shades all resources. A cell is isUnavailable when its resource has no availability that day.

Overflow

SettingDescription
maxEventsPerDayVisible bar rows per grid row. Further rows are hidden and counted; Infinity removes the cap.
dayOverflow(date, resourceId?)Marks a date/resource cell as having more events, such as events not loaded yet.
fixedWeekCountSix rows per month. Allowed with period: 'month' or month grouping. Defaults to false.

See overflow.

Hidden weekdays

hiddenDays omits ISO weekdays. Use the exported DayOfWeek constants (DayOfWeek.Monday is 1, DayOfWeek.Sunday is 7) or the numbers; the same values work for firstDayOfWeek and weekly background daysOfWeek.

import { DayOfWeek, timeGridView } from '@calendar-tsx/core';

timeGridView({ weeks: 1, hiddenDays: [DayOfWeek.Saturday, DayOfWeek.Sunday] }); // a workweek

Hidden weekdays change neither the nominal period, the inclusive fetch range nor the navigation step. Hiding all seven weekdays throws. When every date in the range is hidden, such as a one-day view on a hidden Saturday, the range shows its dates anyway.

Bars project onto the remaining columns, and events entirely on hidden dates disappear. Month rows keep their calendar-week boundaries.

Model

layout is { kind: 'dayGrid', sections }. The view context also has kind: 'dayGrid'.

Each section has key, period, range, optional month and resource, header columns, columnCount and rows. A section's month is its first date. isOutside is relative to the section's period, so a date can be outside in one month and inside the next.

Each row has key, days, bar segments, backgroundEvents, columnCount and stackCount (visible bar rows). Columns hold key, date and optional resource. Day cells add:

Day fieldDescription
isOutsideThe date pads the section and lies outside its period.
isTodayThe date is today in timeZone.
isUnavailableThe resource has no availability overlapping this date.
hiddenCountHidden bar segments crossing this cell.
hasMorehiddenCount > 0, or dayOverflow returned true.
eventsEvents on this date/resource, including hidden events, in order.
Bar segment fieldDescription
eventThe event, in the calendar's time zone.
colStart, colSpanFirst visible column, zero-based, and the number of visible columns covered.
rowStack row, zero-based.
isAllDayThe event is all-day.
isMultiDayThe event covers more than one date, before clipping. A timed event ending at midnight covers only its start date.
continuesBefore, continuesAfterThe event extends beyond the visible dates at that bar's edges.

Keys are stable within their parent. Render background events before bars. Background layers decorate each cell and respect its resource scope.

Read the model from calendar.store.state.layout after checking layout.kind. The quick start renders a month from it.