import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck"; import _createClass from "@babel/runtime/helpers/esm/createClass"; import _inherits from "@babel/runtime/helpers/esm/inherits"; import _createSuper from "@babel/runtime/helpers/esm/createSuper"; import _extends from "@babel/runtime/helpers/esm/extends"; import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2"; import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; /** * Removed: * - getCalendarContainer: use `getPopupContainer` instead * - onOk * * New Feature: * - picker * - allowEmpty * - selectable * * Tips: Should add faq about `datetime` mode with `defaultValue` */ import * as React from 'react'; import classNames from 'classnames'; import warning from "rc-util/es/warning"; import useMergedState from "rc-util/es/hooks/useMergedState"; import PickerPanel from './PickerPanel'; import PickerTrigger from './PickerTrigger'; import { formatValue, isEqual, parseValue } from './utils/dateUtil'; import getDataOrAriaProps, { toArray } from './utils/miscUtil'; import PanelContext from './PanelContext'; import { getDefaultFormat, getInputSize, elementsContains } from './utils/uiUtil'; import usePickerInput from './hooks/usePickerInput'; import useTextValueMapping from './hooks/useTextValueMapping'; import useValueTexts from './hooks/useValueTexts'; import useHoverValue from './hooks/useHoverValue'; function InnerPicker(props) { var _classNames2; var _props$prefixCls = props.prefixCls, prefixCls = _props$prefixCls === void 0 ? 'rc-picker' : _props$prefixCls, id = props.id, tabIndex = props.tabIndex, style = props.style, className = props.className, dropdownClassName = props.dropdownClassName, dropdownAlign = props.dropdownAlign, popupStyle = props.popupStyle, transitionName = props.transitionName, generateConfig = props.generateConfig, locale = props.locale, inputReadOnly = props.inputReadOnly, allowClear = props.allowClear, autoFocus = props.autoFocus, showTime = props.showTime, _props$picker = props.picker, picker = _props$picker === void 0 ? 'date' : _props$picker, format = props.format, use12Hours = props.use12Hours, value = props.value, defaultValue = props.defaultValue, open = props.open, defaultOpen = props.defaultOpen, defaultOpenValue = props.defaultOpenValue, suffixIcon = props.suffixIcon, clearIcon = props.clearIcon, disabled = props.disabled, disabledDate = props.disabledDate, placeholder = props.placeholder, getPopupContainer = props.getPopupContainer, pickerRef = props.pickerRef, panelRender = props.panelRender, onChange = props.onChange, onOpenChange = props.onOpenChange, onFocus = props.onFocus, onBlur = props.onBlur, onMouseDown = props.onMouseDown, onMouseUp = props.onMouseUp, onMouseEnter = props.onMouseEnter, onMouseLeave = props.onMouseLeave, onContextMenu = props.onContextMenu, onClick = props.onClick, _onKeyDown = props.onKeyDown, _onSelect = props.onSelect, direction = props.direction, _props$autoComplete = props.autoComplete, autoComplete = _props$autoComplete === void 0 ? 'off' : _props$autoComplete; var inputRef = React.useRef(null); var needConfirmButton = picker === 'date' && !!showTime || picker === 'time'; // ============================= State ============================= var formatList = toArray(getDefaultFormat(format, picker, showTime, use12Hours)); // Panel ref var panelDivRef = React.useRef(null); var inputDivRef = React.useRef(null); var containerRef = React.useRef(null); // Real value var _useMergedState = useMergedState(null, { value: value, defaultValue: defaultValue }), _useMergedState2 = _slicedToArray(_useMergedState, 2), mergedValue = _useMergedState2[0], setInnerValue = _useMergedState2[1]; // Selected value var _React$useState = React.useState(mergedValue), _React$useState2 = _slicedToArray(_React$useState, 2), selectedValue = _React$useState2[0], setSelectedValue = _React$useState2[1]; // Operation ref var operationRef = React.useRef(null); // Open var _useMergedState3 = useMergedState(false, { value: open, defaultValue: defaultOpen, postState: function postState(postOpen) { return disabled ? false : postOpen; }, onChange: function onChange(newOpen) { if (onOpenChange) { onOpenChange(newOpen); } if (!newOpen && operationRef.current && operationRef.current.onClose) { operationRef.current.onClose(); } } }), _useMergedState4 = _slicedToArray(_useMergedState3, 2), mergedOpen = _useMergedState4[0], triggerInnerOpen = _useMergedState4[1]; // ============================= Text ============================== var _useValueTexts = useValueTexts(selectedValue, { formatList: formatList, generateConfig: generateConfig, locale: locale }), _useValueTexts2 = _slicedToArray(_useValueTexts, 2), valueTexts = _useValueTexts2[0], firstValueText = _useValueTexts2[1]; var _useTextValueMapping = useTextValueMapping({ valueTexts: valueTexts, onTextChange: function onTextChange(newText) { var inputDate = parseValue(newText, { locale: locale, formatList: formatList, generateConfig: generateConfig }); if (inputDate && (!disabledDate || !disabledDate(inputDate))) { setSelectedValue(inputDate); } } }), _useTextValueMapping2 = _slicedToArray(_useTextValueMapping, 3), text = _useTextValueMapping2[0], triggerTextChange = _useTextValueMapping2[1], resetText = _useTextValueMapping2[2]; // ============================ Trigger ============================ var triggerChange = function triggerChange(newValue) { setSelectedValue(newValue); setInnerValue(newValue); if (onChange && !isEqual(generateConfig, mergedValue, newValue)) { onChange(newValue, newValue ? formatValue(newValue, { generateConfig: generateConfig, locale: locale, format: formatList[0] }) : ''); } }; var triggerOpen = function triggerOpen(newOpen) { if (disabled && newOpen) { return; } triggerInnerOpen(newOpen); }; var forwardKeyDown = function forwardKeyDown(e) { if (mergedOpen && operationRef.current && operationRef.current.onKeyDown) { // Let popup panel handle keyboard return operationRef.current.onKeyDown(e); } /* istanbul ignore next */ /* eslint-disable no-lone-blocks */ { warning(false, 'Picker not correct forward KeyDown operation. Please help to fire issue about this.'); return false; } }; var onInternalMouseUp = function onInternalMouseUp() { if (onMouseUp) { onMouseUp.apply(void 0, arguments); } if (inputRef.current) { inputRef.current.focus(); triggerOpen(true); } }; // ============================= Input ============================= var _usePickerInput = usePickerInput({ blurToCancel: needConfirmButton, open: mergedOpen, value: text, triggerOpen: triggerOpen, forwardKeyDown: forwardKeyDown, isClickOutside: function isClickOutside(target) { return !elementsContains([panelDivRef.current, inputDivRef.current, containerRef.current], target); }, onSubmit: function onSubmit() { if ( // When user typing disabledDate with keyboard and enter, this value will be empty !selectedValue || // Normal disabled check disabledDate && disabledDate(selectedValue)) { return false; } triggerChange(selectedValue); triggerOpen(false); resetText(); return true; }, onCancel: function onCancel() { triggerOpen(false); setSelectedValue(mergedValue); resetText(); }, onKeyDown: function onKeyDown(e, preventDefault) { _onKeyDown === null || _onKeyDown === void 0 ? void 0 : _onKeyDown(e, preventDefault); }, onFocus: onFocus, onBlur: onBlur }), _usePickerInput2 = _slicedToArray(_usePickerInput, 2), inputProps = _usePickerInput2[0], _usePickerInput2$ = _usePickerInput2[1], focused = _usePickerInput2$.focused, typing = _usePickerInput2$.typing; // ============================= Sync ============================== // Close should sync back with text value React.useEffect(function () { if (!mergedOpen) { setSelectedValue(mergedValue); if (!valueTexts.length || valueTexts[0] === '') { triggerTextChange(''); } else if (firstValueText !== text) { resetText(); } } }, [mergedOpen, valueTexts]); // Change picker should sync back with text value React.useEffect(function () { if (!mergedOpen) { resetText(); } }, [picker]); // Sync innerValue with control mode React.useEffect(function () { // Sync select value setSelectedValue(mergedValue); }, [mergedValue]); // ============================ Private ============================ if (pickerRef) { pickerRef.current = { focus: function focus() { if (inputRef.current) { inputRef.current.focus(); } }, blur: function blur() { if (inputRef.current) { inputRef.current.blur(); } } }; } var _useHoverValue = useHoverValue(text, { formatList: formatList, generateConfig: generateConfig, locale: locale }), _useHoverValue2 = _slicedToArray(_useHoverValue, 3), hoverValue = _useHoverValue2[0], onEnter = _useHoverValue2[1], onLeave = _useHoverValue2[2]; // ============================= Panel ============================= var panelProps = _objectSpread(_objectSpread({}, props), {}, { className: undefined, style: undefined, pickerValue: undefined, onPickerValueChange: undefined, onChange: null }); var panelNode = /*#__PURE__*/React.createElement(PickerPanel, _extends({}, panelProps, { generateConfig: generateConfig, className: classNames(_defineProperty({}, "".concat(prefixCls, "-panel-focused"), !typing)), value: selectedValue, locale: locale, tabIndex: -1, onSelect: function onSelect(date) { _onSelect === null || _onSelect === void 0 ? void 0 : _onSelect(date); setSelectedValue(date); }, direction: direction, onPanelChange: function onPanelChange(viewDate, mode) { var onPanelChange = props.onPanelChange; onLeave(true); onPanelChange === null || onPanelChange === void 0 ? void 0 : onPanelChange(viewDate, mode); } })); if (panelRender) { panelNode = panelRender(panelNode); } var panel = /*#__PURE__*/React.createElement("div", { className: "".concat(prefixCls, "-panel-container"), onMouseDown: function onMouseDown(e) { e.preventDefault(); } }, panelNode); var suffixNode; if (suffixIcon) { suffixNode = /*#__PURE__*/React.createElement("span", { className: "".concat(prefixCls, "-suffix") }, suffixIcon); } var clearNode; if (allowClear && mergedValue && !disabled) { clearNode = /*#__PURE__*/React.createElement("span", { onMouseDown: function onMouseDown(e) { e.preventDefault(); e.stopPropagation(); }, onMouseUp: function onMouseUp(e) { e.preventDefault(); e.stopPropagation(); triggerChange(null); triggerOpen(false); }, className: "".concat(prefixCls, "-clear"), role: "button" }, clearIcon || /*#__PURE__*/React.createElement("span", { className: "".concat(prefixCls, "-clear-btn") })); } // ============================ Warning ============================ if (process.env.NODE_ENV !== 'production') { warning(!defaultOpenValue, '`defaultOpenValue` may confuse user for the current value status. Please use `defaultValue` instead.'); } // ============================ Return ============================= var onContextSelect = function onContextSelect(date, type) { if (type === 'submit' || type !== 'key' && !needConfirmButton) { // triggerChange will also update selected values triggerChange(date); triggerOpen(false); } }; var popupPlacement = direction === 'rtl' ? 'bottomRight' : 'bottomLeft'; return /*#__PURE__*/React.createElement(PanelContext.Provider, { value: { operationRef: operationRef, hideHeader: picker === 'time', panelRef: panelDivRef, onSelect: onContextSelect, open: mergedOpen, defaultOpenValue: defaultOpenValue, onDateMouseEnter: onEnter, onDateMouseLeave: onLeave } }, /*#__PURE__*/React.createElement(PickerTrigger, { visible: mergedOpen, popupElement: panel, popupStyle: popupStyle, prefixCls: prefixCls, dropdownClassName: dropdownClassName, dropdownAlign: dropdownAlign, getPopupContainer: getPopupContainer, transitionName: transitionName, popupPlacement: popupPlacement, direction: direction }, /*#__PURE__*/React.createElement("div", { ref: containerRef, className: classNames(prefixCls, className, (_classNames2 = {}, _defineProperty(_classNames2, "".concat(prefixCls, "-disabled"), disabled), _defineProperty(_classNames2, "".concat(prefixCls, "-focused"), focused), _defineProperty(_classNames2, "".concat(prefixCls, "-rtl"), direction === 'rtl'), _classNames2)), style: style, onMouseDown: onMouseDown, onMouseUp: onInternalMouseUp, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onContextMenu: onContextMenu, onClick: onClick }, /*#__PURE__*/React.createElement("div", { className: classNames("".concat(prefixCls, "-input"), _defineProperty({}, "".concat(prefixCls, "-input-placeholder"), !!hoverValue)), ref: inputDivRef }, /*#__PURE__*/React.createElement("input", _extends({ id: id, tabIndex: tabIndex, disabled: disabled, readOnly: inputReadOnly || typeof formatList[0] === 'function' || !typing, value: hoverValue || text, onChange: function onChange(e) { triggerTextChange(e.target.value); }, autoFocus: autoFocus, placeholder: placeholder, ref: inputRef, title: text }, inputProps, { size: getInputSize(picker, formatList[0], generateConfig) }, getDataOrAriaProps(props), { autoComplete: autoComplete })), suffixNode, clearNode)))); } // Wrap with class component to enable pass generic with instance method var Picker = /*#__PURE__*/function (_React$Component) { _inherits(Picker, _React$Component); var _super = _createSuper(Picker); function Picker() { var _this; _classCallCheck(this, Picker); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _super.call.apply(_super, [this].concat(args)); _this.pickerRef = /*#__PURE__*/React.createRef(); _this.focus = function () { if (_this.pickerRef.current) { _this.pickerRef.current.focus(); } }; _this.blur = function () { if (_this.pickerRef.current) { _this.pickerRef.current.blur(); } }; return _this; } _createClass(Picker, [{ key: "render", value: function render() { return /*#__PURE__*/React.createElement(InnerPicker, _extends({}, this.props, { pickerRef: this.pickerRef })); } }]); return Picker; }(React.Component); export default Picker;