import React, { useEffect, useState, useRef, RefObject, } from 'react'; import moment, {Moment} from 'moment'; import 'react-dates/initialize'; import {DayPickerSingleDateController} from 'react-dates'; import {SingleDatePickerProps} from './types'; import DatePickerControls from './DatePickerControls'; import {useOnClickOutside} from './helpers'; import {DatePicker, DatePickerSelector, CommonStyles} from './styles'; const SingleDatePicker = ({ date, elementId, placeholder = '', dateFormat = 'DD/MM/YYYY', onChange, onFocus, minDate, maxDate, position = 'bottom', }: SingleDatePickerProps) => { const [isExpanded, setExpanded] = useState(false); const [value, setValue] = useState(null); const pickerRef = useRef(); useEffect(() => { if (moment.isMoment(date)) { setValue(date); } else if (date) { console.error(`${date} isn't a moment object`); } else { setValue(null); } }, [date]); const onDateChange = (momentValue: Moment | null): void => { setValue(momentValue); if (momentValue) onChange(momentValue); }; const onSelectDate = (momentValue: Moment | null): void => { onDateChange(momentValue); setExpanded(false); }; const onFocusChange = (arg: { focused: boolean }): void => { if (onFocus && typeof onFocus === 'function') { onFocus(arg.focused); } }; const getDefaultDate = () => { const dateNow = moment(); const maxMin = minDate ? moment.max(dateNow, minDate) : dateNow; return maxDate ? moment.min(maxMin, maxDate) : maxMin; }; const checkIsInMaxMinRange = (momentDate: Moment): boolean => ( (!minDate || moment.duration(momentDate.diff(minDate.startOf('day'))).asDays()) >= 0 && (!maxDate || moment.duration(momentDate.diff(maxDate)).asDays() <= 0) ); const isValidDate = (inputValue: string): boolean => { const momentDate = moment(inputValue, dateFormat, true); return momentDate.isValid() && checkIsInMaxMinRange(momentDate); }; const onInputChange = (inputValue: string) => { if (isValidDate(inputValue)) { onDateChange(moment(inputValue, dateFormat)); } }; const onEndChange = (inputValue: string) => { if (isValidDate(inputValue)) { onDateChange(moment(inputValue, dateFormat)); } else { onDateChange(getDefaultDate()); } setExpanded(false); }; useOnClickOutside(pickerRef, () => { setExpanded(false); }); const isDayBlocked = (current: Moment) => { const currentStartOfDay = current.startOf('day'); return !checkIsInMaxMinRange(currentStartOfDay); }; return ( }> setExpanded(true)} onChange={onInputChange} onEndChange={onEndChange} value={value} dateFormat={dateFormat} /> {isExpanded && ( )} ); }; export default SingleDatePicker;