1 | import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose";
|
2 | import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
|
3 | import _inheritsLoose from "@babel/runtime/helpers/inheritsLoose";
|
4 | import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
5 | import _extends from "@babel/runtime/helpers/extends";
|
6 | import isEqual from 'fast-deep-equal';
|
7 | import PropTypes from 'prop-types';
|
8 | import React from 'react';
|
9 | import TypeaheadManager from './TypeaheadManager';
|
10 | import { caseSensitiveType, checkPropType, defaultInputValueType, defaultSelectedType, deprecated, highlightOnlyResultType, ignoreDiacriticsType, isRequiredForA11y, labelKeyType, optionType, selectedType } from '../propTypes';
|
11 | import { addCustomOption, defaultFilterBy, getOptionLabel, getStringLabelKey, getUpdatedActiveIndex, getTruncatedOptions, head, isShown, isString, noop, uniqueId, validateSelectedPropChange } from '../utils';
|
12 | import { DEFAULT_LABELKEY, DOWN, ESC, RETURN, TAB, UP } from '../constants';
|
13 | var propTypes = {
|
14 | |
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 | allowNew: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),
|
23 |
|
24 | |
25 |
|
26 |
|
27 | autoFocus: PropTypes.bool,
|
28 |
|
29 | |
30 |
|
31 |
|
32 | caseSensitive: checkPropType(PropTypes.bool, caseSensitiveType),
|
33 |
|
34 | |
35 |
|
36 |
|
37 | defaultInputValue: checkPropType(PropTypes.string, defaultInputValueType),
|
38 |
|
39 | |
40 |
|
41 |
|
42 | defaultOpen: PropTypes.bool,
|
43 |
|
44 | |
45 |
|
46 |
|
47 |
|
48 | defaultSelected: checkPropType(PropTypes.arrayOf(optionType), defaultSelectedType),
|
49 |
|
50 | |
51 |
|
52 |
|
53 |
|
54 | filterBy: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.string.isRequired), PropTypes.func]),
|
55 |
|
56 | |
57 |
|
58 |
|
59 |
|
60 | highlightOnlyResult: checkPropType(PropTypes.bool, highlightOnlyResultType),
|
61 |
|
62 | |
63 |
|
64 |
|
65 |
|
66 | id: checkPropType(PropTypes.oneOfType([PropTypes.number, PropTypes.string]), isRequiredForA11y),
|
67 |
|
68 | |
69 |
|
70 |
|
71 | ignoreDiacritics: checkPropType(PropTypes.bool, ignoreDiacriticsType),
|
72 |
|
73 | |
74 |
|
75 |
|
76 |
|
77 | labelKey: checkPropType(PropTypes.oneOfType([PropTypes.string, PropTypes.func]), labelKeyType),
|
78 |
|
79 | |
80 |
|
81 |
|
82 |
|
83 |
|
84 | maxResults: PropTypes.number,
|
85 |
|
86 | |
87 |
|
88 |
|
89 | minLength: PropTypes.number,
|
90 |
|
91 | |
92 |
|
93 |
|
94 | multiple: PropTypes.bool,
|
95 |
|
96 | |
97 |
|
98 |
|
99 | onBlur: PropTypes.func,
|
100 |
|
101 | |
102 |
|
103 |
|
104 |
|
105 | onChange: PropTypes.func,
|
106 |
|
107 | |
108 |
|
109 |
|
110 | onFocus: PropTypes.func,
|
111 |
|
112 | |
113 |
|
114 |
|
115 |
|
116 | onInputChange: PropTypes.func,
|
117 |
|
118 | |
119 |
|
120 |
|
121 | onKeyDown: PropTypes.func,
|
122 |
|
123 | |
124 |
|
125 |
|
126 | onMenuToggle: PropTypes.func,
|
127 |
|
128 | |
129 |
|
130 |
|
131 | onPaginate: PropTypes.func,
|
132 |
|
133 | |
134 |
|
135 |
|
136 |
|
137 |
|
138 | open: PropTypes.bool,
|
139 |
|
140 | |
141 |
|
142 |
|
143 |
|
144 | options: PropTypes.arrayOf(optionType).isRequired,
|
145 |
|
146 | |
147 |
|
148 |
|
149 |
|
150 | paginate: PropTypes.bool,
|
151 |
|
152 | |
153 |
|
154 |
|
155 |
|
156 | selected: checkPropType(PropTypes.arrayOf(optionType), selectedType),
|
157 |
|
158 | |
159 |
|
160 |
|
161 | selectHintOnEnter: deprecated(PropTypes.bool, 'Use the `shouldSelect` prop on the `Hint` component to define which ' + 'keystrokes can select the hint.')
|
162 | };
|
163 | var defaultProps = {
|
164 | allowNew: false,
|
165 | autoFocus: false,
|
166 | caseSensitive: false,
|
167 | defaultInputValue: '',
|
168 | defaultOpen: false,
|
169 | defaultSelected: [],
|
170 | filterBy: [],
|
171 | highlightOnlyResult: false,
|
172 | ignoreDiacritics: true,
|
173 | labelKey: DEFAULT_LABELKEY,
|
174 | maxResults: 100,
|
175 | minLength: 0,
|
176 | multiple: false,
|
177 | onBlur: noop,
|
178 | onFocus: noop,
|
179 | onInputChange: noop,
|
180 | onKeyDown: noop,
|
181 | onMenuToggle: noop,
|
182 | onPaginate: noop,
|
183 | paginate: true
|
184 | };
|
185 | export function getInitialState(props) {
|
186 | var defaultInputValue = props.defaultInputValue,
|
187 | defaultOpen = props.defaultOpen,
|
188 | defaultSelected = props.defaultSelected,
|
189 | maxResults = props.maxResults,
|
190 | multiple = props.multiple;
|
191 | var selected = props.selected ? props.selected.slice() : defaultSelected.slice();
|
192 | var text = defaultInputValue;
|
193 |
|
194 | if (!multiple && selected.length) {
|
195 |
|
196 | text = getOptionLabel(head(selected), props.labelKey);
|
197 |
|
198 | if (selected.length > 1) {
|
199 |
|
200 | selected = selected.slice(0, 1);
|
201 | }
|
202 | }
|
203 |
|
204 | return {
|
205 | activeIndex: -1,
|
206 | activeItem: null,
|
207 | initialItem: null,
|
208 | isFocused: false,
|
209 | selected: selected,
|
210 | showMenu: defaultOpen,
|
211 | shownResults: maxResults,
|
212 | text: text
|
213 | };
|
214 | }
|
215 | export function clearTypeahead(state, props) {
|
216 | return _extends({}, getInitialState(props), {
|
217 | isFocused: state.isFocused,
|
218 | selected: [],
|
219 | text: ''
|
220 | });
|
221 | }
|
222 | export function hideMenu(state, props) {
|
223 | var _getInitialState = getInitialState(props),
|
224 | activeIndex = _getInitialState.activeIndex,
|
225 | activeItem = _getInitialState.activeItem,
|
226 | initialItem = _getInitialState.initialItem,
|
227 | shownResults = _getInitialState.shownResults;
|
228 |
|
229 | return {
|
230 | activeIndex: activeIndex,
|
231 | activeItem: activeItem,
|
232 | initialItem: initialItem,
|
233 | showMenu: false,
|
234 | shownResults: shownResults
|
235 | };
|
236 | }
|
237 | export function toggleMenu(state, props) {
|
238 | return state.showMenu ? hideMenu(state, props) : {
|
239 | showMenu: true
|
240 | };
|
241 | }
|
242 |
|
243 | var Typeahead = function (_React$Component) {
|
244 | _inheritsLoose(Typeahead, _React$Component);
|
245 |
|
246 | function Typeahead() {
|
247 | var _this;
|
248 |
|
249 | for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
250 | args[_key] = arguments[_key];
|
251 | }
|
252 |
|
253 | _this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;
|
254 |
|
255 | _defineProperty(_assertThisInitialized(_this), "state", getInitialState(_this.props));
|
256 |
|
257 | _defineProperty(_assertThisInitialized(_this), "inputNode", void 0);
|
258 |
|
259 | _defineProperty(_assertThisInitialized(_this), "isMenuShown", false);
|
260 |
|
261 | _defineProperty(_assertThisInitialized(_this), "items", []);
|
262 |
|
263 | _defineProperty(_assertThisInitialized(_this), "blur", function () {
|
264 | _this.inputNode && _this.inputNode.blur();
|
265 |
|
266 | _this.hideMenu();
|
267 | });
|
268 |
|
269 | _defineProperty(_assertThisInitialized(_this), "clear", function () {
|
270 | _this.setState(clearTypeahead);
|
271 | });
|
272 |
|
273 | _defineProperty(_assertThisInitialized(_this), "focus", function () {
|
274 | _this.inputNode && _this.inputNode.focus();
|
275 | });
|
276 |
|
277 | _defineProperty(_assertThisInitialized(_this), "getInput", function () {
|
278 | return _this.inputNode;
|
279 | });
|
280 |
|
281 | _defineProperty(_assertThisInitialized(_this), "inputRef", function (inputNode) {
|
282 | _this.inputNode = inputNode;
|
283 | });
|
284 |
|
285 | _defineProperty(_assertThisInitialized(_this), "setItem", function (item, position) {
|
286 | _this.items[position] = item;
|
287 | });
|
288 |
|
289 | _defineProperty(_assertThisInitialized(_this), "hideMenu", function () {
|
290 | _this.setState(hideMenu);
|
291 | });
|
292 |
|
293 | _defineProperty(_assertThisInitialized(_this), "toggleMenu", function () {
|
294 | _this.setState(toggleMenu);
|
295 | });
|
296 |
|
297 | _defineProperty(_assertThisInitialized(_this), "_handleActiveIndexChange", function (activeIndex) {
|
298 | _this.setState(function (state) {
|
299 | return {
|
300 | activeIndex: activeIndex,
|
301 | activeItem: activeIndex === -1 ? null : state.activeItem
|
302 | };
|
303 | });
|
304 | });
|
305 |
|
306 | _defineProperty(_assertThisInitialized(_this), "_handleActiveItemChange", function (activeItem) {
|
307 |
|
308 | if (!isEqual(activeItem, _this.state.activeItem)) {
|
309 | _this.setState({
|
310 | activeItem: activeItem
|
311 | });
|
312 | }
|
313 | });
|
314 |
|
315 | _defineProperty(_assertThisInitialized(_this), "_handleBlur", function (e) {
|
316 | e.persist();
|
317 |
|
318 | _this.setState({
|
319 | isFocused: false
|
320 | }, function () {
|
321 | return _this.props.onBlur(e);
|
322 | });
|
323 | });
|
324 |
|
325 | _defineProperty(_assertThisInitialized(_this), "_handleChange", function (selected) {
|
326 | _this.props.onChange && _this.props.onChange(selected);
|
327 | });
|
328 |
|
329 | _defineProperty(_assertThisInitialized(_this), "_handleClear", function () {
|
330 | _this.setState(clearTypeahead, function () {
|
331 | return _this._handleChange([]);
|
332 | });
|
333 | });
|
334 |
|
335 | _defineProperty(_assertThisInitialized(_this), "_handleFocus", function (e) {
|
336 | e.persist();
|
337 |
|
338 | _this.setState({
|
339 | isFocused: true,
|
340 | showMenu: true
|
341 | }, function () {
|
342 | return _this.props.onFocus(e);
|
343 | });
|
344 | });
|
345 |
|
346 | _defineProperty(_assertThisInitialized(_this), "_handleInitialItemChange", function (initialItem) {
|
347 |
|
348 | if (!isEqual(initialItem, _this.state.initialItem)) {
|
349 | _this.setState({
|
350 | initialItem: initialItem
|
351 | });
|
352 | }
|
353 | });
|
354 |
|
355 | _defineProperty(_assertThisInitialized(_this), "_handleInputChange", function (e) {
|
356 | e.persist();
|
357 | var text = e.currentTarget.value;
|
358 | var _this$props = _this.props,
|
359 | multiple = _this$props.multiple,
|
360 | onInputChange = _this$props.onInputChange;
|
361 |
|
362 | var shouldClearSelections = _this.state.selected.length && !multiple;
|
363 |
|
364 | _this.setState(function (state, props) {
|
365 | var _getInitialState2 = getInitialState(props),
|
366 | activeIndex = _getInitialState2.activeIndex,
|
367 | activeItem = _getInitialState2.activeItem,
|
368 | shownResults = _getInitialState2.shownResults;
|
369 |
|
370 | return {
|
371 | activeIndex: activeIndex,
|
372 | activeItem: activeItem,
|
373 | selected: shouldClearSelections ? [] : state.selected,
|
374 | showMenu: true,
|
375 | shownResults: shownResults,
|
376 | text: text
|
377 | };
|
378 | }, function () {
|
379 | onInputChange(text, e);
|
380 | shouldClearSelections && _this._handleChange([]);
|
381 | });
|
382 | });
|
383 |
|
384 | _defineProperty(_assertThisInitialized(_this), "_handleKeyDown", function (e) {
|
385 | var activeItem = _this.state.activeItem;
|
386 |
|
387 | if (!_this.isMenuShown) {
|
388 | if (e.keyCode === UP || e.keyCode === DOWN) {
|
389 | _this.setState({
|
390 | showMenu: true
|
391 | });
|
392 | }
|
393 |
|
394 | _this.props.onKeyDown(e);
|
395 |
|
396 | return;
|
397 | }
|
398 |
|
399 | switch (e.keyCode) {
|
400 | case UP:
|
401 | case DOWN:
|
402 |
|
403 | e.preventDefault();
|
404 |
|
405 | _this._handleActiveIndexChange(getUpdatedActiveIndex(_this.state.activeIndex, e.keyCode, _this.items));
|
406 |
|
407 | break;
|
408 |
|
409 | case RETURN:
|
410 |
|
411 | e.preventDefault();
|
412 | activeItem && _this._handleMenuItemSelect(activeItem, e);
|
413 | break;
|
414 |
|
415 | case ESC:
|
416 | case TAB:
|
417 |
|
418 |
|
419 | _this.hideMenu();
|
420 |
|
421 | break;
|
422 |
|
423 | default:
|
424 | break;
|
425 | }
|
426 |
|
427 | _this.props.onKeyDown(e);
|
428 | });
|
429 |
|
430 | _defineProperty(_assertThisInitialized(_this), "_handleMenuItemSelect", function (option, e) {
|
431 | if (option.paginationOption) {
|
432 | _this._handlePaginate(e);
|
433 | } else {
|
434 | _this._handleSelectionAdd(option);
|
435 | }
|
436 | });
|
437 |
|
438 | _defineProperty(_assertThisInitialized(_this), "_handlePaginate", function (e) {
|
439 | e.persist();
|
440 |
|
441 | _this.setState(function (state, props) {
|
442 | return {
|
443 | shownResults: state.shownResults + props.maxResults
|
444 | };
|
445 | }, function () {
|
446 | return _this.props.onPaginate(e, _this.state.shownResults);
|
447 | });
|
448 | });
|
449 |
|
450 | _defineProperty(_assertThisInitialized(_this), "_handleSelectionAdd", function (option) {
|
451 | var _this$props2 = _this.props,
|
452 | multiple = _this$props2.multiple,
|
453 | labelKey = _this$props2.labelKey;
|
454 | var selected;
|
455 | var selection = option;
|
456 | var text;
|
457 |
|
458 |
|
459 | if (!isString(selection) && selection.customOption) {
|
460 | selection = _extends({}, selection, {
|
461 | id: uniqueId('new-id-')
|
462 | });
|
463 | }
|
464 |
|
465 | if (multiple) {
|
466 |
|
467 |
|
468 | selected = _this.state.selected.concat(selection);
|
469 | text = '';
|
470 | } else {
|
471 |
|
472 |
|
473 | selected = [selection];
|
474 | text = getOptionLabel(selection, labelKey);
|
475 | }
|
476 |
|
477 | _this.setState(function (state, props) {
|
478 | return _extends({}, hideMenu(state, props), {
|
479 | initialItem: selection,
|
480 | selected: selected,
|
481 | text: text
|
482 | });
|
483 | }, function () {
|
484 | return _this._handleChange(selected);
|
485 | });
|
486 | });
|
487 |
|
488 | _defineProperty(_assertThisInitialized(_this), "_handleSelectionRemove", function (selection) {
|
489 | var selected = _this.state.selected.filter(function (option) {
|
490 | return !isEqual(option, selection);
|
491 | });
|
492 |
|
493 |
|
494 | _this.focus();
|
495 |
|
496 | _this.setState(function (state, props) {
|
497 | return _extends({}, hideMenu(state, props), {
|
498 | selected: selected
|
499 | });
|
500 | }, function () {
|
501 | return _this._handleChange(selected);
|
502 | });
|
503 | });
|
504 |
|
505 | return _this;
|
506 | }
|
507 |
|
508 | var _proto = Typeahead.prototype;
|
509 |
|
510 | _proto.componentDidMount = function componentDidMount() {
|
511 | this.props.autoFocus && this.focus();
|
512 | };
|
513 |
|
514 | _proto.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {
|
515 | var _this$props3 = this.props,
|
516 | labelKey = _this$props3.labelKey,
|
517 | multiple = _this$props3.multiple,
|
518 | selected = _this$props3.selected;
|
519 | validateSelectedPropChange(selected, prevProps.selected);
|
520 |
|
521 | if (selected && !isEqual(selected, prevState.selected)) {
|
522 | this.setState({
|
523 | selected: selected
|
524 | });
|
525 |
|
526 | if (!multiple) {
|
527 | this.setState({
|
528 | text: selected.length ? getOptionLabel(head(selected), labelKey) : ''
|
529 | });
|
530 | }
|
531 | }
|
532 | };
|
533 |
|
534 | _proto.render = function render() {
|
535 |
|
536 | var _this$props4 = this.props,
|
537 | onChange = _this$props4.onChange,
|
538 | otherProps = _objectWithoutPropertiesLoose(_this$props4, ["onChange"]);
|
539 |
|
540 | var mergedPropsAndState = _extends({}, otherProps, this.state);
|
541 |
|
542 | var filterBy = mergedPropsAndState.filterBy,
|
543 | labelKey = mergedPropsAndState.labelKey,
|
544 | options = mergedPropsAndState.options,
|
545 | paginate = mergedPropsAndState.paginate,
|
546 | shownResults = mergedPropsAndState.shownResults,
|
547 | text = mergedPropsAndState.text;
|
548 | this.isMenuShown = isShown(mergedPropsAndState);
|
549 | this.items = [];
|
550 |
|
551 | var results = [];
|
552 |
|
553 | if (this.isMenuShown) {
|
554 | var cb = typeof filterBy === 'function' ? filterBy : defaultFilterBy;
|
555 | results = options.filter(function (option) {
|
556 | return cb(option, mergedPropsAndState);
|
557 | });
|
558 |
|
559 | var shouldPaginate = paginate && results.length > shownResults;
|
560 |
|
561 | results = getTruncatedOptions(results, shownResults);
|
562 |
|
563 | if (addCustomOption(results, mergedPropsAndState)) {
|
564 | var _results$push;
|
565 |
|
566 | results.push((_results$push = {
|
567 | customOption: true
|
568 | }, _results$push[getStringLabelKey(labelKey)] = text, _results$push));
|
569 | }
|
570 |
|
571 |
|
572 | if (shouldPaginate) {
|
573 | var _results$push2;
|
574 |
|
575 | results.push((_results$push2 = {}, _results$push2[getStringLabelKey(labelKey)] = '', _results$push2.paginationOption = true, _results$push2));
|
576 | }
|
577 | }
|
578 |
|
579 | return React.createElement(TypeaheadManager, _extends({}, mergedPropsAndState, {
|
580 | hideMenu: this.hideMenu,
|
581 | inputNode: this.inputNode,
|
582 | inputRef: this.inputRef,
|
583 | isMenuShown: this.isMenuShown,
|
584 | onActiveItemChange: this._handleActiveItemChange,
|
585 | onAdd: this._handleSelectionAdd,
|
586 | onBlur: this._handleBlur,
|
587 | onChange: this._handleInputChange,
|
588 | onClear: this._handleClear,
|
589 | onFocus: this._handleFocus,
|
590 | onHide: this.hideMenu,
|
591 | onInitialItemChange: this._handleInitialItemChange,
|
592 | onKeyDown: this._handleKeyDown,
|
593 | onMenuItemClick: this._handleMenuItemSelect,
|
594 | onRemove: this._handleSelectionRemove,
|
595 | results: results,
|
596 | setItem: this.setItem,
|
597 | toggleMenu: this.toggleMenu
|
598 | }));
|
599 | };
|
600 |
|
601 | return Typeahead;
|
602 | }(React.Component);
|
603 |
|
604 | _defineProperty(Typeahead, "propTypes", propTypes);
|
605 |
|
606 | _defineProperty(Typeahead, "defaultProps", defaultProps);
|
607 |
|
608 | export default Typeahead; |
\ | No newline at end of file |