@douyinfe/semi-ui
Version:
A modern, comprehensive, flexible design system and UI library. Connect DesignOps & DevOps. Quickly build beautiful React apps. Maintained by Douyin-fe team.
458 lines (456 loc) • 18.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _get2 = _interopRequireDefault(require("lodash/get"));
var _react = _interopRequireDefault(require("react"));
var _classnames = _interopRequireDefault(require("classnames"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _inputFoundation = _interopRequireDefault(require("@douyinfe/semi-foundation/lib/cjs/datePicker/inputFoundation"));
var _constants = require("@douyinfe/semi-foundation/lib/cjs/datePicker/constants");
var _function = require("@douyinfe/semi-foundation/lib/cjs/utils/function");
var _isNullOrUndefined = _interopRequireDefault(require("@douyinfe/semi-foundation/lib/cjs/utils/isNullOrUndefined"));
var _semiIcons = require("@douyinfe/semi-icons");
var _baseComponent = _interopRequireDefault(require("../_base/baseComponent"));
var _index = _interopRequireDefault(require("../input/index"));
var _insetInput = require("./insetInput");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
var __rest = void 0 && (void 0).__rest || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
}
return t;
};
/* eslint-disable jsx-a11y/click-events-have-key-events */
/* eslint-disable jsx-a11y/no-static-element-interactions */
// eslint-disable-next-line @typescript-eslint/ban-types
class DateInput extends _baseComponent.default {
constructor(props) {
super(props);
this.handleChange = (value, e) => this.foundation.handleChange(value, e);
this.handleEnterPress = e => this.foundation.handleInputComplete(e);
this.handleInputClear = e => this.foundation.handleInputClear(e);
this.handleRangeInputChange = (rangeStart, rangeEnd, e) => {
const rangeInputValue = this.getRangeInputValue(rangeStart, rangeEnd);
this.foundation.handleChange(rangeInputValue, e);
};
this.handleRangeInputClear = e => {
this.foundation.handleRangeInputClear(e);
};
this.handleRangeInputEnterPress = (e, rangeStart, rangeEnd) => {
const rangeInputValue = this.getRangeInputValue(rangeStart, rangeEnd);
this.foundation.handleRangeInputEnterPress(e, rangeInputValue);
};
this.handleRangeInputEndKeyPress = e => {
this.foundation.handleRangeInputEndKeyPress(e);
};
this.handleRangeInputFocus = (e, rangeType) => {
this.foundation.handleRangeInputFocus(e, rangeType);
};
this.handleRangeStartFocus = e => {
this.handleRangeInputFocus(e, 'rangeStart');
};
this.handleInsetInputChange = options => {
this.foundation.handleInsetInputChange(options);
};
this.getRangeInputValue = (rangeStart, rangeEnd) => {
const {
rangeSeparator
} = this.props;
const rangeInputValue = `${rangeStart}${rangeSeparator}${rangeEnd}`;
return rangeInputValue;
};
this.foundation = new _inputFoundation.default(this.adapter);
}
get adapter() {
var _this = this;
return Object.assign(Object.assign({}, super.adapter), {
updateIsFocusing: isFocusing => this.setState({
isFocusing
}),
notifyClick: function () {
return _this.props.onClick(...arguments);
},
notifyChange: function () {
return _this.props.onChange(...arguments);
},
notifyEnter: function () {
return _this.props.onEnterPress(...arguments);
},
notifyBlur: function () {
return _this.props.onBlur(...arguments);
},
notifyClear: function () {
return _this.props.onClear(...arguments);
},
notifyFocus: function () {
return _this.props.onFocus(...arguments);
},
notifyRangeInputClear: function () {
return _this.props.onRangeClear(...arguments);
},
notifyRangeInputFocus: function () {
return _this.props.onFocus(...arguments);
},
notifyTabPress: function () {
return _this.props.onRangeEndTabPress(...arguments);
},
notifyInsetInputChange: options => this.props.onInsetInputChange(options)
});
}
componentDidMount() {
this.foundation.init();
}
componentWillUnmount() {
this.foundation.destroy();
}
formatText(value) {
return value && value.length ? this.foundation.formatShowText(value) : '';
}
renderRangePrefix() {
const {
prefix,
insetLabel,
prefixCls,
disabled,
rangeInputFocus
} = this.props;
const labelNode = prefix || insetLabel;
return labelNode ? (/*#__PURE__*/_react.default.createElement("div", {
className: `${prefixCls}-range-input-prefix`,
onClick: e => !disabled && !rangeInputFocus && this.handleRangeStartFocus(e),
"x-semi-prop": "prefix,insetLabel"
}, labelNode)) : null;
}
renderRangeSeparator(rangeStart, rangeEnd) {
const {
disabled,
rangeSeparator
} = this.props;
const separatorCls = (0, _classnames.default)({
[`${_constants.cssClasses.PREFIX}-range-input-separator`]: true,
[`${_constants.cssClasses.PREFIX}-range-input-separator-active`]: (rangeStart || rangeEnd) && !disabled
});
return /*#__PURE__*/_react.default.createElement("span", {
onClick: e => !disabled && this.handleRangeStartFocus(e),
className: separatorCls
}, rangeSeparator);
}
renderRangeClearBtn(rangeStart, rangeEnd) {
const {
showClear,
prefixCls,
disabled,
clearIcon,
showClearIgnoreDisabled
} = this.props;
const isRealDisabled = disabled && !showClearIgnoreDisabled;
const allowClear = (rangeStart || rangeEnd) && showClear && !isRealDisabled;
return allowClear ? (/*#__PURE__*/_react.default.createElement("div", {
role: "button",
tabIndex: 0,
"aria-label": "Clear range input value",
className: `${prefixCls}-range-input-clearbtn`,
onMouseDown: e => this.handleRangeInputClear(e)
}, clearIcon ? clearIcon : /*#__PURE__*/_react.default.createElement(_semiIcons.IconClear, {
"aria-hidden": true
}))) : null;
}
renderRangeSuffix(suffix) {
const {
prefixCls,
disabled,
rangeInputFocus
} = this.props;
const rangeSuffix = suffix ? (/*#__PURE__*/_react.default.createElement("div", {
className: `${prefixCls}-range-input-suffix`,
onClick: e => !disabled && !rangeInputFocus && this.handleRangeStartFocus(e)
}, suffix)) : null;
return rangeSuffix;
}
renderRangeInput(rangeProps) {
const {
// this.props
placeholder,
inputStyle,
disabled,
inputReadOnly,
autofocus,
size,
// compute props
text,
suffix,
inputCls,
// range only props
rangeInputStartRef,
rangeInputEndRef,
rangeInputFocus,
prefixCls,
rangeSeparator,
borderless
} = rangeProps;
const [rangeStart, rangeEnd = ''] = text.split(rangeSeparator) || [];
const rangeSize = size === 'large' ? 'default' : 'small';
const rangePlaceholder = Array.isArray(placeholder) ? placeholder : [placeholder, placeholder];
const [rangeStartPlaceholder, rangeEndPlaceholder] = rangePlaceholder;
const inputLeftWrapperCls = (0, _classnames.default)(`${prefixCls}-range-input-wrapper-start`, `${prefixCls}-range-input-wrapper`, {
[`${prefixCls}-range-input-wrapper-active`]: rangeInputFocus === 'rangeStart' && !disabled,
[`${prefixCls}-range-input-wrapper-start-with-prefix`]: this.props.prefix || this.props.insetLabel,
[`${prefixCls}-borderless`]: borderless
});
const inputRightWrapperCls = (0, _classnames.default)(`${prefixCls}-range-input-wrapper-end`, `${prefixCls}-range-input-wrapper`, {
[`${prefixCls}-range-input-wrapper-active`]: rangeInputFocus === 'rangeEnd' && !disabled,
[`${prefixCls}-borderless`]: borderless
});
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, this.renderRangePrefix(), /*#__PURE__*/_react.default.createElement("div", {
onClick: e => !disabled && this.handleRangeInputFocus(e, 'rangeStart'),
className: `${inputCls} ${inputLeftWrapperCls}`
}, /*#__PURE__*/_react.default.createElement(_index.default, {
borderless: borderless,
size: rangeSize,
style: inputStyle,
disabled: disabled,
readonly: inputReadOnly,
placeholder: rangeStartPlaceholder,
value: rangeStart,
// range input onBlur function is called when panel is closed
// onBlur={noop}
onChange: (rangeStartValue, e) => this.handleRangeInputChange(rangeStartValue, rangeEnd, e),
onEnterPress: e => this.handleRangeInputEnterPress(e, rangeStart, rangeEnd),
onFocus: e => this.handleRangeInputFocus(e, 'rangeStart'),
autoFocus: autofocus,
ref: rangeInputStartRef
})), this.renderRangeSeparator(rangeStart, rangeEnd), /*#__PURE__*/_react.default.createElement("div", {
className: `${inputCls} ${inputRightWrapperCls}`,
onClick: e => !disabled && this.handleRangeInputFocus(e, 'rangeEnd')
}, /*#__PURE__*/_react.default.createElement(_index.default, {
borderless: borderless,
size: rangeSize,
style: inputStyle,
disabled: disabled,
readonly: inputReadOnly,
placeholder: rangeEndPlaceholder,
value: rangeEnd,
// range input onBlur function is called when panel is closed
// onBlur={noop}
onChange: (rangeEndValue, e) => this.handleRangeInputChange(rangeStart, rangeEndValue, e),
onEnterPress: e => this.handleRangeInputEnterPress(e, rangeStart, rangeEnd),
onFocus: e => this.handleRangeInputFocus(e, 'rangeEnd'),
onKeyDown: this.handleRangeInputEndKeyPress,
ref: rangeInputEndRef
})), this.renderRangeClearBtn(rangeStart, rangeEnd), this.renderRangeSuffix(suffix));
}
isRenderMultipleInputs() {
const {
type
} = this.props;
// isRange and not monthRange render multiple inputs
return type.includes('Range') && type !== 'monthRange';
}
renderInputInset() {
const {
type,
handleInsetDateFocus,
handleInsetTimeFocus,
value,
insetInputValue,
prefixCls,
rangeInputStartRef,
rangeInputEndRef,
density,
insetInput
} = this.props;
const newInsetInputValue = this.foundation.getInsetInputValue({
value,
insetInputValue
});
const {
dateStart,
dateEnd,
timeStart,
timeEnd
} = (0, _get2.default)(insetInput, 'placeholder', {});
const {
datePlaceholder,
timePlaceholder
} = this.foundation.getInsetInputPlaceholder();
const insetInputWrapperCls = `${prefixCls}-inset-input-wrapper`;
const separatorCls = `${prefixCls}-inset-input-separator`;
return /*#__PURE__*/_react.default.createElement("div", {
className: insetInputWrapperCls,
"x-type": type
}, /*#__PURE__*/_react.default.createElement(_insetInput.InsetDateInput, {
forwardRef: rangeInputStartRef,
insetInputValue: newInsetInputValue,
placeholder: dateStart !== null && dateStart !== void 0 ? dateStart : datePlaceholder,
valuePath: 'monthLeft.dateInput',
onChange: this.handleInsetInputChange,
onFocus: e => handleInsetDateFocus(e, 'rangeStart')
}), /*#__PURE__*/_react.default.createElement(_insetInput.InsetTimeInput, {
disabled: !newInsetInputValue.monthLeft.dateInput,
insetInputValue: newInsetInputValue,
placeholder: timeStart !== null && timeStart !== void 0 ? timeStart : timePlaceholder,
type: type,
valuePath: 'monthLeft.timeInput',
onChange: this.handleInsetInputChange,
onFocus: handleInsetTimeFocus
}), this.isRenderMultipleInputs() && (/*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
className: separatorCls
}, density === 'compact' ? null : '-'), /*#__PURE__*/_react.default.createElement(_insetInput.InsetDateInput, {
forwardRef: rangeInputEndRef,
insetInputValue: newInsetInputValue,
placeholder: dateEnd !== null && dateEnd !== void 0 ? dateEnd : datePlaceholder,
valuePath: 'monthRight.dateInput',
onChange: this.handleInsetInputChange,
onFocus: e => handleInsetDateFocus(e, 'rangeEnd')
}), /*#__PURE__*/_react.default.createElement(_insetInput.InsetTimeInput, {
disabled: !newInsetInputValue.monthRight.dateInput,
insetInputValue: newInsetInputValue,
placeholder: timeEnd !== null && timeEnd !== void 0 ? timeEnd : timePlaceholder,
type: type,
valuePath: 'monthRight.timeInput',
onChange: this.handleInsetInputChange,
onFocus: handleInsetTimeFocus
}))));
}
renderTriggerInput() {
const _a = this.props,
{
placeholder,
type,
value,
inputValue,
inputStyle,
disabled,
showClear,
inputReadOnly,
insetLabel,
validateStatus,
block,
prefixCls,
multiple,
// Whether to allow multiple values for email and file types
dateFnsLocale,
// No need to pass to input
onBlur,
onClear,
onFocus,
prefix,
autofocus,
size,
inputRef,
// range input support props, no need passing to not range type
rangeInputStartRef,
rangeInputEndRef,
onRangeClear,
onRangeBlur,
onRangeEndTabPress,
rangeInputFocus,
rangeSeparator,
insetInput,
insetInputValue,
defaultPickerValue,
showClearIgnoreDisabled
} = _a,
rest = __rest(_a, ["placeholder", "type", "value", "inputValue", "inputStyle", "disabled", "showClear", "inputReadOnly", "insetLabel", "validateStatus", "block", "prefixCls", "multiple", "dateFnsLocale", "onBlur", "onClear", "onFocus", "prefix", "autofocus", "size", "inputRef", "rangeInputStartRef", "rangeInputEndRef", "onRangeClear", "onRangeBlur", "onRangeEndTabPress", "rangeInputFocus", "rangeSeparator", "insetInput", "insetInputValue", "defaultPickerValue", "showClearIgnoreDisabled"]);
const dateIcon = /*#__PURE__*/_react.default.createElement(_semiIcons.IconCalendar, {
"aria-hidden": true
});
const dateTimeIcon = /*#__PURE__*/_react.default.createElement(_semiIcons.IconCalendarClock, {
"aria-hidden": true
});
const suffix = type.includes('Time') ? dateTimeIcon : dateIcon;
let text = '';
if (!(0, _isNullOrUndefined.default)(inputValue)) {
text = inputValue;
} else if (value) {
text = this.formatText(value);
}
const inputCls = (0, _classnames.default)({
[`${prefixCls}-input-readonly`]: inputReadOnly,
[`${prefixCls}-monthRange-input`]: type === 'monthRange'
});
const rangeProps = Object.assign(Object.assign({}, this.props), {
text,
suffix,
inputCls
});
return this.isRenderMultipleInputs() ? this.renderRangeInput(rangeProps) : (/*#__PURE__*/_react.default.createElement(_index.default, Object.assign({}, rest, {
ref: inputRef,
insetLabel: insetLabel,
disabled: disabled,
showClearIgnoreDisabled: showClearIgnoreDisabled,
readonly: inputReadOnly,
className: inputCls,
style: inputStyle,
hideSuffix: showClear,
placeholder: type === 'monthRange' && Array.isArray(placeholder) ? placeholder[0] + rangeSeparator + placeholder[1] : placeholder,
onEnterPress: this.handleEnterPress,
onChange: this.handleChange,
onClear: this.handleInputClear,
suffix: suffix,
showClear: showClear,
value: text,
validateStatus: validateStatus,
prefix: prefix,
autoFocus: autofocus,
size: size,
onBlur: onBlur,
onFocus: onFocus
})));
}
render() {
const {
insetInput
} = this.props;
return insetInput ? this.renderInputInset() : this.renderTriggerInput();
}
}
exports.default = DateInput;
DateInput.propTypes = {
borderless: _propTypes.default.bool,
onClick: _propTypes.default.func,
onChange: _propTypes.default.func,
onEnterPress: _propTypes.default.func,
onBlur: _propTypes.default.func,
onClear: _propTypes.default.func,
onFocus: _propTypes.default.func,
value: _propTypes.default.array,
disabled: _propTypes.default.bool,
type: _propTypes.default.oneOf(_constants.strings.TYPE_SET),
showClear: _propTypes.default.bool,
format: _propTypes.default.string,
inputStyle: _propTypes.default.object,
inputReadOnly: _propTypes.default.bool,
insetLabel: _propTypes.default.node,
validateStatus: _propTypes.default.string,
prefix: _propTypes.default.node,
prefixCls: _propTypes.default.string,
dateFnsLocale: _propTypes.default.object.isRequired,
placeholder: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.array]),
rangeInputFocus: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.bool]),
rangeInputStartRef: _propTypes.default.object,
rangeInputEndRef: _propTypes.default.object,
rangeSeparator: _propTypes.default.string,
insetInput: _propTypes.default.oneOfType([_propTypes.default.bool, _propTypes.default.object]),
insetInputValue: _propTypes.default.object,
defaultPickerValue: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number, _propTypes.default.object, _propTypes.default.array])
};
DateInput.defaultProps = {
borderless: false,
showClear: true,
onClick: _function.noop,
onChange: _function.noop,
onEnterPress: _function.noop,
onBlur: _function.noop,
onClear: _function.noop,
onFocus: _function.noop,
type: 'date',
inputStyle: {},
inputReadOnly: false,
prefixCls: _constants.cssClasses.PREFIX,
rangeSeparator: _constants.strings.DEFAULT_SEPARATOR_RANGE
};