@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.
446 lines (445 loc) • 16.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _get2 = _interopRequireDefault(require("lodash/get"));
var _noop2 = _interopRequireDefault(require("lodash/noop"));
var _react = _interopRequireDefault(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _classnames = _interopRequireDefault(require("classnames"));
var _context = _interopRequireDefault(require("../configProvider/context"));
var _baseComponent = _interopRequireDefault(require("../_base/baseComponent"));
var _constants = require("@douyinfe/semi-foundation/lib/cjs/timePicker/constants");
var _popover = _interopRequireDefault(require("../popover"));
var _constants2 = require("@douyinfe/semi-foundation/lib/cjs/popover/constants");
var _foundation = _interopRequireDefault(require("@douyinfe/semi-foundation/lib/cjs/timePicker/foundation"));
var _isNullOrUndefined = _interopRequireDefault(require("@douyinfe/semi-foundation/lib/cjs/utils/isNullOrUndefined"));
var _Combobox = _interopRequireDefault(require("./Combobox"));
var _TimeInput = _interopRequireDefault(require("./TimeInput"));
var _PanelShape = require("./PanelShape");
var _TimeShape = require("./TimeShape");
require("@douyinfe/semi-foundation/lib/cjs/timePicker/timePicker.css");
var _trigger = _interopRequireDefault(require("../trigger"));
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;
};
class TimePicker extends _baseComponent.default {
constructor(props) {
var _this;
super(props);
_this = this;
this.onCurrentSelectPanelChange = currentSelectPanel => {
this.setState({
currentSelectPanel
});
};
this.handlePanelChange = (value, index) => this.foundation.handlePanelChange(value, index);
this.handleInput = value => this.foundation.handleInputChange(value);
this.createPanelProps = function () {
let index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
const {
panels,
panelFooter,
panelHeader,
locale
} = _this.props;
const panelProps = {
panelHeader,
panelFooter
};
if (_this.adapter.isRangePicker()) {
const defaultHeaderMap = {
0: locale.begin,
1: locale.end
};
panelProps.panelHeader = (0, _get2.default)(panels, index, (0, _isNullOrUndefined.default)(panelHeader) ? (0, _get2.default)(defaultHeaderMap, index, null) : Array.isArray(panelHeader) ? panelHeader[index] : panelHeader);
panelProps.panelFooter = (0, _get2.default)(panels, index, Array.isArray(panelFooter) ? panelFooter[index] : panelFooter);
}
return panelProps;
};
/* istanbul ignore next */
this.handlePanelVisibleChange = visible => this.foundation.handleVisibleChange(visible);
this.openPanel = () => {
this.foundation.handlePanelOpen();
};
this.handleFocus = e => {
this.foundation.handleFocus(e);
};
this.handleBlur = e => this.foundation.handleInputBlur(e);
this.setTimePickerRef = node => this.timePickerRef.current = node;
const {
format = _constants.strings.DEFAULT_FORMAT
} = props;
this.state = {
open: props.open || props.defaultOpen || false,
value: [],
inputValue: '',
currentSelectPanel: 0,
isAM: [true, false],
showHour: Boolean(format.match(/HH|hh|H|h/g)),
showMinute: Boolean(format.match(/mm/g)),
showSecond: Boolean(format.match(/ss/g)),
invalid: undefined
};
this.foundation = new _foundation.default(this.adapter);
this.timePickerRef = /*#__PURE__*/_react.default.createRef();
this.savePanelRef = /*#__PURE__*/_react.default.createRef();
this.useCustomTrigger = typeof this.props.triggerRender === 'function';
}
get adapter() {
var _this2 = this;
return Object.assign(Object.assign({}, super.adapter), {
togglePanel: show => {
this.setState({
open: show
});
},
registerClickOutSide: () => {
if (this.clickOutSideHandler) {
this.adapter.unregisterClickOutSide();
}
this.clickOutSideHandler = e => {
const panel = this.savePanelRef && this.savePanelRef.current;
const trigger = this.timePickerRef && this.timePickerRef.current;
const target = e.target;
const path = e.composedPath && e.composedPath() || [target];
if (!(panel && panel.contains(target)) && !(trigger && trigger.contains(target)) && !(path.includes(trigger) || path.includes(panel))) {
this.foundation.handlePanelClose(true, e);
}
};
document.addEventListener('mousedown', this.clickOutSideHandler);
},
setInputValue: (inputValue, cb) => this.setState({
inputValue
}, cb),
unregisterClickOutSide: () => {
if (this.clickOutSideHandler) {
document.removeEventListener('mousedown', this.clickOutSideHandler);
this.clickOutSideHandler = null;
}
},
notifyOpenChange: function () {
return _this2.props.onOpenChange(...arguments);
},
notifyChange: (agr1, arg2) => this.props.onChange && this.props.onChange(agr1, arg2),
notifyFocus: function () {
return _this2.props.onFocus && _this2.props.onFocus(...arguments);
},
notifyBlur: function () {
return _this2.props.onBlur && _this2.props.onBlur(...arguments);
},
isRangePicker: () => this.props.type === _constants.strings.TYPE_TIME_RANGE_PICKER
});
}
static getDerivedStateFromProps(nextProps, prevState) {
if ('open' in nextProps && nextProps.open !== prevState.open) {
return {
open: nextProps.open
};
}
return null;
}
componentDidUpdate(prevProps) {
// if (this.isControlled('open') && this.props.open != null && this.props.open !== prevProps.open) {
// this.foundation.setPanel(this.props.open);
// }
if (this.isControlled('value') && this.props.value !== prevProps.value) {
this.foundation.refreshProps(Object.assign({}, this.props));
} else if (this.props.timeZone !== prevProps.timeZone) {
this.foundation.refreshProps({
timeZone: this.props.timeZone,
__prevTimeZone: prevProps.timeZone,
value: this.state.value
});
}
}
getPanelElement() {
const {
prefixCls,
type
} = this.props;
const {
isAM,
value
} = this.state;
const format = this.foundation.getDefaultFormatIfNeed();
const timePanels = [/*#__PURE__*/_react.default.createElement(_Combobox.default, Object.assign({}, this.props, {
key: 0,
format: format,
isAM: isAM[0],
timeStampValue: value[0],
prefixCls: `${prefixCls}-panel`,
onChange: v => this.handlePanelChange(v, 0),
onCurrentSelectPanelChange: this.onCurrentSelectPanelChange
}, this.createPanelProps(0)))];
if (type === _constants.strings.TYPE_TIME_RANGE_PICKER) {
timePanels.push(/*#__PURE__*/_react.default.createElement(_Combobox.default, Object.assign({}, this.props, {
key: 1,
format: format,
isAM: isAM[1],
timeStampValue: value[1],
prefixCls: `${prefixCls}-panel`,
onChange: v => this.handlePanelChange(v, 1),
onCurrentSelectPanelChange: this.onCurrentSelectPanelChange
}, this.createPanelProps(1))));
}
const wrapCls = (0, _classnames.default)({
[_constants.cssClasses.RANGE_PANEL_LISTS]: this.adapter.isRangePicker()
});
return /*#__PURE__*/_react.default.createElement("div", {
ref: this.savePanelRef,
className: wrapCls
}, timePanels.map(panel => panel));
}
getPopupClassName() {
const {
use12Hours,
prefixCls,
popupClassName
} = this.props;
const {
showHour,
showMinute,
showSecond
} = this.state;
let selectColumnCount = 0;
if (showHour) {
selectColumnCount += 1;
}
if (showMinute) {
selectColumnCount += 1;
}
if (showSecond) {
selectColumnCount += 1;
}
if (use12Hours) {
selectColumnCount += 1;
}
return (0, _classnames.default)(`${prefixCls}-panel`, popupClassName, {
[`${prefixCls}-panel-narrow`]: (!showHour || !showMinute || !showSecond) && !use12Hours,
[_constants.cssClasses.RANGE_PICKER]: this.adapter.isRangePicker()
}, `${prefixCls}-panel-column-${selectColumnCount}`);
}
focus() {
// TODO this.picker is undefined, confirm keep this func or not
// this.picker.focus();
}
blur() {
// TODO this.picker is undefined, confirm keep this func or not
// this.picker.blur();
}
render() {
const _a = this.props,
{
prefixCls,
placeholder,
disabled,
defaultValue,
dropdownMargin,
className,
popupStyle,
size,
style,
locale,
localeCode,
zIndex,
getPopupContainer,
insetLabel,
insetLabelId,
inputStyle,
showClear,
panelHeader,
panelFooter,
rangeSeparator,
onOpenChange,
onChangeWithDateFirst,
popupClassName: propPopupClassName,
hideDisabledOptions,
use12Hours,
minuteStep,
hourStep,
secondStep,
scrollItemProps,
triggerRender,
motion,
autoAdjustOverflow,
stopPropagation
} = _a,
rest = __rest(_a, ["prefixCls", "placeholder", "disabled", "defaultValue", "dropdownMargin", "className", "popupStyle", "size", "style", "locale", "localeCode", "zIndex", "getPopupContainer", "insetLabel", "insetLabelId", "inputStyle", "showClear", "panelHeader", "panelFooter", "rangeSeparator", "onOpenChange", "onChangeWithDateFirst", "popupClassName", "hideDisabledOptions", "use12Hours", "minuteStep", "hourStep", "secondStep", "scrollItemProps", "triggerRender", "motion", "autoAdjustOverflow", "stopPropagation"]);
const format = this.foundation.getDefaultFormatIfNeed();
const position = this.foundation.getPosition();
const {
open,
inputValue,
invalid,
value
} = this.state;
const popupClassName = this.getPopupClassName();
const headerPrefix = (0, _classnames.default)({
[`${prefixCls}-header`]: true
});
const panelPrefix = (0, _classnames.default)({
[`${prefixCls}-panel`]: true,
[`${prefixCls}-panel-${size}`]: size
});
const inputProps = Object.assign(Object.assign({}, rest), {
disabled,
prefixCls,
size,
showClear: disabled ? false : showClear,
style: inputStyle,
value: inputValue,
onFocus: this.handleFocus,
insetLabel,
insetLabelId,
format,
locale,
localeCode,
invalid,
placeholder,
onChange: this.handleInput,
onBlur: this.handleBlur
});
const outerProps = {};
if (this.useCustomTrigger) {
outerProps.onClick = this.openPanel;
}
return /*#__PURE__*/_react.default.createElement("div", Object.assign({
ref: this.setTimePickerRef,
className: (0, _classnames.default)({
[prefixCls]: true
}, className),
style: style
}, outerProps), /*#__PURE__*/_react.default.createElement(_popover.default, {
getPopupContainer: getPopupContainer,
zIndex: zIndex,
prefixCls: panelPrefix,
contentClassName: popupClassName,
style: popupStyle,
content: this.getPanelElement(),
trigger: 'custom',
position: position,
visible: disabled ? false : Boolean(open),
motion: motion,
margin: dropdownMargin,
autoAdjustOverflow: autoAdjustOverflow,
stopPropagation: stopPropagation
}, this.useCustomTrigger ? (/*#__PURE__*/_react.default.createElement(_trigger.default, {
triggerRender: triggerRender,
disabled: disabled,
value: value,
inputValue: inputValue,
onChange: this.handleInput,
placeholder: placeholder,
componentName: 'TimePicker',
componentProps: Object.assign({}, this.props)
})) : (/*#__PURE__*/_react.default.createElement("span", {
className: headerPrefix
}, /*#__PURE__*/_react.default.createElement(_TimeInput.default, Object.assign({}, inputProps))))));
}
}
exports.default = TimePicker;
TimePicker.contextType = _context.default;
TimePicker.propTypes = Object.assign(Object.assign({
'aria-labelledby': _propTypes.default.string,
'aria-invalid': _propTypes.default.bool,
'aria-errormessage': _propTypes.default.string,
'aria-describedby': _propTypes.default.string,
'aria-required': _propTypes.default.bool,
prefixCls: _propTypes.default.string,
borderless: _propTypes.default.bool,
clearText: _propTypes.default.string,
clearIcon: _propTypes.default.node,
value: _TimeShape.TimeShape,
inputReadOnly: _propTypes.default.bool,
disabled: _propTypes.default.bool,
showClear: _propTypes.default.bool,
defaultValue: _TimeShape.TimeShape,
open: _propTypes.default.bool,
defaultOpen: _propTypes.default.bool,
onOpenChange: _propTypes.default.func,
position: _propTypes.default.any,
getPopupContainer: _propTypes.default.func,
placeholder: _propTypes.default.string,
format: _propTypes.default.string,
style: _propTypes.default.object,
className: _propTypes.default.string,
popupClassName: _propTypes.default.string,
popupStyle: _propTypes.default.object,
disabledHours: _propTypes.default.func,
disabledMinutes: _propTypes.default.func,
disabledSeconds: _propTypes.default.func,
dropdownMargin: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.object]),
hideDisabledOptions: _propTypes.default.bool,
onChange: _propTypes.default.func,
use12Hours: _propTypes.default.bool,
hourStep: _propTypes.default.number,
minuteStep: _propTypes.default.number,
secondStep: _propTypes.default.number,
focusOnOpen: _propTypes.default.bool,
autoFocus: _propTypes.default.bool,
size: _propTypes.default.oneOf(_constants.strings.SIZE),
stopPropagation: _propTypes.default.bool,
panels: _propTypes.default.arrayOf(_propTypes.default.shape(_PanelShape.PanelShape)),
onFocus: _propTypes.default.func,
onBlur: _propTypes.default.func,
locale: _propTypes.default.object,
localeCode: _propTypes.default.string,
dateFnsLocale: _propTypes.default.object,
zIndex: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]),
insetLabel: _propTypes.default.node,
insetLabelId: _propTypes.default.string,
validateStatus: _propTypes.default.oneOf(_constants.strings.STATUS),
type: _propTypes.default.oneOf(_constants.strings.TYPES),
rangeSeparator: _propTypes.default.string,
triggerRender: _propTypes.default.func,
timeZone: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]),
scrollItemProps: _propTypes.default.object,
motion: _propTypes.default.oneOfType([_propTypes.default.bool, _propTypes.default.func, _propTypes.default.object]),
autoAdjustOverflow: _propTypes.default.bool
}, _PanelShape.PanelShape), {
inputStyle: _propTypes.default.object,
preventScroll: _propTypes.default.bool
});
TimePicker.defaultProps = Object.assign({
autoAdjustOverflow: true,
borderless: false,
getPopupContainer: () => document.body,
showClear: true,
zIndex: _constants2.numbers.DEFAULT_Z_INDEX,
rangeSeparator: _constants.strings.DEFAULT_RANGE_SEPARATOR,
onOpenChange: _noop2.default,
clearText: 'clear',
prefixCls: _constants.cssClasses.PREFIX,
inputReadOnly: false,
style: {},
stopPropagation: true,
className: '',
popupClassName: '',
popupStyle: {
left: '0px',
top: '0px'
},
disabledHours: () => [],
disabledMinutes: () => [],
disabledSeconds: () => [],
hideDisabledOptions: false,
// position: 'bottomLeft',
onFocus: _noop2.default,
onBlur: _noop2.default,
onChange: _noop2.default,
onChangeWithDateFirst: true,
use12Hours: false,
focusOnOpen: false,
onKeyDown: _noop2.default,
size: 'default',
type: _constants.strings.DEFAULT_TYPE,
motion: true
}, _PanelShape.PanelShapeDefaults);