UNPKG

12.4 kBJavaScriptView Raw
1import _extends from 'babel-runtime/helpers/extends';
2import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
3import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
4import _inherits from 'babel-runtime/helpers/inherits';
5import React from 'react';
6import ReactDOM from 'react-dom';
7import PropTypes from 'prop-types';
8import KeyCode from 'rc-util/es/KeyCode';
9import { polyfill } from 'react-lifecycles-compat';
10import DateTable from './date/DateTable';
11import CalendarHeader from './calendar/CalendarHeader';
12import CalendarFooter from './calendar/CalendarFooter';
13import { calendarMixinWrapper, calendarMixinPropTypes, calendarMixinDefaultProps, getNowByCurrentStateValue } from './mixin/CalendarMixin';
14import { commonMixinWrapper, propType, defaultProp } from './mixin/CommonMixin';
15import DateInput from './date/DateInput';
16import { getTimeConfig, getTodayTime, syncTime } from './util';
17import { goStartMonth, goEndMonth, goTime } from './util/toTime';
18import moment from 'moment';
19
20function noop() {}
21
22var getMomentObjectIfValid = function getMomentObjectIfValid(date) {
23 if (moment.isMoment(date) && date.isValid()) {
24 return date;
25 }
26 return false;
27};
28
29var Calendar = function (_React$Component) {
30 _inherits(Calendar, _React$Component);
31
32 function Calendar(props) {
33 _classCallCheck(this, Calendar);
34
35 var _this = _possibleConstructorReturn(this, _React$Component.call(this, props));
36
37 _initialiseProps.call(_this);
38
39 _this.state = {
40 mode: _this.props.mode || 'date',
41 value: getMomentObjectIfValid(props.value) || getMomentObjectIfValid(props.defaultValue) || moment(),
42 selectedValue: props.selectedValue || props.defaultSelectedValue
43 };
44 return _this;
45 }
46
47 Calendar.prototype.componentDidMount = function componentDidMount() {
48 if (this.props.showDateInput) {
49 this.saveFocusElement(DateInput.getInstance());
50 }
51 };
52
53 Calendar.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, state) {
54 var value = nextProps.value,
55 selectedValue = nextProps.selectedValue;
56
57 var newState = {};
58
59 if ('mode' in nextProps && state.mode !== nextProps.mode) {
60 newState = { mode: nextProps.mode };
61 }
62 if ('value' in nextProps) {
63 newState.value = getMomentObjectIfValid(value) || getMomentObjectIfValid(nextProps.defaultValue) || getNowByCurrentStateValue(state.value);
64 }
65 if ('selectedValue' in nextProps) {
66 newState.selectedValue = selectedValue;
67 }
68
69 return newState;
70 };
71
72 Calendar.prototype.render = function render() {
73 var props = this.props,
74 state = this.state;
75 var locale = props.locale,
76 prefixCls = props.prefixCls,
77 disabledDate = props.disabledDate,
78 dateInputPlaceholder = props.dateInputPlaceholder,
79 timePicker = props.timePicker,
80 disabledTime = props.disabledTime,
81 clearIcon = props.clearIcon,
82 renderFooter = props.renderFooter,
83 inputMode = props.inputMode,
84 monthCellRender = props.monthCellRender,
85 monthCellContentRender = props.monthCellContentRender;
86 var value = state.value,
87 selectedValue = state.selectedValue,
88 mode = state.mode;
89
90 var showTimePicker = mode === 'time';
91 var disabledTimeConfig = showTimePicker && disabledTime && timePicker ? getTimeConfig(selectedValue, disabledTime) : null;
92
93 var timePickerEle = null;
94
95 if (timePicker && showTimePicker) {
96 var timePickerProps = _extends({
97 showHour: true,
98 showSecond: true,
99 showMinute: true
100 }, timePicker.props, disabledTimeConfig, {
101 onChange: this.onDateInputChange,
102 value: selectedValue,
103 disabledTime: disabledTime
104 });
105
106 if (timePicker.props.defaultValue !== undefined) {
107 timePickerProps.defaultOpenValue = timePicker.props.defaultValue;
108 }
109
110 timePickerEle = React.cloneElement(timePicker, timePickerProps);
111 }
112
113 var dateInputElement = props.showDateInput ? React.createElement(DateInput, {
114 format: this.getFormat(),
115 key: 'date-input',
116 value: value,
117 locale: locale,
118 placeholder: dateInputPlaceholder,
119 showClear: true,
120 disabledTime: disabledTime,
121 disabledDate: disabledDate,
122 onClear: this.onClear,
123 prefixCls: prefixCls,
124 selectedValue: selectedValue,
125 onChange: this.onDateInputChange,
126 onSelect: this.onDateInputSelect,
127 clearIcon: clearIcon,
128 inputMode: inputMode
129 }) : null;
130
131 var children = [];
132 if (props.renderSidebar) {
133 children.push(props.renderSidebar());
134 }
135 children.push(React.createElement(
136 'div',
137 { className: prefixCls + '-panel', key: 'panel' },
138 dateInputElement,
139 React.createElement(
140 'div',
141 {
142 tabIndex: this.props.focusablePanel ? 0 : undefined,
143 className: prefixCls + '-date-panel'
144 },
145 React.createElement(CalendarHeader, {
146 locale: locale,
147 mode: mode,
148 value: value,
149 onValueChange: this.setValue,
150 onPanelChange: this.onPanelChange,
151 renderFooter: renderFooter,
152 showTimePicker: showTimePicker,
153 prefixCls: prefixCls,
154 monthCellRender: monthCellRender,
155 monthCellContentRender: monthCellContentRender
156 }),
157 timePicker && showTimePicker ? React.createElement(
158 'div',
159 { className: prefixCls + '-time-picker' },
160 React.createElement(
161 'div',
162 { className: prefixCls + '-time-picker-panel' },
163 timePickerEle
164 )
165 ) : null,
166 React.createElement(
167 'div',
168 { className: prefixCls + '-body' },
169 React.createElement(DateTable, {
170 locale: locale,
171 value: value,
172 selectedValue: selectedValue,
173 prefixCls: prefixCls,
174 dateRender: props.dateRender,
175 onSelect: this.onDateTableSelect,
176 disabledDate: disabledDate,
177 showWeekNumber: props.showWeekNumber
178 })
179 ),
180 React.createElement(CalendarFooter, {
181 showOk: props.showOk,
182 mode: mode,
183 renderFooter: props.renderFooter,
184 locale: locale,
185 prefixCls: prefixCls,
186 showToday: props.showToday,
187 disabledTime: disabledTime,
188 showTimePicker: showTimePicker,
189 showDateInput: props.showDateInput,
190 timePicker: timePicker,
191 selectedValue: selectedValue,
192 value: value,
193 disabledDate: disabledDate,
194 okDisabled: props.showOk !== false && (!selectedValue || !this.isAllowedDate(selectedValue)),
195 onOk: this.onOk,
196 onSelect: this.onSelect,
197 onToday: this.onToday,
198 onOpenTimePicker: this.openTimePicker,
199 onCloseTimePicker: this.closeTimePicker
200 })
201 )
202 ));
203
204 return this.renderRoot({
205 children: children,
206 className: props.showWeekNumber ? prefixCls + '-week-number' : ''
207 });
208 };
209
210 return Calendar;
211}(React.Component);
212
213Calendar.propTypes = _extends({}, calendarMixinPropTypes, propType, {
214 prefixCls: PropTypes.string,
215 className: PropTypes.string,
216 style: PropTypes.object,
217 defaultValue: PropTypes.object,
218 value: PropTypes.object,
219 selectedValue: PropTypes.object,
220 defaultSelectedValue: PropTypes.object,
221 mode: PropTypes.oneOf(['time', 'date', 'month', 'year', 'decade']),
222 locale: PropTypes.object,
223 showDateInput: PropTypes.bool,
224 showWeekNumber: PropTypes.bool,
225 showToday: PropTypes.bool,
226 showOk: PropTypes.bool,
227 onSelect: PropTypes.func,
228 onOk: PropTypes.func,
229 onKeyDown: PropTypes.func,
230 timePicker: PropTypes.element,
231 dateInputPlaceholder: PropTypes.any,
232 onClear: PropTypes.func,
233 onChange: PropTypes.func,
234 onPanelChange: PropTypes.func,
235 disabledDate: PropTypes.func,
236 disabledTime: PropTypes.any,
237 dateRender: PropTypes.func,
238 renderFooter: PropTypes.func,
239 renderSidebar: PropTypes.func,
240 clearIcon: PropTypes.node,
241 focusablePanel: PropTypes.bool,
242 inputMode: PropTypes.string,
243 onBlur: PropTypes.func
244});
245Calendar.defaultProps = _extends({}, calendarMixinDefaultProps, defaultProp, {
246 showToday: true,
247 showDateInput: true,
248 timePicker: null,
249 onOk: noop,
250 onPanelChange: noop,
251 focusablePanel: true
252});
253
254var _initialiseProps = function _initialiseProps() {
255 var _this2 = this;
256
257 this.onPanelChange = function (value, mode) {
258 var props = _this2.props,
259 state = _this2.state;
260
261 if (!('mode' in props)) {
262 _this2.setState({ mode: mode });
263 }
264 props.onPanelChange(value || state.value, mode);
265 };
266
267 this.onKeyDown = function (event) {
268 if (event.target.nodeName.toLowerCase() === 'input') {
269 return undefined;
270 }
271 var keyCode = event.keyCode;
272 // mac
273 var ctrlKey = event.ctrlKey || event.metaKey;
274 var disabledDate = _this2.props.disabledDate;
275 var value = _this2.state.value;
276
277 switch (keyCode) {
278 case KeyCode.DOWN:
279 _this2.goTime(1, 'weeks');
280 event.preventDefault();
281 return 1;
282 case KeyCode.UP:
283 _this2.goTime(-1, 'weeks');
284 event.preventDefault();
285 return 1;
286 case KeyCode.LEFT:
287 if (ctrlKey) {
288 _this2.goTime(-1, 'years');
289 } else {
290 _this2.goTime(-1, 'days');
291 }
292 event.preventDefault();
293 return 1;
294 case KeyCode.RIGHT:
295 if (ctrlKey) {
296 _this2.goTime(1, 'years');
297 } else {
298 _this2.goTime(1, 'days');
299 }
300 event.preventDefault();
301 return 1;
302 case KeyCode.HOME:
303 _this2.setValue(goStartMonth(_this2.state.value));
304 event.preventDefault();
305 return 1;
306 case KeyCode.END:
307 _this2.setValue(goEndMonth(_this2.state.value));
308 event.preventDefault();
309 return 1;
310 case KeyCode.PAGE_DOWN:
311 _this2.goTime(1, 'month');
312 event.preventDefault();
313 return 1;
314 case KeyCode.PAGE_UP:
315 _this2.goTime(-1, 'month');
316 event.preventDefault();
317 return 1;
318 case KeyCode.ENTER:
319 if (!disabledDate || !disabledDate(value)) {
320 _this2.onSelect(value, {
321 source: 'keyboard'
322 });
323 }
324 event.preventDefault();
325 return 1;
326 default:
327 _this2.props.onKeyDown(event);
328 return 1;
329 }
330 };
331
332 this.onClear = function () {
333 _this2.onSelect(null);
334 _this2.props.onClear();
335 };
336
337 this.onOk = function () {
338 var selectedValue = _this2.state.selectedValue;
339
340 if (_this2.isAllowedDate(selectedValue)) {
341 _this2.props.onOk(selectedValue);
342 }
343 };
344
345 this.onDateInputChange = function (value) {
346 _this2.onSelect(value, {
347 source: 'dateInput'
348 });
349 };
350
351 this.onDateInputSelect = function (value) {
352 _this2.onSelect(value, {
353 source: 'dateInputSelect'
354 });
355 };
356
357 this.onDateTableSelect = function (value) {
358 var timePicker = _this2.props.timePicker;
359 var selectedValue = _this2.state.selectedValue;
360
361 if (!selectedValue && timePicker) {
362 var timePickerDefaultValue = timePicker.props.defaultValue;
363 if (timePickerDefaultValue) {
364 syncTime(timePickerDefaultValue, value);
365 }
366 }
367 _this2.onSelect(value);
368 };
369
370 this.onToday = function () {
371 var value = _this2.state.value;
372
373 var now = getTodayTime(value);
374 _this2.onSelect(now, {
375 source: 'todayButton'
376 });
377 };
378
379 this.onBlur = function (event) {
380 setTimeout(function () {
381 var dateInput = DateInput.getInstance();
382 var rootInstance = _this2.rootInstance;
383
384 if (!rootInstance || rootInstance.contains(document.activeElement) || dateInput && dateInput.contains(document.activeElement)) {
385 // focused element is still part of Calendar
386 return;
387 }
388
389 if (_this2.props.onBlur) {
390 _this2.props.onBlur(event);
391 }
392 }, 0);
393 };
394
395 this.getRootDOMNode = function () {
396 return ReactDOM.findDOMNode(_this2);
397 };
398
399 this.openTimePicker = function () {
400 _this2.onPanelChange(null, 'time');
401 };
402
403 this.closeTimePicker = function () {
404 _this2.onPanelChange(null, 'date');
405 };
406
407 this.goTime = function (direction, unit) {
408 _this2.setValue(goTime(_this2.state.value, direction, unit));
409 };
410};
411
412polyfill(Calendar);
413
414export default calendarMixinWrapper(commonMixinWrapper(Calendar));
\No newline at end of file