@reactleaf/calendar

Props

Calendar props: shared base options, then mode-specific fields for single, multiple, and range.

The root component is Calendar. Its props are a discriminated union on mode: 'single' | 'multiple' | 'range'.

Types are exported from @reactleaf/calendar (for example CalendarProps, CalendarRangeValue, CalendarMessages).

Shared props (CalendarBaseProps)

These apply to every mode. Mode sections below add fields on top of this table.

PropTypeNotes
mode'single' | 'multiple' | 'range'Required.
localestring (BCP 47)Intl formatting. Falls back to navigator.language, then en-US.
weekStartsOn060 = Sunday … 6 = Saturday. Default 0 (same convention as react-infinite-calendar).
messagesPartial<CalendarMessages>Header and ARIA strings; merged with English defaults. See CalendarMessages below.
formattersCalendarFormattersOptional functions for date/time display labels. See CalendarFormatters below.
minDateDateValueInclusive lower bound; also caps the infinite-scroll month list.
maxDateDateValueInclusive upper bound; same as above.
keyboardNavigationbooleanWhen true (default), Arrow keys move focus in the day grid; Enter/Space commits the focused day. Set false to disable that behavior.
includeTimebooleanWhen set, enables time editing in the header and the time subview where applicable.
onFocusedDateChange(date: DateValue | null) => voidCalled when the focused day in the grid changes (keyboard moves focus, clamping, or programmatic updates).

DateValue = Temporal.PlainDate | Temporal.PlainDateTime.
MonthValue = Temporal.PlainYearMonth.

Mode-specific props

Each mode extends CalendarBaseProps with the fields in its subsection (CalendarSingleProps, CalendarMultipleProps, or CalendarRangeProps).

mode: 'single' (CalendarSingleProps)

PropTypeNotes
valueDateValue | nullControlled selection.
defaultValueDateValue | nullUncontrolled initial value.
onSelect(next: DateValue | null) => voidSelection changes.
isDateDisabled(date: Temporal.PlainDate) => booleanOptional. Marks dates non-selectable inside minDatemaxDate. Outside that range is always disabled.

mode: 'multiple' (CalendarMultipleProps)

PropTypeNotes
valueDateValue[]Controlled selected dates.
defaultValueDateValue[]Uncontrolled initial list.
onSelect(next: DateValue[]) => voidSelection changes.
maxSelectionsnumberOptional cap on how many dates can be selected.
isDateDisabled(date: Temporal.PlainDate) => booleanSame contract as single.

mode: 'range' (CalendarRangeProps)

CalendarRangeValue is { start, end } with each field DateValue | null. Both null means nothing selected. After a start is chosen, start is set and end may stay null until the range is finished; onSelect / onRangePreview follow that lifecycle. With includeTime, endpoints may be Temporal.PlainDateTime; otherwise use plain dates.

Range does not support isDateDisabled: the model is a contiguous interval, so “holes” inside a range are not allowed—use minDate / maxDate only.

PropTypeNotes
valueCalendarRangeValueControlled range value; see shape above.
defaultValueCalendarRangeValueUncontrolled initial range.
onSelect(next: CalendarRangeValue) => voidCalled when the range is committed (both ends resolved per internal rules).
onRangePreview(next: CalendarRangeValue | null) => voidFires while the user is still choosing the range (e.g. after the first anchor, before commit). Hover and keyboard focus always update the provisional end; null clears the preview.

CalendarMessages

Pass a partial object; any omitted keys fall back to the built-in English defaults (DEFAULT_CALENDAR_MESSAGES).

KeyRoleen (default)
blankHeader line when there is no selection (single null, multiple [], range with no start). Used in the UI today.Select a date...
rangeFromPrefixPrefix before the range start column label.from
rangeToPrefixPrefix before the range end column label.to
rangeFromPlaceholderDate label when the range start is empty.
rangeToPlaceholderDate label when the range end is empty.
ariaOpenMonthPickerAccessible name for opening the month picker.Open month picker
ariaOpenDayGridAccessible name for returning to the day grid.Show day calendar
ariaCalendarGridAccessible name for the scrollable calendar grid.Infinite scroll calendar
ariaOpenMultipleSelectedListChip aria-label; {count} as above.Show {count} more selected dates
ariaMultipleSelectedDatesPanelaria-label for the extra-dates popover.Selected dates

CalendarFormatters

Formatter callbacks receive the date/time value and { locale }. Omitted callbacks fall back to the built-in Intl formatting.

KeyTypeRole
year(year: number, ctx: { locale: string }) => stringYear label in the month picker.
month(month: number, ctx: { locale: string }) => stringMonth label in the month picker.
monthYear(month: Temporal.PlainYearMonth, ctx: { locale: string }) => stringMonth row overlay label.
monthDate(date: Temporal.PlainDate, ctx: { locale: string }) => stringMonth-date labels in headers, including range start/end columns.
date(date: Temporal.PlainDate, ctx: { locale: string }) => stringFull date labels in the multiple-selection dropdown.
dateTime(value: Temporal.PlainDateTime, ctx: { locale: string }) => stringDate-time label in the multiple-selection time dropdown.
todayLabel(today: Temporal.PlainDate, ctx: { locale: string }) => stringFloating Today button and selected-today day cell label.

On this page