UNPKG

react-native-future-date-range-calendar

Version:
131 lines (130 loc) 7.58 kB
/* eslint-disable @typescript-eslint/restrict-plus-operands */ import React from 'react'; import { Dimensions, FlatList } from 'react-native'; import { findTwoDatesDifference, initializeCalendarData, pushCalendarDaysStructureForCurrentMonth, pushCalendarDaysStructureForNextMonth, pushCalendarDaysStructureForPreviousMonth, resetCalendarDaysStructureForCurrentMonth, resetCalendarDaysStructureForNextMonth, resetCalendarDaysStructureForPreviousMonth, } from './utils'; import moment from 'moment'; import { DateRangeHandler, disablePreviousDays } from './calendar-helper'; import { CommonState } from './context/common-provider'; import { CalendarRenderer } from './calendar-renderer'; export const FutureDateRangeCalendarRenderer = React.memo((props) => { const [disableDays, setDisableDays] = React.useState([]); const { selectedDate, dateSelected } = CommonState(); const flatListRef = React.useRef(null); const [currentIndex, setCurrentIndex] = React.useState(0); const renderMonthsLimit = props?.totalMonthsRenderLimit ?? 12; const cardWidth = props?.width ?? Dimensions.get("screen").width; const { calendarType = 'type1', horizontal = true } = props; const handlePrev = () => { if (currentIndex > 0) { const nextIndex = currentIndex - 1; setCurrentIndex(nextIndex); flatListRef.current.scrollToIndex({ index: nextIndex }); } }; const handleNext = () => { if (currentIndex < renderMonthsLimit) { const nextIndex = currentIndex + 1; setCurrentIndex(nextIndex); flatListRef.current.scrollToIndex({ index: nextIndex }); } }; const handleScroll = (event) => { const index = Math.round(event.nativeEvent.contentOffset.x / cardWidth); setCurrentIndex(index); if (props?.onSwipe) { props?.onSwipe(index); } }; const monthsToScroll = React.useMemo(() => { return new Array(1).fill(0); }, []); const { currentYear, currentMonth, currentDate, currentMonthDate, _currentYear, _currentMonth, calendarDaysList, monthLimit } = initializeCalendarData(); let count = 0; const renderCalendar = ({ index }) => { const month = moment([_currentYear, _currentMonth]) .add(index, "months") .month(); let year = moment([_currentYear, _currentMonth]).year(); if (index > 0 && month === 0) { if (count < 1) { count += 1; } } if (index > monthLimit) { year = moment([_currentYear + count, _currentMonth]).year(); } const firstDayOfTheMonth = moment([_currentYear, _currentMonth]) .add(index, "months") .startOf("month") .day(); const lastDateOfTheMonth = moment([_currentYear, _currentMonth]) .add(index, "months") .endOf("month") .date(); const lastDateOfTheLastMonth = moment([_currentYear, _currentMonth]) .add(index, "months") .subtract(1, "months") .endOf("month") .date(); const lastDayOfTheMonth = moment([_currentYear, _currentMonth]) .add(index, "months") .endOf("month") .day(); resetCalendarDaysStructureForPreviousMonth(calendarDaysList); resetCalendarDaysStructureForCurrentMonth(calendarDaysList); resetCalendarDaysStructureForNextMonth(calendarDaysList); for (let i = firstDayOfTheMonth; i > 0; i--) { const data = { date: lastDateOfTheLastMonth - i + 1, month: month + 1, year, }; pushCalendarDaysStructureForPreviousMonth(calendarDaysList, data); } const daysDiff = findTwoDatesDifference(currentDate, currentMonthDate); for (let i = 1; i <= lastDateOfTheMonth; i++) { const data = { date: i, month: month + 1, year, firstDayOfTheMonth, lastDateOfTheMonth, completeDate: moment({ year, month, day: i }).format('YYYY-MM-DD'), type: i <= daysDiff && month + 1 === currentMonth && year === currentYear ? 'disable' : 'enable', }; pushCalendarDaysStructureForCurrentMonth(calendarDaysList, data); } for (let i = lastDayOfTheMonth; i < 6; i++) { const data = { date: i - lastDayOfTheMonth + 1, month: month + 1, year, }; pushCalendarDaysStructureForNextMonth(calendarDaysList, data); } return (React.createElement(CalendarRenderer, { width: props?.width, horizontal: horizontal, calendarType: calendarType, renderPreviousIcon: props?.renderPreviousIcon, renderNextIcon: props?.renderNextIcon, disableHeaderYearAppearance: props?.disableHeaderYearAppearance, monthTextCustomStyle: props?.monthTextCustomStyle, weekDaysCustomStyle: props?.weekDaysCustomStyle, weekDayCustomStyle: props?.weekDayCustomStyle, dayCustomStyle: props?.dayCustomStyle, disabledDaysCustomStyle: props?.disabledDaysCustomStyle, disabledDaysCustomTextStyle: props?.disabledDaysCustomTextStyle, activeOpacity: props?.activeOpacity, nonRangeDaysCustomStyle: props?.nonRangeDaysCustomStyle, nonRangeDaysCustomTextStyle: props?.nonRangeDaysCustomTextStyle, rangeDaysBackgroundColor: props?.rangeDaysBackgroundColor, startAndEndDateBackgroundColor: props?.startAndEndDateBackgroundColor, startAndEndDateTextColor: props?.startAndEndDateTextColor, rangeDaysTextColor: props?.rangeDaysTextColor, months: props?.months, weekDays: props?.weekDays, totalMonthsRenderLimit: props?.totalMonthsRenderLimit, days: calendarDaysList, month: month, year: year, handleNext: handleNext, handlePrev: handlePrev })); }; React.useEffect(() => { // markedDates() if (selectedDate === '') { setDisableDays(disablePreviousDays(currentMonthDate, currentDate, renderMonthsLimit, _currentMonth, _currentYear, currentMonth).listOfDisabledDates); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [selectedDate, dateSelected]); return (React.createElement(React.Fragment, null, React.createElement(DateRangeHandler, { disablePreviousDateSelection: props?.disablePreviousDateSelection, onDateSelect: props?.onDateSelect }), horizontal ? React.createElement(FlatList, { ref: flatListRef, onScroll: handleScroll, scrollEventThrottle: 16, horizontal: true, pagingEnabled: true, showsHorizontalScrollIndicator: false, snapToInterval: cardWidth, decelerationRate: "fast" // Optional: makes swipe faster and snappier , bounces: false, overScrollMode: 'never', showsVerticalScrollIndicator: false, data: monthsToScroll, keyExtractor: (item, index) => index.toString(), renderItem: renderCalendar, onEndReached: () => { if (monthsToScroll?.length <= renderMonthsLimit) { monthsToScroll.push(0); } } }) : React.createElement(FlatList, { showsVerticalScrollIndicator: false, data: monthsToScroll, keyExtractor: (item, index) => index.toString(), renderItem: renderCalendar, onEndReached: () => { if (monthsToScroll?.length <= renderMonthsLimit) { monthsToScroll.push(0); } } }))); });