| | import { useEffect, useMemo } from "react"; |
| |
|
| | import type { |
| | CalendarDay, |
| | CalendarMonth, |
| | CalendarWeek, |
| | DateLib, |
| | } from "./classes/index.js"; |
| | import { getDates } from "./helpers/getDates.js"; |
| | import { getDays } from "./helpers/getDays.js"; |
| | import { getDisplayMonths } from "./helpers/getDisplayMonths.js"; |
| | import { getInitialMonth } from "./helpers/getInitialMonth.js"; |
| | import { getMonths } from "./helpers/getMonths.js"; |
| | import { getNavMonths } from "./helpers/getNavMonth.js"; |
| | import { getNextMonth } from "./helpers/getNextMonth.js"; |
| | import { getPreviousMonth } from "./helpers/getPreviousMonth.js"; |
| | import { getWeeks } from "./helpers/getWeeks.js"; |
| | import { useControlledValue } from "./helpers/useControlledValue.js"; |
| | import type { DayPickerProps } from "./types/props.js"; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | export interface Calendar { |
| | |
| | |
| | |
| | |
| | |
| | days: CalendarDay[]; |
| | |
| | weeks: CalendarWeek[]; |
| | |
| | months: CalendarMonth[]; |
| |
|
| | |
| | nextMonth: Date | undefined; |
| | |
| | previousMonth: Date | undefined; |
| |
|
| | |
| | |
| | |
| | |
| | navStart: Date | undefined; |
| | |
| | |
| | |
| | |
| | navEnd: Date | undefined; |
| |
|
| | |
| | goToMonth: (month: Date) => void; |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | goToDay: (day: CalendarDay) => void; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | export function useCalendar( |
| | props: Pick< |
| | DayPickerProps, |
| | | "captionLayout" |
| | | "endMonth" |
| | | "startMonth" |
| | | "today" |
| | | "fixedWeeks" |
| | | "ISOWeek" |
| | | "numberOfMonths" |
| | | "pagedNavigation" |
| | | "reverseMonths" |
| | | "disableNavigation" |
| | | "onMonthChange" |
| | | "month" |
| | | "defaultMonth" |
| | | "timeZone" |
| | | "broadcastCalendar" |
| | |
| | | "fromMonth" |
| | | "fromYear" |
| | | "toMonth" |
| | | "toYear" |
| | >, |
| | dateLib: DateLib, |
| | ): Calendar { |
| | const [navStart, navEnd] = getNavMonths(props, dateLib); |
| |
|
| | const { startOfMonth, endOfMonth } = dateLib; |
| | const initialMonth = getInitialMonth(props, navStart, navEnd, dateLib); |
| | const [firstMonth, setFirstMonth] = useControlledValue( |
| | initialMonth, |
| | |
| | props.month ? initialMonth : undefined, |
| | ); |
| |
|
| | |
| | useEffect(() => { |
| | const newInitialMonth = getInitialMonth(props, navStart, navEnd, dateLib); |
| | setFirstMonth(newInitialMonth); |
| | }, [props.timeZone]); |
| |
|
| | |
| | |
| | const { months, weeks, days, previousMonth, nextMonth } = useMemo(() => { |
| | const displayMonths = getDisplayMonths( |
| | firstMonth, |
| | navEnd, |
| | { numberOfMonths: props.numberOfMonths }, |
| | dateLib, |
| | ); |
| |
|
| | const dates = getDates( |
| | displayMonths, |
| | props.endMonth ? endOfMonth(props.endMonth) : undefined, |
| | { |
| | ISOWeek: props.ISOWeek, |
| | fixedWeeks: props.fixedWeeks, |
| | broadcastCalendar: props.broadcastCalendar, |
| | }, |
| | dateLib, |
| | ); |
| |
|
| | const months = getMonths( |
| | displayMonths, |
| | dates, |
| | { |
| | broadcastCalendar: props.broadcastCalendar, |
| | fixedWeeks: props.fixedWeeks, |
| | ISOWeek: props.ISOWeek, |
| | reverseMonths: props.reverseMonths, |
| | }, |
| | dateLib, |
| | ); |
| |
|
| | const weeks = getWeeks(months); |
| | const days = getDays(months); |
| |
|
| | const previousMonth = getPreviousMonth( |
| | firstMonth, |
| | navStart, |
| | props, |
| | dateLib, |
| | ); |
| | const nextMonth = getNextMonth(firstMonth, navEnd, props, dateLib); |
| |
|
| | return { |
| | months, |
| | weeks, |
| | days, |
| | previousMonth, |
| | nextMonth, |
| | }; |
| | }, [ |
| | dateLib, |
| | firstMonth.getTime(), |
| | navEnd?.getTime(), |
| | navStart?.getTime(), |
| | props.disableNavigation, |
| | props.broadcastCalendar, |
| | props.endMonth?.getTime(), |
| | props.fixedWeeks, |
| | props.ISOWeek, |
| | props.numberOfMonths, |
| | props.pagedNavigation, |
| | props.reverseMonths, |
| | ]); |
| |
|
| | const { disableNavigation, onMonthChange } = props; |
| |
|
| | const isDayInCalendar = (day: CalendarDay) => |
| | weeks.some((week: CalendarWeek) => week.days.some((d) => d.isEqualTo(day))); |
| |
|
| | const goToMonth = (date: Date) => { |
| | if (disableNavigation) { |
| | return; |
| | } |
| | let newMonth = startOfMonth(date); |
| | |
| | if (navStart && newMonth < startOfMonth(navStart)) { |
| | newMonth = startOfMonth(navStart); |
| | } |
| | |
| | if (navEnd && newMonth > startOfMonth(navEnd)) { |
| | newMonth = startOfMonth(navEnd); |
| | } |
| | setFirstMonth(newMonth); |
| | onMonthChange?.(newMonth); |
| | }; |
| |
|
| | const goToDay = (day: CalendarDay) => { |
| | |
| | if (isDayInCalendar(day)) { |
| | return; |
| | } |
| | goToMonth(day.date); |
| | }; |
| |
|
| | const calendar = { |
| | months, |
| | weeks, |
| | days, |
| |
|
| | navStart, |
| | navEnd, |
| |
|
| | previousMonth, |
| | nextMonth, |
| |
|
| | goToMonth, |
| | goToDay, |
| | }; |
| |
|
| | return calendar; |
| | } |
| |
|