UNPKG

react-next-dates

Version:

Simple and Customizable DatePicker, DateRangePicker and TimePicker for React.

1,555 lines (1,354 loc) 65.5 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var React = require('react'); var dateFns = require('date-fns'); var classNames = require('classnames'); var reactPopper = require('react-popper'); var reactDom = require('react-dom'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var React__default = /*#__PURE__*/_interopDefaultLegacy(React); var classNames__default = /*#__PURE__*/_interopDefaultLegacy(classNames); function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } var DEFAULT_MODIFIERS_CLASS_NAMES = { disabled: '-disabled', selected: '-selected', today: '-today', selectedStart: '-selected-start', selectedMiddle: '-selected-middle', selectedEnd: '-selected-end' }; function mergeModifiers(baseModifiers, extendsModifiers) { if (baseModifiers === void 0) { baseModifiers = {}; } if (extendsModifiers === void 0) { extendsModifiers = {}; } var newModifiers = Object.keys(extendsModifiers).reduce(function (modifiers, key) { var _extends2; return _extends({}, modifiers, (_extends2 = {}, _extends2[key] = baseModifiers[key] ? function (date) { return baseModifiers[key](date) || extendsModifiers[key](date); } : extendsModifiers[key], _extends2)); }, {}); return _extends({}, baseModifiers, newModifiers); } function mergeCalendarModifiers(baseModifiers, extendsModifiers) { if (baseModifiers === void 0) { baseModifiers = {}; } if (extendsModifiers === void 0) { extendsModifiers = {}; } var newModifiers = Object.keys(extendsModifiers).reduce(function (calendarModifiers, curr) { var _extends3; return _extends({}, calendarModifiers, (_extends3 = {}, _extends3[curr] = mergeModifiers(baseModifiers[curr], extendsModifiers[curr]), _extends3)); }, {}); return _extends({}, baseModifiers, newModifiers); } function computeModifierClassNames(modifiers, modifiersClassNames) { if (modifiers === void 0) { modifiers = {}; } if (modifiersClassNames === void 0) { modifiersClassNames = {}; } var allClassNames = _extends({}, DEFAULT_MODIFIERS_CLASS_NAMES, modifiersClassNames); return function (date) { return Object.keys(modifiers).reduce(function (acc, curr) { var className = allClassNames[curr]; var predicate = modifiers[curr]; if (className && predicate) { var _extends4; return _extends({}, acc, (_extends4 = {}, _extends4[className] = predicate(date), _extends4)); } return acc; }, {}); }; } var CalendarDay = function CalendarDay(_ref) { var locale = _ref.locale, day = _ref.day, receivedModifiers = _ref.modifiers, modifiersClassNames = _ref.modifiersClassNames, onClick = _ref.onClick, onHover = _ref.onHover; var dayNumber = dateFns.getDate(day); var handleClick = function handleClick() { return onClick(day); }; var handleMouseEnter = function handleMouseEnter() { return onHover(day); }; var handleMouseLeave = function handleMouseLeave() { return onHover(null); }; var modifiers = mergeModifiers({ today: function today(date) { return dateFns.isToday(date); } }, receivedModifiers); var dayClassNames = computeModifierClassNames(modifiers, modifiersClassNames)(day); var gridColumnStart = React.useMemo(function () { if (dateFns.getDate(day) === 1) { return dateFns.differenceInDays(day, dateFns.startOfWeek(day, { locale: locale })) + 1; } return undefined; }, [day, locale]); return React__default["default"].createElement("span", { className: classNames__default["default"]('day', dayClassNames), onClick: handleClick, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: { gridColumnStart: gridColumnStart } }, React__default["default"].createElement("span", { className: "day-number" }, dayNumber)); }; function getDefaultDateFormat(locale, formatString) { var _ref, _locale$formatLong; return (_ref = formatString != null ? formatString : (_locale$formatLong = locale.formatLong) == null ? void 0 : _locale$formatLong.date({ width: 'short' })) != null ? _ref : 'MM/dd/yyyy'; } function parseDate(value, formatString, locale) { var parsedDate = dateFns.parse(value, formatString, new Date(), { locale: locale }); if (dateFns.isValid(parsedDate)) { return parsedDate; } return null; } function formatDate(date, formatString, locale) { return dateFns.format(date, formatString, { locale: locale }); } function isDateInRange(date, minDate, maxDate) { return !(minDate ? dateFns.isBefore(date, dateFns.startOfDay(minDate)) : false) && !(maxDate ? dateFns.isAfter(date, maxDate) : false); } function setTime(date, dateWithTime) { return dateFns.set(date, { hours: dateWithTime.getHours(), minutes: dateWithTime.getMinutes(), seconds: dateWithTime.getSeconds(), milliseconds: dateWithTime.getMilliseconds() }); } function setTimeOrRemoveTime(date, dateWithTime) { return dateWithTime ? setTime(date, dateWithTime) : dateFns.startOfDay(date); } function isRangeLengthValid(startDate, endDate, minLength, maxLength) { var start = dateFns.startOfDay(startDate); var end = dateFns.startOfDay(endDate); return dateFns.differenceInDays(end, start) >= minLength && (!maxLength || dateFns.differenceInDays(end, start) <= maxLength); } var CalendarDayHeader = function CalendarDayHeader(_ref) { var locale = _ref.locale; var weekDays = React.useMemo(function () { var today = new Date(); return dateFns.eachDayOfInterval({ start: dateFns.startOfWeek(today, { locale: locale }), end: dateFns.endOfWeek(today, { locale: locale }) }).map(function (date) { return formatDate(date, 'eeeee', locale); }); }, [locale]); return React__default["default"].createElement("div", { className: "day-header" }, weekDays.map(function (day, i) { return React__default["default"].createElement("span", { key: i }, day); })); }; var CalendarDayGrid = function CalendarDayGrid(_ref) { var locale = _ref.locale, month = _ref.month, modifiers = _ref.modifiers, modifiersClassNames = _ref.modifiersClassNames, onSelect = _ref.onSelect, onHover = _ref.onHover; var days = React.useMemo(function () { return dateFns.eachDayOfInterval({ start: dateFns.startOfMonth(month), end: dateFns.endOfMonth(month) }); }, [month]); return React__default["default"].createElement("div", { className: "day-grid" }, React__default["default"].createElement(CalendarDayHeader, { locale: locale }), React__default["default"].createElement("div", { className: "day-grid-content" }, days.map(function (day) { return React__default["default"].createElement(CalendarDay, { key: day.toISOString(), locale: locale, day: day, modifiers: modifiers, modifiersClassNames: modifiersClassNames, onClick: onSelect, onHover: onHover }); }))); }; var CalendarNavigation = function CalendarNavigation(_ref) { var locale = _ref.locale, month = _ref.month, mode = _ref.mode, onChangeMonth = _ref.onChangeMonth, onChangeMode = _ref.onChangeMode; var title = React.useMemo(function () { switch (mode) { case 'day': return formatDate(month, 'LLLL yyyy', locale); case 'month': return formatDate(month, 'yyyy', locale); default: return null; } }, [month, mode, locale]); var handlePrev = function handlePrev() { switch (mode) { case 'day': onChangeMonth(dateFns.startOfMonth(dateFns.subMonths(month, 1))); break; case 'month': onChangeMonth(dateFns.startOfMonth(dateFns.subYears(month, 1))); break; case 'year': onChangeMonth(dateFns.startOfMonth(dateFns.subYears(month, 24))); break; } }; var handleNext = function handleNext() { switch (mode) { case 'day': onChangeMonth(dateFns.startOfMonth(dateFns.addMonths(month, 1))); break; case 'month': onChangeMonth(dateFns.startOfMonth(dateFns.addYears(month, 1))); break; case 'year': onChangeMonth(dateFns.startOfMonth(dateFns.addYears(month, 24))); break; } }; var handleTitleClick = function handleTitleClick() { switch (mode) { case 'day': onChangeMode('month'); break; case 'month': onChangeMode('year'); break; } }; return React__default["default"].createElement("div", { className: "navigation" }, React__default["default"].createElement("div", null, title && React__default["default"].createElement("p", { onClick: handleTitleClick }, title)), React__default["default"].createElement("button", { type: "button", className: "prev", onClick: handlePrev }), React__default["default"].createElement("button", { type: "button", className: "next", onClick: handleNext })); }; var CalendarYear = function CalendarYear(_ref) { var year = _ref.year, receivedModifiers = _ref.modifiers, modifiersClassNames = _ref.modifiersClassNames, onSelect = _ref.onSelect; var handleClick = function handleClick() { return onSelect(year); }; var modifiers = mergeModifiers({ today: function today(date) { return dateFns.isThisYear(date); } }, receivedModifiers); var yearClassNames = computeModifierClassNames(modifiers, modifiersClassNames)(year); return React__default["default"].createElement("span", { className: classNames__default["default"]('year', yearClassNames), onClick: handleClick }, year.getFullYear()); }; var CalendarYearGrid = function CalendarYearGrid(_ref) { var month = _ref.month, modifiers = _ref.modifiers, modifiersClassNames = _ref.modifiersClassNames, onYearChange = _ref.onYearChange; var years = React.useMemo(function () { var gridStartYear = Math.floor(dateFns.getYear(month) / 24) * 24; return dateFns.eachYearOfInterval({ start: dateFns.setYear(month, gridStartYear), end: dateFns.setYear(month, gridStartYear + 23) }); }, [month]); return React__default["default"].createElement("div", { className: "year-grid" }, years.map(function (year) { return React__default["default"].createElement(CalendarYear, { key: year.getFullYear(), year: year, modifiers: modifiers, modifiersClassNames: modifiersClassNames, onSelect: onYearChange }); })); }; var CalendarMonth = function CalendarMonth(_ref) { var locale = _ref.locale, month = _ref.month, receivedModifiers = _ref.modifiers, modifiersClassNames = _ref.modifiersClassNames, onSelect = _ref.onSelect; var handleClick = function handleClick() { return onSelect(month); }; var modifiers = mergeModifiers({ today: function today(date) { return dateFns.isThisMonth(date); } }, receivedModifiers); var monthClassNames = computeModifierClassNames(modifiers, modifiersClassNames)(month); return React__default["default"].createElement("span", { className: classNames__default["default"]('month', monthClassNames), onClick: handleClick }, formatDate(month, 'LLLL', locale)); }; var CalendarMonthGrid = function CalendarMonthGrid(_ref) { var locale = _ref.locale, month = _ref.month, modifiers = _ref.modifiers, modifiersClassNames = _ref.modifiersClassNames, onMonthChange = _ref.onMonthChange; var months = React.useMemo(function () { return Array(12).fill('').map(function (_, i) { return dateFns.setMonth(month, i); }, locale); }, [locale, month]); return React__default["default"].createElement("div", { className: "month-grid" }, months.map(function (m) { return React__default["default"].createElement(CalendarMonth, { key: m.toISOString(), locale: locale, month: m, modifiers: modifiers, modifiersClassNames: modifiersClassNames, onSelect: onMonthChange }); })); }; function useDependentState(factory, inputs) { var _useState = React.useState(factory()), state = _useState[0], setState = _useState[1]; React.useMemo(function () { var newState = factory(state); if (newState !== state) { setState(newState); } // eslint-disable-next-line react-hooks/exhaustive-deps }, inputs); return [state, setState]; } function useControllableState(initialValue, value, onChange) { var _useState2 = React.useState(initialValue), state = _useState2[0], setState = _useState2[1]; return onChange && value ? [value, onChange] : [state, setState]; } function useOutsideClickHandler(callback) { var refA = React.useRef(null); var refB = React.useRef(null); var refC = React.useRef(null); var refD = React.useRef(null); var refE = React.useRef(null); React.useEffect(function () { var handleClickOutside = function handleClickOutside(e) { var _refA$current, _refB$current, _refC$current, _refD$current, _refE$current; if (e.target instanceof Element && !((_refA$current = refA.current) != null && _refA$current.contains(e.target)) && !((_refB$current = refB.current) != null && _refB$current.contains(e.target)) && !((_refC$current = refC.current) != null && _refC$current.contains(e.target)) && !((_refD$current = refD.current) != null && _refD$current.contains(e.target)) && !((_refE$current = refE.current) != null && _refE$current.contains(e.target))) { callback(); } }; document.addEventListener('mousedown', handleClickOutside, { passive: true }); return function () { document.removeEventListener('mousedown', handleClickOutside); }; }, [callback]); return [refA, refB, refC, refD, refE]; } function usePrevious(value) { var ref = React.useRef(value); React.useEffect(function () { ref.current = value; }); return ref.current; } function useDetectTouch() { var _useState3 = React.useState(false), isTouch = _useState3[0], setIsTouch = _useState3[1]; React.useEffect(function () { var handleTouch = function handleTouch() { setIsTouch(true); removeListener(); }; var removeListener = function removeListener() { document.removeEventListener('touchstart', handleTouch); }; document.addEventListener('touchstart', handleTouch); return removeListener; }, []); return isTouch; } function constVoid() {} var Calendar = function Calendar(_ref) { var locale = _ref.locale, _ref$type = _ref.type, type = _ref$type === void 0 ? 'day' : _ref$type, receivedMonth = _ref.month, minDate = _ref.minDate, maxDate = _ref.maxDate, receivedModifiers = _ref.modifiers, modifiersClassNames = _ref.modifiersClassNames, className = _ref.className, onMonthChange = _ref.onMonthChange, _ref$onSelect = _ref.onSelect, onSelect = _ref$onSelect === void 0 ? constVoid : _ref$onSelect, _ref$onHover = _ref.onHover, onHover = _ref$onHover === void 0 ? constVoid : _ref$onHover; var _useDependentState = useDependentState(function () { return type; }, [type]), mode = _useDependentState[0], setMode = _useDependentState[1]; var _useControllableState = useControllableState(function () { return dateFns.startOfMonth(new Date()); }, receivedMonth != null ? receivedMonth : undefined, onMonthChange), month = _useControllableState[0], setMonth = _useControllableState[1]; var modifiers = mergeCalendarModifiers({ day: { disabled: function disabled(date) { return !isDateInRange(date, minDate, maxDate); } }, month: { disabled: function disabled(date) { return (minDate ? dateFns.isBefore(dateFns.startOfMonth(date), dateFns.startOfMonth(minDate)) : false) || (maxDate ? dateFns.isAfter(dateFns.startOfMonth(date), dateFns.startOfMonth(maxDate)) : false); } }, year: { disabled: function disabled(date) { return (minDate ? dateFns.isBefore(dateFns.startOfYear(date), dateFns.startOfYear(minDate)) : false) || (maxDate ? dateFns.isAfter(dateFns.startOfYear(date), dateFns.startOfYear(maxDate)) : false); } } }, receivedModifiers); var handleSelectYear = function handleSelectYear(year) { setMonth(year); if (type !== 'year') { setMode('month'); } else { onSelect(dateFns.set(year, { date: 1, month: 0 })); } }; var handleSelectMonth = function handleSelectMonth(month) { setMonth(month); if (type !== 'month') { setMode('day'); } else { onSelect(dateFns.setDate(month, 1)); } }; return React__default["default"].createElement("div", { className: classNames__default["default"]('react-next-dates', 'calendar', className) }, React__default["default"].createElement(CalendarNavigation, { locale: locale, month: month, mode: mode, onChangeMonth: setMonth, onChangeMode: setMode }), mode === 'day' ? React__default["default"].createElement(CalendarDayGrid, { locale: locale, month: month, modifiers: modifiers.day, modifiersClassNames: modifiersClassNames == null ? void 0 : modifiersClassNames.day, onSelect: onSelect, onHover: onHover }) : mode === 'year' ? React__default["default"].createElement(CalendarYearGrid, { month: month, modifiers: modifiers.year, modifiersClassNames: modifiersClassNames == null ? void 0 : modifiersClassNames.year, onYearChange: handleSelectYear }) : React__default["default"].createElement(CalendarMonthGrid, { locale: locale, month: month, modifiers: modifiers.month, modifiersClassNames: modifiersClassNames == null ? void 0 : modifiersClassNames.month, onMonthChange: handleSelectMonth })); }; var CLOCK_ITEM_WIDTH = 24; var HOUR_ANGLE = 30; // 360 / 12 var MINUTE_ANGLE = 6; // 360 / 50 function getClockItemPosition(index, containerRadius, radius) { return { top: radius * Math.sin(HOUR_ANGLE * (index - 2) * (Math.PI / 180)) + containerRadius - CLOCK_ITEM_WIDTH / 2, left: radius * Math.cos(HOUR_ANGLE * (index - 2) * (Math.PI / 180)) + containerRadius - CLOCK_ITEM_WIDTH / 2 }; } function format2Digits(val) { return "" + (val < 10 ? '0' : '') + val; } var ClockAMHour = function ClockAMHour(_ref) { var date = _ref.date, index = _ref.index, containerRadius = _ref.containerRadius; var label = index + 1; return React__default["default"].createElement("span", { className: classNames__default["default"]({ selected: date && dateFns.getHours(date) === label }), style: getClockItemPosition(index, containerRadius, containerRadius - 20) }, label); }; var ClockPMHour = function ClockPMHour(_ref2) { var date = _ref2.date, index = _ref2.index, containerRadius = _ref2.containerRadius; var hour = index + 13; var label = hour === 24 ? '00' : "" + hour; return React__default["default"].createElement("span", { className: classNames__default["default"]({ selected: date && dateFns.format(date, 'HH') === label }), style: getClockItemPosition(index, containerRadius, containerRadius / 2) }, label); }; var ClockHours = function ClockHours(_ref3) { var date = _ref3.date, containerRadius = _ref3.containerRadius; return React__default["default"].createElement(React__default["default"].Fragment, null, Array(12).fill('').map(function (_, index) { return React__default["default"].createElement(React.Fragment, { key: index }, React__default["default"].createElement(ClockAMHour, { date: date, index: index, containerRadius: containerRadius }), React__default["default"].createElement(ClockPMHour, { date: date, index: index, containerRadius: containerRadius })); })); }; var ClockMinute = function ClockMinute(_ref) { var date = _ref.date, precision = _ref.precision, index = _ref.index, containerRadius = _ref.containerRadius; var value = index === 11 ? 0 : (index + 1) * 5; var label = format2Digits(value); return value % precision === 0 ? React__default["default"].createElement("span", { className: classNames__default["default"]({ selected: date && dateFns.format(date, 'mm') === label }), style: getClockItemPosition(index, containerRadius, containerRadius - 20) }, label) : null; }; var ClockMinutes = function ClockMinutes(_ref2) { var date = _ref2.date, containerRadius = _ref2.containerRadius, precision = _ref2.precision; return React__default["default"].createElement(React__default["default"].Fragment, null, Array(12).fill('').map(function (_, index) { return React__default["default"].createElement(ClockMinute, { key: index, date: date, precision: precision, index: index, containerRadius: containerRadius }); })); }; var ClockNavigation = function ClockNavigation(_ref) { var locale = _ref.locale, date = _ref.date, showNav = _ref.showNav, selection = _ref.selection, onSelectionChange = _ref.onSelectionChange; var handlePrev = function handlePrev() { return onSelectionChange('hours'); }; var handleNext = function handleNext() { return onSelectionChange('minutes'); }; return React__default["default"].createElement("div", { className: "navigation" }, showNav && selection === 'minutes' && React__default["default"].createElement("button", { type: "button", className: "prev", onClick: handlePrev }), React__default["default"].createElement("p", null, date ? formatDate(date, 'HH:mm', locale) : '--:--'), showNav && selection === 'hours' && React__default["default"].createElement("button", { type: "button", className: "next", onClick: handleNext })); }; function getSelectionAngle(date, selection) { if (selection === 'hours') { return HOUR_ANGLE * (dateFns.getHours(date) - 3); } else { return MINUTE_ANGLE * (dateFns.getMinutes(date) - 15); } } var Clock = function Clock(_ref) { var locale = _ref.locale, receivedDate = _ref.date, receivedSelection = _ref.selection, _ref$precision = _ref.precision, precision = _ref$precision === void 0 ? 1 : _ref$precision, _ref$vibrate = _ref.vibrate, vibrate = _ref$vibrate === void 0 ? true : _ref$vibrate, className = _ref.className, _ref$onChange = _ref.onChange, onChange = _ref$onChange === void 0 ? constVoid : _ref$onChange, onSelectionChange = _ref.onSelectionChange, _ref$onSelectionEnd = _ref.onSelectionEnd, onSelectionEnd = _ref$onSelectionEnd === void 0 ? constVoid : _ref$onSelectionEnd; var containerRef = React.useRef(null); var isDragging = React.useRef(false); var _useState = React.useState(function () { return receivedDate != null ? receivedDate : null; }), date = _useState[0], setDate = _useState[1]; var _useState2 = React.useState(function () { var _containerRef$current, _containerRef$current2; return (_containerRef$current = (_containerRef$current2 = containerRef.current) == null ? void 0 : _containerRef$current2.clientWidth) != null ? _containerRef$current : null; }), containerWidth = _useState2[0], setContainerWidth = _useState2[1]; var _useControllableState = useControllableState(function () { return 'hours'; }, receivedSelection, onSelectionChange), selection = _useControllableState[0], setSelection = _useControllableState[1]; var isTouch = useDetectTouch(); React.useEffect(function () { var getContainerWidth = function getContainerWidth() { if (containerRef.current) { setContainerWidth(containerRef.current.clientWidth); } }; window.addEventListener('resize', getContainerWidth, { passive: true }); getContainerWidth(); return function () { window.removeEventListener('resize', getContainerWidth); }; }, []); React.useEffect(function () { setDate(receivedDate != null ? receivedDate : null); }, [receivedDate]); var handleDateChange = function handleDateChange(date, fireChange) { setDate(function (d) { if (d === null || !dateFns.isEqual(d, date)) { if (vibrate && 'vibrate' in navigator) { navigator.vibrate(10); } return date; } return d; }); if (fireChange && (receivedDate == null || !dateFns.isEqual(receivedDate, date))) { onChange(date); } }; var handleCalcSelected = function handleCalcSelected(currentTarget, clientX, clientY, fireChange) { if (fireChange === void 0) { fireChange = false; } var rect = currentTarget.getBoundingClientRect(); var containerRadius = rect.width / 2; var x = clientX - rect.left - containerRadius; var y = clientY - rect.top - containerRadius; var angle = Math.atan2(y, x) * 180.0 / Math.PI; var positiveAngle = angle < 0 ? 360 + angle : angle; if (selection === 'hours') { var hour = Math.round(positiveAngle / HOUR_ANGLE + 3); var pmRadius = containerRadius / 2 + 12; var amHour = hour > 12 ? hour - 12 : hour; if (Math.abs(x) < pmRadius && Math.abs(y) < pmRadius) { handleDateChange(dateFns.setHours(date != null ? date : dateFns.startOfDay(new Date()), amHour === 12 ? 0 : amHour + 12), fireChange); } else { handleDateChange(dateFns.setHours(date != null ? date : dateFns.startOfDay(new Date()), amHour), fireChange); } } else { var minute = Math.round(positiveAngle / MINUTE_ANGLE + 15); var computedMinute = minute >= 60 ? minute - 60 : minute; var roundedWithPrecision = Math.round(computedMinute / precision) * precision % 60; handleDateChange(dateFns.setMinutes(date != null ? date : dateFns.startOfDay(new Date()), roundedWithPrecision), fireChange); } }; var handleSelectStart = function handleSelectStart(currentTarget, clientX, clientY) { handleCalcSelected(currentTarget, clientX, clientY); isDragging.current = true; }; var handleSelecting = function handleSelecting(currentTarget, clientX, clientY) { if (isDragging.current) { handleCalcSelected(currentTarget, clientX, clientY); } }; var handleSelectEnd = function handleSelectEnd(currentTarget, clientX, clientY) { isDragging.current = false; handleCalcSelected(currentTarget, clientX, clientY, true); var newSelection = selection === 'hours' && precision !== 60 ? 'minutes' : 'hours'; setSelection(newSelection); if (newSelection === 'hours') { onSelectionEnd(); } }; var handleMouseDown = function handleMouseDown(e) { return handleSelectStart(e.currentTarget, e.clientX, e.clientY); }; var handleMouseMove = function handleMouseMove(e) { return handleSelecting(e.currentTarget, e.clientX, e.clientY); }; var handleMouseUp = function handleMouseUp(e) { return handleSelectEnd(e.currentTarget, e.clientX, e.clientY); }; var handleTouchStart = function handleTouchStart(e) { if (e.changedTouches[0]) { handleSelectStart(e.currentTarget, e.changedTouches[0].clientX, e.changedTouches[0].clientY); } }; var handleTouchMove = function handleTouchMove(e) { if (e.changedTouches[0]) { isDragging.current = true; handleSelecting(e.currentTarget, e.changedTouches[0].clientX, e.changedTouches[0].clientY); } }; var handleTouchEnd = function handleTouchEnd(e) { if (e.changedTouches[0]) { handleSelectEnd(e.currentTarget, e.changedTouches[0].clientX, e.changedTouches[0].clientY); } }; return React__default["default"].createElement("div", { className: classNames__default["default"]('react-next-dates', 'clock', className) }, React__default["default"].createElement(ClockNavigation, { locale: locale, date: date, selection: selection, showNav: precision !== 60, onSelectionChange: setSelection }), React__default["default"].createElement("div", { className: "clock-wrapper" }, React__default["default"].createElement("div", { ref: containerRef, className: "clock-content", onMouseDown: isTouch ? undefined : handleMouseDown, onMouseMove: isTouch ? undefined : handleMouseMove, onMouseUp: isTouch ? undefined : handleMouseUp, onTouchStart: isTouch ? handleTouchStart : undefined, onTouchMove: isTouch ? handleTouchMove : undefined, onTouchEnd: isTouch ? handleTouchEnd : undefined }, containerWidth !== null ? React__default["default"].createElement(React__default["default"].Fragment, null, selection === 'hours' ? React__default["default"].createElement(ClockHours, { date: date, containerRadius: containerWidth / 2 }) : React__default["default"].createElement(ClockMinutes, { date: date, containerRadius: containerWidth / 2, precision: precision }), date != null ? React__default["default"].createElement("div", { className: classNames__default["default"]('clock-selection', { pm: selection === 'hours' && (date.getHours() === 0 || date.getHours() > 12) }), style: { transform: "rotate(" + getSelectionAngle(date, selection) + "deg)" } }) : null) : null))); }; function isDateValid(date) { return date != null && dateFns.isValid(date); } function useDateInput(_ref) { var locale = _ref.locale, date = _ref.date, format = _ref.format, placeholder = _ref.placeholder, _ref$onChange = _ref.onChange, onChange = _ref$onChange === void 0 ? constVoid : _ref$onChange; var defaultFormat = React.useMemo(function () { return getDefaultDateFormat(locale, format); }, [locale, format]); var _useState = React.useState(function () { return date != null && isDateValid(date) ? formatDate(date, defaultFormat, locale) : ''; }), value = _useState[0], setValue = _useState[1]; var _useState2 = React.useState(false), focused = _useState2[0], setFocused = _useState2[1]; var handleChange = function handleChange(e) { var newValue = e.target.value; setValue(newValue); var parsedDate = parseDate(newValue, defaultFormat, locale); if (isDateValid(parsedDate)) { onChange(parsedDate); } }; var handleBlur = function handleBlur() { if (value) { var parsedDate = parseDate(value, defaultFormat, locale); if (isDateValid(parsedDate)) { setValue(formatDate(parsedDate, defaultFormat, locale)); } else if (isDateValid(date)) { setValue(formatDate(date, defaultFormat, locale)); } else { setValue(''); } } else { onChange(null); } setFocused(false); }; var handleFocus = function handleFocus() { return setFocused(true); }; React.useEffect(function () { if (!focused) { setValue(isDateValid(date) ? formatDate(date, defaultFormat, locale) : ''); } }, [focused, date, defaultFormat, locale]); return { type: 'text', value: value, placeholder: placeholder != null ? placeholder : defaultFormat, onChange: handleChange, onBlur: handleBlur, onFocus: handleFocus }; } var DatePickerCalendar = function DatePickerCalendar(_ref) { var locale = _ref.locale, _ref$type = _ref.type, type = _ref$type === void 0 ? 'day' : _ref$type, _ref$date = _ref.date, date = _ref$date === void 0 ? null : _ref$date, receivedMonth = _ref.month, minDate = _ref.minDate, maxDate = _ref.maxDate, receivedModifiers = _ref.modifiers, modifiersClassNames = _ref.modifiersClassNames, className = _ref.className, _ref$onDateChange = _ref.onDateChange, onDateChange = _ref$onDateChange === void 0 ? constVoid : _ref$onDateChange, onMonthChange = _ref.onMonthChange; var _useControllableState = useControllableState(function () { return dateFns.startOfMonth(date != null ? date : new Date()); }, receivedMonth != null ? receivedMonth : undefined, onMonthChange), month = _useControllableState[0], setMonth = _useControllableState[1]; var isSelected = function isSelected(d) { if (date === null) { return false; } switch (type) { case 'month': return dateFns.isSameMonth(d, date); case 'year': return dateFns.isSameYear(d, date); default: return dateFns.isSameDay(d, date); } }; var baseModifier = { selected: isSelected }; var modifiers = mergeCalendarModifiers({ day: baseModifier, month: baseModifier, year: baseModifier }, receivedModifiers); var handleSelectDate = function handleSelectDate(d) { return onDateChange(setTimeOrRemoveTime(d, date)); }; return React__default["default"].createElement(Calendar, { locale: locale, type: type, month: month, minDate: minDate, maxDate: maxDate, modifiers: modifiers, modifiersClassNames: modifiersClassNames, className: className, onMonthChange: setMonth, onSelect: handleSelectDate }); }; var Popper = /*#__PURE__*/React.forwardRef(function (_ref, ref) { var isOpen = _ref.isOpen, referenceElement = _ref.referenceElement, popperElement = _ref.popperElement, portalContainer = _ref.portalContainer, _ref$offset = _ref.offset, offset = _ref$offset === void 0 ? [0, 5] : _ref$offset, className = _ref.className, children = _ref.children; var _usePopper = reactPopper.usePopper(referenceElement, popperElement, { placement: 'bottom-start', strategy: portalContainer ? 'fixed' : 'absolute', modifiers: [{ name: 'offset', options: { offset: offset } }, { name: 'flip' }, { name: 'preventOverflow' }] }), styles = _usePopper.styles, attributes = _usePopper.attributes, forceUpdate = _usePopper.forceUpdate; React.useLayoutEffect(function () { if (isOpen && forceUpdate) { forceUpdate(); } }, [isOpen, forceUpdate]); var popperStyle = isOpen ? styles.popper : { display: 'none' }; var popper = React__default["default"].createElement("div", _extends({ ref: ref, className: classNames__default["default"]('react-next-dates', 'popper', className), style: popperStyle }, attributes.popper), isOpen ? children : null); return portalContainer ? reactDom.createPortal(popper, portalContainer) : popper; }); var DatePicker = function DatePicker(_ref) { var locale = _ref.locale, _ref$type = _ref.type, type = _ref$type === void 0 ? 'day' : _ref$type, date = _ref.date, format = _ref.format, minDate = _ref.minDate, maxDate = _ref.maxDate, placeholder = _ref.placeholder, className = _ref.className, modifiers = _ref.modifiers, modifiersClassNames = _ref.modifiersClassNames, portalContainer = _ref.portalContainer, _ref$readonlyOnTouch = _ref.readonlyOnTouch, readonlyOnTouch = _ref$readonlyOnTouch === void 0 ? true : _ref$readonlyOnTouch, _ref$autoOpen = _ref.autoOpen, autoOpen = _ref$autoOpen === void 0 ? true : _ref$autoOpen, _ref$onChange = _ref.onChange, onChange = _ref$onChange === void 0 ? constVoid : _ref$onChange, children = _ref.children; var _useState = React.useState(function () { return date != null ? date : new Date(); }), month = _useState[0], setMonth = _useState[1]; var _useState2 = React.useState(false), isOpen = _useState2[0], setOpen = _useState2[1]; var _useOutsideClickHandl = useOutsideClickHandler(function () { return setOpen(false); }), inputRef = _useOutsideClickHandl[0], popperRef = _useOutsideClickHandl[1]; var openDatePicker = function openDatePicker() { var _inputRef$current; setOpen(true); (_inputRef$current = inputRef.current) == null ? void 0 : _inputRef$current.focus(); }; var isTouch = useDetectTouch(); var handleDateInputChange = function handleDateInputChange(date) { onChange(date); if (date) { setMonth(date); } }; var inputProps = useDateInput({ locale: locale, date: date, format: format, placeholder: placeholder, onChange: handleDateInputChange }); var handleChange = function handleChange(date) { onChange(date); setOpen(false); }; var readOnly = readonlyOnTouch && isTouch; return React__default["default"].createElement(React__default["default"].Fragment, null, children({ inputProps: _extends({}, inputProps, { onFocus: function onFocus(e) { inputProps.onFocus(e); if (autoOpen) { setOpen(true); } if (readOnly) { var _inputRef$current2; (_inputRef$current2 = inputRef.current) == null ? void 0 : _inputRef$current2.blur(); } }, ref: inputRef, readOnly: readOnly }), openDatePicker: openDatePicker }), React__default["default"].createElement(Popper, { ref: popperRef, isOpen: isOpen, referenceElement: inputRef.current, popperElement: popperRef.current, portalContainer: portalContainer, className: "date" }, React__default["default"].createElement(DatePickerCalendar, { locale: locale, type: type, date: date, month: month, minDate: minDate, maxDate: maxDate, modifiers: modifiers, modifiersClassNames: modifiersClassNames, className: className, onDateChange: handleChange, onMonthChange: setMonth }))); }; var DateRangePickerCalendar = function DateRangePickerCalendar(_ref) { var locale = _ref.locale, focus = _ref.focus, _ref$startDate = _ref.startDate, startDate = _ref$startDate === void 0 ? null : _ref$startDate, _ref$endDate = _ref.endDate, endDate = _ref$endDate === void 0 ? null : _ref$endDate, receivedMonth = _ref.month, minDate = _ref.minDate, maxDate = _ref.maxDate, _ref$minLength = _ref.minLength, minLength = _ref$minLength === void 0 ? 0 : _ref$minLength, maxLength = _ref.maxLength, receivedModifiers = _ref.modifiers, modifiersClassNames = _ref.modifiersClassNames, className = _ref.className, _ref$onStartDateChang = _ref.onStartDateChange, onStartDateChange = _ref$onStartDateChang === void 0 ? constVoid : _ref$onStartDateChang, _ref$onEndDateChange = _ref.onEndDateChange, onEndDateChange = _ref$onEndDateChange === void 0 ? constVoid : _ref$onEndDateChange, onFocusChange = _ref.onFocusChange, onMonthChange = _ref.onMonthChange; var _useControllableState = useControllableState(function () { var _ref2; return dateFns.startOfMonth((_ref2 = startDate != null ? startDate : endDate) != null ? _ref2 : new Date()); }, receivedMonth != null ? receivedMonth : undefined, onMonthChange), month = _useControllableState[0], setMonth = _useControllableState[1]; var _useState = React.useState(null), hoveredDate = _useState[0], setHoveredDate = _useState[1]; var displayedStartDate = startDate ? dateFns.startOfDay(startDate) : null; var displayedEndDate = endDate ? dateFns.startOfDay(endDate) : null; var isStartDate = function isStartDate(date) { return displayedStartDate !== null && dateFns.isSameDay(date, displayedStartDate); }; var isEndDate = function isEndDate(date) { return displayedEndDate !== null && dateFns.isSameDay(date, displayedEndDate); }; var isSelectedMiddleDate = function isSelectedMiddleDate(date) { return displayedStartDate !== null && displayedEndDate !== null && dateFns.isAfter(date, displayedStartDate) && dateFns.isBefore(date, displayedEndDate); }; var isHoverDate = function isHoverDate(date) { return hoveredDate !== null && displayedStartDate !== null && displayedEndDate === null && dateFns.isAfter(date, displayedStartDate) && (dateFns.isBefore(date, hoveredDate) || dateFns.isSameDay(date, hoveredDate)); }; var isMiddleDate = function isMiddleDate(date) { return isSelectedMiddleDate(date) || isHoverDate(date); }; var modifiers = mergeModifiers({ selectedStart: isStartDate, selectedMiddle: isMiddleDate, selectedEnd: isEndDate, disabled: function disabled(date) { if (focus === 'endDate' && startDate !== null) { return dateFns.isAfter(date, dateFns.startOfDay(startDate)) && !isRangeLengthValid(startDate, date, minLength, maxLength); } else if (focus === 'startDate' && endDate !== null) { return dateFns.isBefore(date, dateFns.startOfDay(endDate)) && !isRangeLengthValid(date, endDate, minLength, maxLength); } return false; } }, receivedModifiers); var handleSelectDate = function handleSelectDate(d) { if (focus === 'startDate') { var date = setTimeOrRemoveTime(d, startDate); if (endDate !== null && dateFns.isAfter(date, endDate)) { onEndDateChange(null); } onStartDateChange(date); onFocusChange('endDate'); } else if (focus === 'endDate') { var _date = setTimeOrRemoveTime(d, endDate != null ? endDate : startDate); if (startDate !== null && dateFns.isBefore(_date, startDate)) { onStartDateChange(setTimeOrRemoveTime(d, startDate)); onEndDateChange(null); onFocusChange('endDate'); } else { onEndDateChange(_date); onFocusChange(null); } } }; return React__default["default"].createElement(Calendar, { type: "day", locale: locale, month: month, minDate: minDate, maxDate: maxDate, modifiers: { day: modifiers }, modifiersClassNames: { day: modifiersClassNames }, className: className, onMonthChange: setMonth, onSelect: handleSelectDate, onHover: setHoveredDate }); }; var DateRangePicker = function DateRangePicker(_ref) { var locale = _ref.locale, format = _ref.format, startDate = _ref.startDate, endDate = _ref.endDate, minDate = _ref.minDate, maxDate = _ref.maxDate, _ref$minLength = _ref.minLength, minLength = _ref$minLength === void 0 ? 0 : _ref$minLength, maxLength = _ref.maxLength, modifiers = _ref.modifiers, modifiersClassNames = _ref.modifiersClassNames, startDatePlaceholder = _ref.startDatePlaceholder, endDatePlaceholder = _ref.endDatePlaceholder, className = _ref.className, portalContainer = _ref.portalContainer, _ref$readonlyOnTouch = _ref.readonlyOnTouch, readonlyOnTouch = _ref$readonlyOnTouch === void 0 ? true : _ref$readonlyOnTouch, _ref$autoOpen = _ref.autoOpen, autoOpen = _ref$autoOpen === void 0 ? true : _ref$autoOpen, _ref$onStartDateChang = _ref.onStartDateChange, onStartDateChange = _ref$onStartDateChang === void 0 ? constVoid : _ref$onStartDateChang, _ref$onEndDateChange = _ref.onEndDateChange, onEndDateChange = _ref$onEndDateChange === void 0 ? constVoid : _ref$onEndDateChange, children = _ref.children; var _useState = React.useState(function () { var _ref2; return (_ref2 = startDate != null ? startDate : endDate) != null ? _ref2 : new Date(); }), month = _useState[0], setMonth = _useState[1]; var _useState2 = React.useState(null), focus = _useState2[0], setFocus = _useState2[1]; var _useState3 = React.useState(null), popperFocus = _useState3[0], setPopperFocus = _useState3[1]; var _useOutsideClickHandl = useOutsideClickHandler(function () { return setFocus(null); }), startDateInputRef = _useOutsideClickHandl[0], endDateInputRef = _useOutsideClickHandl[1], popperRef = _useOutsideClickHandl[2]; var openStartDatePicker = function openStartDatePicker() { var _startDateInputRef$cu; setFocus('startDate'); (_startDateInputRef$cu = startDateInputRef.current) == null ? void 0 : _startDateInputRef$cu.focus(); }; var openEndDatePicker = function openEndDatePicker() { var _endDateInputRef$curr; setFocus('endDate'); (_endDateInputRef$curr = endDateInputRef.current) == null ? void 0 : _endDateInputRef$curr.focus(); }; var isTouch = useDetectTouch(); var prevFocus = usePrevious(focus); React.useEffect(function () { if (prevFocus === null) { setPopperFocus(focus); } if (prevFocus === 'startDate' && focus === 'endDate') { var _endDateInputRef$curr2; (_endDateInputRef$curr2 = endDateInputRef.current) == null ? void 0 : _endDateInputRef$curr2.focus(); } }, [focus, prevFocus, endDateInputRef]); var handleStartDateInputChange = function handleStartDateInputChange(date) { onStartDateChange(date); if (date) { setMonth(date); } }; var handleEndDateInputChange = function handleEndDateInputChange(date) { onEndDateChange(date); if (date) { setMonth(date); } }; var startDateInputProps = useDateInput({ date: startDate, locale: locale, format: format, placeholder: startDatePlaceholder, onChange: handleStartDateInputChange }); var endDateInputProps = useDateInput({ date: endDate, locale: locale, format: format, placeholder: endDatePlaceholder, onChange: handleEndDateInputChange }); var readOnly = readonlyOnTouch && isTouch; var getRefFromFocus = function getRefFromFocus(focus) { return focus === 'endDate' ? endDateInputRef.current : startDateInputRef.current; }; var handleFocus = function handleFocus(inputProps, focus) { return function (e) { inputProps.onFocus(e); if (focus === 'startDate' && startDate) { setMonth(startDate); } else if (focus === 'endDate' && endDate) { setMonth(endDate); } if (autoOpen) { setFocus(focus); } if (readOnly) { var _getRefFromFocus; (_getRefFromFocus = getRefFromFocus(focus)) == null ? void 0 : _getRefFromFocus.blur(); } }; }; return React__default["default"].createElement(React__default["default"].Fragment, null, children({ startDateInputProps: _extends({}, startDateInputProps, { onFocus: handleFocus(startDateInputProps, 'startDate'), ref: startDateInputRef, readOnly: readOnly }), endDateInputProps: _extends({}, endDateInputProps, { onFocus: handleFocus(endDateInputProps, 'endDate'), ref: endDateInputRef, readOnly: readOnly }), openStartDatePicker: openStartDatePicker, openEndDatePicker: openEndDatePicker }), React__default["default"].createElement(Popper, { ref: popperRef, isOpen: focus !== null, referenceElement: getRefFromFocus(popperFocus), popperElement: popperRef.current, portalContainer: portalContainer, className: "date" }, React__default["default"].createElement(DateRangePickerCalendar, { locale: locale, focus: focus != null ? focus : 'startDate', startDate: startDate, endDate: endDate, month: month, minDate: minDate, maxDate: maxDate, minLength: minLength, maxLength: maxLength, modifiers: modifiers, modifiersClassNames: modifiersClassNames, className: className, onStartDateChange: onStartDateChange, onEndDateChange: onEndDateChange, onFocusChange: setFocus, onMonthChange: setMonth }))); }; var DateTimePicker = function DateTimePicker(_ref) { var locale = _ref.locale, date = _ref.date, dateFormat = _ref.dateFormat, _ref$timeFormat = _ref.timeFormat, timeFormat = _ref$timeFormat === void 0 ? 'HH:mm' : _ref$timeFormat, minDate = _ref.minDate, maxDate = _ref.maxDate, datePlaceholder = _ref.datePlaceholder, timePlaceholder = _ref.timePlaceholder, _ref$timePrecision = _ref.timePrecision, timePrecision = _ref$timePrecision === void 0 ? 1 : _ref$timePrecision, _ref$vibrate = _ref.vibrate, vibrate = _ref$vibrate === void 0 ? true : _ref$vibrate, className = _ref.className, modifiers = _ref.modifiers, modifiersClassNames = _ref.modifiersClassNames, portalContainer = _ref.portalContainer, _ref$readonlyOnTouch = _ref.readonlyOnTouch, readonlyOnTouch = _ref$readonlyOnTouch === void 0 ? true : _ref$readonlyOnTouch, _ref$autoOpen = _ref.autoOpen, autoOpen = _ref$autoOpen === void 0 ? true : _ref$autoOpen, _ref$onChange = _ref.onChange, onChange = _ref$onChange === void 0 ? constVoid : _ref$onChange, children = _ref.children; var _useState = React.useState(function () { return date != null ? date : new Date(); }), month = _useState[0], setMonth = _useState[1]; var _useState2 = React.useState(null), focus = _useState2[0], setFocus = _useState2[1]; var _useState3 = React.useState('hours'), clockSelection = _useState3[0], setClockSelection = _useState3[1]; var _useOutsideClickHandl = useOutsideClickHandler(function () { setFocus(null); setClockSelection('hours'); }), dateInputRef = _useOutsideClickHandl[0], timeInputRef = _useOutsideClickHandl[1], popperRef = _useOutsideClickHandl[2]; var isTouch = useDetectTouch(); var openDatePicker = function openDatePicker() { var _dateInputRef$current; setFocus('date'); (_dateInputRef$current = dateInputRef