import {View, Text, Modal, Pressable, Image, TextStyle} from 'react-native'; import React, {ReactElement, useCallback, useState} from 'react'; import {styles} from './styles'; import {Calendar} from 'react-native-calendars'; import moment from 'moment'; import {headerInterface, props} from './interface'; import {MarkingProps} from 'react-native-calendars/src/calendar/day/marking'; import {days} from './useDatePicker'; const DatePicker: React.FC = props => { const { type = 'modal', showFooter = props?.type === 'modal', current, initialDate, minDate, maxDate, style, mode = 'single', theme, markingType, showLeftArrow = true, showRightArrow = true, hideArrows = false, showWeekDays = true, showTitle = true, header, dayNames, title, onChnage, ...rest } = props; const [markedDates, setmarkedDates] = useState<{[key: string]: any}>({}); const [startDate, setstartDate] = useState(null); const [endDate, setendDate] = useState(null); const [currentMonth, setcurrentMonth] = useState(moment().format('MMMM')); // calender view type const Root = useCallback( ({children}: {children: ReactElement}) => { if (type === 'modal') { return ( {children} ); } else { return {children}; } }, [props], ); // on press any date const onPressDay = (selected: string) => { // if mode is single markedDates always store ony one date element if (mode === 'single') { setmarkedDates({ [selected]: { selected: true, selectedColor: theme?.selectedDateColor ?? 'blue', }, }); // return single date as string onChnage(selected); } else { if (!startDate || (startDate && endDate)) { // If start date is not set or both start and end dates are set, // set the selected date as the start date. setstartDate(selected); setendDate(null); setmarkedDates({ [selected]: { selected: true, color: theme?.selectedDateBackground ?? 'blue', customTextStyle: { color: theme?.selectedDateColor ?? 'white', ...(style?.customTextStyle as TextStyle), }, customContainerStyle: style?.customContainerStyle, }, }); } else { // If start date is set but end date is not set, set the selected date as the end date. let range: {[key: string]: MarkingProps} = {}; // start date let date = new Date(startDate); // end date let end = new Date(selected); // select all dates between start and end while (date <= end) { let dateString = moment(date).format('YYYY-MM-DD'); range[dateString] = { type: 'period', // selectedTextColor: props?.theme?.selectedDateColor ?? 'green', startingDay: startDate === dateString, endingDay: selected === dateString, selected: true, color: theme?.selectedDateBackground ?? 'blue', customTextStyle: { color: theme?.selectedDateColor ?? 'white', ...(style?.customTextStyle as TextStyle), }, customContainerStyle: style?.customContainerStyle, }; date.setDate(date.getDate() + 1); } setendDate(selected); // return all selected dates in array of strings props.onChnage(Object.keys(range)); setmarkedDates(range); } } }; const Footer = () => { return ( {props?.cancelButton ? ( props.cancelButton ) : ( {props?.cancelButtonText ?? 'Cancel'} )} {props?.confirmButton ? ( props.confirmButton ) : ( {props?.cancelButtonText ?? 'Ok'} )} ); }; const Header = (header: headerInterface) => { return ( {!hideArrows && showLeftArrow && ( (!!header?.addMonth ? header?.addMonth(-1) : {})} style={[ styles.arrow_button, style?.headerButton, style?.leftArrowButton, ]}> )} {showTitle && title ? ( title ) : ( {currentMonth} )} {!hideArrows && showRightArrow && ( (!!header?.addMonth ? header?.addMonth(1) : {})} style={[ styles.arrow_button, style?.headerButton, style?.RightArrowButton, ]}> )} {showWeekDays && ( {(dayNames && dayNames.length === 7 ? dayNames : days).map( (item, index) => { return ( {item} ); }, )} )} ); }; return ( onPressDay(day.dateString)} current={props?.current ?? moment().format('YYYY-MM-DD')} initialDate={props?.initialDate ?? ''} minDate={props?.minDate ?? ''} maxDate={props?.maxDate ?? ''} style={[styles.calender_wrapper, props?.style?.calender]} markedDates={markedDates} enableSwipeMonths={true} hideExtraDays={props?.hideExtraDays ?? false} showSixWeeks={props?.showSixWeeks ?? false} disableArrowLeft={true} disableArrowRight={true} onMonthChange={e => { setcurrentMonth(moment(e.timestamp).format('MMMM')); }} markingType={ markingType ? markingType : mode === 'rangePicker' ? 'period' : undefined } customHeader={(e: headerInterface) => // props includes header , render props header !!header ? header(e, currentMonth) :
} /> {props?.footer ? props.footer : props?.type === 'modal' && showFooter &&