UNPKG

rsuite

Version:

A suite of react components

880 lines (843 loc) 35.7 kB
'use client'; import _taggedTemplateLiteralLoose from "@babel/runtime/helpers/esm/taggedTemplateLiteralLoose"; import _extends from "@babel/runtime/helpers/esm/extends"; import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose"; var _templateObject, _templateObject2; var _excluded = ["as", "classPrefix", "className", "appearance", "editable", "cleanable", "character", "calendarSnapping", "defaultCalendarValue", "defaultValue", "plaintext", "disabled", "disabledDate", "shouldDisableDate", "shouldDisableHour", "shouldDisableMinute", "shouldDisableSecond", "format", "hoverRange", "id", "isoWeek", "weekStart", "limitEndYear", "limitStartYear", "locale", "loading", "label", "menuClassName", "menuStyle", "oneTap", "placeholder", "placement", "ranges", "readOnly", "showOneCalendar", "showWeekNumbers", "showMeridian", "showMeridiem", "showHeader", "style", "size", "caretAs", "value", "monthDropdownProps", "hideHours", "hideMinutes", "hideSeconds", "onChange", "onClean", "onEnter", "onExit", "onOk", "onSelect", "onShortcutClick", "renderTitle", "renderValue", "renderCell"]; import React, { useEffect, useRef, useState, useMemo } from 'react'; import isNil from 'lodash/isNil'; import omit from 'lodash/omit'; import pick from 'lodash/pick'; import PropTypes from 'prop-types'; import CalendarIcon from '@rsuite/icons/Calendar'; import TimeIcon from '@rsuite/icons/Time'; import Toolbar from "../DatePicker/Toolbar.js"; import PredefinedRanges from "../DatePicker/PredefinedRanges.js"; import Stack from "../Stack/index.js"; import { DateRangePickerProvider } from "./DateRangePickerProvider.js"; import DateRangeInput from "../DateRangeInput/index.js"; import InputGroup from "../InputGroup/index.js"; import Header from "./Header.js"; import useDateDisabled from "./hooks/useDateDisabled.js"; import useCustomizedInput from "../DatePicker/hooks/useCustomizedInput.js"; import Calendar from "./Calendar.js"; import { getSafeCalendarDate, getMonthHoverRange, getWeekHoverRange, isSameRange } from "./utils.js"; import { deprecatePropTypeNew, oneOf } from "../internals/propTypes/index.js"; import { DATERANGE_DISABLED_TARGET as TARGET } from "../internals/constants/index.js"; import { useClassNames, useControlled, useUniqueId, useEventCallback } from "../internals/hooks/index.js"; import { omitTriggerPropKeys, PickerPopup, pickerPropTypes, PickerToggleTrigger, PickerIndicator, PickerLabel, pickTriggerPropKeys, usePickerClassName, usePickerRef, onMenuKeyDown } from "../internals/Picker/index.js"; import { createChainedFunction, mergeRefs, partitionHTMLProps, getStringLength } from "../internals/utils/index.js"; import { addMonths, addDays, copyTime, calendarOnlyProps, endOfDay, isValid, isBefore, isSameDay, isAfter, isSameMonth, reverseDateRangeOmitTime, startOfDay, DateMode, useDateMode } from "../internals/utils/date/index.js"; import { useCustom } from "../CustomProvider/index.js"; /** * A date range picker allows you to select a date range from a calendar. * * @see https://rsuitejs.com/components/date-range-picker */ var DateRangePicker = /*#__PURE__*/React.forwardRef(function (props, ref) { var _ref, _ref2, _merge; var _useCustom = useCustom('DateRangePicker', props), formatDate = _useCustom.formatDate, propsWithDefaults = _useCustom.propsWithDefaults; var _propsWithDefaults$as = propsWithDefaults.as, Component = _propsWithDefaults$as === void 0 ? 'div' : _propsWithDefaults$as, _propsWithDefaults$cl = propsWithDefaults.classPrefix, classPrefix = _propsWithDefaults$cl === void 0 ? 'picker' : _propsWithDefaults$cl, className = propsWithDefaults.className, _propsWithDefaults$ap = propsWithDefaults.appearance, appearance = _propsWithDefaults$ap === void 0 ? 'default' : _propsWithDefaults$ap, _propsWithDefaults$ed = propsWithDefaults.editable, editable = _propsWithDefaults$ed === void 0 ? true : _propsWithDefaults$ed, _propsWithDefaults$cl2 = propsWithDefaults.cleanable, cleanable = _propsWithDefaults$cl2 === void 0 ? true : _propsWithDefaults$cl2, _propsWithDefaults$ch = propsWithDefaults.character, character = _propsWithDefaults$ch === void 0 ? ' ~ ' : _propsWithDefaults$ch, calendarSnapping = propsWithDefaults.calendarSnapping, defaultCalendarValue = propsWithDefaults.defaultCalendarValue, defaultValue = propsWithDefaults.defaultValue, plaintext = propsWithDefaults.plaintext, disabled = propsWithDefaults.disabled, DEPRECATED_disabledDate = propsWithDefaults.disabledDate, shouldDisableDate = propsWithDefaults.shouldDisableDate, shouldDisableHour = propsWithDefaults.shouldDisableHour, shouldDisableMinute = propsWithDefaults.shouldDisableMinute, shouldDisableSecond = propsWithDefaults.shouldDisableSecond, format = propsWithDefaults.format, hoverRange = propsWithDefaults.hoverRange, idProp = propsWithDefaults.id, _propsWithDefaults$is = propsWithDefaults.isoWeek, isoWeek = _propsWithDefaults$is === void 0 ? false : _propsWithDefaults$is, _propsWithDefaults$we = propsWithDefaults.weekStart, weekStart = _propsWithDefaults$we === void 0 ? 0 : _propsWithDefaults$we, _propsWithDefaults$li = propsWithDefaults.limitEndYear, limitEndYear = _propsWithDefaults$li === void 0 ? 1000 : _propsWithDefaults$li, limitStartYear = propsWithDefaults.limitStartYear, locale = propsWithDefaults.locale, loading = propsWithDefaults.loading, label = propsWithDefaults.label, menuClassName = propsWithDefaults.menuClassName, menuStyle = propsWithDefaults.menuStyle, oneTap = propsWithDefaults.oneTap, _propsWithDefaults$pl = propsWithDefaults.placeholder, placeholder = _propsWithDefaults$pl === void 0 ? '' : _propsWithDefaults$pl, _propsWithDefaults$pl2 = propsWithDefaults.placement, placement = _propsWithDefaults$pl2 === void 0 ? 'bottomStart' : _propsWithDefaults$pl2, ranges = propsWithDefaults.ranges, readOnly = propsWithDefaults.readOnly, _propsWithDefaults$sh = propsWithDefaults.showOneCalendar, showOneCalendar = _propsWithDefaults$sh === void 0 ? false : _propsWithDefaults$sh, showWeekNumbers = propsWithDefaults.showWeekNumbers, DEPRECATED_showMeridian = propsWithDefaults.showMeridian, _propsWithDefaults$sh2 = propsWithDefaults.showMeridiem, showMeridiem = _propsWithDefaults$sh2 === void 0 ? DEPRECATED_showMeridian : _propsWithDefaults$sh2, _propsWithDefaults$sh3 = propsWithDefaults.showHeader, showHeader = _propsWithDefaults$sh3 === void 0 ? true : _propsWithDefaults$sh3, style = propsWithDefaults.style, size = propsWithDefaults.size, caretAsProp = propsWithDefaults.caretAs, valueProp = propsWithDefaults.value, monthDropdownProps = propsWithDefaults.monthDropdownProps, hideHours = propsWithDefaults.hideHours, hideMinutes = propsWithDefaults.hideMinutes, hideSeconds = propsWithDefaults.hideSeconds, onChange = propsWithDefaults.onChange, onClean = propsWithDefaults.onClean, onEnter = propsWithDefaults.onEnter, onExit = propsWithDefaults.onExit, onOk = propsWithDefaults.onOk, onSelect = propsWithDefaults.onSelect, onShortcutClick = propsWithDefaults.onShortcutClick, renderTitle = propsWithDefaults.renderTitle, renderValue = propsWithDefaults.renderValue, renderCell = propsWithDefaults.renderCell, restProps = _objectWithoutPropertiesLoose(propsWithDefaults, _excluded); var id = useUniqueId('rs-', idProp); var _usePickerRef = usePickerRef(ref), trigger = _usePickerRef.trigger, root = _usePickerRef.root, target = _usePickerRef.target, overlay = _usePickerRef.overlay; var _useClassNames = useClassNames(classPrefix), merge = _useClassNames.merge, prefix = _useClassNames.prefix; var formatStr = format || (locale === null || locale === void 0 ? void 0 : locale.shortDateFormat) || 'yyyy-MM-dd'; var rangeFormatStr = "" + formatStr + character + formatStr; var _useControlled = useControlled(valueProp, defaultValue !== null && defaultValue !== void 0 ? defaultValue : null), value = _useControlled[0], setValue = _useControlled[1]; var _useDateMode = useDateMode(formatStr), mode = _useDateMode.mode, has = _useDateMode.has; // Show only the calendar month panel. formatStr = 'yyyy-MM' var onlyShowMonth = mode === DateMode.Month; // Only show the time panel. formatStr = 'HH:mm:ss' var onlyShowTime = mode === DateMode.Time; // Allows two calendar panels to display the same month. var allowSameMonth = onlyShowMonth || showOneCalendar || onlyShowTime; // Default gap between two calendars, if `showOneCalendar` is set, the gap is 0 var calendarGap = allowSameMonth ? 0 : 1; /** * Whether to complete the selection. * Everytime selection will change this value. If the value is false, it means that the selection has not been completed. * * In `oneTap` mode, select action will not change this value, its value should be true always. */ var _useState = useState(true), isSelectedIdle = _useState[0], setSelectedIdle = _useState[1]; /** * The currently selected date range. * * The time range is selected by two clicks. After the first click, * the cursor will store a temporary event date in the process until * the second click to determine the end date of the date range. * */ var _useState2 = useState((_ref = valueProp !== null && valueProp !== void 0 ? valueProp : defaultValue) !== null && _ref !== void 0 ? _ref : []), selectedDates = _useState2[0], setSelectedDates = _useState2[1]; // The date of the current hover, used to reduce the calculation of `handleMouseMove` var _useState3 = useState(value), hoverDateRange = _useState3[0], setHoverDateRange = _useState3[1]; // The displayed calendar panel is rendered based on this value. var _useState4 = useState(getSafeCalendarDate({ value: (_ref2 = value !== null && value !== void 0 ? value : defaultCalendarValue) !== null && _ref2 !== void 0 ? _ref2 : null, allowSameMonth: allowSameMonth })), calendarDateRange = _useState4[0], setCalendarDateRangeValue = _useState4[1]; /** * When hoverRange is set, `selectValue` will be updated during the hover process, * which will cause the `selectValue` to be updated after the first click, * so declare a Ref to temporarily store the `selectValue` of the first click. */ var selectRangeValueRef = useRef(null); /** * * The key of the currently active calendar panel. * Used to switch when only one calendar panel is displayed. */ var _useState5 = useState(), activeCalendarKey = _useState5[0], setActiveCalendarKey = _useState5[1]; /** * Get the time on the calendar. */ var getCalendarDatetime = function getCalendarDatetime(calendarKey) { var index = calendarKey === 'start' ? 0 : 1; return (calendarDateRange === null || calendarDateRange === void 0 ? void 0 : calendarDateRange[index]) || (defaultCalendarValue === null || defaultCalendarValue === void 0 ? void 0 : defaultCalendarValue[index]); }; /** * Call this function to update the calendar panel rendering benchmark value. * If params `value` is not passed, it defaults to [new Date(), addMonth(new Date(), 1)]. */ var setCalendarDateRange = function setCalendarDateRange(_ref3) { var dateRange = _ref3.dateRange, calendarKey = _ref3.calendarKey, eventName = _ref3.eventName; var nextValue = dateRange; // The time should remain the same when the dates in the date range are changed. if (has('time') && dateRange !== null && dateRange !== void 0 && dateRange.length && (eventName === 'changeDate' || eventName === 'changeMonth')) { var startDate = copyTime({ from: getCalendarDatetime('start'), to: dateRange[0] }); var endDate = copyTime({ from: getCalendarDatetime('end'), to: dateRange.length === 1 ? addMonths(startDate, calendarGap) : dateRange[1] }); nextValue = [startDate, endDate]; } else if (dateRange === null && typeof defaultCalendarValue !== 'undefined') { // Make the calendar render the value of defaultCalendarValue after clearing the value. nextValue = defaultCalendarValue; } var nextCalendarDate = getSafeCalendarDate({ value: nextValue, calendarKey: calendarKey, allowSameMonth: allowSameMonth }); setCalendarDateRangeValue(nextCalendarDate); if (onlyShowMonth && eventName === 'changeMonth') { setSelectedDates(nextCalendarDate); } }; useEffect(function () { // If value changes, update the selected and hover date values on the calendar panel. setSelectedDates(valueProp !== null && valueProp !== void 0 ? valueProp : []); setHoverDateRange(valueProp !== null && valueProp !== void 0 ? valueProp : null); }, [valueProp]); var getInputHtmlSize = function getInputHtmlSize() { var padding = 4; var strings = rangeFormatStr; if (value) { var startDate = value[0], endDate = value[1]; strings = "" + formatDate(startDate, formatStr) + character + formatDate(endDate, formatStr); } return getStringLength(strings) + padding; }; /** * preset hover range */ var getHoverRangeValue = function getHoverRangeValue(date) { function getHoverRangeFunc() { if (hoverRange === 'week') { return function (date) { return getWeekHoverRange(date, { isoWeek: isoWeek, weekStart: weekStart, locale: locale === null || locale === void 0 ? void 0 : locale.dateLocale }); }; } else if (hoverRange === 'month') { return getMonthHoverRange; } return hoverRange; } var hoverRangeFunc = getHoverRangeFunc(); if (isNil(hoverRangeFunc)) { return null; } var hoverValues = hoverRangeFunc(date); var isHoverRangeValid = hoverValues instanceof Array && hoverValues.length === 2; if (!isHoverRangeValid) { return null; } if (isAfter(hoverValues[0], hoverValues[1])) { hoverValues = reverseDateRangeOmitTime(hoverValues); } return hoverValues; }; var setDateRange = function setDateRange(event, nextValue, closeOverlay) { if (closeOverlay === void 0) { closeOverlay = true; } // If nextValue is null, it means that the user is erasing the selected dates. setSelectedDates(nextValue !== null && nextValue !== void 0 ? nextValue : []); setValue(nextValue); if (!isSameRange(nextValue, value, formatStr)) { onChange === null || onChange === void 0 || onChange(nextValue, event); } // `closeOverlay` default value is `true` if (closeOverlay !== false) { handleClose(); } }; /** * Select the date range. If oneTap is not set, you need to click twice to select the start time and end time. * The MouseMove event is called between the first click and the second click to update the selection state. */ var onMouseMove = useEventCallback(function (date) { var nextHoverDateRange = getHoverRangeValue(date); // If hasDoneSelect is false, // it means there's already one selected date // and waiting for user to select the second date to complete the selection. if (!isSelectedIdle) { // If `hoverRange` is set, you need to change the value of hoverDateRange according to the rules if (!isNil(nextHoverDateRange) && !isNil(selectRangeValueRef.current)) { var nextSelectedDates = [selectRangeValueRef.current[0], nextHoverDateRange[1]]; if (isBefore(nextHoverDateRange[0], selectRangeValueRef.current[0])) { nextSelectedDates = [nextHoverDateRange[0], selectRangeValueRef.current[1]]; } setSelectedDates(nextSelectedDates); } else { setHoverDateRange(function (prevHoverValue) { return isNil(prevHoverValue) ? null : [prevHoverValue[0], date]; }); } // Before the first click, if nextHoverDateRange has a value, hoverDateRange needs to be updated } else if (!isNil(nextHoverDateRange)) { setHoverDateRange(nextHoverDateRange); } }); /** * Callback for selecting a date cell in the calendar grid */ var handleSelectDate = useEventCallback(function (index, date, event) { var calendarKey = index === 0 ? 'start' : 'end'; var nextSelectDates = hoverDateRange !== null && hoverDateRange !== void 0 ? hoverDateRange : []; var hoverRangeValue = getHoverRangeValue(date); var noHoverRangeValid = isNil(hoverRangeValue); // in `oneTap` mode if (oneTap) { setDateRange(event, noHoverRangeValid ? [startOfDay(date), endOfDay(date)] : hoverRangeValue); onSelect === null || onSelect === void 0 || onSelect(date, event); return; } // no preset hover range can use if (noHoverRangeValid) { // start select if (isSelectedIdle) { nextSelectDates = [date]; } else { // finish select nextSelectDates[1] = date; } } else { if (!isSelectedIdle) { nextSelectDates = selectedDates; selectRangeValueRef.current = null; } else { nextSelectDates = hoverRangeValue; selectRangeValueRef.current = hoverRangeValue; } } if (nextSelectDates.length === 2) { // If user have completed the selection, then sort the selected dates. if (isAfter(nextSelectDates[0], nextSelectDates[1])) { nextSelectDates = reverseDateRangeOmitTime(nextSelectDates); } if (has('time')) { nextSelectDates = [copyTime({ from: getCalendarDatetime('start'), to: nextSelectDates[0] }), copyTime({ from: getCalendarDatetime('end'), to: nextSelectDates[1] })]; } setHoverDateRange(nextSelectDates); } else { setHoverDateRange([nextSelectDates[0], nextSelectDates[0]]); } if (isSelectedIdle) { setActiveCalendarKey('end'); } else { setActiveCalendarKey('start'); } setSelectedDates(nextSelectDates); if (!isSameMonth(calendarDateRange[index], date) || calendarSnapping) { setCalendarDateRange({ dateRange: nextSelectDates, calendarKey: calendarKey, eventName: 'changeDate' }); } onSelect === null || onSelect === void 0 || onSelect(date, event); setSelectedIdle(!isSelectedIdle); }); /** * If `selectValue` changed, there will be the following effects. * 1. Check if the selection is completed. * 2. if the selection is completed, set the temporary `hoverValue` empty. */ useEffect(function () { var selectValueLength = selectedDates.length; var doneSelected = selectValueLength === 0 || selectValueLength === 2; doneSelected && setHoverDateRange(null); }, [selectedDates]); var onChangeCalendarMonth = useEventCallback(function (index, date) { var calendarKey = index === 0 ? 'start' : 'end'; var nextCalendarDate = Array.from(calendarDateRange); nextCalendarDate[index] = date; setCalendarDateRange({ dateRange: nextCalendarDate, calendarKey: calendarKey, eventName: 'changeMonth' }); }); var onChangeCalendarTime = useEventCallback(function (index, date) { var calendarKey = index === 0 ? 'start' : 'end'; var nextCalendarDate = Array.from(calendarDateRange); nextCalendarDate[index] = date; setCalendarDateRange({ dateRange: nextCalendarDate, calendarKey: calendarKey, eventName: 'changeTime' }); setSelectedDates(function (prev) { var next = [].concat(prev); // if next[index] is not empty, only update the time after aligning the year, month and day next[index] = next[index] ? copyTime({ from: date, to: next[index] }) : new Date(date.valueOf()); return next; }); }); var handleEnter = useEventCallback(function () { var nextCalendarDate; if (value && value.length) { var startDate = value[0], endData = value[1]; nextCalendarDate = [startDate, isSameMonth(startDate, endData) ? addMonths(endData, calendarGap) : endData]; } else { // Reset the date on the calendar to the default date nextCalendarDate = getSafeCalendarDate({ value: defaultCalendarValue !== null && defaultCalendarValue !== void 0 ? defaultCalendarValue : null, allowSameMonth: allowSameMonth }); } setSelectedDates(value !== null && value !== void 0 ? value : []); setCalendarDateRange({ dateRange: nextCalendarDate }); }); var handleExit = useEventCallback(function () { setSelectedIdle(true); }); /** * Toolbar operation callback function */ var handleShortcutPageDate = useEventCallback(function (range, closeOverlay, event) { if (closeOverlay === void 0) { closeOverlay = false; } var value = range.value; setCalendarDateRange({ dateRange: value, eventName: 'shortcutSelection' }); if (closeOverlay) { setDateRange(event, value, closeOverlay); } else { setSelectedDates(value !== null && value !== void 0 ? value : []); } onShortcutClick === null || onShortcutClick === void 0 || onShortcutClick(range, event); // End unfinished selections. setSelectedIdle(true); }); var calculateDateRange = function calculateDateRange() { var _selectedDates$ = selectedDates[0], start = _selectedDates$ === void 0 ? calendarDateRange[0] : _selectedDates$, _selectedDates$2 = selectedDates[1], end = _selectedDates$2 === void 0 ? calendarDateRange[1] : _selectedDates$2; if (onlyShowTime) { return [start, end]; } return selectedDates; }; var handleClickOK = useEventCallback(function (event) { var nextValue = calculateDateRange(); setDateRange(event, nextValue); onOk === null || onOk === void 0 || onOk(nextValue, event); }); var handleClean = useEventCallback(function (event) { setCalendarDateRange({ dateRange: null }); setDateRange(event, null); onClean === null || onClean === void 0 || onClean(event); event.stopPropagation(); }); /** * Callback after the input box value is changed. */ var handleInputChange = useEventCallback(function (value, event) { if (!value) { return; } var startDate = value[0], endDate = value[1]; var selectValue = [startDate, endDate]; setHoverDateRange(selectValue); setSelectedDates(selectValue); setCalendarDateRange({ dateRange: selectValue }); setDateRange(event, selectValue, false); }); /** * Check if the date is disabled */ var isDateDisabled = useDateDisabled({ shouldDisableDate: shouldDisableDate, DEPRECATED_disabledDate: DEPRECATED_disabledDate }); /** * Check if a date range is disabled */ var isRangeDisabled = function isRangeDisabled(start, end, target) { if (isDateDisabled) { // If the date is between the start and the end the button is disabled while (isBefore(start, end) || isSameDay(start, end)) { if (isDateDisabled(start, { selectDate: selectedDates, selectedDone: isSelectedIdle, target: target })) { return true; } start = addDays(start, 1); } } return false; }; /** * Determine if the OK button should be disabled */ var shouldDisableOkButton = function shouldDisableOkButton() { var _calculateDateRange = calculateDateRange(), startDate = _calculateDateRange[0], endDate = _calculateDateRange[1]; // Check if start or end dates are missing if (!startDate || !endDate) { return true; } // Additional condition if only showing time if (!onlyShowTime && !isSelectedIdle) { return true; } // Check if there is any error in the selected date range if (isErrorValue([startDate, endDate])) { return true; } return false; }; /** * Check if a shortcut is disabled based on the selected date range */ var shouldDisableShortcut = function shouldDisableShortcut(selectedDates) { if (selectedDates === void 0) { selectedDates = []; } if (selectedDates === null) { return false; } var _selectedDates = selectedDates, startDate = _selectedDates[0], endDate = _selectedDates[1]; // Disable if either start or end date is missing if (!startDate || !endDate) { return true; } // Check if the date range is disabled for the shortcut return isRangeDisabled(startDate, endDate, TARGET.TOOLBAR_SHORTCUT); }; var handleClose = useEventCallback(function () { var _trigger$current, _trigger$current$clos; (_trigger$current = trigger.current) === null || _trigger$current === void 0 || (_trigger$current$clos = _trigger$current.close) === null || _trigger$current$clos === void 0 || _trigger$current$clos.call(_trigger$current); }); var handleInputKeyDown = useEventCallback(function (event) { onMenuKeyDown(event, { esc: handleClose, enter: function enter() { var _trigger$current2; var _ref4 = ((_trigger$current2 = trigger.current) === null || _trigger$current2 === void 0 ? void 0 : _trigger$current2.getState()) || {}, open = _ref4.open; if (!open) { var _trigger$current3; (_trigger$current3 = trigger.current) === null || _trigger$current3 === void 0 || _trigger$current3.open(); } } }); }); var disableCalendarDate = isDateDisabled ? function (date, values, type) { return isDateDisabled(date, { selectDate: values, selectedDone: isSelectedIdle, target: type }); } : undefined; var renderCalendarOverlay = function renderCalendarOverlay(positionProps, speakerRef) { var left = positionProps.left, top = positionProps.top, className = positionProps.className; var classes = merge(className, menuClassName, prefix('popup-daterange')); var panelClasses = prefix('daterange-panel', { 'daterange-panel-show-one-calendar': showOneCalendar, 'daterange-panel-only-time': onlyShowTime }); /** * Set a min-width (528px) when there are two calendars * @see https://github.com/rsuite/rsuite/issues/3522 */ var panelStyles = { minWidth: showOneCalendar || onlyShowTime ? 'auto' : 528 }; var styles = _extends({}, menuStyle, { left: left, top: top }); var calendarProps = { locale: locale, isoWeek: isoWeek, weekStart: weekStart, limitEndYear: limitEndYear, showMeridiem: showMeridiem, calendarDateRange: calendarDateRange, limitStartYear: limitStartYear, showWeekNumbers: showWeekNumbers, format: formatStr, value: selectedDates, monthDropdownProps: monthDropdownProps, hoverRangeValue: hoverDateRange !== null && hoverDateRange !== void 0 ? hoverDateRange : undefined, hideHours: hideHours, hideMinutes: hideMinutes, hideSeconds: hideSeconds, disabledHours: shouldDisableHour, disabledMinutes: shouldDisableMinute, disabledSeconds: shouldDisableSecond, disabledDate: disableCalendarDate, onSelect: handleSelectDate, onChangeCalendarMonth: onChangeCalendarMonth, onChangeCalendarTime: onChangeCalendarTime, onMouseMove: onMouseMove, renderTitle: renderTitle, renderCellOnPicker: renderCell }; var getCalendars = function getCalendars() { if (showOneCalendar) { return /*#__PURE__*/React.createElement(Calendar, _extends({ index: activeCalendarKey === 'end' ? 1 : 0 }, calendarProps)); } return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Calendar, _extends({ index: 0 }, calendarProps)), /*#__PURE__*/React.createElement(Calendar, _extends({ index: 1 }, calendarProps))); }; var sideRanges = (ranges === null || ranges === void 0 ? void 0 : ranges.filter(function (range) { return (range === null || range === void 0 ? void 0 : range.placement) === 'left'; })) || []; var bottomRanges = ranges === null || ranges === void 0 ? void 0 : ranges.filter(function (range) { return (range === null || range === void 0 ? void 0 : range.placement) === 'bottom' || (range === null || range === void 0 ? void 0 : range.placement) === undefined; }); return /*#__PURE__*/React.createElement(PickerPopup, { role: "dialog", "aria-labelledby": label ? id + "-label" : undefined, tabIndex: -1, className: classes, ref: mergeRefs(overlay, speakerRef), target: trigger, style: styles }, /*#__PURE__*/React.createElement("div", { className: panelClasses, style: panelStyles }, /*#__PURE__*/React.createElement(Stack, { alignItems: "flex-start" }, sideRanges.length > 0 && /*#__PURE__*/React.createElement(PredefinedRanges, { direction: "column", spacing: 0, className: prefix('daterange-predefined'), ranges: sideRanges, calendarDate: calendarDateRange, locale: locale, disableShortcut: shouldDisableShortcut, onShortcutClick: handleShortcutPageDate, "data-testid": "daterange-predefined-side" }), /*#__PURE__*/React.createElement(Stack.Item, null, /*#__PURE__*/React.createElement("div", { className: prefix('daterange-content') }, showHeader && /*#__PURE__*/React.createElement(Header, { value: isSelectedIdle ? selectedDates : hoverDateRange, formatStr: formatStr, character: character, clickable: showOneCalendar, activeKey: activeCalendarKey, onSelect: setActiveCalendarKey }), /*#__PURE__*/React.createElement("div", { className: prefix("daterange-calendar-" + (showOneCalendar ? 'single' : 'group')) }, /*#__PURE__*/React.createElement(DateRangePickerProvider, { value: { isSelectedIdle: isSelectedIdle } }, getCalendars()))), /*#__PURE__*/React.createElement(Toolbar, { locale: locale, calendarDate: selectedDates, disableOkBtn: shouldDisableOkButton, disableShortcut: shouldDisableShortcut, hideOkBtn: oneTap, onOk: handleClickOK, onShortcutClick: handleShortcutPageDate, ranges: bottomRanges }))))); }; var hasValue = !isNil(value) && value.length > 1; var _usePickerClassName = usePickerClassName(_extends({}, props, { classPrefix: classPrefix, className: className, name: 'daterange', appearance: appearance, hasValue: hasValue, cleanable: cleanable })), classes = _usePickerClassName[0], usedClassNamePropKeys = _usePickerClassName[1]; var caretAs = useMemo(function () { if (caretAsProp === null) { return null; } return caretAsProp || (onlyShowTime ? TimeIcon : CalendarIcon); }, [caretAsProp, onlyShowTime]); var isErrorValue = function isErrorValue(value) { if (!value) { return false; } // If the value is an empty array, it is not an error value. if (Array.isArray(value) && value.length === 0) { return false; } var startDate = value[0], endDate = value[1]; if (!isValid(startDate) || !isValid(endDate)) { return true; } if (isBefore(endDate, startDate)) { return true; } var disabledOptions = { selectDate: value, selectedDone: isSelectedIdle, target: TARGET.INPUT }; if (isDateDisabled !== null && isDateDisabled !== void 0 && isDateDisabled(startDate, disabledOptions) || isDateDisabled !== null && isDateDisabled !== void 0 && isDateDisabled(endDate, disabledOptions)) { return true; } return false; }; var _partitionHTMLProps = partitionHTMLProps(restProps, { htmlProps: [], includeAria: true }), ariaProps = _partitionHTMLProps[0], rest = _partitionHTMLProps[1]; var showCleanButton = cleanable && hasValue && !readOnly; var invalidValue = value && isErrorValue(value); var _useCustomizedInput = useCustomizedInput({ mode: 'dateRange', value: value, formatStr: formatStr, renderValue: renderValue, readOnly: readOnly, editable: editable, loading: loading }), customValue = _useCustomizedInput.customValue, inputReadOnly = _useCustomizedInput.inputReadOnly, Input = _useCustomizedInput.Input, events = _useCustomizedInput.events; return /*#__PURE__*/React.createElement(PickerToggleTrigger, { trigger: "active", ref: trigger, pickerProps: pick(props, pickTriggerPropKeys), placement: placement, onEnter: createChainedFunction(events.onActive, handleEnter, onEnter), onExit: createChainedFunction(events.onInactive, handleExit, onExit), speaker: renderCalendarOverlay }, /*#__PURE__*/React.createElement(Component, { ref: root, className: merge(classes, (_merge = {}, _merge[prefix('error')] = invalidValue, _merge)), style: style }, plaintext ? /*#__PURE__*/React.createElement(DateRangeInput, { value: value, format: formatStr, plaintext: plaintext }) : /*#__PURE__*/React.createElement(InputGroup, _extends({}, omit(rest, [].concat(omitTriggerPropKeys, usedClassNamePropKeys, calendarOnlyProps)), { inside: true, className: prefix(_templateObject || (_templateObject = _taggedTemplateLiteralLoose(["input-group"]))), disabled: disabled, size: size }), /*#__PURE__*/React.createElement(PickerLabel, { className: prefix(_templateObject2 || (_templateObject2 = _taggedTemplateLiteralLoose(["label"]))), id: id + "-label" }, label), /*#__PURE__*/React.createElement(Input, _extends({ "aria-haspopup": "dialog", "aria-invalid": invalidValue, "aria-labelledby": label ? id + "-label" : undefined }, ariaProps, { ref: target, id: id, value: customValue || value, character: character, format: formatStr, placeholder: placeholder ? placeholder : rangeFormatStr, disabled: disabled, readOnly: inputReadOnly, htmlSize: getInputHtmlSize(), onChange: handleInputChange, onKeyDown: handleInputKeyDown })), /*#__PURE__*/React.createElement(PickerIndicator, { loading: loading, caretAs: caretAs, onClose: handleClean, showCleanButton: showCleanButton })))); }); DateRangePicker.displayName = 'DateRangePicker'; DateRangePicker.propTypes = _extends({}, pickerPropTypes, { ranges: PropTypes.array, value: PropTypes.arrayOf(PropTypes.instanceOf(Date)), defaultValue: PropTypes.arrayOf(PropTypes.instanceOf(Date)), defaultCalendarValue: PropTypes.arrayOf(PropTypes.instanceOf(Date)), hoverRange: PropTypes.oneOfType([oneOf(['week', 'month']), PropTypes.func]), format: PropTypes.string, hideHours: PropTypes.func, hideMinutes: PropTypes.func, hideSeconds: PropTypes.func, isoWeek: PropTypes.bool, weekStart: PropTypes.oneOf([0, 1, 2, 3, 4, 5, 6]), oneTap: PropTypes.bool, limitEndYear: PropTypes.number, limitStartYear: PropTypes.number, onChange: PropTypes.func, onOk: PropTypes.func, disabledDate: deprecatePropTypeNew(PropTypes.func, 'Use "shouldDisableDate" property instead.'), shouldDisableDate: PropTypes.func, onSelect: PropTypes.func, showWeekNumbers: PropTypes.bool, showMeridiem: PropTypes.bool, showOneCalendar: PropTypes.bool }); export default DateRangePicker;