1 | import _extends from 'babel-runtime/helpers/extends';
|
2 | import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
|
3 | import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
|
4 | import _inherits from 'babel-runtime/helpers/inherits';
|
5 |
|
6 | var _class, _temp;
|
7 |
|
8 | import React from 'react';
|
9 | import PropTypes from 'prop-types';
|
10 | import classNames from 'classnames';
|
11 | import { polyfill } from 'react-lifecycles-compat';
|
12 |
|
13 | import { func, obj, KEYCODE } from '../util';
|
14 | import Input from '../input';
|
15 | import Base from './base';
|
16 |
|
17 | var bindCtx = func.bindCtx,
|
18 | noop = func.noop;
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 | var AutoComplete = (_temp = _class = function (_Base) {
|
25 | _inherits(AutoComplete, _Base);
|
26 |
|
27 | function AutoComplete(props) {
|
28 | _classCallCheck(this, AutoComplete);
|
29 |
|
30 | var _this = _possibleConstructorReturn(this, _Base.call(this, props));
|
31 |
|
32 | _this.handleChange = function (value, proxy, item) {
|
33 | var _this$props = _this.props,
|
34 | disabled = _this$props.disabled,
|
35 | readOnly = _this$props.readOnly,
|
36 | filterLocal = _this$props.filterLocal;
|
37 |
|
38 |
|
39 | if (disabled || readOnly) {
|
40 | return false;
|
41 | }
|
42 |
|
43 | var actionType = typeof proxy === 'string' ? proxy : 'change';
|
44 |
|
45 | _this.isInputing = actionType === 'change';
|
46 |
|
47 | if (filterLocal) {
|
48 | _this.setState({
|
49 | dataSource: _this.dataStore.updateByKey(value)
|
50 | });
|
51 |
|
52 | _this.shouldControlPopup(_this.props, actionType);
|
53 | _this.setFirstHightLightKeyForMenu(value);
|
54 | }
|
55 |
|
56 |
|
57 | if (!('value' in _this.props)) {
|
58 | _this.setState({
|
59 | value: value
|
60 | });
|
61 | }
|
62 |
|
63 |
|
64 | if (!_this.props.autoHighlightFirstItem) {
|
65 | _this.setState({
|
66 | highlightKey: value
|
67 | });
|
68 | }
|
69 |
|
70 | _this.props.onChange(value, actionType, item);
|
71 |
|
72 | if (actionType === 'itemClick' || actionType === 'enter') {
|
73 |
|
74 | _this.setVisible(false, actionType);
|
75 | }
|
76 | };
|
77 |
|
78 | _this.isAutoComplete = true;
|
79 | _this.isInputing = false;
|
80 |
|
81 | _this.dataStore.setOptions({ key: _this.state.value });
|
82 | _extends(_this.state, {
|
83 | dataSource: _this.setDataSource(props)
|
84 | });
|
85 |
|
86 | bindCtx(_this, ['handleTriggerKeyDown', 'handleMenuSelect', 'handleItemClick']);
|
87 | return _this;
|
88 | }
|
89 |
|
90 | AutoComplete.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, prevState) {
|
91 | var state = {};
|
92 |
|
93 | if ('value' in nextProps && nextProps.value !== prevState.value) {
|
94 | _extends(state, {
|
95 | value: nextProps.value
|
96 | });
|
97 | }
|
98 |
|
99 | if ('visible' in nextProps && nextProps.visible !== prevState.visible) {
|
100 | _extends(state, {
|
101 | visible: nextProps.visible
|
102 | });
|
103 | }
|
104 |
|
105 | if (Object.keys(state).length) {
|
106 | return state;
|
107 | }
|
108 |
|
109 | return null;
|
110 | };
|
111 |
|
112 | AutoComplete.prototype.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {
|
113 | var props = this.props;
|
114 |
|
115 | if ('value' in props) {
|
116 | this.dataStore.setOptions({ key: props.value });
|
117 | }
|
118 |
|
119 | if (props.filter !== prevProps.filter) {
|
120 | this.dataStore.setOptions({
|
121 | filter: props.filter
|
122 | });
|
123 | }
|
124 | if (props.filterLocal !== prevProps.filterLocal) {
|
125 | this.dataStore.setOptions({
|
126 | filterLocal: props.filterLocal
|
127 | });
|
128 | }
|
129 |
|
130 | if (prevProps.children !== props.children || prevProps.dataSource !== props.dataSource) {
|
131 |
|
132 | this.setState({
|
133 | dataSource: this.setDataSource(props)
|
134 | });
|
135 |
|
136 |
|
137 |
|
138 | if (!props.filterLocal && this.isInputing) {
|
139 | this.shouldControlPopup(props, 'update');
|
140 | }
|
141 | if (!props.filterLocal && !props.popupContent) {
|
142 | this.setFirstHightLightKeyForMenu();
|
143 | }
|
144 | }
|
145 | };
|
146 |
|
147 | AutoComplete.prototype.shouldControlPopup = function shouldControlPopup() {
|
148 | var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props;
|
149 | var type = arguments[1];
|
150 |
|
151 | var hasPopup = props.popupContent || this.dataStore.getMenuDS().length;
|
152 | if (hasPopup) {
|
153 | this.setVisible(true, type);
|
154 | } else {
|
155 | this.setVisible(false, type);
|
156 | }
|
157 | };
|
158 |
|
159 | AutoComplete.prototype.handleMenuSelect = function handleMenuSelect(keys) {
|
160 | var key = keys[0];
|
161 |
|
162 | var mapDS = this.dataStore.getMapDS();
|
163 |
|
164 | if (key in mapDS) {
|
165 | var item = mapDS[key];
|
166 | this.handleSelectEvent(key, item, 'itemClick');
|
167 | }
|
168 | };
|
169 |
|
170 | AutoComplete.prototype.handleItemClick = function handleItemClick() {
|
171 | this.setVisible(false, 'itemClick');
|
172 | };
|
173 |
|
174 | AutoComplete.prototype.handleSelectEvent = function handleSelectEvent(key, item, triggerType) {
|
175 | var value = item && item[this.props.fillProps] || key;
|
176 |
|
177 | if (triggerType === 'itemClick' || triggerType === 'enter') {
|
178 |
|
179 | this.setVisible(false, triggerType);
|
180 | }
|
181 |
|
182 | this.handleChange(value, triggerType, item);
|
183 | };
|
184 |
|
185 | AutoComplete.prototype.handleVisibleChange = function handleVisibleChange(visible, type) {
|
186 | if (!('visible' in this.props) && visible && !this.props.popupContent && !this.dataStore.getMenuDS().length) {
|
187 | return;
|
188 | }
|
189 |
|
190 | this.setVisible(visible, type);
|
191 | };
|
192 |
|
193 | AutoComplete.prototype.beforeClose = function beforeClose() {
|
194 | this.isInputing = false;
|
195 | };
|
196 |
|
197 | |
198 |
|
199 |
|
200 |
|
201 |
|
202 |
|
203 | AutoComplete.prototype.handleTriggerKeyDown = function handleTriggerKeyDown(e) {
|
204 | var _props = this.props,
|
205 | popupContent = _props.popupContent,
|
206 | onToggleHighlightItem = _props.onToggleHighlightItem,
|
207 | onKeyDown = _props.onKeyDown;
|
208 |
|
209 | if (popupContent) {
|
210 | e.stopPropagation();
|
211 | return onKeyDown(e);
|
212 | }
|
213 |
|
214 | switch (e.keyCode) {
|
215 | case KEYCODE.UP:
|
216 | e.preventDefault();
|
217 | onToggleHighlightItem(this.toggleHighlightItem(-1, e), 'up');
|
218 | break;
|
219 | case KEYCODE.DOWN:
|
220 | e.preventDefault();
|
221 | onToggleHighlightItem(this.toggleHighlightItem(1, e), 'down');
|
222 | break;
|
223 | case KEYCODE.ENTER:
|
224 | e.preventDefault();
|
225 | this.chooseHighlightItem(e);
|
226 | break;
|
227 | case KEYCODE.SPACE:
|
228 |
|
229 | e.stopPropagation();
|
230 | break;
|
231 | case KEYCODE.ESC:
|
232 | e.preventDefault();
|
233 | this.state.visible && this.setVisible(false, 'esc');
|
234 | break;
|
235 | default:
|
236 | break;
|
237 | }
|
238 |
|
239 | onKeyDown(e);
|
240 | };
|
241 |
|
242 |
|
243 |
|
244 |
|
245 | AutoComplete.prototype.chooseHighlightItem = function chooseHighlightItem() {
|
246 | if (!this.state.visible) {
|
247 | return false;
|
248 | }
|
249 |
|
250 | var highlightKey = this.state.highlightKey;
|
251 |
|
252 | var highlightItem = this.dataStore.getEnableDS().find(function (item) {
|
253 | return highlightKey === '' + item.value;
|
254 | });
|
255 |
|
256 | if (highlightItem) {
|
257 | this.handleSelectEvent(highlightKey, highlightItem, 'enter');
|
258 | }
|
259 | };
|
260 |
|
261 | AutoComplete.prototype.hasClear = function hasClear() {
|
262 | var _props2 = this.props,
|
263 | hasClear = _props2.hasClear,
|
264 | readOnly = _props2.readOnly,
|
265 | disabled = _props2.disabled;
|
266 | var value = this.state.value;
|
267 |
|
268 |
|
269 | return value && hasClear && !readOnly && !disabled;
|
270 | };
|
271 |
|
272 | |
273 |
|
274 |
|
275 |
|
276 |
|
277 |
|
278 |
|
279 | AutoComplete.prototype.renderSelect = function renderSelect() {
|
280 | var _classNames;
|
281 |
|
282 | var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props;
|
283 | var placeholder = props.placeholder,
|
284 | size = props.size,
|
285 | prefix = props.prefix,
|
286 | className = props.className,
|
287 | style = props.style,
|
288 | label = props.label,
|
289 | readOnly = props.readOnly,
|
290 | disabled = props.disabled,
|
291 | highlightHolder = props.highlightHolder,
|
292 | locale = props.locale,
|
293 | hasClear = props.hasClear,
|
294 | state = props.state,
|
295 | rtl = props.rtl;
|
296 |
|
297 | var others = obj.pickOthers(AutoComplete.propTypes, props);
|
298 | var othersData = obj.pickAttrsWith(others, 'data-');
|
299 |
|
300 | var value = this.state.value;
|
301 | var visible = this.state.visible;
|
302 |
|
303 |
|
304 |
|
305 |
|
306 |
|
307 |
|
308 |
|
309 |
|
310 | var triggerClazz = classNames([prefix + 'select', prefix + 'select-auto-complete', prefix + 'size-' + size, className], (_classNames = {}, _classNames[prefix + 'active'] = visible, _classNames[prefix + 'disabled'] = disabled, _classNames));
|
311 |
|
312 |
|
313 |
|
314 | var _placeholder = placeholder || locale.autoCompletePlaceholder || locale.autoCompletePlaceHolder;
|
315 | if (highlightHolder && visible) {
|
316 | _placeholder = this.state.highlightKey || _placeholder;
|
317 | }
|
318 |
|
319 |
|
320 | var _inputProps = _extends({}, obj.pickOthers(othersData, others), {
|
321 | state: state,
|
322 | ref: this.saveInputRef,
|
323 | hasClear: hasClear,
|
324 | value: value,
|
325 | size: size,
|
326 | disabled: disabled,
|
327 | readOnly: readOnly,
|
328 | placeholder: _placeholder,
|
329 | label: label,
|
330 |
|
331 | onChange: this.handleChange,
|
332 | onKeyDown: this.handleTriggerKeyDown
|
333 | });
|
334 |
|
335 | return React.createElement(
|
336 | 'span',
|
337 | _extends({}, othersData, {
|
338 | className: triggerClazz,
|
339 | style: style,
|
340 | dir: rtl ? 'rtl' : undefined,
|
341 | ref: this.saveSelectRef,
|
342 | onClick: this.focusInput
|
343 | }),
|
344 | React.createElement(Input, _extends({
|
345 | role: 'combobox',
|
346 | 'aria-autocomplete': 'list',
|
347 | 'aria-disabled': disabled,
|
348 | 'aria-expanded': this.state.visible
|
349 | }, _inputProps)),
|
350 | React.createElement(
|
351 | 'span',
|
352 | { className: prefix + 'sr-only', 'aria-live': 'polite' },
|
353 | this.state.srReader
|
354 | )
|
355 | );
|
356 | };
|
357 |
|
358 | AutoComplete.prototype.render = function render() {
|
359 | var _this2 = this;
|
360 |
|
361 | if (this.hasClear()) {
|
362 |
|
363 | var safeNode = this.props.popupProps.safeNode || [];
|
364 | var safeNodes = Array.isArray(safeNode) ? safeNode : [safeNode];
|
365 | safeNodes.push(function () {
|
366 | return _this2.clearNode;
|
367 | });
|
368 | this.props.popupProps.safeNode = safeNodes;
|
369 | }
|
370 |
|
371 | return _Base.prototype.render.call(this, _extends({}, this.props, { canCloseByTrigger: false }));
|
372 | };
|
373 |
|
374 | return AutoComplete;
|
375 | }(Base), _class.propTypes = _extends({}, Base.propTypes, {
|
376 | |
377 |
|
378 |
|
379 | value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
380 | |
381 |
|
382 |
|
383 | defaultValue: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
384 | |
385 |
|
386 |
|
387 |
|
388 |
|
389 |
|
390 | onChange: PropTypes.func,
|
391 | |
392 |
|
393 |
|
394 | dataSource: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.shape({
|
395 | value: PropTypes.string,
|
396 | label: PropTypes.any,
|
397 | disabled: PropTypes.bool,
|
398 | children: PropTypes.array
|
399 | }), PropTypes.string])),
|
400 | |
401 |
|
402 |
|
403 | fillProps: PropTypes.string,
|
404 | |
405 |
|
406 |
|
407 |
|
408 |
|
409 | itemRender: PropTypes.func,
|
410 |
|
411 | onKeyDown: PropTypes.func,
|
412 |
|
413 | highlightHolder: PropTypes.bool,
|
414 | style: PropTypes.object
|
415 | }), _class.defaultProps = _extends({}, Base.defaultProps, {
|
416 | onKeyDown: noop,
|
417 | fillProps: 'value'
|
418 | }), _temp);
|
419 |
|
420 |
|
421 | export default polyfill(AutoComplete); |
\ | No newline at end of file |