UNPKG

6.87 kBJavaScriptView Raw
1import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
2import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
3import _inherits from 'babel-runtime/helpers/inherits';
4import React from 'react';
5import ReactDOM from 'react-dom';
6import PropTypes from 'prop-types';
7import { polyfill } from 'react-lifecycles-compat';
8import createChainedFunction from 'rc-util/es/createChainedFunction';
9import KeyCode from 'rc-util/es/KeyCode';
10import placements from './picker/placements';
11import Trigger from 'rc-trigger';
12
13function noop() {}
14
15function refFn(field, component) {
16 this[field] = component;
17}
18
19var Picker = function (_React$Component) {
20 _inherits(Picker, _React$Component);
21
22 function Picker(props) {
23 _classCallCheck(this, Picker);
24
25 var _this = _possibleConstructorReturn(this, _React$Component.call(this, props));
26
27 _initialiseProps.call(_this);
28
29 var open = void 0;
30 if ('open' in props) {
31 open = props.open;
32 } else {
33 open = props.defaultOpen;
34 }
35 var value = props.value || props.defaultValue;
36 _this.saveCalendarRef = refFn.bind(_this, 'calendarInstance');
37
38 _this.state = {
39 open: open,
40 value: value
41 };
42 return _this;
43 }
44
45 Picker.prototype.componentDidUpdate = function componentDidUpdate(_, prevState) {
46 if (!prevState.open && this.state.open) {
47 // setTimeout is for making sure saveCalendarRef happen before focusCalendar
48 this.focusTimeout = setTimeout(this.focusCalendar, 0, this);
49 }
50 };
51
52 Picker.prototype.componentWillUnmount = function componentWillUnmount() {
53 clearTimeout(this.focusTimeout);
54 };
55
56 Picker.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps) {
57 var newState = {};
58 var value = nextProps.value,
59 open = nextProps.open;
60
61 if ('value' in nextProps) {
62 newState.value = value;
63 }
64 if (open !== undefined) {
65 newState.open = open;
66 }
67 return newState;
68 };
69
70 Picker.prototype.render = function render() {
71 var props = this.props;
72 var prefixCls = props.prefixCls,
73 placement = props.placement,
74 style = props.style,
75 getCalendarContainer = props.getCalendarContainer,
76 align = props.align,
77 animation = props.animation,
78 disabled = props.disabled,
79 dropdownClassName = props.dropdownClassName,
80 transitionName = props.transitionName,
81 children = props.children;
82
83 var state = this.state;
84 return React.createElement(
85 Trigger,
86 {
87 popup: this.getCalendarElement(),
88 popupAlign: align,
89 builtinPlacements: placements,
90 popupPlacement: placement,
91 action: disabled && !state.open ? [] : ['click'],
92 destroyPopupOnHide: true,
93 getPopupContainer: getCalendarContainer,
94 popupStyle: style,
95 popupAnimation: animation,
96 popupTransitionName: transitionName,
97 popupVisible: state.open,
98 onPopupVisibleChange: this.onVisibleChange,
99 prefixCls: prefixCls,
100 popupClassName: dropdownClassName
101 },
102 React.cloneElement(children(state, props), { onKeyDown: this.onKeyDown })
103 );
104 };
105
106 return Picker;
107}(React.Component);
108
109Picker.propTypes = {
110 animation: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
111 disabled: PropTypes.bool,
112 transitionName: PropTypes.string,
113 onChange: PropTypes.func,
114 onOpenChange: PropTypes.func,
115 children: PropTypes.func,
116 getCalendarContainer: PropTypes.func,
117 calendar: PropTypes.element,
118 style: PropTypes.object,
119 open: PropTypes.bool,
120 defaultOpen: PropTypes.bool,
121 prefixCls: PropTypes.string,
122 placement: PropTypes.any,
123 value: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
124 defaultValue: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
125 align: PropTypes.object,
126 onBlur: PropTypes.func
127};
128Picker.defaultProps = {
129 prefixCls: 'rc-calendar-picker',
130 style: {},
131 align: {},
132 placement: 'bottomLeft',
133 defaultOpen: false,
134 onChange: noop,
135 onOpenChange: noop,
136 onBlur: noop
137};
138
139var _initialiseProps = function _initialiseProps() {
140 var _this2 = this;
141
142 this.onCalendarKeyDown = function (event) {
143 if (event.keyCode === KeyCode.ESC) {
144 event.stopPropagation();
145 _this2.close(_this2.focus);
146 }
147 };
148
149 this.onCalendarSelect = function (value) {
150 var cause = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
151
152 var props = _this2.props;
153 if (!('value' in props)) {
154 _this2.setState({
155 value: value
156 });
157 }
158 if (cause.source === 'keyboard' || cause.source === 'dateInputSelect' || !props.calendar.props.timePicker && cause.source !== 'dateInput' || cause.source === 'todayButton') {
159 _this2.close(_this2.focus);
160 }
161 props.onChange(value);
162 };
163
164 this.onKeyDown = function (event) {
165 if (!_this2.state.open && (event.keyCode === KeyCode.DOWN || event.keyCode === KeyCode.ENTER)) {
166 _this2.open();
167 event.preventDefault();
168 }
169 };
170
171 this.onCalendarOk = function () {
172 _this2.close(_this2.focus);
173 };
174
175 this.onCalendarClear = function () {
176 _this2.close(_this2.focus);
177 };
178
179 this.onCalendarBlur = function () {
180 _this2.setOpen(false);
181 };
182
183 this.onVisibleChange = function (open) {
184 _this2.setOpen(open);
185 };
186
187 this.getCalendarElement = function () {
188 var props = _this2.props;
189 var state = _this2.state;
190 var calendarProps = props.calendar.props;
191 var value = state.value;
192
193 var defaultValue = value;
194 var extraProps = {
195 ref: _this2.saveCalendarRef,
196 defaultValue: defaultValue || calendarProps.defaultValue,
197 selectedValue: value,
198 onKeyDown: _this2.onCalendarKeyDown,
199 onOk: createChainedFunction(calendarProps.onOk, _this2.onCalendarOk),
200 onSelect: createChainedFunction(calendarProps.onSelect, _this2.onCalendarSelect),
201 onClear: createChainedFunction(calendarProps.onClear, _this2.onCalendarClear),
202 onBlur: createChainedFunction(calendarProps.onBlur, _this2.onCalendarBlur)
203 };
204
205 return React.cloneElement(props.calendar, extraProps);
206 };
207
208 this.setOpen = function (open, callback) {
209 var onOpenChange = _this2.props.onOpenChange;
210
211 if (_this2.state.open !== open) {
212 if (!('open' in _this2.props)) {
213 _this2.setState({
214 open: open
215 }, callback);
216 }
217 onOpenChange(open);
218 }
219 };
220
221 this.open = function (callback) {
222 _this2.setOpen(true, callback);
223 };
224
225 this.close = function (callback) {
226 _this2.setOpen(false, callback);
227 };
228
229 this.focus = function () {
230 if (!_this2.state.open) {
231 ReactDOM.findDOMNode(_this2).focus();
232 }
233 };
234
235 this.focusCalendar = function () {
236 if (_this2.state.open && !!_this2.calendarInstance) {
237 _this2.calendarInstance.focus();
238 }
239 };
240};
241
242polyfill(Picker);
243
244export default Picker;
\No newline at end of file