import { ChevronLeftIcon, ChevronRightIcon } from "@heroicons/react/solid";
import dayjs from "dayjs";
import isToday from "dayjs/plugin/isToday";
import { useMemo, useState } from "react";
import classNames from "@calcom/lib/classNames";
import { daysInMonth, yyyymmdd } from "@calcom/lib/date-fns";
import { weekdayNames } from "@calcom/lib/weekday";
dayjs.extend(isToday);
export type DatePickerProps = {
/** which day of the week to render the calendar. Usually Sunday (=0) or Monday (=1) - default: Sunday */
weekStart?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
/** Fires whenever a selected date is changed. */
onChange: (date: Date) => void;
/** Fires when the month is changed. */
onMonthChange?: (date: Date) => void;
/** which date is currently selected (not tracked from here) */
selected?: Date;
/** defaults to current date. */
minDate?: Date;
/** Furthest date selectable in the future, default = UNLIMITED */
maxDate?: Date;
/** locale, any IETF language tag, e.g. "hu-HU" - defaults to Browser settings */
locale: string;
/** Defaults to [], which dates are not bookable. Array of valid dates like: ["2022-04-23", "2022-04-24"] */
excludedDates?: string[];
/** defaults to all, which dates are bookable (inverse of excludedDates) */
includedDates?: string[];
/** allows adding classes to the container */
className?: string;
/** Shows a small loading spinner next to the month name */
isLoading?: boolean;
};
const Day = ({
date,
active,
...props
}: JSX.IntrinsicElements["button"] & { active: boolean; date: Date }) => {
return (
);
};
const Days = ({
minDate,
excludedDates = [],
includedDates = [],
browsingDate,
weekStart,
selected,
...props
}: Omit & {
browsingDate: Date;
weekStart: number;
}) => {
// Create placeholder elements for empty days in first week
const weekdayOfFirst = new Date(new Date(browsingDate).setDate(1)).getDay();
// memoize to prevent a flicker on redraw on the current day
const minDateValueOf = useMemo(() => {
return minDate?.valueOf() || new Date().valueOf();
}, [minDate]);
const days: (Date | null)[] = Array((weekdayOfFirst - weekStart + 7) % 7).fill(null);
for (let day = 1, dayCount = daysInMonth(browsingDate); day <= dayCount; day++) {
const date = new Date(new Date(browsingDate).setDate(day));
days.push(date);
}
return (
<>
{days.map((day, idx) => (