calendar-tsx

Now and today

Today's highlight, the now indicator and the clock.

The current time sets which day is today and where the now indicator sits. The calendar reads it from a clock:

WhereField
Day-grid daysisToday, rendered as data-today
Time-grid columnsisToday, and now: the fraction of the day for the now indicator
TimelinesDay headers' isToday, and the layout's now: the fraction of the range, absent outside it
Statestate.now, a Temporal.ZonedDateTime in timeZone
Navigationtoday() goes to today in timeZone

Clock

Without a clock option, the calendar ticks every minute. Each tick re-derives the state only when the time changed. Two clocks are built in:

// tick every 15 seconds instead of every minute
export const clock = intervalClock({ every: Temporal.Duration.from({ seconds: 15 }) });

fixedClock(instant) never ticks, for tests, stories and screenshots. Any { now, subscribe } object is a clock.

The clock starts when the calendar mounts and stops when it unmounts. Before that, the current time comes from initialNow if given; see server rendering.

Freezing time

// a frozen "now", for tests, stories and screenshots
export const useFrozenCalendar = () =>
  useCalendar({
    timeZone,
    views,
    features,
    view: 'week',
    date: Temporal.PlainDate.from('2026-03-11'),
    events: bookings,
    onNavigate: () => {},
    clock: fixedClock(Temporal.Instant.from('2026-03-11T14:30:00Z')),
  });

Now indicator

Render TimeGridViewNowIndicator in every column; it renders only in today's column, at column.now. See the week and day view.

In timelines, render one TimelineViewNowIndicator with the layout as model; it renders only while now is in the visible range.