import React from 'react';
import clsx from 'clsx';
import {m} from 'framer-motion';
import {
CalendarDate,
endOfMonth,
getWeeksInMonth,
startOfMonth,
startOfWeek,
} from '@internationalized/date';
import {KeyboardArrowLeftIcon} from '../../../../../icons/material/KeyboardArrowLeft';
import {IconButton} from '../../../../buttons/icon-button';
import {KeyboardArrowRightIcon} from '../../../../../icons/material/KeyboardArrowRight';
import {CalendarCell} from './calendar-cell';
import {DatePickerState} from '../date-picker/use-date-picker-state';
import {useDateFormatter} from '../../../../../i18n/use-date-formatter';
import {useSelectedLocale} from '../../../../../i18n/selected-locale';
import {dateIsInvalid} from '../utils';
import {DateRangePickerState} from '../date-range-picker/use-date-range-picker-state';
export interface CalendarMonthProps {
state: DatePickerState | DateRangePickerState;
startDate: CalendarDate;
isFirst: boolean;
isLast: boolean;
}
export function CalendarMonth({
startDate,
state,
isFirst,
isLast,
}: CalendarMonthProps) {
const {localeCode} = useSelectedLocale();
const weeksInMonth = getWeeksInMonth(startDate, localeCode);
const monthStart = startOfWeek(startDate, localeCode);
return (
{[...new Array(weeksInMonth).keys()].map(weekIndex => (
{[...new Array(7).keys()].map(dayIndex => (
))}
))}
);
}
interface CalendarMonthHeaderProps {
state: DatePickerState | DateRangePickerState;
currentMonth: CalendarDate;
isFirst: boolean;
isLast: boolean;
}
function CalendarMonthHeader({
currentMonth,
isFirst,
isLast,
state: {calendarDates, setCalendarDates, timezone, min, max},
}: CalendarMonthHeaderProps) {
const shiftCalendars = (direction: 'forward' | 'backward') => {
const count = calendarDates.length;
let newDates: CalendarDate[];
if (direction === 'forward') {
newDates = calendarDates.map(date =>
endOfMonth(date.add({months: count}))
);
} else {
newDates = calendarDates.map(date =>
endOfMonth(date.subtract({months: count}))
);
}
setCalendarDates(newDates);
};
const monthFormatter = useDateFormatter({
month: 'long',
year: 'numeric',
era: currentMonth.calendar.identifier !== 'gregory' ? 'long' : undefined,
calendar: currentMonth.calendar.identifier,
});
const isBackwardDisabled = dateIsInvalid(
currentMonth.subtract({days: 1}),
min,
max
);
const isForwardDisabled = dateIsInvalid(
startOfMonth(currentMonth.add({months: 1})),
min,
max
);
return (
{
shiftCalendars('backward');
}}
>
{monthFormatter.format(currentMonth.toDate(timezone))}
{
shiftCalendars('forward');
}}
>
);
}
interface WeekdayHeaderProps {
state: DatePickerState | DateRangePickerState;
startDate: CalendarDate;
}
function WeekdayHeader({state: {timezone}, startDate}: WeekdayHeaderProps) {
const {localeCode} = useSelectedLocale();
const dayFormatter = useDateFormatter({weekday: 'short'});
const monthStart = startOfWeek(startDate, localeCode);
return (
{[...new Array(7).keys()].map(index => {
const date = monthStart.add({days: index});
const dateDay = date.toDate(timezone);
const weekday = dayFormatter.format(dateDay);
return (
);
})}
);
}