← All components
forms / stable

Calendar

Month grid for one date or a range; click the title to jump months and years, quick-range presets and side-by-side months for periods.

LIVE PREVIEW
Loading preview…

When to use

  • Inline date picking where the calendar is the main input (scheduling, availability).
  • Reporting periods: RangeCalendar with `presets` and `visibleMonths={2}`.

Consider an alternative

  • Dates inside forms — use DatePicker / DateRangePicker (they open this in a popover).

Import

import { Calendar } from '@revido-llc/kit';

Keyboard interaction

  • Arrows — day / week
  • Page Up / Page Down — month
  • Home / End — week edges
  • Enter — select
  • Esc — leave the month / year picker

Props

Props documented by the Kit. Refer to the TypeScript types for the complete interface, including inherited props.

classNamestring—
errorMessagestring—Shown under the grid while the value is invalid.
showFooterbooleantrueThe "Today" button and selection summary under the grid. Default true.
visibleMonths1 | 2 | 31Months shown side by side (1–3). Default 1.
createCalendar((identifier: CalendarIdentifier) => Calendar)—A function to create a new [Calendar](https://react-spectrum.adobe.com/internationalized/date/Calendar.html) object for a given calendar identifier. If not provided, the `createCalendar` function from `@internationalized/date` will be used.
defaultValueT—The default value (uncontrolled).
onChange((value: MappedDateValue<T>) => void)—Handler that is called when the value changes.
renderDOMRenderFunction<"div", CalendarRenderProps<"single">>—Overrides the default DOM element with a custom render function. This allows rendering existing components with built-in styles and behaviors such as router links, animation libraries, and pre-styled components. Requirements: - You must render the expected element type (e.g. if `<button>` is expected, you cannot render an `<a>`). - Only a single root DOM element can be rendered (no fragments). - You must pass through props and ref to the underlying DOM element, merging with your own prop as appropriate.
valueT—The current value (controlled).

Related exports

RangeCalendar

Examples

Single date (nl-NL)

Today has a cobalt number and dot, or an inner ring when selected; Monday starts the week in nl-NL.

<Calendar aria-label="Due date" value={date} onChange={setDate} />

Jump to a month or year

Click the month/year title, then the year in the month picker header. Picking a year opens its months; Esc goes back to the days.

<Calendar aria-label="Start date" value={date} onChange={setDate} />

Range with presets

Two months side by side, quick ranges on the left; the band previews while you hover after the first click.

<RangeCalendar aria-label="Reporting period" visibleMonths={2} presets value={range} onChange={setRange} />
// Your own (translated) presets:
<RangeCalendar presets={[{ label: "Deze week", range: (t) => ({ start: startOfWeek(t, "nl-NL"), end: t }) }]} />

Constraints

`minValue` and `isDateUnavailable` (weekends struck through); months before the minimum are disabled in the month picker.

<Calendar minValue={today(tz)} isDateUnavailable={(d) => isWeekend(d, locale)} />

Static anatomy 1

A literal starting point; bind selection and validation in the consuming app.

<Calendar aria-label="Choose a date" />

Static anatomy 2

A literal starting point; bind selection and validation in the consuming app.

<RangeCalendar aria-label="Choose a date range" />

Related components