UNPKG

17.3 kBJavaScriptView Raw
1import _objectWithoutProperties from 'babel-runtime/helpers/objectWithoutProperties';
2import _extends from 'babel-runtime/helpers/extends';
3import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
4import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
5import _inherits from 'babel-runtime/helpers/inherits';
6
7var _class, _temp, _initialiseProps;
8
9import React from 'react';
10import { polyfill } from 'react-lifecycles-compat';
11import classnames from 'classnames';
12import * as PT from 'prop-types';
13
14import SharedPT from '../prop-types';
15import { func, datejs, obj } from '../../util';
16import { setTime, switchInputType, mode2unit } from '../util';
17
18import { DATE_INPUT_TYPE } from '../constant';
19import { DATE_PANEL_MODE, CALENDAR_CELL_STATE } from '../../calendar2/constant';
20import Calendar from '../../calendar2';
21import TimePanel from './time-panel';
22
23var DATE = DATE_PANEL_MODE.DATE,
24 WEEK = DATE_PANEL_MODE.WEEK,
25 MONTH = DATE_PANEL_MODE.MONTH,
26 QUARTER = DATE_PANEL_MODE.QUARTER,
27 YEAR = DATE_PANEL_MODE.YEAR;
28var UN_SELECTED = CALENDAR_CELL_STATE.UN_SELECTED,
29 SELECTED = CALENDAR_CELL_STATE.SELECTED,
30 SELECTED_BEGIN = CALENDAR_CELL_STATE.SELECTED_BEGIN,
31 SELECTED_END = CALENDAR_CELL_STATE.SELECTED_END;
32var BEGIN = DATE_INPUT_TYPE.BEGIN,
33 END = DATE_INPUT_TYPE.END;
34
35
36var operate = function operate(mode, value, operator) {
37 var newVal = value.clone();
38
39 switch (mode) {
40 case DATE:
41 case WEEK:
42 return newVal[operator](1, 'month');
43 case QUARTER:
44 case MONTH:
45 return newVal[operator](1, 'year');
46 case YEAR:
47 return newVal[operator](10, 'year');
48 }
49};
50
51var isSamePanel = function isSamePanel(a, b, mode) {
52 switch (mode) {
53 case DATE:
54 case WEEK:
55 return a.isSame(b, 'month');
56 case QUARTER:
57 case MONTH:
58 return a.isSame(b, 'year');
59 case YEAR:
60 {
61 var begin = a.year() - a.year() % 20;
62 var byear = b.year();
63
64 return byear >= begin && byear < begin + 20;
65 }
66 }
67};
68
69// 计算 面板日期
70var getPanelValue = function getPanelValue(_ref, defaultValue) {
71 var mode = _ref.mode,
72 value = _ref.value,
73 inputType = _ref.inputType,
74 showTime = _ref.showTime;
75 var begin = value[0],
76 end = value[1];
77
78 var otherType = inputType === BEGIN ? END : BEGIN;
79 var _inputType = inputType;
80
81 if (!value[inputType] && value[otherType]) {
82 _inputType = otherType;
83 }
84
85 var panelValue = value[_inputType] || datejs(defaultValue);
86
87 // https://github.com/alibaba-fusion/next/issues/3186
88 if (!showTime && _inputType === END && end && (begin && !isSamePanel(begin, end, mode) || !begin)) {
89 panelValue = operate(mode, panelValue, 'subtract');
90 }
91
92 return panelValue && panelValue.isValid() ? panelValue : datejs();
93};
94
95var RangePanel = (_temp = _class = function (_React$Component) {
96 _inherits(RangePanel, _React$Component);
97
98 function RangePanel(props) {
99 _classCallCheck(this, RangePanel);
100
101 var _this = _possibleConstructorReturn(this, _React$Component.call(this, props));
102
103 _initialiseProps.call(_this);
104
105 var mode = props.mode,
106 defaultPanelValue = props.defaultPanelValue,
107 _props$timePanelProps = props.timePanelProps,
108 timePanelProps = _props$timePanelProps === undefined ? {} : _props$timePanelProps;
109
110 // 默认时间
111
112 var defaultTime = timePanelProps.defaultValue || [];
113 if (!Array.isArray(defaultTime)) {
114 defaultTime = [defaultTime, defaultTime];
115 }
116 defaultTime = defaultTime.map(function (t) {
117 return datejs(t, timePanelProps.format || 'HH:mm:ss');
118 });
119
120 _this.state = {
121 mode: mode,
122 panelValue: getPanelValue(props, defaultPanelValue),
123 inputType: props.inputType,
124 curHoverValue: null,
125 defaultTime: defaultTime
126 };
127 return _this;
128 }
129
130 RangePanel.getDerivedStateFromProps = function getDerivedStateFromProps(props, state) {
131 if (props.inputType !== state.inputType) {
132 return {
133 inputType: props.inputType,
134 panelValue: getPanelValue(props, state.panelValue)
135 };
136 }
137 return null;
138 };
139
140 RangePanel.prototype.componentWillUnmount = function componentWillUnmount() {
141 this.currentRaf && window.cancelAnimationFrame(this.currentRaf);
142 };
143
144 // 日期面板显示的日期区间
145
146
147 RangePanel.prototype.getRanges = function getRanges() {
148 var mode = this.props.mode;
149 var v = this.state.panelValue;
150
151
152 var begin = v.clone();
153 var end = operate(mode, v, 'add');
154
155 return [begin, end];
156 };
157
158 // 日期cell状态
159 RangePanel.prototype.handleCellState = function handleCellState(v, value) {
160 var mode = this.props.mode;
161 var begin = value[0],
162 end = value[1];
163
164
165 var unit = this.getUnitByMode(mode);
166
167 return begin && begin.isSame(v, unit) ? SELECTED_BEGIN : end && end.isSame(v, unit) ? SELECTED_END : begin && end && v.isAfter(begin, unit) && v.isBefore(end, unit) ? SELECTED : UN_SELECTED;
168 };
169
170 RangePanel.prototype.getUnitByMode = function getUnitByMode(mode) {
171 return mode === DATE ? 'day' : mode;
172 };
173
174 // 头部面板日期切换点击事件
175
176
177 RangePanel.prototype.renderRange = function renderRange(sharedProps) {
178 var _classnames;
179
180 var handlePanelChange = this.handlePanelChange,
181 handleCanlendarClick = this.handleCanlendarClick,
182 hasModeChanged = this.hasModeChanged;
183 var _props = this.props,
184 value = _props.value,
185 prefix = _props.prefix;
186
187 var ranges = this.getRanges();
188
189 var calendarProps = function calendarProps(idx) {
190 return _extends({}, sharedProps, {
191 value: value[idx],
192 panelValue: ranges[idx],
193 onPanelChange: function onPanelChange(v, m) {
194 return handlePanelChange(v, m, idx);
195 }
196 });
197 };
198
199 var calendarNodes = [React.createElement(Calendar, _extends({}, calendarProps(0), { className: prefix + 'range-picker-left', key: 'range-panel-calendar-left' })), React.createElement(Calendar, _extends({}, calendarProps(1), {
200 className: prefix + 'range-picker-right',
201 key: 'range-panel-calendar-right',
202 onNext: handleCanlendarClick,
203 onSuperNext: handleCanlendarClick
204 }))];
205
206 var className = classnames(prefix + 'range-picker2-panel', (_classnames = {}, _classnames[prefix + 'range-picker2-panel-single'] = hasModeChanged, _classnames));
207
208 return React.createElement(
209 'div',
210 { key: 'range-panel', className: className },
211 !this.hasModeChanged ? calendarNodes : calendarNodes[this.state.calendarIdx]
212 );
213 };
214
215 RangePanel.prototype.render = function render() {
216 var handleSelect = this.handleSelect,
217 getCellClassName = this.getCellClassName,
218 handleMouseEnter = this.handleMouseEnter,
219 handleMouseLeave = this.handleMouseLeave;
220
221 var _props2 = this.props,
222 mode = _props2.mode,
223 justBeginInput = _props2.justBeginInput,
224 dateCellRender = _props2.dateCellRender,
225 restProps = _objectWithoutProperties(_props2, ['mode', 'justBeginInput', 'dateCellRender']);
226
227 // 切换面板mode
228
229
230 this.hasModeChanged = this.state.mode !== this.props.mode;
231
232 var sharedProps = _extends({}, obj.pickProps(Calendar.propTypes, restProps), {
233 shape: 'panel',
234 panelMode: mode,
235 dateCellRender: dateCellRender
236 });
237
238 sharedProps.disabledDate = justBeginInput ? this.props.disabledDate : this.disabledDate;
239
240 // 日期面板固定列数 保证对齐
241 if ([DATE, WEEK].includes(mode)) {
242 sharedProps.colNum = 6;
243 }
244
245 if (!this.hasModeChanged) {
246 sharedProps = _extends({}, sharedProps, {
247 onSelect: handleSelect,
248 cellClassName: getCellClassName,
249 cellProps: {
250 onMouseEnter: handleMouseEnter,
251 onMouseLeave: handleMouseLeave
252 }
253 });
254 }
255
256 return this.props.showTime ? this.renderRangeTime(sharedProps) : this.renderRange(sharedProps);
257 };
258
259 return RangePanel;
260}(React.Component), _class.propTypes = {
261 rtl: PT.bool,
262 prefix: PT.string,
263 locale: PT.object,
264 mode: SharedPT.mode,
265 value: PT.arrayOf(SharedPT.date),
266 inputType: SharedPT.inputType,
267 handleCellState: PT.func,
268 disabledDate: PT.func,
269 justBeginInput: PT.bool,
270 resetTime: PT.bool,
271 showTime: PT.bool,
272 timePanelProps: PT.object,
273 disabledTime: PT.object,
274 dateCellRender: PT.func
275}, _class.defaultProps = {
276 disabledDate: function disabledDate() {
277 return false;
278 },
279 justBeginInput: true
280}, _initialiseProps = function _initialiseProps() {
281 var _this2 = this;
282
283 this.disabledDate = function (v) {
284 var _props3 = _this2.props,
285 mode = _props3.mode,
286 inputType = _props3.inputType,
287 disabledDate = _props3.disabledDate,
288 _props3$value = _props3.value,
289 begin = _props3$value[0],
290 end = _props3$value[1];
291
292
293 var unit = mode2unit(mode);
294
295 return disabledDate(v, mode) || inputType === END && begin && begin.isAfter(v, unit) || inputType === BEGIN && end && end.isBefore(v, unit);
296 };
297
298 this.onTimeSelect = function (v) {
299 var _props4 = _this2.props,
300 value = _props4.value,
301 inputType = _props4.inputType;
302 var begin = value[0],
303 end = value[1];
304
305
306 var curDateVal = value[inputType];
307 if (!curDateVal) {
308 curDateVal = inputType === BEGIN && end ? end.subtract(1, 'day') : inputType === END && begin ? begin.add(1, 'day') : datejs();
309 }
310 curDateVal = setTime(curDateVal, v);
311
312 _this2.handleSelect(curDateVal, true);
313 };
314
315 this.handleSelect = function (v, fromTimeChange) {
316 var _props5 = _this2.props,
317 value = _props5.value,
318 inputType = _props5.inputType,
319 resetTime = _props5.resetTime;
320
321 var otherType = switchInputType(inputType);
322 var newValue = [].concat(value);
323
324 var defaultTime = _this2.state.defaultTime[inputType];
325 var timeVal = null;
326
327 // 如果不是选择时间面板触发的时间改变或不需要重置时间
328 // 则需要设置时间值,优先级如下:
329 // - 目前这个日期时间
330 // - 默认时间
331 // - 另一日期时间
332 // - 当前时间
333 if (!fromTimeChange && !resetTime) {
334 timeVal = value[inputType] || defaultTime || value[otherType] || datejs();
335 }
336
337 newValue[inputType === BEGIN ? 0 : 1] = setTime(v, timeVal);
338
339 func.invoke(_this2.props, 'onSelect', [newValue]);
340 };
341
342 this.handlePanelChange = function (v, mode, idx) {
343 _this2.setState({
344 mode: mode,
345 panelValue: v,
346 calendarIdx: idx
347 });
348
349 func.invoke(_this2.props, 'onPanelChange', [v, mode]);
350 };
351
352 this.handleMouseEnter = function (value) {
353 _this2.currentRaf && window.cancelAnimationFrame(_this2.currentRaf);
354 _this2.currentRaf = window.requestAnimationFrame(function () {
355 _this2.setState({
356 curHoverValue: value
357 });
358 });
359 };
360
361 this.handleMouseLeave = function () {
362 _this2.currentRaf && window.cancelAnimationFrame(_this2.currentRaf);
363 _this2.setState({
364 curHoverValue: null
365 });
366 };
367
368 this.handleEdgeState = function (value, mode) {
369 var unit = _this2.getUnitByMode(mode);
370
371 switch (mode) {
372 case DATE:
373 {
374 var endDate = value.endOf('month');
375 var beginDate = value.startOf('month');
376 return beginDate.isSame(value, unit) ? 1 : endDate.isSame(value, unit) ? 2 : 0;
377 }
378 case YEAR:
379 {
380 var year = value.year();
381
382 var beginYear = value.year() - value.year() % 10;
383 var endYear = beginYear + 9;
384 return year === beginYear ? 1 : year === endYear ? 2 : 0;
385 }
386 default:
387 return 0;
388 }
389 };
390
391 this.getCellClassName = function (value) {
392 var _extends2;
393
394 var _props6 = _this2.props,
395 prefix = _props6.prefix,
396 inputType = _props6.inputType,
397 mode = _props6.mode;
398 var curHoverValue = _this2.state.curHoverValue;
399 var _props$value = _this2.props.value,
400 begin = _props$value[0],
401 end = _props$value[1];
402
403 var unit = _this2.getUnitByMode(mode);
404
405 var state = _this2.handleCellState(value, _this2.props.value);
406 var prefixCls = prefix + 'calendar2-cell';
407
408 var hoverClassName = void 0;
409 if (curHoverValue) {
410 var hoverValue = [].concat(_this2.props.value);
411 hoverValue[inputType] = curHoverValue;
412 var hoverBegin = hoverValue[0],
413 hoverEnd = hoverValue[1];
414
415
416 if (hoverBegin && hoverEnd && hoverBegin.isBefore(hoverEnd, unit)) {
417 var _hoverClassName;
418
419 var hoverState = _this2.handleCellState(value, hoverValue);
420
421 hoverClassName = (_hoverClassName = {}, _hoverClassName[prefixCls + '-hover'] = hoverState >= SELECTED, _hoverClassName[prefixCls + '-hover-begin'] = hoverState === SELECTED_BEGIN, _hoverClassName[prefixCls + '-hover-end'] = hoverState === SELECTED_END, _hoverClassName[prefixCls + '-hover-end'] = hoverState === SELECTED_END, _hoverClassName);
422 }
423 }
424
425 var rangeClassName = void 0;
426 if (!_this2.hasModeChanged) {
427 var _ref2, _ref3;
428
429 var edgeState = _this2.handleEdgeState(value, mode);
430 var isIllegal = end && begin && begin.isAfter(end);
431
432 rangeClassName = mode === WEEK ? (_ref2 = {}, _ref2[prefixCls + '-week-range-begin'] = state === SELECTED_BEGIN, _ref2[prefixCls + '-week-range-end'] = state === SELECTED_END, _ref2) : (_ref3 = {}, _ref3[prefixCls + '-range-begin'] = state === SELECTED_BEGIN, _ref3[prefixCls + '-range-end'] = state === SELECTED_END, _ref3[prefixCls + '-range-begin-single'] = state >= SELECTED && (!end || end.isSame(begin, unit) || isIllegal), _ref3[prefixCls + '-range-end-single'] = state >= SELECTED && (!begin || begin.isSame(end, unit) || isIllegal), _ref3[prefixCls + '-edge-begin'] = edgeState === 1, _ref3[prefixCls + '-edge-end'] = edgeState === 2, _ref3);
433 }
434
435 return _extends((_extends2 = {}, _extends2[prefixCls + '-selected'] = state >= SELECTED, _extends2), rangeClassName, hoverClassName);
436 };
437
438 this.handleCanlendarClick = function (_, _ref4) {
439 var unit = _ref4.unit,
440 num = _ref4.num;
441
442 _this2.setState({
443 panelValue: _this2.state.panelValue.clone().add(num, unit)
444 });
445 };
446
447 this.renderRangeTime = function (sharedProps) {
448 var _classnames2;
449
450 var _props7 = _this2.props,
451 value = _props7.value,
452 prefix = _props7.prefix,
453 showTime = _props7.showTime,
454 inputType = _props7.inputType,
455 _props7$timePanelProp = _props7.timePanelProps,
456 timePanelProps = _props7$timePanelProp === undefined ? {} : _props7$timePanelProp,
457 disabledTime = _props7.disabledTime;
458
459
460 var className = classnames(prefix + 'range-picker2-panel', (_classnames2 = {}, _classnames2[prefix + 'range-picker2-panel-single'] = _this2.hasModeChanged, _classnames2));
461
462 // 禁用时间
463 var _disabledTime = void 0;
464 if (showTime && !_this2.hasModeChanged && disabledTime) {
465 _disabledTime = typeof disabledTime === 'function' ? disabledTime(value, inputType) : disabledTime;
466 }
467
468 return React.createElement(
469 'div',
470 { key: 'range-time-panel', className: className },
471 React.createElement(Calendar, _extends({
472 panelValue: _this2.state.panelValue
473 }, sharedProps, {
474 value: value[inputType],
475 onPanelChange: _this2.handlePanelChange
476 })),
477 showTime && !_this2.hasModeChanged ? React.createElement(TimePanel, {
478 prefix: prefix,
479 inputType: inputType,
480 value: value[inputType] || _this2.state.defaultTime[inputType],
481 onSelect: _this2.onTimeSelect,
482 disabledTime: disabledTime,
483 timePanelProps: _extends({}, _disabledTime, timePanelProps)
484 }) : null
485 );
486 };
487}, _temp);
488RangePanel.displayName = 'RangePanel';
489
490
491export default polyfill(RangePanel);
\No newline at end of file