ChronousDocumentation

API

useCalendarNavigation

The ranges to move to — next, prev, today and withView — and nothing that sets state.

Signature

useCalendarNavigation(range) is a thin wrapper over calendarReducer: it returns the ranges to move to and never sets state itself.

tsx
import type {
  CalendarNavigation,
  CalendarRange,
} from '@midstem/chronous-react'

export declare function useCalendarNavigation(
  range: CalendarRange,
): CalendarNavigation
Type
type CalendarNavigation = {
  next: CalendarRange | null
  prev: CalendarRange | null
  today: (() => CalendarRange) | null
  withView: (view: ViewKind) => CalendarRange
}
FieldTypeDescription
nextCalendarRange | nullThe range one period forward, or null when it cannot be stepped.
prevCalendarRange | nullThe range one period back, on the same terms.
today(() => CalendarRange) | nullA function, because it reads the wall clock at the click — in range.timeZone. Null only when that zone cannot be read.
withView(view: ViewKind) => CalendarRangeThe same range under another view. Never null: it is pure arithmetic.

Usage

tsx
import { useCalendar, useCalendarNavigation } from '@midstem/chronous-react'
import type { CalendarRange, ViewKind } from '@midstem/chronous-react'
import { useState } from 'react'

const INITIAL: CalendarRange = {
  view: 'week',
  currentDate: '2026-03-18',
  timeZone: 'Europe/Kyiv',
}

const VIEWS: ViewKind[] = ['day', 'week', 'month', 'agenda']

export const Board = () => {
  const [range, setRange] = useState<CalendarRange>(INITIAL)
  const { next, prev, today, withView } = useCalendarNavigation(range)
  const { calendar } = useCalendar(range, [])

  return (
    <>
      <nav>
        <button disabled={!prev} onClick={() => prev && setRange(prev)}>
          Back
        </button>
        <button disabled={!today} onClick={() => today && setRange(today())}>
          Today
        </button>
        <button disabled={!next} onClick={() => next && setRange(next)}>
          Forward
        </button>

        <select
          value={range.view}
          onChange={event => setRange(withView(event.target.value as ViewKind))}
        >
          {VIEWS.map(view => (
            <option key={view} value={view}>
              {view}
            </option>
          ))}
        </select>
      </nav>

      <p>{calendar?.days.length ?? 0} days drawn</p>
    </>
  )
}

Navigation covers what a step does per view, and Calendar.Toolbar wraps all of this when you would rather not wire the buttons yourself.