import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; import _extends from "@babel/runtime/helpers/esm/extends"; import * as React from 'react'; import useEventCallback from '@mui/utils/useEventCallback'; import { useIsDateDisabled } from './useIsDateDisabled'; import { useUtils } from '../internals/hooks/useUtils'; import { singleItemValueManager } from '../internals/utils/valueManagers'; import { SECTION_TYPE_GRANULARITY } from '../internals/utils/getDefaultReferenceDate'; export var createCalendarStateReducer = function createCalendarStateReducer(reduceAnimations, disableSwitchToMonthOnDayFocus, utils) { return function (state, action) { switch (action.type) { case 'changeMonth': return _extends({}, state, { slideDirection: action.direction, currentMonth: action.newMonth, isMonthSwitchingAnimating: !reduceAnimations }); case 'finishMonthSwitchingAnimation': return _extends({}, state, { isMonthSwitchingAnimating: false }); case 'changeFocusedDay': { if (state.focusedDay != null && action.focusedDay != null && utils.isSameDay(action.focusedDay, state.focusedDay)) { return state; } var needMonthSwitch = action.focusedDay != null && !disableSwitchToMonthOnDayFocus && !utils.isSameMonth(state.currentMonth, action.focusedDay); return _extends({}, state, { focusedDay: action.focusedDay, isMonthSwitchingAnimating: needMonthSwitch && !reduceAnimations && !action.withoutMonthSwitchingAnimation, currentMonth: needMonthSwitch ? utils.startOfMonth(action.focusedDay) : state.currentMonth, slideDirection: action.focusedDay != null && utils.isAfterDay(action.focusedDay, state.currentMonth) ? 'left' : 'right' }); } default: throw new Error('missing support'); } }; }; export var useCalendarState = function useCalendarState(params) { var value = params.value, referenceDateProp = params.referenceDate, defaultCalendarMonth = params.defaultCalendarMonth, disableFuture = params.disableFuture, disablePast = params.disablePast, _params$disableSwitch = params.disableSwitchToMonthOnDayFocus, disableSwitchToMonthOnDayFocus = _params$disableSwitch === void 0 ? false : _params$disableSwitch, maxDate = params.maxDate, minDate = params.minDate, onMonthChange = params.onMonthChange, reduceAnimations = params.reduceAnimations, shouldDisableDate = params.shouldDisableDate, timezone = params.timezone; var utils = useUtils(); var reducerFn = React.useRef(createCalendarStateReducer(Boolean(reduceAnimations), disableSwitchToMonthOnDayFocus, utils)).current; var referenceDate = React.useMemo(function () { var externalReferenceDate = null; if (referenceDateProp) { externalReferenceDate = referenceDateProp; } else if (defaultCalendarMonth) { // For `defaultCalendarMonth`, we just want to keep the month and the year to avoid a behavior change. externalReferenceDate = utils.startOfMonth(defaultCalendarMonth); } return singleItemValueManager.getInitialReferenceValue({ value: value, utils: utils, timezone: timezone, props: params, referenceDate: externalReferenceDate, granularity: SECTION_TYPE_GRANULARITY.day }); }, [] // eslint-disable-line react-hooks/exhaustive-deps ); var _React$useReducer = React.useReducer(reducerFn, { isMonthSwitchingAnimating: false, focusedDay: referenceDate, currentMonth: utils.startOfMonth(referenceDate), slideDirection: 'left' }), _React$useReducer2 = _slicedToArray(_React$useReducer, 2), calendarState = _React$useReducer2[0], dispatch = _React$useReducer2[1]; var handleChangeMonth = React.useCallback(function (payload) { dispatch(_extends({ type: 'changeMonth' }, payload)); if (onMonthChange) { onMonthChange(payload.newMonth); } }, [onMonthChange]); var changeMonth = React.useCallback(function (newDate) { var newDateRequested = newDate; if (utils.isSameMonth(newDateRequested, calendarState.currentMonth)) { return; } handleChangeMonth({ newMonth: utils.startOfMonth(newDateRequested), direction: utils.isAfterDay(newDateRequested, calendarState.currentMonth) ? 'left' : 'right' }); }, [calendarState.currentMonth, handleChangeMonth, utils]); var isDateDisabled = useIsDateDisabled({ shouldDisableDate: shouldDisableDate, minDate: minDate, maxDate: maxDate, disableFuture: disableFuture, disablePast: disablePast, timezone: timezone }); var onMonthSwitchingAnimationEnd = React.useCallback(function () { dispatch({ type: 'finishMonthSwitchingAnimation' }); }, []); var changeFocusedDay = useEventCallback(function (newFocusedDate, withoutMonthSwitchingAnimation) { if (!isDateDisabled(newFocusedDate)) { dispatch({ type: 'changeFocusedDay', focusedDay: newFocusedDate, withoutMonthSwitchingAnimation: withoutMonthSwitchingAnimation }); } }); return { referenceDate: referenceDate, calendarState: calendarState, changeMonth: changeMonth, changeFocusedDay: changeFocusedDay, isDateDisabled: isDateDisabled, onMonthSwitchingAnimationEnd: onMonthSwitchingAnimationEnd, handleChangeMonth: handleChangeMonth }; };