@reactleaf/calendar

Introduction

Calendar with single, multiple, and range selection—Temporal dates, optional time editing, and keyboard-friendly interaction.

@reactleaf/calendar is a date and optional-time picker for React. It targets the same product niche as react-infinite-calendar, but the implementation is new: built for React 19, with @js-temporal/polyfill for values.

Compared with react-infinite-calendar

Spiritual successor, not a drop-in replacement:

  • Values: Props expect Temporal.PlainDate or Temporal.PlainDateTime only—not Date or raw ISO strings. Parse strings at your app boundary with Temporal.PlainDate.from(...) / Temporal.PlainDateTime.from(...) (or your own conversion into those types).
  • Time: Optional includeTime adds header time fields, direct hour/minute input, and a dedicated time subview (scroll picker). Date-only flows stay on plain dates; time is minute-precision wall time, not IANA time zones.
  • Modes: First-class single, multiple, and range on one component (mode discriminant).
  • Stable shell: The card height is stabilized with CSS tokens so switching between day, month, and time views does not resize the shell, even as the infinite-scroll month list grows.
  • Accessibility: Grid-oriented ARIA for the day body, localized labels via locale + overridable messages.

Features

  • Modes: single, multiple, and range selection.
  • Dates: Temporal.PlainDate / Temporal.PlainDateTime only; turn ISO or other formats into those types before passing them in.
  • Optional time: includeTime enables header time editing and the time subview when you need clock times.
  • Bounds: minDate / maxDate, plus per-day disabling in single and multiple (isDateDisabled). Range uses bounds only (no per-day blacklist).
  • Accessibility: Focus management, ARIA on key regions, and keyboard navigation for the day grid.

Requirements

  • React 19+ and react-dom (peers).
  • @js-temporal/polyfill (dependency alongside this package) for Temporal in environments that lack it.
  • Styles: Import the package stylesheet so layout and tokens apply (see below).

Install

The package is published as @reactleaf/calendar. It ships ESM, TypeScript types, and a stylesheet entry.

Use your package manager of choice, e.g. pnpm add @reactleaf/calendar @js-temporal/polyfill, or npm install @reactleaf/calendar @js-temporal/polyfill, or yarn add @reactleaf/calendar @js-temporal/polyfill. Peers: react, react-dom.

Import the default styles once (path may vary by bundler):

import '@reactleaf/calendar/index.css'

Theme hooks such as --calendar-color-accent, --calendar-body-height, and related tokens live in the bundled CSS; override them in your own stylesheet after the import if you need branding or density tweaks.

Minimal usage

import { useState } from 'react'
import type { DateValue } from '@reactleaf/calendar'
import { Calendar } from '@reactleaf/calendar'
import '@reactleaf/calendar/index.css'

export function Demo() {
  const [date, setDate] = useState<DateValue | null>(null)
  return <Calendar mode="single" value={date} onSelect={setDate} />
}

Next steps

On this page