UNPKG

preact-arco-design

Version:

Arco Design React UI Library.

597 lines (508 loc) 18.1 kB
var __assign = this && this.__assign || function () { __assign = Object.assign || function (t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) { if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } } return t; }; return __assign.apply(this, arguments); }; var __read = this && this.__read || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) { ar.push(r.value); } } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; import React, { useState, useRef, useEffect, useContext } from "preact/compat"; import Trigger from "../Trigger"; import DateInput from "../_class/picker/input"; import { isArray, isDayjs, isObject, isUndefined } from "../_util/is"; import cs from "../_util/classNames"; import { ConfigContext } from "../ConfigProvider"; import omit from "../_util/omit"; import { getDayjsValue, dayjs, getNow, getValueWithTime, methods, isDayjsChange, toLocal, toTimezone } from "../_util/dayjs"; import IconCalendar from "../../icon/react-icon/IconCalendar"; import IconCalendarClock from "../../icon/react-icon/IconCalendarClock"; import Footer from "./panels/footer"; import Shortcuts from "./panels/shortcuts"; import useMergeProps from "../_util/hooks/useMergeProps"; import PickerContext from "./context"; import usePrevious from "../_util/hooks/usePrevious"; import useUpdate from "../_util/hooks/useUpdate"; import { getDefaultWeekStart } from "./util"; function getFormat(props) { var format = props.format, picker = props.picker, showTime = props.showTime; var valueFormat; switch (picker.props.pickerType) { case 'date': valueFormat = showTime ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD'; break; case 'month': valueFormat = 'YYYY-MM'; break; case 'year': valueFormat = 'YYYY'; break; case 'week': valueFormat = 'gggg-wo'; break; case 'quarter': valueFormat = 'YYYY-[Q]Q'; break; default: valueFormat = 'YYYY-MM-DD'; } if (format) { valueFormat = format; } return valueFormat; } var defaultProps = { allowClear: true, unmountOnExit: true, position: 'bl', editable: true, showNowBtn: true }; var Picker = function Picker(baseProps) { var _a = useContext(ConfigContext), getPrefixCls = _a.getPrefixCls, locale = _a.locale, ctxSize = _a.size, componentConfig = _a.componentConfig, rtl = _a.rtl; if (rtl) { defaultProps.position = 'br'; } var props = useMergeProps(baseProps, defaultProps, componentConfig === null || componentConfig === void 0 ? void 0 : componentConfig.DatePicker); var allowClear = props.allowClear, className = props.className, style = props.style, placeholder = props.placeholder, getPopupContainer = props.getPopupContainer, disabled = props.disabled, position = props.position, error = props.error, unmountOnExit = props.unmountOnExit, editable = props.editable, triggerProps = props.triggerProps, picker = props.picker, shortcuts = props.shortcuts, onSelect = props.onSelect, onVisibleChange = props.onVisibleChange, propsValue = props.value, onChange = props.onChange, icons = props.icons, disabledDate = props.disabledDate, showTime = props.showTime, showNowBtn = props.showNowBtn, onSelectShortcut = props.onSelectShortcut, extra = props.extra, shortcutsPlacementLeft = props.shortcutsPlacementLeft, onOk = props.onOk, defaultPickerValue = props.defaultPickerValue, pickerValue = props.pickerValue, onPickerValueChange = props.onPickerValueChange, triggerElement = props.triggerElement, utcOffset = props.utcOffset, timezone = props.timezone, panelRender = props.panelRender; var prefixCls = getPrefixCls('picker'); var DATEPICKER_LOCALE = locale.DatePicker; var weekStart = isUndefined(props.dayStartOfWeek) ? getDefaultWeekStart(locale.dayjsLocale) : props.dayStartOfWeek; var mode = picker.props.pickerType; var refInput = useRef(null); var refPanel = useRef(null); var refShortcuts = useRef(null); var realFormat = getFormat(props); var format = realFormat; if (typeof format === 'function') { format = showTime ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD'; } function getDefaultValue() { var value; if (props.value) { value = getDayjsValue(props.value, format, utcOffset, timezone); } else { value = getDayjsValue(props.defaultValue, format, utcOffset, timezone); } return value; } var _b = __read(useState(getDefaultValue()), 2), value = _b[0], setValue = _b[1]; var _c = __read(useState(props.popupVisible), 2), popupVisible = _c[0], setPopupVisible = _c[1]; var _d = __read(useState(false), 2), isTimePanel = _d[0], setIsTimePanel = _d[1]; var _e = __read(useState(), 2), hoverPlaceholderValue = _e[0], setHoverPlaceholderValue = _e[1]; var mergedPopupVisible = 'popupVisible' in props ? props.popupVisible : popupVisible; var mergedValue = 'value' in props ? getDayjsValue(propsValue, format, utcOffset, timezone) : value; var defaultPageShowDate = mergedValue || getDayjsValue(defaultPickerValue, format) || getNow(); var _f = __read(useState(), 2), inputValue = _f[0], setInputValue = _f[1]; var _g = __read(useState(), 2), valueShow = _g[0], setValueShow = _g[1]; var _h = __read(useState(), 2), shortcutValue = _h[0], setShortcutValue = _h[1]; var _j = __read(useState(defaultPageShowDate), 2), pageShowDate = _j[0], _setPageShowDate = _j[1]; var mergedPageShowDate = getDayjsValue(pickerValue, format) || pageShowDate; var panelValue = shortcutValue || valueShow || mergedValue; var _k = __read(useState(mode), 2), panelMode = _k[0], setPanelMode = _k[1]; var defaultTimeValue = isObject(showTime) && getDayjsValue(showTime.defaultValue, showTime.format || 'HH:mm:ss', utcOffset, timezone) || getNow(utcOffset, timezone); var timeValue = panelValue || defaultTimeValue; function focusInput() { refInput.current && refInput.current.blur && refInput.current.focus(); } function blurInput() { refInput.current && refInput.current.blur && refInput.current.blur(); } var previousUtcOffset = usePrevious(utcOffset); var previousTimezone = usePrevious(timezone); // when timezone or utcOffset change changed useUpdate(function () { if (value && (previousUtcOffset !== utcOffset || timezone !== previousTimezone)) { var localValue = toLocal(value, previousUtcOffset, previousTimezone); setValue(toTimezone(localValue, utcOffset, timezone)); } }, [utcOffset, previousUtcOffset, timezone, previousTimezone]); useEffect(function () { setInputValue(undefined); setHoverPlaceholderValue(undefined); if (mergedPopupVisible) { _setPageShowDate(defaultPageShowDate); if (shortcutsPlacementLeft) { refShortcuts.current.style.maxHeight = "".concat(refPanel.current.clientHeight, "px"); } } else { setValueShow(undefined); setShortcutValue(undefined); setTimeout(function () { setIsTimePanel(false); setPanelMode(mode); blurInput(); }, 100); } }, [mergedPopupVisible]); function visibleChange(visible) { if (visible) { setOpen(visible, function () { focusInput(); }); } else { setOpen(false); } } function handlePickerValueChange(v) { onPickerValueChange && onPickerValueChange(v.format(format), v); } function setOpen(visible, callback) { setPopupVisible(visible); onVisibleChange && onVisibleChange(visible); callback && callback(); } function onClear(e) { e.stopPropagation(); setValue(undefined); setValueShow(undefined); onHandleChange(undefined); props.onClear && props.onClear(); } function onClickConfirmBtn() { onConfirmValue(); onOk && onOk(panelValue && panelValue.format(format), panelValue); } function onConfirmValue() { setValue(panelValue); onHandleChange(panelValue); setOpen(false); } function onHandleSelect(_, date, now) { setInputValue(undefined); setHoverPlaceholderValue(undefined); if (showTime) { var newTime = now ? date : getValueWithTime(date, timeValue); setValueShow(newTime); _setPageShowDate(newTime); var localTime = toLocal(newTime, utcOffset, timezone); onSelect && onSelect(localTime.format(format), localTime); } else { var localTime = toLocal(date, utcOffset, timezone); onSelect && onSelect(localTime ? localTime.format(format) : undefined, localTime); setValue(date); onHandleChange(date); setOpen(false); } } function onHandleChange(newValue) { if (isDayjsChange(newValue, mergedValue)) { var localValue = toLocal(newValue, utcOffset, timezone); onChange && onChange(localValue ? localValue.format(format) : undefined, localValue); } } function onTimePickerSelect(_, time) { var _valueShow = panelValue || getNow(utcOffset, timezone); var newValueShow = getValueWithTime(_valueShow, time); setValueShow(newValueShow); var localNewValueShow = toLocal(newValueShow, utcOffset, timezone); onSelect && onSelect(localNewValueShow.format(format), localNewValueShow); } function isValid(time) { return typeof time === 'string' && dayjs(time, format).format(format) === time && (typeof disabledDate === 'function' ? !disabledDate(dayjs(time, format)) : true); } function onChangeInput(e) { var niv = e.target.value; setInputValue(niv); if (!mergedPopupVisible) { setOpen(true); } if (isValid(niv)) { var newValue = getDayjsValue(niv, format, utcOffset, timezone); setValueShow(newValue); _setPageShowDate(newValue); setInputValue(undefined); } } function onPressEnter() { if (panelValue) { onConfirmValue(); blurInput(); } else if (mergedPopupVisible) { setOpen(false); } } function changePageShowDate(type, unit, num) { if (num === void 0) { num = 1; } var newPageShowDate; if (type === 'prev') { newPageShowDate = methods.subtract(mergedPageShowDate, num, unit); } if (type === 'next') { newPageShowDate = methods.add(mergedPageShowDate, num, unit); } handlePickerValueChange(newPageShowDate); _setPageShowDate(newPageShowDate); } function getHeaderOperations(pickMode) { if (pickMode === void 0) { pickMode = mode; } if (pickMode === 'date' || pickMode === 'week') { return { onPrev: function onPrev() { return changePageShowDate('prev', 'month'); }, onNext: function onNext() { return changePageShowDate('next', 'month'); }, onSuperPrev: function onSuperPrev() { return changePageShowDate('prev', 'year'); }, onSuperNext: function onSuperNext() { return changePageShowDate('next', 'year'); } }; } if (pickMode === 'month' || pickMode === 'quarter') { return { onSuperPrev: function onSuperPrev() { return changePageShowDate('prev', 'year'); }, onSuperNext: function onSuperNext() { return changePageShowDate('next', 'year'); } }; } if (pickMode === 'year') { return { onSuperPrev: function onSuperPrev() { return changePageShowDate('prev', 'year', 10); }, onSuperNext: function onSuperNext() { return changePageShowDate('next', 'year', 10); } }; } } function onSelectNow() { var now = getNow(utcOffset, timezone); handlePickerValueChange(now); onHandleSelect(now.format(format), now, true); } function onMouseEnterCell(value, disabled) { if (!disabled) { var placeHolderValue = showTime ? getValueWithTime(value, timeValue) : value; setHoverPlaceholderValue(typeof realFormat === 'function' ? realFormat(value) : placeHolderValue.locale(locale.dayjsLocale).format(format)); } } function onMouseLeaveCell() { setHoverPlaceholderValue(undefined); } function onMouseEnterShortcut(shortcut) { if (typeof shortcut.value === 'function' && isDayjs(shortcut.value())) { var sv = getDayjsValue(shortcut.value(), format, utcOffset, timezone); _setPageShowDate(sv); handlePickerValueChange(sv); setShortcutValue(sv); } } function onMouseLeaveShortcut() { var newValue = valueShow || mergedValue || getNow(utcOffset, timezone); setShortcutValue(undefined); _setPageShowDate(newValue); handlePickerValueChange(newValue); } function onHandleSelectShortcut(shortcut) { onSelectShortcut && onSelectShortcut(shortcut); if (typeof shortcut.value === 'function' && isDayjs(shortcut.value())) { var time = getDayjsValue(shortcut.value(), format, utcOffset, timezone); setValue(time); onHandleChange(time); setOpen(false); } } function onClickSelectTimeBtn() { setIsTimePanel(!isTimePanel); } function renderPopup(panelOnly) { var _a; var classNames = cs("".concat(prefixCls, "-container"), (_a = {}, _a["".concat(prefixCls, "-panel-only")] = panelOnly, _a["".concat(prefixCls, "-container-shortcuts-placement-left")] = isArray(shortcuts) && shortcutsPlacementLeft, _a["".concat(prefixCls, "-container-rtl")] = rtl, _a), panelOnly ? className : ''); var shortcutsProps = { prefixCls: prefixCls, showTime: showTime, shortcuts: shortcuts, onSelectNow: onSelectNow, showNowBtn: showNowBtn, onMouseEnterShortcut: onMouseEnterShortcut, onMouseLeaveShortcut: onMouseLeaveShortcut, onSelectShortcut: onHandleSelectShortcut }; var shouldShowFooter = showTime && panelMode === 'date' || extra || isArray(shortcuts) && shortcuts.length && !shortcutsPlacementLeft || !showTime && panelMode === 'date' && showNowBtn; var content = React.createElement(React.Fragment, null, React.cloneElement(picker, __assign(__assign(__assign({}, omit(props, ['style'])), getHeaderOperations()), { getHeaderOperations: getHeaderOperations, onSelect: onHandleSelect, onTimePickerSelect: onTimePickerSelect, onSelectNow: onSelectNow, popupVisible: mergedPopupVisible, format: format, value: panelValue, pageShowDate: mergedPageShowDate, localeName: locale.dayjsLocale, setPageShowDate: function setPageShowDate(v) { _setPageShowDate(v); handlePickerValueChange(v); }, timeValue: timeValue, isTimePanel: isTimePanel, panelMode: panelMode, setPanelMode: setPanelMode, onMouseEnterCell: onMouseEnterCell, onMouseLeaveCell: onMouseLeaveCell })), shouldShowFooter && React.createElement(Footer, __assign({}, shortcutsProps, { DATEPICKER_LOCALE: DATEPICKER_LOCALE, disabled: !panelValue, onClickConfirmBtn: onClickConfirmBtn, extra: extra, mode: panelMode, shortcutsPlacementLeft: shortcutsPlacementLeft, onClickSelectTimeBtn: onClickSelectTimeBtn, isTimePanel: isTimePanel }))); var contentWithShortcuts = shortcutsPlacementLeft ? React.createElement(React.Fragment, null, React.createElement(Shortcuts, __assign({ ref: refShortcuts }, shortcutsProps)), React.createElement("div", { ref: refPanel, className: "".concat(prefixCls, "-panel-wrapper") }, content)) : content; var panelNode = typeof panelRender === 'function' ? panelRender(contentWithShortcuts) : contentWithShortcuts; return React.createElement("div", { className: classNames, onClick: function onClick() { refInput.current && refInput.current.focus && refInput.current.focus(); }, style: panelOnly ? style : {} }, panelNode); } var size = props.size || ctxSize; var suffixIcon = icons && icons.inputSuffix === null ? null : icons && icons.inputSuffix || (showTime ? React.createElement(IconCalendarClock, null) : React.createElement(IconCalendar, null)); var baseInputProps = { style: style, className: className, popupVisible: mergedPopupVisible, format: realFormat, disabled: disabled, error: error, size: size, onPressEnter: onPressEnter, onClear: onClear, suffixIcon: suffixIcon, editable: editable && typeof realFormat !== 'function', allowClear: allowClear }; return React.createElement(PickerContext.Provider, { value: { utcOffset: utcOffset, timezone: timezone, weekStart: weekStart } }, triggerElement === null ? renderPopup(true) : React.createElement(Trigger, __assign({ popup: renderPopup, trigger: "click", clickToClose: false, position: position, disabled: disabled, popupAlign: { bottom: 4 }, getPopupContainer: getPopupContainer, onVisibleChange: visibleChange, popupVisible: mergedPopupVisible, classNames: "slideDynamicOrigin", unmountOnExit: unmountOnExit }, triggerProps), triggerElement || React.createElement(DateInput, __assign({}, baseInputProps, { ref: refInput, placeholder: placeholder || DATEPICKER_LOCALE.placeholder[mode], popupVisible: mergedPopupVisible, value: valueShow || mergedValue, inputValue: hoverPlaceholderValue || inputValue, prefixCls: prefixCls, onChange: onChangeInput, isPlaceholder: !!hoverPlaceholderValue })))); }; export default Picker;