import { Locale, isSameYear } from "date-fns"; import React from "react"; import { createStrictContext } from "../../utils/helpers"; import { useControllableState } from "../../utils/hooks"; import { clampDisplayYear } from "../date-utils"; import { MonthPickerProps } from "./MonthPicker.types"; type MonthPickerProviderProps = Pick< MonthPickerProps, | "dropdownCaption" | "disabled" | "selected" | "defaultSelected" | "onMonthSelect" | "year" | "onYearChange" | "fromDate" | "toDate" > & { children: React.ReactNode; locale: Locale; }; type MonthPickerContextProps = { caption: "label" | "dropdown"; year: Date; onYearChange: (year: Date) => void; selected: MonthPickerProps["selected"]; onMonthSelect: MonthPickerProps["onMonthSelect"]; disabled: NonNullable; locale: Locale; fromDate?: MonthPickerProps["fromDate"]; toDate?: MonthPickerProps["toDate"]; }; const { Provider: MonthPickerContextProvider, useContext: useMonthPickerContext, } = createStrictContext({ name: "MonthPickerContext", errorMessage: "useMonthPickerContext must be used within an MonthPickerContextProvider", }); const MonthPickerProvider = ({ children, disabled = [], year, onYearChange, fromDate, toDate, selected, defaultSelected, onMonthSelect, dropdownCaption, locale, }: MonthPickerProviderProps) => { /** * Controlls current displayed year in MonthPicker */ const [displayYear, setDisplayYear] = useControllableState({ defaultValue: clampDisplayYear({ month: year ?? selected ?? defaultSelected, start: fromDate, end: toDate, }) ?? new Date(), value: year, onChange: onYearChange, }); /** * Allows both controlled and uncontrolled use of MonthPicker */ const [month, setMonth] = useControllableState({ defaultValue: defaultSelected, value: selected, onChange: onMonthSelect, }); const handleDisplayYearUpdate = (newYear: Date) => { if (isSameYear(newYear, displayYear)) { return; } setDisplayYear(newYear); }; return ( {children} ); }; export { MonthPickerProvider, useMonthPickerContext };