import { MonthYearPickerDialogueAndroid, MonthYearPickerViewIOS, } from '@hero-design/react-native-month-year-picker'; import format from 'date-fns/fp/format'; import React, { useState } from 'react'; import { Platform, TouchableOpacity } from 'react-native'; import { useTheme } from '../../theme'; import { noop } from '../../utils/functions'; import Box from '../Box'; import ContentNavigator from '../ContentNavigator'; import Icon from '../Icon'; import Typography from '../Typography'; import CalendarRowItem from './CalendarRowItem'; import { StyledCalendarDayNameCell, StyledCalendarHeader, StyledCalendarRow, StyledCalendarRowItem, StyledContainer, StyledDisabledCalendarRowItem, } from './StyledCalendar'; import { getCalendarButtonState, getCalendarDate, isDateInRange, isEqDate, setStartOrEndDate, shouldUseMonthPicker, } from './helpers'; import SelectedDate from './CalendarRangeConnector'; import type { CalendarProps } from './types'; import { DAYS_OF_WEEK } from './constants'; import { useCalendarLayout } from './shared/hooks/useCalendarLayout'; export type CalendarDateRange = { startDate?: Date; endDate?: Date; }; const CalendarRange = ({ value, visibleDate, onChange, onPreviousPress = noop, onNextPress = noop, onTitlePress = noop, minDate, maxDate, markedDates = [], testID, onMonthChange = noop, onToggleMonthPicker = noop, monthPickerConfirmLabel, monthPickerCancelLabel, }: Omit & { value?: CalendarDateRange; onChange?: (date: CalendarDateRange) => void; }) => { const theme = useTheme(); const [monthPickerVisible, setMonthPickerVisible] = useState(false); const { onLayout, contentHeight, contentWidth, calendarItemWidth } = useCalendarLayout(); const { parsedMaskedDate, daysOfPreviousMonth, daysOfCurrentMonth, daysOfNextMonth, } = getCalendarDate({ visibleDate, markedDates, minDate, maxDate, onMonthChange, }); const { disablePrevButton, disableNextButton } = getCalendarButtonState({ visibleDate, minDate, maxDate, }); const shouldShowMonthPicker = shouldUseMonthPicker(onMonthChange); const now = new Date(); const onDateChange = (date: Date) => { const newDateRange = setStartOrEndDate({ date, startDate: value?.startDate, endDate: value?.endDate, }); onChange?.(newDateRange); }; const renderDateCell = ({ date, isCurrentMonth, }: { date?: Date; isCurrentMonth: boolean; }) => { if (!date) { return ( ); } if (isEqDate(value?.startDate, date) || isEqDate(value?.endDate, date)) { return ( onDateChange(date)} marked={parsedMaskedDate[date.toDateString()]} itemWidth={calendarItemWidth} /> ); } return ( onDateChange(date)} marked={parsedMaskedDate[date.toDateString()]} textIntent={isCurrentMonth ? undefined : 'subdued'} /> ); }; return ( { onToggleMonthPicker?.(!monthPickerVisible); setMonthPickerVisible(!monthPickerVisible); }} > {format('MMMM yyyy', visibleDate)} ) } onPreviousPress={onPreviousPress} onNextPress={onNextPress} onPress={shouldShowMonthPicker ? undefined : onTitlePress} previousDisabled={disablePrevButton} nextDisabled={disableNextButton} fontSize="large" /> {Platform.OS === 'ios' && monthPickerVisible ? ( ) : ( {DAYS_OF_WEEK.map((day) => ( {day} ))} {daysOfPreviousMonth.map((date) => renderDateCell({ date, isCurrentMonth: false }) )} {daysOfCurrentMonth.map((date) => renderDateCell({ date, isCurrentMonth: true }) )} {daysOfNextMonth.map((date) => renderDateCell({ date, isCurrentMonth: false }) )} {Platform.OS === 'android' && monthPickerVisible && ( { setMonthPickerVisible(false); onToggleMonthPicker?.(false); if (action === 'dateSetAction' && !!date) { onMonthChange(date); } }} /> )} )} ); }; export default CalendarRange;