Skip to content

Calendar

export type CalendarWeekStart = 0 | 1 | 2 | 3 | 4 | 5 | 6;

export type CalendarView = 'month' | 'year';

interface CalendarDateRange {
readonly from: ISODateString;
readonly to: ISODateString
}

All non-date text rendered by the shared calendar.

interface CalendarTranslations {
readonly previousMonth: string;
readonly nextMonth: string;
readonly previousYear: string;
readonly nextYear: string;
readonly chooseMonth: string;
readonly calendar: string;
readonly today: string;
readonly invalidSelection: string
}

interface CalendarDayContext {
readonly outside: boolean;
readonly disabled: boolean;
readonly selected: boolean;
readonly previewed: boolean;
readonly today: boolean
}

interface CalendarSelectionValidationContext {
readonly month: ISODateString;
readonly view: CalendarView;
readonly selection?: CalendarDateRange;
readonly preview?: CalendarDateRange;
readonly referenceDate?: ISODateString
}

export type CalendarSelectionValidationResult = boolean | string;

interface CalendarProps {
readonly month: ISODateString;
readonly focusedDate: ISODateString;
readonly referenceDate?: ISODateString;
readonly selection?: CalendarDateRange;
readonly preview?: CalendarDateRange;
readonly locale?: string;
readonly weekStartsOn?: CalendarWeekStart;
readonly minDate?: ISODateString;
readonly maxDate?: ISODateString;
readonly isDateDisabled?: (date: ISODateString) => boolean;
readonly showOutsideDays?: boolean;
readonly allowOutsideMonthSelection?: boolean;
readonly fixedWeeks?: boolean;
readonly showTodayButton?: boolean;
/** Hides the complete month/year heading and navigation row. */
readonly showHeader?: boolean;
/** Convenience switch for both previous and next actions. */
readonly showNavigation?: boolean;
readonly showPreviousButton?: boolean;
readonly showNextButton?: boolean;
readonly showMonthLabel?: boolean;
readonly showWeekdays?: boolean;
/** Allows the month/year heading to open a twelve-month overview. Defaults to true. */
readonly enableYearView?: boolean;
/** Available views. Defaults to month and year; supersedes `enableYearView`. */
readonly views?: readonly CalendarView[];
readonly defaultView?: CalendarView;
readonly isMonthDisabled?: (month: ISODateString) => boolean;
/** Overrides any subset of the exported English calendar translations. */
readonly translations?: Partial<CalendarTranslations>;
readonly className?: string;
readonly dayClassName?: string | ((date: ISODateString, context: CalendarDayContext) => string | undefined);
readonly renderDay?: (date: ISODateString, context: CalendarDayContext) => ComponentChildren;
readonly formatMonth?: (month: ISODateString, locale: string) => string;
readonly formatWeekday?: (date: ISODateString, locale: string) => string;
readonly formatDayLabel?: (date: ISODateString, locale: string) => string;
readonly onMonthChange: (month: ISODateString) => void;
readonly onFocusedDateChange: (date: ISODateString) => void;
readonly onSelect: (date: ISODateString) => void;
readonly onPreviewDateChange?: (date?: ISODateString) => void;
readonly validateSelection?: (
date: ISODateString,
context: CalendarSelectionValidationContext,
) => CalendarSelectionValidationResult;
readonly onInvalidSelection?: (reason: string, date: ISODateString) => void;
readonly onViewChange?: (view: CalendarView) => void
}

interface MoveCalendarFocusOptions {
readonly date: ISODateString;
readonly key: string;
readonly shiftKey?: boolean;
readonly weekStartsOn: CalendarWeekStart;
readonly minDate?: ISODateString;
readonly maxDate?: ISODateString;
readonly isDisabled?: (date: ISODateString) => boolean
}

Complete English fallback used when a consumer does not override independent calendar text.

DEFAULT_CALENDAR_TRANSLATIONS: Readonly<CalendarTranslations>;

export function createCalendarMonth(
month: ISODateString,
weekStartsOn: CalendarWeekStart,
fixedWeeks = true,
): readonly ISODateString[];

export function orderCalendarRange(from: ISODateString, to: ISODateString): CalendarDateRange;

export function isDateInCalendarRange(date: ISODateString, range?: CalendarDateRange): boolean;

export function isCalendarDateDisabled(
date: ISODateString,
options: Pick<MoveCalendarFocusOptions, 'minDate' | 'maxDate' | 'isDisabled'>,
): boolean;

