@arco-design/web-react
Version:
Arco Design React UI Library.
405 lines (404 loc) • 19.8 kB
JavaScript
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, useImperativeHandle, forwardRef, } from 'react';
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, getLocaleDayjsValue } from './util';
import { pickDataAttributes } from '../_util/pick';
function getFormat(props) {
var format = props.format, picker = props.picker, showTime = props.showTime;
var valueFormat;
var mode = props.mode || picker.props.pickerType;
switch (mode) {
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 triggerPopupAlign = { bottom: 4 };
var Picker = function (baseProps, ref) {
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, status = props.status, 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, inputProps = props.inputProps;
var prefixCls = getPrefixCls('picker');
var DATEPICKER_LOCALE = locale.DatePicker;
var weekStart = isUndefined(props.dayStartOfWeek)
? getDefaultWeekStart(locale.dayjsLocale)
: props.dayStartOfWeek;
// picker.props.pickerType: Compatible with defaultProps
var mode = props.mode || picker.props.pickerType;
var refInput = useRef(null);
var refPanel = useRef(null);
var refShortcuts = useRef(null);
useImperativeHandle(ref, function () { return ({
focus: function () {
refInput.current && refInput.current.focus && refInput.current.focus();
},
blur: function () {
refInput.current && refInput.current.blur && refInput.current.blur();
},
}); }, []);
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')) ||
getNow(utcOffset, timezone);
var timeValue = panelValue || defaultTimeValue;
function focusInput() {
var _a, _b;
refInput.current && ((_b = (_a = refInput.current).focus) === null || _b === void 0 ? void 0 : _b.call(_a));
}
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 = 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 === null || callback === void 0 ? void 0 : callback();
}
function onClear(e) {
e.stopPropagation();
setValue(undefined);
setValueShow(undefined);
onHandleChange(undefined);
props.onClear && props.onClear();
}
function onClickConfirmBtn() {
var pv = getLocaleDayjsValue(panelValue, locale.dayjsLocale);
onConfirmValue();
onOk && onOk(pv && pv.format(format), pv);
}
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 = getLocaleDayjsValue(toLocal(newTime, utcOffset, timezone), locale.dayjsLocale);
onSelect && onSelect(localTime.format(format), localTime);
}
else {
var localTime = getLocaleDayjsValue(toLocal(date, utcOffset, timezone).locale(locale.dayjsLocale), locale.dayjsLocale);
onSelect && onSelect(localTime ? localTime.format(format) : undefined, localTime);
setValue(date);
onHandleChange(date);
setOpen(false);
}
}
function onHandleChange(newValue) {
if (isDayjsChange(newValue, mergedValue)) {
var localValue = getLocaleDayjsValue(toLocal(newValue, utcOffset, timezone), locale.dayjsLocale);
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 = getLocaleDayjsValue(toLocal(newValueShow, utcOffset, timezone), locale.dayjsLocale);
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)) {
// https://github.com/arco-design/arco-design/issues/1986
var newValue = getDayjsValue(niv, format);
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 () { return changePageShowDate('prev', 'month'); },
onNext: function () { return changePageShowDate('next', 'month'); },
onSuperPrev: function () { return changePageShowDate('prev', 'year'); },
onSuperNext: function () { return changePageShowDate('next', 'year'); },
};
}
if (pickMode === 'month' || pickMode === 'quarter') {
return {
onSuperPrev: function () { return changePageShowDate('prev', 'year'); },
onSuperNext: function () { return changePageShowDate('next', 'year'); },
};
}
if (pickMode === 'year') {
return {
onSuperPrev: function () { return changePageShowDate('prev', 'year', 10); },
onSuperNext: function () { return changePageShowDate('next', 'year', 10); },
};
}
}
function onSelectNow() {
var now = getLocaleDayjsValue(getNow(utcOffset, timezone), locale.dayjsLocale);
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(prefixCls + "-container", (_a = {},
_a[prefixCls + "-panel-only"] = panelOnly,
_a[prefixCls + "-container-shortcuts-placement-left"] = isArray(shortcuts) && shortcutsPlacementLeft,
_a[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 (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: prefixCls + "-panel-wrapper" }, content))) : (content);
var panelNode = typeof panelRender === 'function' ? panelRender(contentWithShortcuts) : contentWithShortcuts;
return (React.createElement("div", { className: classNames, onClick: function () {
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,
status: status,
size: size,
onPressEnter: onPressEnter,
onClear: onClear,
prefix: props.prefix,
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: triggerPopupAlign, getPopupContainer: getPopupContainer, onVisibleChange: visibleChange, popupVisible: mergedPopupVisible, classNames: "slideDynamicOrigin", unmountOnExit: unmountOnExit }, triggerProps), triggerElement || (React.createElement(DateInput, __assign({}, pickDataAttributes(props), baseInputProps, { ref: refInput, placeholder: placeholder || DATEPICKER_LOCALE.placeholder[mode], popupVisible: mergedPopupVisible, value: valueShow || mergedValue, inputValue: hoverPlaceholderValue || inputValue, prefixCls: prefixCls, onChange: onChangeInput, isPlaceholder: !!hoverPlaceholderValue, inputProps: inputProps })))))));
};
var PickerComponent = forwardRef(Picker);
export default PickerComponent;