chowa
Version:
UI component library based on React
272 lines (271 loc) • 12.1 kB
JavaScript
/**
* @license chowa v1.1.3
*
* Copyright (c) Chowa Techonlogies Co.,Ltd.(http://www.chowa.cn).
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const React = require("react");
const PropTypes = require("prop-types");
const moment = require("moment");
const classnames_1 = require("classnames");
const utils_1 = require("../../utils");
const calendar_mode_1 = require("../calendar-mode");
const header_1 = require("./header");
const body_1 = require("./body");
const footer_1 = require("./footer");
class MinRangeCalendar extends React.PureComponent {
constructor(props) {
super(props);
const [beginRange, endRange] = props.value || props.defaultValue || [];
const beginDisplay = moment.isMoment(beginRange) ? beginRange.clone() : moment();
const endDisplay = moment.isMoment(endRange) ? endRange.clone() : moment();
if (utils_1.isSameMoment(beginDisplay, endDisplay, 'month')) {
endDisplay.add(1, 'month');
}
this.state = {
beginActiveMode: calendar_mode_1.DAY_MODE,
beginDate: beginRange,
beginTime: beginRange,
beginDisplay,
beginEach: beginDisplay,
endActiveMode: calendar_mode_1.DAY_MODE,
endDate: endRange,
endTime: endRange,
endDisplay,
endEach: endDisplay,
prepareEndDate: undefined
};
[
'triggerChange',
'updateBeginEach',
'updateBeginDisplay',
'updateBeginMode',
'onBeginTimeSelectHandler',
'updateEndEach',
'updateEndDisplay',
'updateEndMode',
'onEndTimeSelectHandler',
'onRangeSelectHandler',
'updateBothMode',
'onClearHandler',
'onConfirmHandler',
'onBeofreSelectHandler',
'onDeDateBeforeSelectHandler'
].forEach((fn) => {
this[fn] = this[fn].bind(this);
});
}
componentDidUpdate(preProps) {
if (!utils_1.isEqual(preProps.value, this.props.value)) {
const [beginRange, endRange] = this.props.value || [];
if (moment.isMoment(beginRange) && moment.isMoment(endRange)) {
const beginDisplay = moment.isMoment(beginRange) ? beginRange.clone() : moment();
const endDisplay = moment.isMoment(endRange) ? endRange.clone() : moment();
if (utils_1.isSameMoment(beginDisplay, endDisplay, 'month')) {
endDisplay.add(1, 'month');
}
this.setState({
beginDate: beginRange,
beginTime: beginRange,
beginDisplay: beginDisplay.clone(),
beginEach: beginDisplay.clone(),
endDate: endRange,
endTime: endRange,
endDisplay: endDisplay.clone(),
endEach: endDisplay.clone(),
prepareEndDate: undefined
});
}
}
}
triggerChange(force = false) {
const { determinable, timeable, value, onChange } = this.props;
const { beginDate, endDate, beginTime, endTime } = this.state;
if (determinable && !force) {
return;
}
const beginEmpty = !moment.isMoment(beginDate) || (timeable && !moment.isMoment(beginTime));
const begin = beginEmpty ? undefined : beginDate.clone();
if (timeable && !beginEmpty) {
begin.hour(beginTime.hour())
.minute(beginTime.minute())
.second(beginTime.second());
}
const endEmpty = !moment.isMoment(endDate) || (timeable && !moment.isMoment(endTime));
const end = endEmpty ? undefined : endDate.clone();
if (timeable && !endEmpty) {
end.hour(endTime.hour())
.minute(endTime.minute())
.second(endTime.second());
}
const result = beginEmpty || endEmpty
? undefined
: [begin, end].sort(((a, b) => moment(a).isBefore(moment(b)) ? -1 : 1));
if ((!utils_1.isExist(value) && (endEmpty || beginEmpty)) || utils_1.isEqual(value, result)) {
return;
}
if (onChange) {
onChange(result);
}
}
updateBeginEach(beginEach) {
this.setState({ beginEach });
}
updateBeginDisplay(newBeginDisplay) {
const { endDisplay, endDate } = this.state;
const isSameMonth = utils_1.isSameMoment(newBeginDisplay, endDisplay, 'month');
let newEndDisplay = endDisplay.clone();
if (isSameMonth) {
newEndDisplay.startOf('month').add(1, 'month');
}
else if (newBeginDisplay.isAfter(newEndDisplay, 'month')) {
newEndDisplay = newBeginDisplay;
newBeginDisplay = endDisplay.clone();
}
this.setState({
beginDate: undefined,
beginDisplay: newBeginDisplay,
endDate: isSameMonth ? undefined : endDate,
endDisplay: newEndDisplay,
prepareEndDate: undefined
});
this.updateBeginMode(calendar_mode_1.DAY_MODE);
}
updateBeginMode(beginActiveMode) {
this.setState({ beginActiveMode });
}
onBeginTimeSelectHandler(beginTime) {
this.setState({ beginTime }, this.triggerChange);
}
updateEndEach(endEach) {
this.setState({ endEach });
}
updateEndDisplay(newEndDisplay) {
const { beginDisplay, beginDate } = this.state;
const isSameMonth = utils_1.isSameMoment(newEndDisplay, beginDisplay, 'month');
let newBeginDisplay = beginDisplay.clone();
if (isSameMonth) {
newBeginDisplay.startOf('month').subtract(1, 'month');
}
else if (newEndDisplay.isBefore(newBeginDisplay, 'month')) {
newBeginDisplay = newEndDisplay;
newEndDisplay = beginDisplay.clone();
}
this.setState({
beginDate: isSameMonth ? undefined : beginDate,
beginDisplay: newBeginDisplay,
endDate: undefined,
endDisplay: newEndDisplay,
prepareEndDate: undefined
});
this.updateEndMode(calendar_mode_1.DAY_MODE);
}
updateEndMode(endActiveMode) {
this.setState({ endActiveMode });
}
onEndTimeSelectHandler(endTime) {
this.setState({ endTime }, this.triggerChange);
}
onRangeSelectHandler(date) {
const { beginDate, endDate } = this.state;
let queue = [beginDate, endDate];
if (queue.every((item) => moment.isMoment(item))) {
queue = [undefined, undefined];
}
if (!moment.isMoment(queue[0])) {
queue[0] = date;
}
else {
queue[1] = date;
}
const [newBeginDate, newEndDate] = queue;
this.setState({
beginDate: newBeginDate,
endDate: newEndDate,
prepareEndDate: undefined
}, this.triggerChange);
}
updateBothMode(mode) {
this.setState({
beginActiveMode: mode,
endActiveMode: mode
});
}
onClearHandler() {
this.setState({
beginDate: undefined,
beginTime: undefined,
endDate: undefined,
endTime: undefined
}, () => {
this.triggerChange(true);
if (this.props.onClear) {
this.props.onClear();
}
});
}
onConfirmHandler() {
this.triggerChange(true);
if (this.props.onConfirm) {
this.props.onConfirm();
}
}
onBeofreSelectHandler(prepareEndDate) {
this.setState({ prepareEndDate });
}
onDeDateBeforeSelectHandler() {
this.setState({ prepareEndDate: undefined });
}
render() {
const { className, style, secondable, timeable, determinable, disabledDate, clearable } = this.props;
const { beginActiveMode, beginDate, beginTime, beginDisplay, beginEach, endActiveMode, endDate, endTime, endDisplay, endEach, prepareEndDate } = this.state;
const listenBeforeSelect = (moment.isMoment(beginDate) && !moment.isMoment(endDate))
|| (!moment.isMoment(beginDate) && moment.isMoment(endDate));
const rangeClass = classnames_1.default({
[utils_1.preClass('min-calendar-range-selector')]: true,
[className]: utils_1.isExist(className)
});
const rangeQueue = [prepareEndDate, beginDate, endDate]
.filter((val) => moment.isMoment(val));
rangeQueue.sort((a, b) => moment(a).isBefore(moment(b)) ? -1 : 1);
const [begin, end] = rangeQueue;
const rangeDate = { begin, end };
return (React.createElement("div", { className: rangeClass, style: style },
React.createElement("div", { className: utils_1.preClass('min-calendar-range-body'), onMouseLeave: listenBeforeSelect ? this.onDeDateBeforeSelectHandler : null },
React.createElement("div", { className: utils_1.preClass('min-calendar-begin-range') },
React.createElement(header_1.default, { mode: beginActiveMode, display: beginDisplay, each: beginEach, time: beginTime, updateEach: this.updateBeginEach, updateDisplay: this.updateBeginDisplay, updateMode: this.updateBeginMode }),
React.createElement(body_1.default, { values: [beginDate, endDate], time: beginTime, each: beginEach, mode: beginActiveMode, defaultMode: calendar_mode_1.DAY_MODE, display: beginDisplay, secondable: secondable, weeksable: false, disabledDate: disabledDate, rangeDate: rangeDate, onDateSelect: this.onRangeSelectHandler, onMonthSelect: this.updateBeginDisplay, onYearSelect: this.updateBeginDisplay, onTimeSelect: this.onBeginTimeSelectHandler, onDateBeforeSelect: listenBeforeSelect ? this.onBeofreSelectHandler : null })),
React.createElement("div", { className: utils_1.preClass('min-calendar-end-range') },
React.createElement(header_1.default, { mode: endActiveMode, display: endDisplay, each: endEach, time: endTime, updateEach: this.updateEndEach, updateDisplay: this.updateEndDisplay, updateMode: this.updateEndMode }),
React.createElement(body_1.default, { values: [beginDate, endDate], time: endTime, each: endEach, mode: endActiveMode, defaultMode: calendar_mode_1.DAY_MODE, display: endDisplay, secondable: secondable, weeksable: false, disabledDate: disabledDate, rangeDate: rangeDate, onDateSelect: this.onRangeSelectHandler, onMonthSelect: this.updateEndDisplay, onYearSelect: this.updateEndDisplay, onTimeSelect: this.onEndTimeSelectHandler, onDateBeforeSelect: listenBeforeSelect ? this.onBeofreSelectHandler : null }))),
React.createElement(footer_1.default, { switchable: timeable, defaultMode: calendar_mode_1.DAY_MODE, mode: beginActiveMode, updateMode: this.updateBothMode, clearable: clearable, onClear: this.onClearHandler, determinable: determinable, onConfirm: this.onConfirmHandler, disabled: !moment.isMoment(beginDate)
|| (timeable ? !moment.isMoment(beginTime) : false)
|| !moment.isMoment(endDate)
|| (timeable ? !moment.isMoment(endTime) : false), updateable: false })));
}
}
MinRangeCalendar.propTypes = {
className: PropTypes.string,
style: PropTypes.object,
defaultValue: PropTypes.array,
value: PropTypes.array,
timeable: PropTypes.bool,
secondable: PropTypes.bool,
determinable: PropTypes.bool,
disabledDate: PropTypes.object,
onConfirm: PropTypes.func,
onChange: PropTypes.func,
clearable: PropTypes.bool,
onClear: PropTypes.func
};
MinRangeCalendar.defaultProps = {
timeable: false,
secondable: true,
clearable: false,
determinable: false
};
exports.default = MinRangeCalendar;