UNPKG

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