export function isCalendarMonthDisabled(
month: ISODateString,
options: Pick<MoveCalendarFocusOptions, 'minDate' | 'maxDate'> & {
readonly isMonthDisabled?: (month: ISODateString) => boolean;
},
): boolean;

export function moveCalendarFocus(options: MoveCalendarFocusOptions): ISODateString | undefined;

export function Calendar({
locale = 'en-US',
weekStartsOn = 1,
showOutsideDays = false,
allowOutsideMonthSelection = false,
fixedWeeks = true,
showTodayButton = false,
showHeader = true,
showNavigation = true,
showPreviousButton = showNavigation,
showNextButton = showNavigation,
showMonthLabel = true,
showWeekdays = true,
enableYearView = true,
translations = {},
formatMonth = defaultMonthFormat,
formatWeekday = defaultWeekdayFormat,
formatDayLabel = defaultDayLabel,
...props
}: CalendarProps);

export function CalendarHeader({
label,
previousLabel,
nextLabel,
labelAction,
showLabel = true,
showPrevious = true,
showNext = true,
previousDisabled = false,
nextDisabled = false,
onPrevious,
onNext,
}: {
label: string;
previousLabel: string;
nextLabel: string;
labelAction?: { ariaLabel: string; onClick: () => void };
showLabel?: boolean;
showPrevious?: boolean;
showNext?: boolean;
previousDisabled?: boolean;
nextDisabled?: boolean;
onPrevious: () => void;
onNext: () => void;
});

export function CalendarWeekdays({
dates,
locale,
format,
}: {
dates: readonly ISODateString[];
locale: string;
format: (date: ISODateString, locale: string) => string;
});

export function CalendarDay(props: CalendarDayProps);

interface CalendarDayProps {
readonly date: ISODateString;
readonly label: string;
readonly className?: string;
readonly outside: boolean;
readonly hidden: boolean;
readonly disabled: boolean;
readonly focused: boolean;
readonly selected: boolean;
readonly previewed: boolean;
readonly rangeStart: boolean;
readonly rangeEnd: boolean;
readonly previewStart: boolean;
readonly previewEnd: boolean;
readonly today: boolean;
readonly content?: ComponentChildren;
readonly setRef: (date: ISODateString, element: HTMLButtonElement | null) => void;
readonly onFocus: (date: ISODateString) => void;
readonly onPreview: (date?: ISODateString) => void;
readonly onKeyDown: (event: h.JSX.TargetedKeyboardEvent<HTMLButtonElement>, date: ISODateString) => void;
readonly onSelect: (date: ISODateString) => void
}

export function CalendarMonthGrid({
dates,
month,
focusedDate,
referenceDate,
selection,
preview,
showOutsideDays,
allowOutsideMonthSelection,
dayClassName,
renderDay,
isDisabled,
formatDayLabel,
setDayRef,
onFocus,
onPreview,
onKeyDown,
onSelect,
}: {
dates: readonly ISODateString[];
month: ISODateString;
focusedDate: ISODateString;
referenceDate?: ISODateString;
selection?: CalendarDateRange;
preview?: CalendarDateRange;
showOutsideDays: boolean;
allowOutsideMonthSelection: boolean;
dayClassName?: string | ((date: ISODateString, context: CalendarDayContext) => string | undefined);
renderDay?: (date: ISODateString, context: CalendarDayContext) => ComponentChildren;
isDisabled: (date: ISODateString) => boolean;
formatDayLabel: (date: ISODateString) => string;
setDayRef: (date: ISODateString, element: HTMLButtonElement | null) => void;
onFocus: (date: ISODateString) => void;
onPreview: (date?: ISODateString) => void;
onKeyDown: (event: h.JSX.TargetedKeyboardEvent<HTMLButtonElement>, date: ISODateString) => void;
onSelect: (date: ISODateString) => void;
});

export function CalendarYearGrid({
month,
referenceDate,
minDate,
maxDate,
isMonthDisabled,
locale,
ariaLabel,
onSelect,
onEscape,
}: {
month: ISODateString;
referenceDate?: ISODateString;
minDate?: ISODateString;
maxDate?: ISODateString;
isMonthDisabled?: (month: ISODateString) => boolean;
locale: string;
ariaLabel: string;
onSelect: (month: ISODateString) => void;
onEscape: () => void;
});