zent
Version:
一套前端设计语言和基于React的实现
579 lines (474 loc) • 17 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends2 = require('babel-runtime/helpers/extends');
var _extends3 = _interopRequireDefault(_extends2);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _classnames = require('classnames');
var _classnames2 = _interopRequireDefault(_classnames);
var _popover = require('../popover');
var _popover2 = _interopRequireDefault(_popover);
var _formatDate = require('zan-utils/date/formatDate');
var _formatDate2 = _interopRequireDefault(_formatDate);
var _parseDate = require('zan-utils/date/parseDate');
var _parseDate2 = _interopRequireDefault(_parseDate);
var _DatePanel = require('./date/DatePanel');
var _DatePanel2 = _interopRequireDefault(_DatePanel);
var _PanelFooter = require('./common/PanelFooter');
var _PanelFooter2 = _interopRequireDefault(_PanelFooter);
var _utils = require('./utils');
var _date = require('./utils/date');
var _constants = require('./constants/');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var retType = 'string';
function isValidValue(val) {
if (!(0, _utils.isArray)(val)) return false;
var ret = val.filter(function (item) {
return !!item;
});
return ret.length === 2;
}
function getDateTime(date, time) {
return new Date(date.getFullYear(), date.getMonth(), date.getDate(), time.getHours(), time.getMinutes(), time.getSeconds());
}
var extractStateFromProps = function extractStateFromProps(props) {
var format = props.format,
defaultValue = props.defaultValue,
defaultTime = props.defaultTime;
var showPlaceholder = void 0;
var selected = [];
var actived = [];
var range = [];
var value = [];
if (isValidValue(props.value)) {
showPlaceholder = false;
selected = [(0, _parseDate2['default'])(props.value[0], format), (0, _parseDate2['default'])(props.value[1], format)];
var tmp = [(0, _date.setTime)(selected[0]), (0, _date.setTime)(selected[1])];
range = tmp.slice();
actived = tmp.slice();
value = [(0, _formatDate2['default'])(selected[0], format), (0, _formatDate2['default'])(selected[1], format)];
// 特殊处理:如果两个时间在同一个月,右边的面板月份加一
if ((0, _utils.isSameMonth)(actived[0], actived[1])) {
actived[1] = (0, _utils.goMonths)(actived[1], 1);
}
} else {
showPlaceholder = true;
value = [];
if (defaultValue && isValidValue(defaultValue)) {
actived = [(0, _parseDate2['default'])(defaultValue[0], format), (0, _parseDate2['default'])(defaultValue[1], format)];
} else {
var start = (0, _date.dayStart)();
actived = [start, (0, _utils.goMonths)(start, 1)];
}
}
if (defaultTime && isValidValue(defaultTime)) {
actived = actived.map(function (item, idx) {
return (0, _date.setTime)(item, defaultTime[idx]);
});
range = range.map(function (item, idx) {
return (0, _date.setTime)(item, defaultTime[idx]);
});
}
var activedTime = void 0;
if (selected.length === 2) {
activedTime = selected.slice();
} else {
activedTime = actived.slice();
}
return {
value: value,
range: range,
selected: selected,
actived: actived,
activedTime: activedTime,
openPanel: false,
showError: false,
openStartTimePanel: false,
openEndTimePanel: false,
showPlaceholder: showPlaceholder
};
};
var _ref3 = _react2['default'].createElement('span', { className: 'zenticon zenticon-calendar-o' });
var CombineDateRangePicker = function (_ref) {
(0, _inherits3['default'])(CombineDateRangePicker, _ref);
function CombineDateRangePicker(props) {
(0, _classCallCheck3['default'])(this, CombineDateRangePicker);
var _this = (0, _possibleConstructorReturn3['default'])(this, (CombineDateRangePicker.__proto__ || Object.getPrototypeOf(CombineDateRangePicker)).call(this, props));
_this.getDate = function () {
return _this.state.actived;
};
_this.onHover = function (val) {
var _this$state = _this.state,
selected = _this$state.selected,
range = _this$state.range;
var scp = selected.slice();
var rcp = range.slice();
if (scp.length !== 1) {
rcp.splice(0, 2);
return;
}
if (rcp[0] && rcp[0] < val) {
rcp.splice(1, 1, val);
_this.setState({
range: rcp
});
}
};
_this.onSelectDate = function (val) {
var _this$state2 = _this.state,
selected = _this$state2.selected,
actived = _this$state2.actived,
range = _this$state2.range;
var onClick = _this.props.onClick;
var scp = selected.slice();
var acp = actived.slice();
var rcp = range.slice();
var type = void 0;
/**
* 选择日期时,可能如下出现四种情况
* 1. 还没有选择过,这次选择的日期作为开始日期
* 2. 选择过一次,并且第二次选择日期大于第一次,这次选择的日期作为结束日期
* 3. 有效选择过两次,清空之前的选择,重新设置这次选择的日期作为开始日期
* 4. 选择过一次,并且这次选择的日期小于第一次,替换这次选择的日期为开始日期
*/
if (scp.length === 2) {
scp.splice(0, 2, val);
rcp.splice(0, 2, val);
acp.splice(0, 2, val, (0, _utils.goMonths)(val, 1));
type = 'start';
// 支持选择同一天
} else if (scp[0] && (scp[0] < val || (0, _formatDate2['default'])(scp[0]) === (0, _formatDate2['default'])(val))) {
scp.splice(1, 1, val);
if (scp[0].getMonth() < val.getMonth()) {
acp.splice(1, 1, val);
}
type = 'end';
} else {
acp.splice(0, 2, val, (0, _utils.goMonths)(val, 1));
scp.splice(0, 1, val);
rcp.splice(0, 1, val);
type = 'start';
}
_this.setState({
selected: scp,
actived: acp,
range: rcp
});
onClick && onClick(val, type);
};
_this.isDisabled = function (val) {
var _this$props = _this.props,
disabledDate = _this$props.disabledDate,
format = _this$props.format,
min = _this$props.min,
max = _this$props.max;
if (disabledDate && disabledDate(val)) return true;
if (min && val < (0, _parseDate2['default'])(min, format)) return true;
if (max && val > (0, _parseDate2['default'])(max, format)) return true;
return false;
};
_this.onChangeDate = function (val, i) {
var actived = _this.state.actived;
var acp = actived.slice();
acp.splice(i, 1, val);
_this.setState({
actived: acp
});
};
_this.onChangeStart = function (val) {
_this.onChangeDate(val, 0);
};
_this.onChangeEnd = function (val) {
_this.onChangeDate(val, 1);
};
_this.onChangeTime = function (val, i, type) {
var activedTime = _this.state.activedTime;
var tcp = activedTime.slice();
var fn = _constants.timeFnMap[type];
tcp[i][fn](val);
_this.setState({
activedTime: tcp
});
};
_this.onChangeStartTime = function (val, type) {
_this.onChangeTime(val, 0, type);
};
_this.onChangeEndTime = function (val, type) {
_this.onChangeTime(val, 1, type);
};
_this.onChangeMonth = function (type) {
var baseMap = {
prev: 0,
next: 1
};
var typeMap = {
prev: -1,
next: 1
};
return function () {
var actived = _this.state.actived;
var base = actived[baseMap[type]];
var acp = [base, base];
acp.splice(baseMap[type], 1, (0, _utils.goMonths)(base, typeMap[type]));
_this.setState({
actived: acp
});
};
};
_this.onOpenStartTime = function () {
_this.setState({
openStartTimePanel: true,
openEndTimePanel: false
});
};
_this.onOpenEndTime = function () {
_this.setState({
openStartTimePanel: false,
openEndTimePanel: true
});
};
_this.onClearInput = function (evt) {
evt.stopPropagation();
_this.props.onChange([]);
};
_this.onConfirm = function () {
var _this$state3 = _this.state,
selected = _this$state3.selected,
activedTime = _this$state3.activedTime;
if (selected.length !== 2) {
_this.setState({
showError: true
});
// eslint-disable-next-line
var timer = setTimeout(function () {
_this.setState({
showError: false
});
timer = null;
}, 2000);
return;
}
var _this$props2 = _this.props,
format = _this$props2.format,
showTime = _this$props2.showTime;
var tmp = selected.slice();
if (showTime) {
tmp = [getDateTime(tmp[0], activedTime[0]), getDateTime(tmp[1], activedTime[1])];
}
var vcp = [(0, _formatDate2['default'])(tmp[0], format), (0, _formatDate2['default'])(tmp[1], format)];
_this.setState({
value: vcp,
showPlaceholder: false,
openPanel: false
});
var ret = [_this.getReturnValue(tmp[0], format), _this.getReturnValue(tmp[1], format)];
_this.props.onChange(ret);
};
_this.togglePicker = function (visible) {
var _this$props3 = _this.props,
onOpen = _this$props3.onOpen,
onClose = _this$props3.onClose,
disabled = _this$props3.disabled;
if (disabled) return;
visible ? onOpen && onOpen() : onClose && onClose();
_this.setState({
openPanel: visible
});
};
var value = props.value,
valueType = props.valueType;
if (valueType) {
retType = valueType.toLowerCase();
} else if (isValidValue(value)) {
if (typeof value[0] === 'number') retType = 'number';
if (value[0] instanceof Date) retType = 'date';
}
_this.state = extractStateFromProps(props);
return _this;
}
(0, _createClass3['default'])(CombineDateRangePicker, [{
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(next) {
var state = extractStateFromProps(next);
this.setState(state);
}
// next&prev month 翻页效果联动
}, {
key: 'getReturnValue',
/**
* 如果传入为数字,返回值也为数字
* 如果传入为 Date 的实例,返回值也为 Date 的实例
* 默认返回 format 格式的字符串
*/
value: function getReturnValue(date, format) {
if (retType === 'number') {
return date.getTime();
}
if (retType === 'date') {
return date;
}
return (0, _formatDate2['default'])(date, format);
}
}, {
key: 'renderPicker',
value: function renderPicker() {
var _this2 = this;
var state = this.state;
var props = this.props;
var rangePicker = void 0;
var getTimeConfig = function getTimeConfig(type) {
if (!props.showTime) return false;
var handleMap = {
start: _this2.onChangeStartTime,
end: _this2.onChangeEndTime
};
var indexMap = {
start: 0,
end: 1
};
var timeStatusMap = {
start: 'openEndTimePanel',
end: 'openStartTimePanel'
};
var timeHandleMap = {
start: _this2.onOpenStartTime,
end: _this2.onOpenEndTime
};
return {
hidePanel: state[timeStatusMap[type]],
actived: state.activedTime[indexMap[type]],
disabledTime: props.disabledTime && props.disabledTime(type),
onChange: handleMap[type],
onOpen: timeHandleMap[type]
};
};
if (state.openPanel) {
var pickerCls = (0, _classnames2['default'])({
'range-picker': true,
'range-picker--showTime': props.showTime
});
rangePicker = _react2['default'].createElement(
'div',
{ className: pickerCls, ref: function ref(_ref2) {
return _this2.picker = _ref2;
} },
_react2['default'].createElement(
'div',
{ className: 'date-picker' },
_react2['default'].createElement(_DatePanel2['default'], {
range: state.range,
showTime: getTimeConfig('start'),
actived: state.actived[0],
selected: state.selected,
disabledDate: this.isDisabled,
onSelect: this.onSelectDate,
onChange: this.onChangeStart,
onHover: this.onHover,
onPrev: this.onChangeMonth('prev'),
onNext: _constants.noop,
showPrev: true,
showNext: false
})
),
_react2['default'].createElement(
'div',
{ className: 'date-picker' },
_react2['default'].createElement(_DatePanel2['default'], {
range: state.range,
showTime: getTimeConfig('end'),
actived: state.actived[1],
selected: state.selected,
disabledDate: this.isDisabled,
onSelect: this.onSelectDate,
onChange: this.onChangeEnd,
onHover: this.onHover,
onPrev: _constants.noop,
onNext: this.onChangeMonth('next'),
showPrev: false,
showNext: true
})
),
_react2['default'].createElement(_PanelFooter2['default'], {
buttonText: props.confirmText,
onClickButton: this.onConfirm,
showError: state.showError,
errorText: props.errorText
})
);
}
return rangePicker;
}
}, {
key: 'render',
value: function render() {
var state = this.state;
var props = this.props;
var prefixCls = props.prefix + '-datetime-picker ' + props.className;
var inputCls = (0, _classnames2['default'])({
'picker-input--range picker-input picker-input--combine': true,
'picker-input--filled': !state.showPlaceholder,
'picker-input--showTime': props.showTime,
'picker-input--disabled': props.disabled
});
return _react2['default'].createElement(
'div',
{ className: prefixCls },
_react2['default'].createElement(
_popover2['default'],
{
cushion: 5,
visible: state.openPanel,
onVisibleChange: this.togglePicker,
className: props.prefix + '-datetime-picker-popover ' + props.className + '-popover',
position: _constants.popPositionMap[props.popPosition.toLowerCase()]
},
_react2['default'].createElement(
_popover2['default'].Trigger.Click,
null,
_react2['default'].createElement(
'div',
{ className: inputCls, onClick: function onClick(evt) {
return evt.preventDefault();
} },
state.showPlaceholder ? props.placeholder.join(' 至 ') : state.value.join(' 至 '),
_ref3,
_react2['default'].createElement('span', {
onClick: this.onClearInput,
className: 'zenticon zenticon-close-circle'
})
)
),
_react2['default'].createElement(
_popover2['default'].Content,
null,
this.renderPicker()
)
)
);
}
}]);
return CombineDateRangePicker;
}(_react.PureComponent || _react.Component);
CombineDateRangePicker.PropTypes = (0, _extends3['default'])({}, _constants.commonPropTypes, {
showTime: _propTypes2['default'].bool,
placeholder: _propTypes2['default'].array,
defaultTime: _propTypes2['default'].arrayOf(_propTypes2['default'].string)
});
CombineDateRangePicker.defaultProps = (0, _extends3['default'])({}, _constants.commonProps, {
placeholder: ['开始日期', '结束日期'],
errorText: '请选择起止时间',
defaultTime: ['00:00:00', '00:00:00']
});
exports['default'] = CombineDateRangePicker;