import React, { Fragment, useState } from 'react'; import classnames from 'classnames'; import moment from 'moment-timezone'; import DayPicker from 'react-day-picker'; import 'react-day-picker/lib/style.css'; import styles from './styles.module.scss'; import colors from '../../variables/colors.json'; import { CompatibleDateValue, DateDisplay, elementContains } from '../date-picker'; import Icons from '../icons'; export type ActiveDate = 'startDate' | 'endDate' | null; export type CommonRange = { id: string, name: React.ReactNode, startDate: CompatibleDateValue, endDate: CompatibleDateValue, }; export const DateRangePickerContext = React.createContext(null); export default function DateRangePicker({ startDate, endDate, focusedInput, anchor = 'ANCHOR_LEFT', floating = true, autoClose = false, commonRanges = [], numberOfMonths = 2, onChange, onFocusChange, onSelectCommonRange, isOutsideRange, }: { startDate: CompatibleDateValue, endDate: CompatibleDateValue, // This should be renamed to "activeDate" or some such in a future version focusedInput?: ActiveDate, anchor?: 'ANCHOR_LEFT' | 'ANCHOR_RIGHT', floating?: boolean, autoClose?: boolean, commonRanges?: Array, numberOfMonths?: 1 | 2, onChange: (values: {startDate: CompatibleDateValue, endDate: CompatibleDateValue}) => void, onFocusChange?: (active: ActiveDate) => void, onSelectCommonRange?: (range: any) => void, isOutsideRange?: (date: CompatibleDateValue) => boolean, }) { const [mouseMode, setMouseMode] = useState(true); const [uncontrolledActiveDate, setUncontrolledActiveDate] = useState(null); const startValue = moment(startDate).toDate(); const endValue = moment(endDate).toDate(); // Either controlled or uncontrolled "active date" state const activeDate = focusedInput === undefined ? uncontrolledActiveDate : focusedInput; const setActiveDate = onFocusChange === undefined ? setUncontrolledActiveDate : onFocusChange; return ( {context => { const isTimeRangeControlBar = context === 'TIME_RANGE_CONTROL_BAR'; const isNoHeader = context === 'NO_HEADER'; return
{ const relatedTarget = e.relatedTarget || document.activeElement; if (!elementContains(e.currentTarget, relatedTarget as EventTarget & HTMLElement)) { setActiveDate(null); } }} onMouseDown={() => setMouseMode(true)} onKeyDown={() => setMouseMode(false)} > {!isNoHeader ?
{isTimeRangeControlBar ?
 
: null} setActiveDate(focused ? 'startDate' : null)} /> setActiveDate(focused ? 'endDate' : null)} />
: null } {activeDate ?
{commonRanges.length ?
Range
{commonRanges.map(range => (
onSelectCommonRange(range)} onKeyDown={e => { if (e.key === 'Enter') { onSelectCommonRange(range); } }} >{range.name}
))}
: null} isOutsideRange(moment(day)) : undefined, }} numberOfMonths={numberOfMonths || 2} initialMonth={activeDate === 'endDate' ? endValue : startValue} onDayClick={day => { if (!isOutsideRange || !isOutsideRange(moment(day))) { const active = moment(day).diff(startDate) < 0 ? 'startDate' : activeDate onChange({ startDate: active === 'startDate' ? moment(day) : startDate, endDate: moment(day), }); if (active === 'startDate') { setActiveDate('endDate'); } else if (active === 'endDate') { setActiveDate(autoClose ? null : 'startDate'); } } }} />
: null}
}}
); }