UNPKG

rsuite

Version:

A suite of react components

519 lines (442 loc) 20.5 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.default = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose")); var _react = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _mapValues = _interopRequireDefault(require("lodash/mapValues")); var _pick = _interopRequireDefault(require("lodash/pick")); var _omit = _interopRequireDefault(require("lodash/omit")); var _Calendar = _interopRequireDefault(require("@rsuite/icons/legacy/Calendar")); var _ClockO = _interopRequireDefault(require("@rsuite/icons/legacy/ClockO")); var _Calendar2 = require("../Calendar"); var _useCalendarDate2 = _interopRequireDefault(require("../Calendar/useCalendarDate")); var _Toolbar = _interopRequireDefault(require("./Toolbar")); var _utils = require("../utils"); var _Picker = require("../Picker"); var _utils2 = require("./utils"); var DatePicker = /*#__PURE__*/_react.default.forwardRef(function (props, ref) { var _props$as = props.as, Component = _props$as === void 0 ? 'div' : _props$as, className = props.className, _props$classPrefix = props.classPrefix, classPrefix = _props$classPrefix === void 0 ? 'picker' : _props$classPrefix, calendarDefaultDate = props.calendarDefaultDate, _props$cleanable = props.cleanable, cleanable = _props$cleanable === void 0 ? true : _props$cleanable, defaultValue = props.defaultValue, disabled = props.disabled, _props$format = props.format, formatStr = _props$format === void 0 ? 'yyyy-MM-dd' : _props$format, isoWeek = props.isoWeek, _props$limitEndYear = props.limitEndYear, limitEndYear = _props$limitEndYear === void 0 ? 1000 : _props$limitEndYear, overrideLocale = props.locale, menuClassName = props.menuClassName, _props$appearance = props.appearance, appearance = _props$appearance === void 0 ? 'default' : _props$appearance, _props$placement = props.placement, placement = _props$placement === void 0 ? 'bottomStart' : _props$placement, oneTap = props.oneTap, _props$placeholder = props.placeholder, placeholder = _props$placeholder === void 0 ? '' : _props$placeholder, ranges = props.ranges, valueProp = props.value, showMeridian = props.showMeridian, showWeekNumbers = props.showWeekNumbers, style = props.style, toggleAs = props.toggleAs, caretAsProp = props.caretAs, disabledDateProp = props.disabledDate, renderValue = props.renderValue, onChange = props.onChange, onChangeCalendarDate = props.onChangeCalendarDate, onClean = props.onClean, onClose = props.onClose, onEntered = props.onEntered, onExited = props.onExited, onNextMonth = props.onNextMonth, onOk = props.onOk, onOpen = props.onOpen, onPrevMonth = props.onPrevMonth, onSelect = props.onSelect, onToggleMonthDropdown = props.onToggleMonthDropdown, onToggleTimeDropdown = props.onToggleTimeDropdown, rest = (0, _objectWithoutPropertiesLoose2.default)(props, ["as", "className", "classPrefix", "calendarDefaultDate", "cleanable", "defaultValue", "disabled", "format", "isoWeek", "limitEndYear", "locale", "menuClassName", "appearance", "placement", "oneTap", "placeholder", "ranges", "value", "showMeridian", "showWeekNumbers", "style", "toggleAs", "caretAs", "disabledDate", "renderValue", "onChange", "onChangeCalendarDate", "onClean", "onClose", "onEntered", "onExited", "onNextMonth", "onOk", "onOpen", "onPrevMonth", "onSelect", "onToggleMonthDropdown", "onToggleTimeDropdown"]); var _useCustom = (0, _utils.useCustom)('DatePicker', overrideLocale), locale = _useCustom.locale, formatDate = _useCustom.formatDate, parseDate = _useCustom.parseDate; var _useClassNames = (0, _utils.useClassNames)(classPrefix), merge = _useClassNames.merge, prefix = _useClassNames.prefix; var _useControlled = (0, _utils.useControlled)(valueProp, defaultValue), value = _useControlled[0], setValue = _useControlled[1]; var _useCalendarDate = (0, _useCalendarDate2.default)(valueProp, calendarDefaultDate), calendarDate = _useCalendarDate.calendarDate, setCalendarDate = _useCalendarDate.setCalendarDate; var _useState = (0, _react.useState)(), inputState = _useState[0], setInputState = _useState[1]; var _useCalendarState = (0, _utils2.useCalendarState)(), calendarState = _useCalendarState.calendarState, reset = _useCalendarState.reset, openMonth = _useCalendarState.openMonth, openTime = _useCalendarState.openTime; var _useState2 = (0, _react.useState)(false), active = _useState2[0], setActive = _useState2[1]; var triggerRef = (0, _react.useRef)(null); var rootRef = (0, _react.useRef)(null); var targetRef = (0, _react.useRef)(null); var overlayRef = (0, _react.useRef)(null); (0, _Picker.usePublicMethods)(ref, { rootRef: rootRef, triggerRef: triggerRef, overlayRef: overlayRef, targetRef: targetRef }); /** * Switch to the callback triggered after the next month. */ var handleMoveForward = (0, _react.useCallback)(function (nextPageDate) { setCalendarDate(nextPageDate); onNextMonth === null || onNextMonth === void 0 ? void 0 : onNextMonth(nextPageDate); onChangeCalendarDate === null || onChangeCalendarDate === void 0 ? void 0 : onChangeCalendarDate(nextPageDate); }, [onChangeCalendarDate, onNextMonth, setCalendarDate]); /** * Switch to the callback triggered after the previous month. */ var handleMoveBackward = (0, _react.useCallback)(function (nextPageDate) { setCalendarDate(nextPageDate); onPrevMonth === null || onPrevMonth === void 0 ? void 0 : onPrevMonth(nextPageDate); onChangeCalendarDate === null || onChangeCalendarDate === void 0 ? void 0 : onChangeCalendarDate(nextPageDate); }, [onChangeCalendarDate, onPrevMonth, setCalendarDate]); /** * The callback triggered when the date changes. */ var handleDateChange = (0, _react.useCallback)(function (nextValue, event) { onSelect === null || onSelect === void 0 ? void 0 : onSelect(nextValue, event); onChangeCalendarDate === null || onChangeCalendarDate === void 0 ? void 0 : onChangeCalendarDate(nextValue, event); }, [onChangeCalendarDate, onSelect]); /** * A callback triggered when the time on the calendar changes. */ var handleChangePageTime = (0, _react.useCallback)(function (nextPageTime) { setCalendarDate(nextPageTime); handleDateChange(nextPageTime); }, [handleDateChange, setCalendarDate]); var handleClose = (0, _react.useCallback)(function () { var _triggerRef$current, _triggerRef$current$c; (_triggerRef$current = triggerRef.current) === null || _triggerRef$current === void 0 ? void 0 : (_triggerRef$current$c = _triggerRef$current.close) === null || _triggerRef$current$c === void 0 ? void 0 : _triggerRef$current$c.call(_triggerRef$current); }, []); /** * The callback triggered when PM/AM is switched. */ var handleToggleMeridian = (0, _react.useCallback)(function () { var hours = _utils.DateUtils.getHours(calendarDate); var nextHours = hours >= 12 ? hours - 12 : hours + 12; var nextDate = _utils.DateUtils.setHours(calendarDate, nextHours); setCalendarDate(nextDate); }, [calendarDate, setCalendarDate]); var updateValue = (0, _react.useCallback)(function (event, nextPageDate, closeOverlay) { if (closeOverlay === void 0) { closeOverlay = true; } var nextValue = typeof nextPageDate !== 'undefined' ? nextPageDate : calendarDate; setCalendarDate(nextValue || new Date()); setValue(nextValue); if (nextValue !== value) { onChange === null || onChange === void 0 ? void 0 : onChange(nextValue, event); } // `closeOverlay` default value is `true` if (closeOverlay !== false) { handleClose(); } }, [handleClose, onChange, calendarDate, setCalendarDate, setValue, value]); /** * The callback triggered after the date in the shortcut area is clicked. */ var handleShortcutPageDate = (0, _react.useCallback)(function (value, closeOverlay, event) { updateValue(event, value, closeOverlay); handleDateChange(value, event); }, [handleDateChange, updateValue]); /** * The callback triggered after clicking the OK button. */ var handleOK = (0, _react.useCallback)(function (event) { updateValue(event); onOk === null || onOk === void 0 ? void 0 : onOk(calendarDate, event); }, [updateValue, onOk, calendarDate]); /** * Toggle month selection panel */ var handleMonthDropdown = (0, _react.useCallback)(function () { if (calendarState === _Calendar2.CalendarState.DROP_MONTH) { reset(); } else { openMonth(); } onToggleMonthDropdown === null || onToggleMonthDropdown === void 0 ? void 0 : onToggleMonthDropdown(calendarState !== _Calendar2.CalendarState.DROP_MONTH); }, [calendarState, onToggleMonthDropdown, openMonth, reset]); /** * Switch time selection panel */ var handleTimeDropdown = (0, _react.useCallback)(function () { if (calendarState === _Calendar2.CalendarState.DROP_TIME) { reset(); } else { openTime(); } onToggleTimeDropdown === null || onToggleTimeDropdown === void 0 ? void 0 : onToggleTimeDropdown(calendarState !== _Calendar2.CalendarState.DROP_TIME); }, [calendarState, onToggleTimeDropdown, openTime, reset]); /** * Callback after clicking the clear button. */ var handleClean = (0, _react.useCallback)(function (event) { setCalendarDate(new Date()); updateValue(event, null); }, [setCalendarDate, updateValue]); /** * Handle keyboard events. */ var onPickerKeyDown = (0, _Picker.useToggleKeyDownEvent)((0, _extends2.default)({ triggerRef: triggerRef, targetRef: targetRef, active: active, onExit: handleClean }, rest)); /** * Callback after the date is selected. */ var handleSelect = (0, _react.useCallback)(function (nextValue, event, updatableValue) { if (updatableValue === void 0) { updatableValue = true; } setCalendarDate( // Determine whether the current value contains time, if not, use calendarDate. _utils.DateUtils.shouldTime(formatStr) ? nextValue : (0, _utils.composeFunctions)(function (d) { return _utils.DateUtils.setHours(d, _utils.DateUtils.getHours(calendarDate)); }, function (d) { return _utils.DateUtils.setMinutes(d, _utils.DateUtils.getMinutes(calendarDate)); }, function (d) { return _utils.DateUtils.setSeconds(d, _utils.DateUtils.getSeconds(calendarDate)); })(nextValue)); handleDateChange(nextValue); if (oneTap && updatableValue) { updateValue(event, nextValue); } }, [formatStr, handleDateChange, oneTap, calendarDate, setCalendarDate, updateValue]); /** * A callback triggered when the date on the calendar changes. */ var handleChangePageDate = (0, _react.useCallback)(function (nextPageDate, event) { setCalendarDate(nextPageDate); reset(); handleDateChange(nextPageDate); // Show only the calendar month panel. formatStr = 'yyyy-MM' var onlyShowMonth = _utils.DateUtils.shouldMonth(formatStr) && !_utils.DateUtils.shouldDate(formatStr); if (oneTap && onlyShowMonth) { updateValue(event, nextPageDate); } }, [formatStr, handleDateChange, oneTap, reset, setCalendarDate, updateValue]); var disabledDate = (0, _react.useCallback)(function (date) { var _disabledDateProp; return (_disabledDateProp = disabledDateProp === null || disabledDateProp === void 0 ? void 0 : disabledDateProp(date)) !== null && _disabledDateProp !== void 0 ? _disabledDateProp : false; }, [disabledDateProp]); /** * Callback after the input box value is changed. */ var handleInputChange = (0, _react.useCallback)(function (value, event) { setInputState('Typing'); // isMatch('01/11/2020', 'MM/dd/yyyy') ==> true // isMatch('2020-11-01', 'MM/dd/yyyy') ==> false if (!_utils.DateUtils.isMatch(value, formatStr, { locale: locale.dateLocale })) { setInputState('Error'); return; } var date = parseDate(value, formatStr); // If only the time is included in the characters, it will default to today. if (_utils.DateUtils.shouldOnlyTime(formatStr)) { date = new Date(_utils.DateUtils.format(new Date(), 'yyyy-MM-dd') + " " + value); } if (!_utils.DateUtils.isValid(date)) { setInputState('Error'); return; } if (disabledDate(date)) { setInputState('Error'); return; } handleSelect(date, event, false); }, [formatStr, locale, parseDate, disabledDate, handleSelect]); /** * The callback after the enter key is triggered on the input */ var handleInputPressEnd = (0, _react.useCallback)(function (event) { if (inputState === 'Typing') { updateValue(event, calendarDate); } setInputState('Initial'); }, [inputState, calendarDate, updateValue]); var handleEntered = (0, _react.useCallback)(function () { onOpen === null || onOpen === void 0 ? void 0 : onOpen(); setActive(true); }, [onOpen]); var handleExited = (0, _react.useCallback)(function () { onClose === null || onClose === void 0 ? void 0 : onClose(); reset(); setActive(false); }, [onClose, reset]); // Check whether the time is within the time range of the shortcut option in the toolbar. var disabledToolbarHandle = (0, _react.useCallback)(function (date) { var _disabledDateProp2; var allowDate = (_disabledDateProp2 = disabledDateProp === null || disabledDateProp === void 0 ? void 0 : disabledDateProp(date)) !== null && _disabledDateProp2 !== void 0 ? _disabledDateProp2 : false; var allowTime = _utils.DateUtils.disabledTime(props, date); return allowDate || allowTime; }, [disabledDateProp, props]); var calendarProps = (0, _react.useMemo)(function () { return (0, _mapValues.default)((0, _pick.default)(props, _utils.DateUtils.calendarOnlyProps), function (disabledOrHiddenTimeFunc) { return function (next, date) { var _disabledOrHiddenTime; return (_disabledOrHiddenTime = disabledOrHiddenTimeFunc === null || disabledOrHiddenTimeFunc === void 0 ? void 0 : disabledOrHiddenTimeFunc(next, date)) !== null && _disabledOrHiddenTime !== void 0 ? _disabledOrHiddenTime : false; }; }); }, [props]); var inSameMonth = (0, _react.useCallback)(function (date) { return _utils.DateUtils.isSameMonth(date, calendarDate); }, [calendarDate]); var calendar = /*#__PURE__*/_react.default.createElement(_Calendar2.Calendar, (0, _extends2.default)({}, calendarProps, { locale: locale, showWeekNumbers: showWeekNumbers, showMeridian: showMeridian, disabledDate: disabledDate, limitEndYear: limitEndYear, format: formatStr, isoWeek: isoWeek, inSameMonth: inSameMonth, calendarState: calendarState, calendarDate: calendarDate, onMoveForward: handleMoveForward, onMoveBackward: handleMoveBackward, onSelect: handleSelect, onToggleMonthDropdown: handleMonthDropdown, onToggleTimeDropdown: handleTimeDropdown, onChangePageDate: handleChangePageDate, onChangePageTime: handleChangePageTime, onToggleMeridian: handleToggleMeridian })); var renderDropdownMenu = function renderDropdownMenu(positionProps, speakerRef) { var left = positionProps.left, top = positionProps.top, className = positionProps.className; var classes = merge(menuClassName, className, prefix('date-menu')); var styles = { left: left, top: top }; return /*#__PURE__*/_react.default.createElement(_Picker.PickerOverlay, { role: "dialog", className: classes, ref: (0, _utils.mergeRefs)(overlayRef, speakerRef), style: styles, target: triggerRef }, calendar, /*#__PURE__*/_react.default.createElement(_Toolbar.default, { locale: locale, ranges: ranges, calendarDate: calendarDate, disabledOkBtn: disabledToolbarHandle, disabledShortcut: disabledToolbarHandle, onClickShortcut: handleShortcutPageDate, onOk: handleOK, hideOkBtn: oneTap })); }; var hasValue = !!value; var _usePickerClassName = (0, _Picker.usePickerClassName)((0, _extends2.default)({}, props, { classPrefix: classPrefix, name: 'date', appearance: appearance, hasValue: hasValue, cleanable: cleanable })), classes = _usePickerClassName[0], usedClassNamePropKeys = _usePickerClassName[1]; var renderDate = (0, _react.useCallback)(function () { var _renderValue; if (!value) { return placeholder || formatStr; } return (_renderValue = renderValue === null || renderValue === void 0 ? void 0 : renderValue(value, formatStr)) !== null && _renderValue !== void 0 ? _renderValue : formatDate(value, formatStr); }, [formatStr, formatDate, placeholder, renderValue, value]); var caretAs = (0, _react.useMemo)(function () { return caretAsProp || (_utils.DateUtils.shouldOnlyTime(formatStr) ? _ClockO.default : _Calendar.default); }, [caretAsProp, formatStr]); return /*#__PURE__*/_react.default.createElement(_Picker.PickerToggleTrigger, { trigger: "active", pickerProps: (0, _pick.default)(props, _Picker.pickTriggerPropKeys), ref: triggerRef, placement: placement, onEntered: (0, _utils.createChainedFunction)(handleEntered, onEntered), onExited: (0, _utils.createChainedFunction)(handleExited, onExited), speaker: renderDropdownMenu }, /*#__PURE__*/_react.default.createElement(Component, { className: merge(className, classes), style: style, ref: rootRef }, /*#__PURE__*/_react.default.createElement(_Picker.PickerToggle, (0, _extends2.default)({}, (0, _omit.default)(rest, [].concat(_Picker.omitTriggerPropKeys, usedClassNamePropKeys, _utils.DateUtils.calendarOnlyProps)), { className: prefix({ error: inputState === 'Error' }), as: toggleAs, ref: targetRef, appearance: appearance, input: true, inputValue: value ? formatDate(value, formatStr) : '', inputPlaceholder: typeof placeholder === 'string' && placeholder ? placeholder : formatStr, inputMask: _utils.DateUtils.getDateMask(formatStr), onInputChange: handleInputChange, onInputBlur: handleInputPressEnd, onInputPressEnter: handleInputPressEnd, onKeyDown: onPickerKeyDown, onClean: (0, _utils.createChainedFunction)(handleClean, onClean), cleanable: cleanable && !disabled, hasValue: hasValue, active: active, placement: placement, disabled: disabled, caretAs: caretAs, "aria-haspopup": "dialog" }), renderDate()))); }); DatePicker.displayName = 'DatePicker'; DatePicker.propTypes = (0, _extends2.default)({}, _Picker.pickerPropTypes, { calendarDefaultDate: _propTypes.default.instanceOf(Date), defaultValue: _propTypes.default.instanceOf(Date), disabledDate: _propTypes.default.func, disabledHours: _propTypes.default.func, disabledMinutes: _propTypes.default.func, disabledSeconds: _propTypes.default.func, format: _propTypes.default.string, hideHours: _propTypes.default.func, hideMinutes: _propTypes.default.func, hideSeconds: _propTypes.default.func, isoWeek: _propTypes.default.bool, limitEndYear: _propTypes.default.number, onChange: _propTypes.default.func, onChangeCalendarDate: _propTypes.default.func, onNextMonth: _propTypes.default.func, onOk: _propTypes.default.func, onPrevMonth: _propTypes.default.func, onSelect: _propTypes.default.func, onToggleMonthDropdown: _propTypes.default.func, onToggleTimeDropdown: _propTypes.default.func, oneTap: _propTypes.default.bool, panelContainerRef: _propTypes.default.any, ranges: _propTypes.default.array, showMeridian: _propTypes.default.bool, showWeekNumbers: _propTypes.default.bool, value: _propTypes.default.instanceOf(Date) }); var _default = DatePicker; exports.default = _default;