UNPKG

6.9 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 dateRender: PropTypes.func,
127 onBlur: PropTypes.func
128};
129Picker.defaultProps = {
130 prefixCls: 'rc-calendar-picker',
131 style: {},
132 align: {},
133 placement: 'bottomLeft',
134 defaultOpen: false,
135 onChange: noop,
136 onOpenChange: noop,
137 onBlur: noop
138};
139
140var _initialiseProps = function _initialiseProps() {
141 var _this2 = this;
142
143 this.onCalendarKeyDown = function (event) {
144 if (event.keyCode === KeyCode.ESC) {
145 event.stopPropagation();
146 _this2.close(_this2.focus);
147 }
148 };
149
150 this.onCalendarSelect = function (value) {
151 var cause = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
152
153 var props = _this2.props;
154 if (!('value' in props)) {
155 _this2.setState({
156 value: value
157 });
158 }
159 if (cause.source === 'keyboard' || cause.source === 'dateInputSelect' || !props.calendar.props.timePicker && cause.source !== 'dateInput' || cause.source === 'todayButton') {
160 _this2.close(_this2.focus);
161 }
162 props.onChange(value);
163 };
164
165 this.onKeyDown = function (event) {
166 if (!_this2.state.open && (event.keyCode === KeyCode.DOWN || event.keyCode === KeyCode.ENTER)) {
167 _this2.open();
168 event.preventDefault();
169 }
170 };
171
172 this.onCalendarOk = function () {
173 _this2.close(_this2.focus);
174 };
175
176 this.onCalendarClear = function () {
177 _this2.close(_this2.focus);
178 };
179
180 this.onCalendarBlur = function () {
181 _this2.setOpen(false);
182 };
183
184 this.onVisibleChange = function (open) {
185 _this2.setOpen(open);
186 };
187
188 this.getCalendarElement = function () {
189 var props = _this2.props;
190 var state = _this2.state;
191 var calendarProps = props.calendar.props;
192 var value = state.value;
193
194 var defaultValue = value;
195 var extraProps = {
196 ref: _this2.saveCalendarRef,
197 defaultValue: defaultValue || calendarProps.defaultValue,
198 selectedValue: value,
199 onKeyDown: _this2.onCalendarKeyDown,
200 onOk: createChainedFunction(calendarProps.onOk, _this2.onCalendarOk),
201 onSelect: createChainedFunction(calendarProps.onSelect, _this2.onCalendarSelect),
202 onClear: createChainedFunction(calendarProps.onClear, _this2.onCalendarClear),
203 onBlur: createChainedFunction(calendarProps.onBlur, _this2.onCalendarBlur)
204 };
205
206 return React.cloneElement(props.calendar, extraProps);
207 };
208
209 this.setOpen = function (open, callback) {
210 var onOpenChange = _this2.props.onOpenChange;
211
212 if (_this2.state.open !== open) {
213 if (!('open' in _this2.props)) {
214 _this2.setState({
215 open: open
216 }, callback);
217 }
218 onOpenChange(open);
219 }
220 };
221
222 this.open = function (callback) {
223 _this2.setOpen(true, callback);
224 };
225
226 this.close = function (callback) {
227 _this2.setOpen(false, callback);
228 };
229
230 this.focus = function () {
231 if (!_this2.state.open) {
232 ReactDOM.findDOMNode(_this2).focus();
233 }
234 };
235
236 this.focusCalendar = function () {
237 if (_this2.state.open && !!_this2.calendarInstance) {
238 _this2.calendarInstance.focus();
239 }
240 };
241};
242
243polyfill(Picker);
244
245export default Picker;
\No newline at end of file