UNPKG

react-native-easy-calendar

Version:

Customizable, easy-to-use, performant calendar components for React Native

157 lines (150 loc) 6.01 kB
import React, { useEffect, useState, useCallback } from 'react'; import { View } from 'react-native'; import dayjs from 'dayjs'; import localeData from 'dayjs/plugin/localeData'; import localizedFormat from 'dayjs/plugin/localizedFormat'; import utc from 'dayjs/plugin/utc'; import { getSurroundingTimeUnits } from '../Utils'; import { useSurroundingTimeUnits } from '../Hooks'; import { ThemeContext, LocaleContext } from '../Contexts'; import { VIEW } from '../Constants'; import { Months, Days, Arrow as DefaultArrow, Title as DefaultTitle, Weekdays as DefaultWeekdays } from '../Components'; dayjs.extend(localeData); dayjs.extend(localizedFormat); dayjs.extend(utc); const BaseCalendar = ({ ArrowComponent: CustomArrow, TitleComponent: CustomTitle, WeekdaysComponent: CustomWeekdays, DayComponent, MonthComponent, allowYearView, showExtraDates, onPressDay, maxDate, minDate, initVisibleDate, dateProperties, testID }) => { const theme = React.useContext(ThemeContext); const locale = React.useContext(LocaleContext); const [rightArrowDisabled, disableRightArrow] = useState(false); const [leftArrowDisabled, disableLeftArrow] = useState(false); const [activeView, setActiveView] = useState(VIEW.MONTH); const [visibleDate, setVisibleDate] = useState(initVisibleDate !== null && initVisibleDate !== void 0 ? initVisibleDate : dayjs().local().format()); const localeAwareVisibleDate = React.useMemo(() => dayjs(visibleDate).locale(locale.name, locale), [locale, visibleDate]); const weekdays = React.useMemo(() => { var _locale$weekdaysShort; return (_locale$weekdaysShort = locale.weekdaysShort) !== null && _locale$weekdaysShort !== void 0 ? _locale$weekdaysShort : ['']; }, [locale]); const { month, year } = useSurroundingTimeUnits(visibleDate); const verifyUnitIsPastMaxDate = useCallback(unit => { if (maxDate) { if (unit.isAfter(maxDate)) { disableRightArrow(true); } else { disableRightArrow(false); } } }, [disableRightArrow, maxDate]); const verifyUnitIsBeforeMinDate = useCallback(unit => { if (minDate) { if (unit.isBefore(minDate)) { disableLeftArrow(true); } else { disableLeftArrow(false); } } }, [disableLeftArrow, minDate]); const toggleCalendarView = useCallback((newVisibleDate = visibleDate) => { const { month: _month, year: _year } = getSurroundingTimeUnits(newVisibleDate); if (activeView === VIEW.MONTH) { setActiveView(VIEW.YEAR); verifyUnitIsPastMaxDate(_year.next); verifyUnitIsBeforeMinDate(_year.last); } if (activeView === VIEW.YEAR) { setActiveView(VIEW.MONTH); verifyUnitIsPastMaxDate(_month.next); verifyUnitIsBeforeMinDate(_month.last); } }, [activeView, verifyUnitIsBeforeMinDate, verifyUnitIsPastMaxDate, visibleDate]); useEffect(() => { verifyUnitIsPastMaxDate(month.next.start); verifyUnitIsBeforeMinDate(month.last.end); }, [month.last.end, month.next.start, verifyUnitIsPastMaxDate, verifyUnitIsBeforeMinDate]); const addMonth = useCallback(() => { setVisibleDate(month.next.start.local().format()); verifyUnitIsPastMaxDate(month.afterNext); verifyUnitIsBeforeMinDate(month.current.end); }, [month, verifyUnitIsBeforeMinDate, verifyUnitIsPastMaxDate]); const subtractMonth = useCallback(() => { setVisibleDate(month.last.start.local().format()); verifyUnitIsPastMaxDate(month.current.start); verifyUnitIsBeforeMinDate(month.beforeLast); }, [month, verifyUnitIsBeforeMinDate, verifyUnitIsPastMaxDate]); const addYear = useCallback(() => { setVisibleDate(year.next.persistMonth.local().format()); verifyUnitIsPastMaxDate(year.afterNext); verifyUnitIsBeforeMinDate(year.current.end); }, [year, verifyUnitIsBeforeMinDate, verifyUnitIsPastMaxDate]); const subtractYear = useCallback(() => { setVisibleDate(year.last.persistMonth.local().format()); verifyUnitIsPastMaxDate(year.current.start); verifyUnitIsBeforeMinDate(year.beforeLast); }, [year, verifyUnitIsBeforeMinDate, verifyUnitIsPastMaxDate]); const onPressMonth = newVisibleDate => { setVisibleDate(newVisibleDate); toggleCalendarView(newVisibleDate); }; const Weekdays = CustomWeekdays || DefaultWeekdays; const Arrow = CustomArrow || DefaultArrow; const Title = CustomTitle || DefaultTitle; return /*#__PURE__*/React.createElement(View, { style: theme.calendarContainer, testID: testID }, /*#__PURE__*/React.createElement(View, { testID: 'header', style: theme.headerContainer }, /*#__PURE__*/React.createElement(Arrow, { direction: 'left', isDisabled: leftArrowDisabled, onPress: activeView === VIEW.MONTH ? subtractMonth : subtractYear }), /*#__PURE__*/React.createElement(Title, { activeView: activeView, locale: locale, date: localeAwareVisibleDate.format('YYYY-MM-DD'), isDisabled: !allowYearView, onPress: toggleCalendarView }), /*#__PURE__*/React.createElement(Arrow, { direction: 'right', isDisabled: rightArrowDisabled, onPress: activeView === VIEW.MONTH ? addMonth : addYear })), activeView === VIEW.MONTH ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Weekdays, { days: weekdays }), /*#__PURE__*/React.createElement(Days, { DayComponent: DayComponent, visibleDate: localeAwareVisibleDate, showExtraDates: !!showExtraDates, dateProperties: dateProperties, onPressDay: onPressDay, minDate: minDate, maxDate: maxDate })) : /*#__PURE__*/React.createElement(Months, { MonthComponent: MonthComponent, visibleDate: localeAwareVisibleDate, minDate: minDate ? dayjs(minDate).local().format() : undefined, maxDate: maxDate ? dayjs(maxDate).local().format() : undefined, dateProperties: dateProperties, onPressMonth: onPressMonth })); }; export default BaseCalendar; //# sourceMappingURL=BaseCalendar.js.map