import * as React from 'react'; import { makeStyles } from '@material-ui/core/styles'; import { MonthSelection } from './MonthSelection'; import { DatePickerView } from '../../DatePicker'; import { useCalendarState } from './useCalendarState'; import { useUtils } from '../../_shared/hooks/useUtils'; import { FadeTransitionGroup } from './FadeTransitionGroup'; import { Calendar, ExportedCalendarProps } from './Calendar'; import { PickerOnChangeFn } from '../../_shared/hooks/useViews'; import { useDefaultProps } from '../../_shared/withDefaultProps'; import { DAY_SIZE, DAY_MARGIN } from '../../constants/dimensions'; import { CalendarHeader, ExportedCalendarHeaderProps } from './CalendarHeader'; import { YearSelection, ExportedYearSelectionProps } from './YearSelection'; import { defaultMinDate, defaultMaxDate } from '../../constants/prop-types'; import { IsStaticVariantContext } from '../../wrappers/WrapperVariantContext'; import { DateValidationProps, findClosestEnabledDate } from '../../_helpers/date-utils'; import { MonthProps } from './Month'; export interface CalendarViewProps extends DateValidationProps, ExportedCalendarProps, ExportedYearSelectionProps, ExportedCalendarHeaderProps { date: TDate; view: DatePickerView; views: DatePickerView[]; changeView: (view: DatePickerView) => void; onChange: PickerOnChangeFn; /** * Disable heavy animations. * * @default /(android)/i.test(window.navigator.userAgent). */ reduceAnimations?: boolean; /** * Callback firing on month change. @DateIOType */ onMonthChange?: (date: TDate) => void; renderMonth?: (date: TDate, monthProps: MonthProps) => JSX.Element; hijri?: any } export type ExportedCalendarViewProps = Omit< CalendarViewProps, 'date' | 'view' | 'views' | 'onChange' | 'changeView' | 'slideDirection' | 'currentMonth' >; const muiComponentConfig = { name: 'MuiPickersCalendarView' }; export const useStyles = makeStyles( { viewTransitionContainer: { overflowY: 'auto', }, fullHeightContainer: { flex: 1, display: 'flex', justifyContent: 'center', alignItems: 'center', minHeight: (DAY_SIZE + DAY_MARGIN * 4) * 7, height: '100%', }, }, muiComponentConfig ); export const defaultReduceAnimations = typeof navigator !== 'undefined' && /(android)/i.test(navigator.userAgent); export function CalendarView(props: CalendarViewProps) { const { allowKeyboardControl: allowKeyboardControlProp, changeView, date, disableFuture, disablePast, loading, maxDate: maxDateProp, minDate: minDateProp, onChange, onMonthChange, reduceAnimations = defaultReduceAnimations, renderLoading, shouldDisableDate, shouldDisableYear, view, renderMonth, hijri, ...other } = useDefaultProps(props, muiComponentConfig); const utils = useUtils(); const classes = useStyles(); const isStatic = React.useContext(IsStaticVariantContext); const allowKeyboardControl = allowKeyboardControlProp ?? !isStatic; const minDate = minDateProp || utils.date(defaultMinDate)!; const maxDate = maxDateProp || utils.date(defaultMaxDate)!; const { calendarState, changeFocusedDay, changeMonth, isDateDisabled, handleChangeMonth, onMonthSwitchingAnimationEnd, } = useCalendarState({ date, reduceAnimations, onMonthChange, minDate, maxDate, shouldDisableDate, disablePast, disableFuture, }); React.useEffect(() => { if (date && isDateDisabled(date)) { const closestEnabledDate = findClosestEnabledDate({ utils, date, minDate, maxDate, disablePast: Boolean(disablePast), disableFuture: Boolean(disableFuture), shouldDisableDate: isDateDisabled, }); onChange(closestEnabledDate, 'partial'); } // This call is too expensive to run it on each prop change. // So just ensure that we are not rendering disabled as selected on mount. }, []); // eslint-disable-line React.useEffect(() => { changeMonth(date); }, [date]); // eslint-disable-line return ( handleChangeMonth({ newMonth, direction })} minDate={minDate} maxDate={maxDate} disablePast={disablePast} disableFuture={disableFuture} reduceAnimations={reduceAnimations} />
{view === 'year' && ( )} {view === 'month' && ( )} {view === 'date' && ( )}
); }