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 { polyfill } from 'react-lifecycles-compat'; import createChainedFunction from 'rc-util/es/createChainedFunction'; import KeyCode from 'rc-util/es/KeyCode'; import placements from './picker/placements'; import Trigger from 'rc-trigger'; function noop() {} function refFn(field, component) { this[field] = component; } var Picker = function (_React$Component) { _inherits(Picker, _React$Component); function Picker(props) { _classCallCheck(this, Picker); var _this = _possibleConstructorReturn(this, _React$Component.call(this, props)); _initialiseProps.call(_this); var open = void 0; if ('open' in props) { open = props.open; } else { open = props.defaultOpen; } var value = props.value || props.defaultValue; _this.saveCalendarRef = refFn.bind(_this, 'calendarInstance'); _this.state = { open: open, value: value }; return _this; } Picker.prototype.componentDidUpdate = function componentDidUpdate(_, prevState) { if (!prevState.open && this.state.open) { // setTimeout is for making sure saveCalendarRef happen before focusCalendar this.focusTimeout = setTimeout(this.focusCalendar, 0, this); } }; Picker.prototype.componentWillUnmount = function componentWillUnmount() { clearTimeout(this.focusTimeout); }; Picker.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps) { var newState = {}; var value = nextProps.value, open = nextProps.open; if ('value' in nextProps) { newState.value = value; } if (open !== undefined) { newState.open = open; } return newState; }; Picker.prototype.render = function render() { var props = this.props; var prefixCls = props.prefixCls, placement = props.placement, style = props.style, getCalendarContainer = props.getCalendarContainer, align = props.align, animation = props.animation, disabled = props.disabled, dropdownClassName = props.dropdownClassName, transitionName = props.transitionName, children = props.children; var state = this.state; return React.createElement( Trigger, { popup: this.getCalendarElement(), popupAlign: align, builtinPlacements: placements, popupPlacement: placement, action: disabled && !state.open ? [] : ['click'], destroyPopupOnHide: true, getPopupContainer: getCalendarContainer, popupStyle: style, popupAnimation: animation, popupTransitionName: transitionName, popupVisible: state.open, onPopupVisibleChange: this.onVisibleChange, prefixCls: prefixCls, popupClassName: dropdownClassName }, React.cloneElement(children(state, props), { onKeyDown: this.onKeyDown }) ); }; return Picker; }(React.Component); Picker.propTypes = { animation: PropTypes.oneOfType([PropTypes.func, PropTypes.string]), disabled: PropTypes.bool, transitionName: PropTypes.string, onChange: PropTypes.func, onOpenChange: PropTypes.func, children: PropTypes.func, getCalendarContainer: PropTypes.func, calendar: PropTypes.element, style: PropTypes.object, open: PropTypes.bool, defaultOpen: PropTypes.bool, prefixCls: PropTypes.string, placement: PropTypes.any, value: PropTypes.oneOfType([PropTypes.object, PropTypes.array]), defaultValue: PropTypes.oneOfType([PropTypes.object, PropTypes.array]), align: PropTypes.object, dateRender: PropTypes.func, onBlur: PropTypes.func }; Picker.defaultProps = { prefixCls: 'rc-calendar-picker', style: {}, align: {}, placement: 'bottomLeft', defaultOpen: false, onChange: noop, onOpenChange: noop, onBlur: noop }; var _initialiseProps = function _initialiseProps() { var _this2 = this; this.onCalendarKeyDown = function (event) { if (event.keyCode === KeyCode.ESC) { event.stopPropagation(); _this2.close(_this2.focus); } }; this.onCalendarSelect = function (value) { var cause = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var props = _this2.props; if (!('value' in props)) { _this2.setState({ value: value }); } if (cause.source === 'keyboard' || cause.source === 'dateInputSelect' || !props.calendar.props.timePicker && cause.source !== 'dateInput' || cause.source === 'todayButton') { _this2.close(_this2.focus); } props.onChange(value); }; this.onKeyDown = function (event) { if (!_this2.state.open && (event.keyCode === KeyCode.DOWN || event.keyCode === KeyCode.ENTER)) { _this2.open(); event.preventDefault(); } }; this.onCalendarOk = function () { _this2.close(_this2.focus); }; this.onCalendarClear = function () { _this2.close(_this2.focus); }; this.onCalendarBlur = function () { _this2.setOpen(false); }; this.onVisibleChange = function (open) { _this2.setOpen(open); }; this.getCalendarElement = function () { var props = _this2.props; var state = _this2.state; var calendarProps = props.calendar.props; var value = state.value; var defaultValue = value; var extraProps = { ref: _this2.saveCalendarRef, defaultValue: defaultValue || calendarProps.defaultValue, selectedValue: value, onKeyDown: _this2.onCalendarKeyDown, onOk: createChainedFunction(calendarProps.onOk, _this2.onCalendarOk), onSelect: createChainedFunction(calendarProps.onSelect, _this2.onCalendarSelect), onClear: createChainedFunction(calendarProps.onClear, _this2.onCalendarClear), onBlur: createChainedFunction(calendarProps.onBlur, _this2.onCalendarBlur) }; return React.cloneElement(props.calendar, extraProps); }; this.setOpen = function (open, callback) { var onOpenChange = _this2.props.onOpenChange; if (_this2.state.open !== open) { if (!('open' in _this2.props)) { _this2.setState({ open: open }, callback); } onOpenChange(open); } }; this.open = function (callback) { _this2.setOpen(true, callback); }; this.close = function (callback) { _this2.setOpen(false, callback); }; this.focus = function () { if (!_this2.state.open) { ReactDOM.findDOMNode(_this2).focus(); } }; this.focusCalendar = function () { if (_this2.state.open && !!_this2.calendarInstance) { _this2.calendarInstance.focus(); } }; }; polyfill(Picker); export default Picker;