import _extends from 'babel-runtime/helpers/extends'; import _classCallCheck from 'babel-runtime/helpers/classCallCheck'; import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn'; import _inherits from 'babel-runtime/helpers/inherits'; import React from 'react'; import ReactDOM from 'react-dom'; import PropTypes from 'prop-types'; import KeyCode from 'rc-util/es/KeyCode'; import { polyfill } from 'react-lifecycles-compat'; import DateTable from './date/DateTable'; import CalendarHeader from './calendar/CalendarHeader'; import CalendarFooter from './calendar/CalendarFooter'; import { calendarMixinWrapper, calendarMixinPropTypes, calendarMixinDefaultProps, getNowByCurrentStateValue } from './mixin/CalendarMixin'; import { commonMixinWrapper, propType, defaultProp } from './mixin/CommonMixin'; import DateInput from './date/DateInput'; import { getTimeConfig, getTodayTime, syncTime } from './util'; import { goStartMonth, goEndMonth, goTime } from './util/toTime'; import moment from 'moment'; function noop() {} var getMomentObjectIfValid = function getMomentObjectIfValid(date) { if (moment.isMoment(date) && date.isValid()) { return date; } return false; }; var Calendar = function (_React$Component) { _inherits(Calendar, _React$Component); function Calendar(props) { _classCallCheck(this, Calendar); var _this = _possibleConstructorReturn(this, _React$Component.call(this, props)); _initialiseProps.call(_this); _this.state = { mode: _this.props.mode || 'date', value: getMomentObjectIfValid(props.value) || getMomentObjectIfValid(props.defaultValue) || moment(), selectedValue: props.selectedValue || props.defaultSelectedValue }; return _this; } Calendar.prototype.componentDidMount = function componentDidMount() { if (this.props.showDateInput) { this.saveFocusElement(DateInput.getInstance()); } }; Calendar.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, state) { var value = nextProps.value, selectedValue = nextProps.selectedValue; var newState = {}; if ('mode' in nextProps && state.mode !== nextProps.mode) { newState = { mode: nextProps.mode }; } if ('value' in nextProps) { newState.value = getMomentObjectIfValid(value) || getMomentObjectIfValid(nextProps.defaultValue) || getNowByCurrentStateValue(state.value); } if ('selectedValue' in nextProps) { newState.selectedValue = selectedValue; } return newState; }; Calendar.prototype.render = function render() { var props = this.props, state = this.state; var locale = props.locale, prefixCls = props.prefixCls, disabledDate = props.disabledDate, dateInputPlaceholder = props.dateInputPlaceholder, timePicker = props.timePicker, disabledTime = props.disabledTime, clearIcon = props.clearIcon, renderFooter = props.renderFooter, inputMode = props.inputMode, monthCellRender = props.monthCellRender, monthCellContentRender = props.monthCellContentRender; var value = state.value, selectedValue = state.selectedValue, mode = state.mode; var showTimePicker = mode === 'time'; var disabledTimeConfig = showTimePicker && disabledTime && timePicker ? getTimeConfig(selectedValue, disabledTime) : null; var timePickerEle = null; if (timePicker && showTimePicker) { var timePickerProps = _extends({ showHour: true, showSecond: true, showMinute: true }, timePicker.props, disabledTimeConfig, { onChange: this.onDateInputChange, value: selectedValue, disabledTime: disabledTime }); if (timePicker.props.defaultValue !== undefined) { timePickerProps.defaultOpenValue = timePicker.props.defaultValue; } timePickerEle = React.cloneElement(timePicker, timePickerProps); } var dateInputElement = props.showDateInput ? React.createElement(DateInput, { format: this.getFormat(), key: 'date-input', value: value, locale: locale, placeholder: dateInputPlaceholder, showClear: true, disabledTime: disabledTime, disabledDate: disabledDate, onClear: this.onClear, prefixCls: prefixCls, selectedValue: selectedValue, onChange: this.onDateInputChange, onSelect: this.onDateInputSelect, clearIcon: clearIcon, inputMode: inputMode }) : null; var children = []; if (props.renderSidebar) { children.push(props.renderSidebar()); } children.push(React.createElement( 'div', { className: prefixCls + '-panel', key: 'panel' }, dateInputElement, React.createElement( 'div', { tabIndex: this.props.focusablePanel ? 0 : undefined, className: prefixCls + '-date-panel' }, React.createElement(CalendarHeader, { locale: locale, mode: mode, value: value, onValueChange: this.setValue, onPanelChange: this.onPanelChange, renderFooter: renderFooter, showTimePicker: showTimePicker, prefixCls: prefixCls, monthCellRender: monthCellRender, monthCellContentRender: monthCellContentRender }), timePicker && showTimePicker ? React.createElement( 'div', { className: prefixCls + '-time-picker' }, React.createElement( 'div', { className: prefixCls + '-time-picker-panel' }, timePickerEle ) ) : null, React.createElement( 'div', { className: prefixCls + '-body' }, React.createElement(DateTable, { locale: locale, value: value, selectedValue: selectedValue, prefixCls: prefixCls, dateRender: props.dateRender, onSelect: this.onDateTableSelect, disabledDate: disabledDate, showWeekNumber: props.showWeekNumber }) ), React.createElement(CalendarFooter, { showOk: props.showOk, mode: mode, renderFooter: props.renderFooter, locale: locale, prefixCls: prefixCls, showToday: props.showToday, disabledTime: disabledTime, showTimePicker: showTimePicker, showDateInput: props.showDateInput, timePicker: timePicker, selectedValue: selectedValue, timePickerDisabled: !selectedValue, value: value, disabledDate: disabledDate, okDisabled: props.showOk !== false && (!selectedValue || !this.isAllowedDate(selectedValue)), onOk: this.onOk, onSelect: this.onSelect, onToday: this.onToday, onOpenTimePicker: this.openTimePicker, onCloseTimePicker: this.closeTimePicker }) ) )); return this.renderRoot({ children: children, className: props.showWeekNumber ? prefixCls + '-week-number' : '' }); }; return Calendar; }(React.Component); Calendar.propTypes = _extends({}, calendarMixinPropTypes, propType, { prefixCls: PropTypes.string, className: PropTypes.string, style: PropTypes.object, defaultValue: PropTypes.object, value: PropTypes.object, selectedValue: PropTypes.object, defaultSelectedValue: PropTypes.object, mode: PropTypes.oneOf(['time', 'date', 'month', 'year', 'decade']), locale: PropTypes.object, showDateInput: PropTypes.bool, showWeekNumber: PropTypes.bool, showToday: PropTypes.bool, showOk: PropTypes.bool, onSelect: PropTypes.func, onOk: PropTypes.func, onKeyDown: PropTypes.func, timePicker: PropTypes.element, dateInputPlaceholder: PropTypes.any, onClear: PropTypes.func, onChange: PropTypes.func, onPanelChange: PropTypes.func, disabledDate: PropTypes.func, disabledTime: PropTypes.any, dateRender: PropTypes.func, renderFooter: PropTypes.func, renderSidebar: PropTypes.func, clearIcon: PropTypes.node, focusablePanel: PropTypes.bool, inputMode: PropTypes.string, onBlur: PropTypes.func }); Calendar.defaultProps = _extends({}, calendarMixinDefaultProps, defaultProp, { showToday: true, showDateInput: true, timePicker: null, onOk: noop, onPanelChange: noop, focusablePanel: true }); var _initialiseProps = function _initialiseProps() { var _this2 = this; this.onPanelChange = function (value, mode) { var props = _this2.props, state = _this2.state; if (!('mode' in props)) { _this2.setState({ mode: mode }); } props.onPanelChange(value || state.value, mode); }; this.onKeyDown = function (event) { if (event.target.nodeName.toLowerCase() === 'input') { return undefined; } var keyCode = event.keyCode; // mac var ctrlKey = event.ctrlKey || event.metaKey; var disabledDate = _this2.props.disabledDate; var value = _this2.state.value; switch (keyCode) { case KeyCode.DOWN: _this2.goTime(1, 'weeks'); event.preventDefault(); return 1; case KeyCode.UP: _this2.goTime(-1, 'weeks'); event.preventDefault(); return 1; case KeyCode.LEFT: if (ctrlKey) { _this2.goTime(-1, 'years'); } else { _this2.goTime(-1, 'days'); } event.preventDefault(); return 1; case KeyCode.RIGHT: if (ctrlKey) { _this2.goTime(1, 'years'); } else { _this2.goTime(1, 'days'); } event.preventDefault(); return 1; case KeyCode.HOME: _this2.setValue(goStartMonth(_this2.state.value)); event.preventDefault(); return 1; case KeyCode.END: _this2.setValue(goEndMonth(_this2.state.value)); event.preventDefault(); return 1; case KeyCode.PAGE_DOWN: _this2.goTime(1, 'month'); event.preventDefault(); return 1; case KeyCode.PAGE_UP: _this2.goTime(-1, 'month'); event.preventDefault(); return 1; case KeyCode.ENTER: if (!disabledDate || !disabledDate(value)) { _this2.onSelect(value, { source: 'keyboard' }); } event.preventDefault(); return 1; default: _this2.props.onKeyDown(event); return 1; } }; this.onClear = function () { _this2.onSelect(null); _this2.props.onClear(); }; this.onOk = function () { var selectedValue = _this2.state.selectedValue; if (_this2.isAllowedDate(selectedValue)) { _this2.props.onOk(selectedValue); } }; this.onDateInputChange = function (value) { _this2.onSelect(value, { source: 'dateInput' }); }; this.onDateInputSelect = function (value) { _this2.onSelect(value, { source: 'dateInputSelect' }); }; this.onDateTableSelect = function (value) { var timePicker = _this2.props.timePicker; var selectedValue = _this2.state.selectedValue; if (!selectedValue && timePicker) { var timePickerDefaultValue = timePicker.props.defaultValue; if (timePickerDefaultValue) { syncTime(timePickerDefaultValue, value); } } _this2.onSelect(value); }; this.onToday = function () { var value = _this2.state.value; var now = getTodayTime(value); _this2.onSelect(now, { source: 'todayButton' }); }; this.onBlur = function (event) { setTimeout(function () { var dateInput = DateInput.getInstance(); var rootInstance = _this2.rootInstance; if (!rootInstance || rootInstance.contains(document.activeElement) || dateInput && dateInput.contains(document.activeElement)) { // focused element is still part of Calendar return; } if (_this2.props.onBlur) { _this2.props.onBlur(event); } }, 0); }; this.getRootDOMNode = function () { return ReactDOM.findDOMNode(_this2); }; this.openTimePicker = function () { _this2.onPanelChange(null, 'time'); }; this.closeTimePicker = function () { _this2.onPanelChange(null, 'date'); }; this.goTime = function (direction, unit) { _this2.setValue(goTime(_this2.state.value, direction, unit)); }; }; polyfill(Calendar); export default calendarMixinWrapper(commonMixinWrapper(Calendar));