UNPKG

202 kBJavaScriptView Raw
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react')) :
3 typeof define === 'function' && define.amd ? define(['exports', 'react'], factory) :
4 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Downshift = {}, global.React));
5}(this, (function (exports, react) { 'use strict';
6
7 function _objectWithoutPropertiesLoose(source, excluded) {
8 if (source == null) return {};
9 var target = {};
10 var sourceKeys = Object.keys(source);
11 var key, i;
12
13 for (i = 0; i < sourceKeys.length; i++) {
14 key = sourceKeys[i];
15 if (excluded.indexOf(key) >= 0) continue;
16 target[key] = source[key];
17 }
18
19 return target;
20 }
21
22 function _extends() {
23 _extends = Object.assign || function (target) {
24 for (var i = 1; i < arguments.length; i++) {
25 var source = arguments[i];
26
27 for (var key in source) {
28 if (Object.prototype.hasOwnProperty.call(source, key)) {
29 target[key] = source[key];
30 }
31 }
32 }
33
34 return target;
35 };
36
37 return _extends.apply(this, arguments);
38 }
39
40 function _assertThisInitialized(self) {
41 if (self === void 0) {
42 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
43 }
44
45 return self;
46 }
47
48 function _inheritsLoose(subClass, superClass) {
49 subClass.prototype = Object.create(superClass.prototype);
50 subClass.prototype.constructor = subClass;
51 subClass.__proto__ = superClass;
52 }
53
54 function createCommonjsModule(fn) {
55 var module = { exports: {} };
56 return fn(module, module.exports), module.exports;
57 }
58
59 /** @license React v16.13.1
60 * react-is.development.js
61 *
62 * Copyright (c) Facebook, Inc. and its affiliates.
63 *
64 * This source code is licensed under the MIT license found in the
65 * LICENSE file in the root directory of this source tree.
66 */
67 var reactIs_development = createCommonjsModule(function (module, exports) {
68
69 {
70 (function () {
71 // nor polyfill, then a plain number is used for performance.
72
73 var hasSymbol = typeof Symbol === 'function' && Symbol.for;
74 var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;
75 var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
76 var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
77 var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
78 var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
79 var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
80 var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace; // TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary
81 // (unstable) APIs that have been removed. Can we remove the symbols?
82
83 var REACT_ASYNC_MODE_TYPE = hasSymbol ? Symbol.for('react.async_mode') : 0xeacf;
84 var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;
85 var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
86 var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
87 var REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for('react.suspense_list') : 0xead8;
88 var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
89 var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
90 var REACT_BLOCK_TYPE = hasSymbol ? Symbol.for('react.block') : 0xead9;
91 var REACT_FUNDAMENTAL_TYPE = hasSymbol ? Symbol.for('react.fundamental') : 0xead5;
92 var REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for('react.responder') : 0xead6;
93 var REACT_SCOPE_TYPE = hasSymbol ? Symbol.for('react.scope') : 0xead7;
94
95 function isValidElementType(type) {
96 return typeof type === 'string' || typeof type === 'function' || // Note: its typeof might be other than 'symbol' or 'number' if it's a polyfill.
97 type === REACT_FRAGMENT_TYPE || type === REACT_CONCURRENT_MODE_TYPE || type === REACT_PROFILER_TYPE || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || typeof type === 'object' && type !== null && (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || type.$$typeof === REACT_FUNDAMENTAL_TYPE || type.$$typeof === REACT_RESPONDER_TYPE || type.$$typeof === REACT_SCOPE_TYPE || type.$$typeof === REACT_BLOCK_TYPE);
98 }
99
100 function typeOf(object) {
101 if (typeof object === 'object' && object !== null) {
102 var $$typeof = object.$$typeof;
103
104 switch ($$typeof) {
105 case REACT_ELEMENT_TYPE:
106 var type = object.type;
107
108 switch (type) {
109 case REACT_ASYNC_MODE_TYPE:
110 case REACT_CONCURRENT_MODE_TYPE:
111 case REACT_FRAGMENT_TYPE:
112 case REACT_PROFILER_TYPE:
113 case REACT_STRICT_MODE_TYPE:
114 case REACT_SUSPENSE_TYPE:
115 return type;
116
117 default:
118 var $$typeofType = type && type.$$typeof;
119
120 switch ($$typeofType) {
121 case REACT_CONTEXT_TYPE:
122 case REACT_FORWARD_REF_TYPE:
123 case REACT_LAZY_TYPE:
124 case REACT_MEMO_TYPE:
125 case REACT_PROVIDER_TYPE:
126 return $$typeofType;
127
128 default:
129 return $$typeof;
130 }
131
132 }
133
134 case REACT_PORTAL_TYPE:
135 return $$typeof;
136 }
137 }
138
139 return undefined;
140 } // AsyncMode is deprecated along with isAsyncMode
141
142
143 var AsyncMode = REACT_ASYNC_MODE_TYPE;
144 var ConcurrentMode = REACT_CONCURRENT_MODE_TYPE;
145 var ContextConsumer = REACT_CONTEXT_TYPE;
146 var ContextProvider = REACT_PROVIDER_TYPE;
147 var Element = REACT_ELEMENT_TYPE;
148 var ForwardRef = REACT_FORWARD_REF_TYPE;
149 var Fragment = REACT_FRAGMENT_TYPE;
150 var Lazy = REACT_LAZY_TYPE;
151 var Memo = REACT_MEMO_TYPE;
152 var Portal = REACT_PORTAL_TYPE;
153 var Profiler = REACT_PROFILER_TYPE;
154 var StrictMode = REACT_STRICT_MODE_TYPE;
155 var Suspense = REACT_SUSPENSE_TYPE;
156 var hasWarnedAboutDeprecatedIsAsyncMode = false; // AsyncMode should be deprecated
157
158 function isAsyncMode(object) {
159 {
160 if (!hasWarnedAboutDeprecatedIsAsyncMode) {
161 hasWarnedAboutDeprecatedIsAsyncMode = true; // Using console['warn'] to evade Babel and ESLint
162
163 console['warn']('The ReactIs.isAsyncMode() alias has been deprecated, ' + 'and will be removed in React 17+. Update your code to use ' + 'ReactIs.isConcurrentMode() instead. It has the exact same API.');
164 }
165 }
166 return isConcurrentMode(object) || typeOf(object) === REACT_ASYNC_MODE_TYPE;
167 }
168
169 function isConcurrentMode(object) {
170 return typeOf(object) === REACT_CONCURRENT_MODE_TYPE;
171 }
172
173 function isContextConsumer(object) {
174 return typeOf(object) === REACT_CONTEXT_TYPE;
175 }
176
177 function isContextProvider(object) {
178 return typeOf(object) === REACT_PROVIDER_TYPE;
179 }
180
181 function isElement(object) {
182 return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;
183 }
184
185 function isForwardRef(object) {
186 return typeOf(object) === REACT_FORWARD_REF_TYPE;
187 }
188
189 function isFragment(object) {
190 return typeOf(object) === REACT_FRAGMENT_TYPE;
191 }
192
193 function isLazy(object) {
194 return typeOf(object) === REACT_LAZY_TYPE;
195 }
196
197 function isMemo(object) {
198 return typeOf(object) === REACT_MEMO_TYPE;
199 }
200
201 function isPortal(object) {
202 return typeOf(object) === REACT_PORTAL_TYPE;
203 }
204
205 function isProfiler(object) {
206 return typeOf(object) === REACT_PROFILER_TYPE;
207 }
208
209 function isStrictMode(object) {
210 return typeOf(object) === REACT_STRICT_MODE_TYPE;
211 }
212
213 function isSuspense(object) {
214 return typeOf(object) === REACT_SUSPENSE_TYPE;
215 }
216
217 exports.AsyncMode = AsyncMode;
218 exports.ConcurrentMode = ConcurrentMode;
219 exports.ContextConsumer = ContextConsumer;
220 exports.ContextProvider = ContextProvider;
221 exports.Element = Element;
222 exports.ForwardRef = ForwardRef;
223 exports.Fragment = Fragment;
224 exports.Lazy = Lazy;
225 exports.Memo = Memo;
226 exports.Portal = Portal;
227 exports.Profiler = Profiler;
228 exports.StrictMode = StrictMode;
229 exports.Suspense = Suspense;
230 exports.isAsyncMode = isAsyncMode;
231 exports.isConcurrentMode = isConcurrentMode;
232 exports.isContextConsumer = isContextConsumer;
233 exports.isContextProvider = isContextProvider;
234 exports.isElement = isElement;
235 exports.isForwardRef = isForwardRef;
236 exports.isFragment = isFragment;
237 exports.isLazy = isLazy;
238 exports.isMemo = isMemo;
239 exports.isPortal = isPortal;
240 exports.isProfiler = isProfiler;
241 exports.isStrictMode = isStrictMode;
242 exports.isSuspense = isSuspense;
243 exports.isValidElementType = isValidElementType;
244 exports.typeOf = typeOf;
245 })();
246 }
247 });
248
249 var reactIs = createCommonjsModule(function (module) {
250
251 {
252 module.exports = reactIs_development;
253 }
254 });
255
256 /*
257 object-assign
258 (c) Sindre Sorhus
259 @license MIT
260 */
261 /* eslint-disable no-unused-vars */
262
263 var getOwnPropertySymbols = Object.getOwnPropertySymbols;
264 var hasOwnProperty = Object.prototype.hasOwnProperty;
265 var propIsEnumerable = Object.prototype.propertyIsEnumerable;
266
267 function toObject(val) {
268 if (val === null || val === undefined) {
269 throw new TypeError('Object.assign cannot be called with null or undefined');
270 }
271
272 return Object(val);
273 }
274
275 function shouldUseNative() {
276 try {
277 if (!Object.assign) {
278 return false;
279 } // Detect buggy property enumeration order in older V8 versions.
280 // https://bugs.chromium.org/p/v8/issues/detail?id=4118
281
282
283 var test1 = new String('abc'); // eslint-disable-line no-new-wrappers
284
285 test1[5] = 'de';
286
287 if (Object.getOwnPropertyNames(test1)[0] === '5') {
288 return false;
289 } // https://bugs.chromium.org/p/v8/issues/detail?id=3056
290
291
292 var test2 = {};
293
294 for (var i = 0; i < 10; i++) {
295 test2['_' + String.fromCharCode(i)] = i;
296 }
297
298 var order2 = Object.getOwnPropertyNames(test2).map(function (n) {
299 return test2[n];
300 });
301
302 if (order2.join('') !== '0123456789') {
303 return false;
304 } // https://bugs.chromium.org/p/v8/issues/detail?id=3056
305
306
307 var test3 = {};
308 'abcdefghijklmnopqrst'.split('').forEach(function (letter) {
309 test3[letter] = letter;
310 });
311
312 if (Object.keys(Object.assign({}, test3)).join('') !== 'abcdefghijklmnopqrst') {
313 return false;
314 }
315
316 return true;
317 } catch (err) {
318 // We don't expect any of the above to throw, but better to be safe.
319 return false;
320 }
321 }
322
323 var objectAssign = shouldUseNative() ? Object.assign : function (target, source) {
324 var from;
325 var to = toObject(target);
326 var symbols;
327
328 for (var s = 1; s < arguments.length; s++) {
329 from = Object(arguments[s]);
330
331 for (var key in from) {
332 if (hasOwnProperty.call(from, key)) {
333 to[key] = from[key];
334 }
335 }
336
337 if (getOwnPropertySymbols) {
338 symbols = getOwnPropertySymbols(from);
339
340 for (var i = 0; i < symbols.length; i++) {
341 if (propIsEnumerable.call(from, symbols[i])) {
342 to[symbols[i]] = from[symbols[i]];
343 }
344 }
345 }
346 }
347
348 return to;
349 };
350
351 /**
352 * Copyright (c) 2013-present, Facebook, Inc.
353 *
354 * This source code is licensed under the MIT license found in the
355 * LICENSE file in the root directory of this source tree.
356 */
357
358 var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
359 var ReactPropTypesSecret_1 = ReactPropTypesSecret;
360
361 /**
362 * Copyright (c) 2013-present, Facebook, Inc.
363 *
364 * This source code is licensed under the MIT license found in the
365 * LICENSE file in the root directory of this source tree.
366 */
367
368 var printWarning = function () {};
369
370 {
371 var ReactPropTypesSecret$1 = ReactPropTypesSecret_1;
372 var loggedTypeFailures = {};
373 var has = Function.call.bind(Object.prototype.hasOwnProperty);
374
375 printWarning = function (text) {
376 var message = 'Warning: ' + text;
377
378 if (typeof console !== 'undefined') {
379 console.error(message);
380 }
381
382 try {
383 // --- Welcome to debugging React ---
384 // This error was thrown as a convenience so that you can use this stack
385 // to find the callsite that caused this warning to fire.
386 throw new Error(message);
387 } catch (x) {}
388 };
389 }
390 /**
391 * Assert that the values match with the type specs.
392 * Error messages are memorized and will only be shown once.
393 *
394 * @param {object} typeSpecs Map of name to a ReactPropType
395 * @param {object} values Runtime values that need to be type-checked
396 * @param {string} location e.g. "prop", "context", "child context"
397 * @param {string} componentName Name of the component for error messages.
398 * @param {?Function} getStack Returns the component stack.
399 * @private
400 */
401
402
403 function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
404 {
405 for (var typeSpecName in typeSpecs) {
406 if (has(typeSpecs, typeSpecName)) {
407 var error; // Prop type validation may throw. In case they do, we don't want to
408 // fail the render phase where it didn't fail before. So we log it.
409 // After these have been cleaned up, we'll let them throw.
410
411 try {
412 // This is intentionally an invariant that gets caught. It's the same
413 // behavior as without this statement except with a better message.
414 if (typeof typeSpecs[typeSpecName] !== 'function') {
415 var err = Error((componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' + 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.');
416 err.name = 'Invariant Violation';
417 throw err;
418 }
419
420 error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret$1);
421 } catch (ex) {
422 error = ex;
423 }
424
425 if (error && !(error instanceof Error)) {
426 printWarning((componentName || 'React class') + ': type specification of ' + location + ' `' + typeSpecName + '` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a ' + typeof error + '. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).');
427 }
428
429 if (error instanceof Error && !(error.message in loggedTypeFailures)) {
430 // Only monitor this failure once because there tends to be a lot of the
431 // same error.
432 loggedTypeFailures[error.message] = true;
433 var stack = getStack ? getStack() : '';
434 printWarning('Failed ' + location + ' type: ' + error.message + (stack != null ? stack : ''));
435 }
436 }
437 }
438 }
439 }
440 /**
441 * Resets warning cache when testing.
442 *
443 * @private
444 */
445
446
447 checkPropTypes.resetWarningCache = function () {
448 {
449 loggedTypeFailures = {};
450 }
451 };
452
453 var checkPropTypes_1 = checkPropTypes;
454
455 /**
456 * Copyright (c) 2013-present, Facebook, Inc.
457 *
458 * This source code is licensed under the MIT license found in the
459 * LICENSE file in the root directory of this source tree.
460 */
461
462 var has$1 = Function.call.bind(Object.prototype.hasOwnProperty);
463
464 var printWarning$1 = function () {};
465
466 {
467 printWarning$1 = function (text) {
468 var message = 'Warning: ' + text;
469
470 if (typeof console !== 'undefined') {
471 console.error(message);
472 }
473
474 try {
475 // --- Welcome to debugging React ---
476 // This error was thrown as a convenience so that you can use this stack
477 // to find the callsite that caused this warning to fire.
478 throw new Error(message);
479 } catch (x) {}
480 };
481 }
482
483 function emptyFunctionThatReturnsNull() {
484 return null;
485 }
486
487 var factoryWithTypeCheckers = function (isValidElement, throwOnDirectAccess) {
488 /* global Symbol */
489 var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
490 var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec.
491
492 /**
493 * Returns the iterator method function contained on the iterable object.
494 *
495 * Be sure to invoke the function with the iterable as context:
496 *
497 * var iteratorFn = getIteratorFn(myIterable);
498 * if (iteratorFn) {
499 * var iterator = iteratorFn.call(myIterable);
500 * ...
501 * }
502 *
503 * @param {?object} maybeIterable
504 * @return {?function}
505 */
506
507 function getIteratorFn(maybeIterable) {
508 var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]);
509
510 if (typeof iteratorFn === 'function') {
511 return iteratorFn;
512 }
513 }
514 /**
515 * Collection of methods that allow declaration and validation of props that are
516 * supplied to React components. Example usage:
517 *
518 * var Props = require('ReactPropTypes');
519 * var MyArticle = React.createClass({
520 * propTypes: {
521 * // An optional string prop named "description".
522 * description: Props.string,
523 *
524 * // A required enum prop named "category".
525 * category: Props.oneOf(['News','Photos']).isRequired,
526 *
527 * // A prop named "dialog" that requires an instance of Dialog.
528 * dialog: Props.instanceOf(Dialog).isRequired
529 * },
530 * render: function() { ... }
531 * });
532 *
533 * A more formal specification of how these methods are used:
534 *
535 * type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...)
536 * decl := ReactPropTypes.{type}(.isRequired)?
537 *
538 * Each and every declaration produces a function with the same signature. This
539 * allows the creation of custom validation functions. For example:
540 *
541 * var MyLink = React.createClass({
542 * propTypes: {
543 * // An optional string or URI prop named "href".
544 * href: function(props, propName, componentName) {
545 * var propValue = props[propName];
546 * if (propValue != null && typeof propValue !== 'string' &&
547 * !(propValue instanceof URI)) {
548 * return new Error(
549 * 'Expected a string or an URI for ' + propName + ' in ' +
550 * componentName
551 * );
552 * }
553 * }
554 * },
555 * render: function() {...}
556 * });
557 *
558 * @internal
559 */
560
561
562 var ANONYMOUS = '<<anonymous>>'; // Important!
563 // Keep this list in sync with production version in `./factoryWithThrowingShims.js`.
564
565 var ReactPropTypes = {
566 array: createPrimitiveTypeChecker('array'),
567 bool: createPrimitiveTypeChecker('boolean'),
568 func: createPrimitiveTypeChecker('function'),
569 number: createPrimitiveTypeChecker('number'),
570 object: createPrimitiveTypeChecker('object'),
571 string: createPrimitiveTypeChecker('string'),
572 symbol: createPrimitiveTypeChecker('symbol'),
573 any: createAnyTypeChecker(),
574 arrayOf: createArrayOfTypeChecker,
575 element: createElementTypeChecker(),
576 elementType: createElementTypeTypeChecker(),
577 instanceOf: createInstanceTypeChecker,
578 node: createNodeChecker(),
579 objectOf: createObjectOfTypeChecker,
580 oneOf: createEnumTypeChecker,
581 oneOfType: createUnionTypeChecker,
582 shape: createShapeTypeChecker,
583 exact: createStrictShapeTypeChecker
584 };
585 /**
586 * inlined Object.is polyfill to avoid requiring consumers ship their own
587 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
588 */
589
590 /*eslint-disable no-self-compare*/
591
592 function is(x, y) {
593 // SameValue algorithm
594 if (x === y) {
595 // Steps 1-5, 7-10
596 // Steps 6.b-6.e: +0 != -0
597 return x !== 0 || 1 / x === 1 / y;
598 } else {
599 // Step 6.a: NaN == NaN
600 return x !== x && y !== y;
601 }
602 }
603 /*eslint-enable no-self-compare*/
604
605 /**
606 * We use an Error-like object for backward compatibility as people may call
607 * PropTypes directly and inspect their output. However, we don't use real
608 * Errors anymore. We don't inspect their stack anyway, and creating them
609 * is prohibitively expensive if they are created too often, such as what
610 * happens in oneOfType() for any type before the one that matched.
611 */
612
613
614 function PropTypeError(message) {
615 this.message = message;
616 this.stack = '';
617 } // Make `instanceof Error` still work for returned errors.
618
619
620 PropTypeError.prototype = Error.prototype;
621
622 function createChainableTypeChecker(validate) {
623 {
624 var manualPropTypeCallCache = {};
625 var manualPropTypeWarningCount = 0;
626 }
627
628 function checkType(isRequired, props, propName, componentName, location, propFullName, secret) {
629 componentName = componentName || ANONYMOUS;
630 propFullName = propFullName || propName;
631
632 if (secret !== ReactPropTypesSecret_1) {
633 if (throwOnDirectAccess) {
634 // New behavior only for users of `prop-types` package
635 var err = new Error('Calling PropTypes validators directly is not supported by the `prop-types` package. ' + 'Use `PropTypes.checkPropTypes()` to call them. ' + 'Read more at http://fb.me/use-check-prop-types');
636 err.name = 'Invariant Violation';
637 throw err;
638 } else if ( typeof console !== 'undefined') {
639 // Old behavior for people using React.PropTypes
640 var cacheKey = componentName + ':' + propName;
641
642 if (!manualPropTypeCallCache[cacheKey] && // Avoid spamming the console because they are often not actionable except for lib authors
643 manualPropTypeWarningCount < 3) {
644 printWarning$1('You are manually calling a React.PropTypes validation ' + 'function for the `' + propFullName + '` prop on `' + componentName + '`. This is deprecated ' + 'and will throw in the standalone `prop-types` package. ' + 'You may be seeing this warning due to a third-party PropTypes ' + 'library. See https://fb.me/react-warning-dont-call-proptypes ' + 'for details.');
645 manualPropTypeCallCache[cacheKey] = true;
646 manualPropTypeWarningCount++;
647 }
648 }
649 }
650
651 if (props[propName] == null) {
652 if (isRequired) {
653 if (props[propName] === null) {
654 return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required ' + ('in `' + componentName + '`, but its value is `null`.'));
655 }
656
657 return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required in ' + ('`' + componentName + '`, but its value is `undefined`.'));
658 }
659
660 return null;
661 } else {
662 return validate(props, propName, componentName, location, propFullName);
663 }
664 }
665
666 var chainedCheckType = checkType.bind(null, false);
667 chainedCheckType.isRequired = checkType.bind(null, true);
668 return chainedCheckType;
669 }
670
671 function createPrimitiveTypeChecker(expectedType) {
672 function validate(props, propName, componentName, location, propFullName, secret) {
673 var propValue = props[propName];
674 var propType = getPropType(propValue);
675
676 if (propType !== expectedType) {
677 // `propValue` being instance of, say, date/regexp, pass the 'object'
678 // check, but we can offer a more precise error message here rather than
679 // 'of type `object`'.
680 var preciseType = getPreciseType(propValue);
681 return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + preciseType + '` supplied to `' + componentName + '`, expected ') + ('`' + expectedType + '`.'));
682 }
683
684 return null;
685 }
686
687 return createChainableTypeChecker(validate);
688 }
689
690 function createAnyTypeChecker() {
691 return createChainableTypeChecker(emptyFunctionThatReturnsNull);
692 }
693
694 function createArrayOfTypeChecker(typeChecker) {
695 function validate(props, propName, componentName, location, propFullName) {
696 if (typeof typeChecker !== 'function') {
697 return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside arrayOf.');
698 }
699
700 var propValue = props[propName];
701
702 if (!Array.isArray(propValue)) {
703 var propType = getPropType(propValue);
704 return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an array.'));
705 }
706
707 for (var i = 0; i < propValue.length; i++) {
708 var error = typeChecker(propValue, i, componentName, location, propFullName + '[' + i + ']', ReactPropTypesSecret_1);
709
710 if (error instanceof Error) {
711 return error;
712 }
713 }
714
715 return null;
716 }
717
718 return createChainableTypeChecker(validate);
719 }
720
721 function createElementTypeChecker() {
722 function validate(props, propName, componentName, location, propFullName) {
723 var propValue = props[propName];
724
725 if (!isValidElement(propValue)) {
726 var propType = getPropType(propValue);
727 return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected a single ReactElement.'));
728 }
729
730 return null;
731 }
732
733 return createChainableTypeChecker(validate);
734 }
735
736 function createElementTypeTypeChecker() {
737 function validate(props, propName, componentName, location, propFullName) {
738 var propValue = props[propName];
739
740 if (!reactIs.isValidElementType(propValue)) {
741 var propType = getPropType(propValue);
742 return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected a single ReactElement type.'));
743 }
744
745 return null;
746 }
747
748 return createChainableTypeChecker(validate);
749 }
750
751 function createInstanceTypeChecker(expectedClass) {
752 function validate(props, propName, componentName, location, propFullName) {
753 if (!(props[propName] instanceof expectedClass)) {
754 var expectedClassName = expectedClass.name || ANONYMOUS;
755 var actualClassName = getClassName(props[propName]);
756 return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + actualClassName + '` supplied to `' + componentName + '`, expected ') + ('instance of `' + expectedClassName + '`.'));
757 }
758
759 return null;
760 }
761
762 return createChainableTypeChecker(validate);
763 }
764
765 function createEnumTypeChecker(expectedValues) {
766 if (!Array.isArray(expectedValues)) {
767 {
768 if (arguments.length > 1) {
769 printWarning$1('Invalid arguments supplied to oneOf, expected an array, got ' + arguments.length + ' arguments. ' + 'A common mistake is to write oneOf(x, y, z) instead of oneOf([x, y, z]).');
770 } else {
771 printWarning$1('Invalid argument supplied to oneOf, expected an array.');
772 }
773 }
774
775 return emptyFunctionThatReturnsNull;
776 }
777
778 function validate(props, propName, componentName, location, propFullName) {
779 var propValue = props[propName];
780
781 for (var i = 0; i < expectedValues.length; i++) {
782 if (is(propValue, expectedValues[i])) {
783 return null;
784 }
785 }
786
787 var valuesString = JSON.stringify(expectedValues, function replacer(key, value) {
788 var type = getPreciseType(value);
789
790 if (type === 'symbol') {
791 return String(value);
792 }
793
794 return value;
795 });
796 return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of value `' + String(propValue) + '` ' + ('supplied to `' + componentName + '`, expected one of ' + valuesString + '.'));
797 }
798
799 return createChainableTypeChecker(validate);
800 }
801
802 function createObjectOfTypeChecker(typeChecker) {
803 function validate(props, propName, componentName, location, propFullName) {
804 if (typeof typeChecker !== 'function') {
805 return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside objectOf.');
806 }
807
808 var propValue = props[propName];
809 var propType = getPropType(propValue);
810
811 if (propType !== 'object') {
812 return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an object.'));
813 }
814
815 for (var key in propValue) {
816 if (has$1(propValue, key)) {
817 var error = typeChecker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret_1);
818
819 if (error instanceof Error) {
820 return error;
821 }
822 }
823 }
824
825 return null;
826 }
827
828 return createChainableTypeChecker(validate);
829 }
830
831 function createUnionTypeChecker(arrayOfTypeCheckers) {
832 if (!Array.isArray(arrayOfTypeCheckers)) {
833 printWarning$1('Invalid argument supplied to oneOfType, expected an instance of array.') ;
834 return emptyFunctionThatReturnsNull;
835 }
836
837 for (var i = 0; i < arrayOfTypeCheckers.length; i++) {
838 var checker = arrayOfTypeCheckers[i];
839
840 if (typeof checker !== 'function') {
841 printWarning$1('Invalid argument supplied to oneOfType. Expected an array of check functions, but ' + 'received ' + getPostfixForTypeWarning(checker) + ' at index ' + i + '.');
842 return emptyFunctionThatReturnsNull;
843 }
844 }
845
846 function validate(props, propName, componentName, location, propFullName) {
847 for (var i = 0; i < arrayOfTypeCheckers.length; i++) {
848 var checker = arrayOfTypeCheckers[i];
849
850 if (checker(props, propName, componentName, location, propFullName, ReactPropTypesSecret_1) == null) {
851 return null;
852 }
853 }
854
855 return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`.'));
856 }
857
858 return createChainableTypeChecker(validate);
859 }
860
861 function createNodeChecker() {
862 function validate(props, propName, componentName, location, propFullName) {
863 if (!isNode(props[propName])) {
864 return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`, expected a ReactNode.'));
865 }
866
867 return null;
868 }
869
870 return createChainableTypeChecker(validate);
871 }
872
873 function createShapeTypeChecker(shapeTypes) {
874 function validate(props, propName, componentName, location, propFullName) {
875 var propValue = props[propName];
876 var propType = getPropType(propValue);
877
878 if (propType !== 'object') {
879 return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.'));
880 }
881
882 for (var key in shapeTypes) {
883 var checker = shapeTypes[key];
884
885 if (!checker) {
886 continue;
887 }
888
889 var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret_1);
890
891 if (error) {
892 return error;
893 }
894 }
895
896 return null;
897 }
898
899 return createChainableTypeChecker(validate);
900 }
901
902 function createStrictShapeTypeChecker(shapeTypes) {
903 function validate(props, propName, componentName, location, propFullName) {
904 var propValue = props[propName];
905 var propType = getPropType(propValue);
906
907 if (propType !== 'object') {
908 return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.'));
909 } // We need to check all keys in case some are required but missing from
910 // props.
911
912
913 var allKeys = objectAssign({}, props[propName], shapeTypes);
914
915 for (var key in allKeys) {
916 var checker = shapeTypes[key];
917
918 if (!checker) {
919 return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` key `' + key + '` supplied to `' + componentName + '`.' + '\nBad object: ' + JSON.stringify(props[propName], null, ' ') + '\nValid keys: ' + JSON.stringify(Object.keys(shapeTypes), null, ' '));
920 }
921
922 var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret_1);
923
924 if (error) {
925 return error;
926 }
927 }
928
929 return null;
930 }
931
932 return createChainableTypeChecker(validate);
933 }
934
935 function isNode(propValue) {
936 switch (typeof propValue) {
937 case 'number':
938 case 'string':
939 case 'undefined':
940 return true;
941
942 case 'boolean':
943 return !propValue;
944
945 case 'object':
946 if (Array.isArray(propValue)) {
947 return propValue.every(isNode);
948 }
949
950 if (propValue === null || isValidElement(propValue)) {
951 return true;
952 }
953
954 var iteratorFn = getIteratorFn(propValue);
955
956 if (iteratorFn) {
957 var iterator = iteratorFn.call(propValue);
958 var step;
959
960 if (iteratorFn !== propValue.entries) {
961 while (!(step = iterator.next()).done) {
962 if (!isNode(step.value)) {
963 return false;
964 }
965 }
966 } else {
967 // Iterator will provide entry [k,v] tuples rather than values.
968 while (!(step = iterator.next()).done) {
969 var entry = step.value;
970
971 if (entry) {
972 if (!isNode(entry[1])) {
973 return false;
974 }
975 }
976 }
977 }
978 } else {
979 return false;
980 }
981
982 return true;
983
984 default:
985 return false;
986 }
987 }
988
989 function isSymbol(propType, propValue) {
990 // Native Symbol.
991 if (propType === 'symbol') {
992 return true;
993 } // falsy value can't be a Symbol
994
995
996 if (!propValue) {
997 return false;
998 } // 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol'
999
1000
1001 if (propValue['@@toStringTag'] === 'Symbol') {
1002 return true;
1003 } // Fallback for non-spec compliant Symbols which are polyfilled.
1004
1005
1006 if (typeof Symbol === 'function' && propValue instanceof Symbol) {
1007 return true;
1008 }
1009
1010 return false;
1011 } // Equivalent of `typeof` but with special handling for array and regexp.
1012
1013
1014 function getPropType(propValue) {
1015 var propType = typeof propValue;
1016
1017 if (Array.isArray(propValue)) {
1018 return 'array';
1019 }
1020
1021 if (propValue instanceof RegExp) {
1022 // Old webkits (at least until Android 4.0) return 'function' rather than
1023 // 'object' for typeof a RegExp. We'll normalize this here so that /bla/
1024 // passes PropTypes.object.
1025 return 'object';
1026 }
1027
1028 if (isSymbol(propType, propValue)) {
1029 return 'symbol';
1030 }
1031
1032 return propType;
1033 } // This handles more types than `getPropType`. Only used for error messages.
1034 // See `createPrimitiveTypeChecker`.
1035
1036
1037 function getPreciseType(propValue) {
1038 if (typeof propValue === 'undefined' || propValue === null) {
1039 return '' + propValue;
1040 }
1041
1042 var propType = getPropType(propValue);
1043
1044 if (propType === 'object') {
1045 if (propValue instanceof Date) {
1046 return 'date';
1047 } else if (propValue instanceof RegExp) {
1048 return 'regexp';
1049 }
1050 }
1051
1052 return propType;
1053 } // Returns a string that is postfixed to a warning about an invalid type.
1054 // For example, "undefined" or "of type array"
1055
1056
1057 function getPostfixForTypeWarning(value) {
1058 var type = getPreciseType(value);
1059
1060 switch (type) {
1061 case 'array':
1062 case 'object':
1063 return 'an ' + type;
1064
1065 case 'boolean':
1066 case 'date':
1067 case 'regexp':
1068 return 'a ' + type;
1069
1070 default:
1071 return type;
1072 }
1073 } // Returns class name of the object, if any.
1074
1075
1076 function getClassName(propValue) {
1077 if (!propValue.constructor || !propValue.constructor.name) {
1078 return ANONYMOUS;
1079 }
1080
1081 return propValue.constructor.name;
1082 }
1083
1084 ReactPropTypes.checkPropTypes = checkPropTypes_1;
1085 ReactPropTypes.resetWarningCache = checkPropTypes_1.resetWarningCache;
1086 ReactPropTypes.PropTypes = ReactPropTypes;
1087 return ReactPropTypes;
1088 };
1089
1090 /**
1091 * Copyright (c) 2013-present, Facebook, Inc.
1092 *
1093 * This source code is licensed under the MIT license found in the
1094 * LICENSE file in the root directory of this source tree.
1095 */
1096 var propTypes = createCommonjsModule(function (module) {
1097 {
1098 var ReactIs = reactIs; // By explicitly using `prop-types` you are opting into new development behavior.
1099 // http://fb.me/prop-types-in-prod
1100
1101 var throwOnDirectAccess = true;
1102 module.exports = factoryWithTypeCheckers(ReactIs.isElement, throwOnDirectAccess);
1103 }
1104 });
1105
1106 /** @license React v17.0.1
1107 * react-is.production.min.js
1108 *
1109 * Copyright (c) Facebook, Inc. and its affiliates.
1110 *
1111 * This source code is licensed under the MIT license found in the
1112 * LICENSE file in the root directory of this source tree.
1113 */
1114
1115 if ("function" === typeof Symbol && Symbol.for) {
1116 var x = Symbol.for;
1117 x("react.element");
1118 x("react.portal");
1119 x("react.fragment");
1120 x("react.strict_mode");
1121 x("react.profiler");
1122 x("react.provider");
1123 x("react.context");
1124 x("react.forward_ref");
1125 x("react.suspense");
1126 x("react.suspense_list");
1127 x("react.memo");
1128 x("react.lazy");
1129 x("react.block");
1130 x("react.server.block");
1131 x("react.fundamental");
1132 x("react.debug_trace_mode");
1133 x("react.legacy_hidden");
1134 }
1135
1136 /** @license React v17.0.1
1137 * react-is.development.js
1138 *
1139 * Copyright (c) Facebook, Inc. and its affiliates.
1140 *
1141 * This source code is licensed under the MIT license found in the
1142 * LICENSE file in the root directory of this source tree.
1143 */
1144 var reactIs_development$1 = createCommonjsModule(function (module, exports) {
1145
1146 {
1147 (function () {
1148 // When adding new symbols to this file,
1149 // Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
1150 // The Symbol used to tag the ReactElement-like types. If there is no native Symbol
1151 // nor polyfill, then a plain number is used for performance.
1152
1153 var REACT_ELEMENT_TYPE = 0xeac7;
1154 var REACT_PORTAL_TYPE = 0xeaca;
1155 var REACT_FRAGMENT_TYPE = 0xeacb;
1156 var REACT_STRICT_MODE_TYPE = 0xeacc;
1157 var REACT_PROFILER_TYPE = 0xead2;
1158 var REACT_PROVIDER_TYPE = 0xeacd;
1159 var REACT_CONTEXT_TYPE = 0xeace;
1160 var REACT_FORWARD_REF_TYPE = 0xead0;
1161 var REACT_SUSPENSE_TYPE = 0xead1;
1162 var REACT_SUSPENSE_LIST_TYPE = 0xead8;
1163 var REACT_MEMO_TYPE = 0xead3;
1164 var REACT_LAZY_TYPE = 0xead4;
1165 var REACT_BLOCK_TYPE = 0xead9;
1166 var REACT_SERVER_BLOCK_TYPE = 0xeada;
1167 var REACT_FUNDAMENTAL_TYPE = 0xead5;
1168 var REACT_DEBUG_TRACING_MODE_TYPE = 0xeae1;
1169 var REACT_LEGACY_HIDDEN_TYPE = 0xeae3;
1170
1171 if (typeof Symbol === 'function' && Symbol.for) {
1172 var symbolFor = Symbol.for;
1173 REACT_ELEMENT_TYPE = symbolFor('react.element');
1174 REACT_PORTAL_TYPE = symbolFor('react.portal');
1175 REACT_FRAGMENT_TYPE = symbolFor('react.fragment');
1176 REACT_STRICT_MODE_TYPE = symbolFor('react.strict_mode');
1177 REACT_PROFILER_TYPE = symbolFor('react.profiler');
1178 REACT_PROVIDER_TYPE = symbolFor('react.provider');
1179 REACT_CONTEXT_TYPE = symbolFor('react.context');
1180 REACT_FORWARD_REF_TYPE = symbolFor('react.forward_ref');
1181 REACT_SUSPENSE_TYPE = symbolFor('react.suspense');
1182 REACT_SUSPENSE_LIST_TYPE = symbolFor('react.suspense_list');
1183 REACT_MEMO_TYPE = symbolFor('react.memo');
1184 REACT_LAZY_TYPE = symbolFor('react.lazy');
1185 REACT_BLOCK_TYPE = symbolFor('react.block');
1186 REACT_SERVER_BLOCK_TYPE = symbolFor('react.server.block');
1187 REACT_FUNDAMENTAL_TYPE = symbolFor('react.fundamental');
1188 symbolFor('react.scope');
1189 symbolFor('react.opaque.id');
1190 REACT_DEBUG_TRACING_MODE_TYPE = symbolFor('react.debug_trace_mode');
1191 symbolFor('react.offscreen');
1192 REACT_LEGACY_HIDDEN_TYPE = symbolFor('react.legacy_hidden');
1193 } // Filter certain DOM attributes (e.g. src, href) if their values are empty strings.
1194
1195
1196 var enableScopeAPI = false; // Experimental Create Event Handle API.
1197
1198 function isValidElementType(type) {
1199 if (typeof type === 'string' || typeof type === 'function') {
1200 return true;
1201 } // Note: typeof might be other than 'symbol' or 'number' (e.g. if it's a polyfill).
1202
1203
1204 if (type === REACT_FRAGMENT_TYPE || type === REACT_PROFILER_TYPE || type === REACT_DEBUG_TRACING_MODE_TYPE || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || type === REACT_LEGACY_HIDDEN_TYPE || enableScopeAPI) {
1205 return true;
1206 }
1207
1208 if (typeof type === 'object' && type !== null) {
1209 if (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || type.$$typeof === REACT_FUNDAMENTAL_TYPE || type.$$typeof === REACT_BLOCK_TYPE || type[0] === REACT_SERVER_BLOCK_TYPE) {
1210 return true;
1211 }
1212 }
1213
1214 return false;
1215 }
1216
1217 function typeOf(object) {
1218 if (typeof object === 'object' && object !== null) {
1219 var $$typeof = object.$$typeof;
1220
1221 switch ($$typeof) {
1222 case REACT_ELEMENT_TYPE:
1223 var type = object.type;
1224
1225 switch (type) {
1226 case REACT_FRAGMENT_TYPE:
1227 case REACT_PROFILER_TYPE:
1228 case REACT_STRICT_MODE_TYPE:
1229 case REACT_SUSPENSE_TYPE:
1230 case REACT_SUSPENSE_LIST_TYPE:
1231 return type;
1232
1233 default:
1234 var $$typeofType = type && type.$$typeof;
1235
1236 switch ($$typeofType) {
1237 case REACT_CONTEXT_TYPE:
1238 case REACT_FORWARD_REF_TYPE:
1239 case REACT_LAZY_TYPE:
1240 case REACT_MEMO_TYPE:
1241 case REACT_PROVIDER_TYPE:
1242 return $$typeofType;
1243
1244 default:
1245 return $$typeof;
1246 }
1247
1248 }
1249
1250 case REACT_PORTAL_TYPE:
1251 return $$typeof;
1252 }
1253 }
1254
1255 return undefined;
1256 }
1257
1258 var ContextConsumer = REACT_CONTEXT_TYPE;
1259 var ContextProvider = REACT_PROVIDER_TYPE;
1260 var Element = REACT_ELEMENT_TYPE;
1261 var ForwardRef = REACT_FORWARD_REF_TYPE;
1262 var Fragment = REACT_FRAGMENT_TYPE;
1263 var Lazy = REACT_LAZY_TYPE;
1264 var Memo = REACT_MEMO_TYPE;
1265 var Portal = REACT_PORTAL_TYPE;
1266 var Profiler = REACT_PROFILER_TYPE;
1267 var StrictMode = REACT_STRICT_MODE_TYPE;
1268 var Suspense = REACT_SUSPENSE_TYPE;
1269 var hasWarnedAboutDeprecatedIsAsyncMode = false;
1270 var hasWarnedAboutDeprecatedIsConcurrentMode = false; // AsyncMode should be deprecated
1271
1272 function isAsyncMode(object) {
1273 {
1274 if (!hasWarnedAboutDeprecatedIsAsyncMode) {
1275 hasWarnedAboutDeprecatedIsAsyncMode = true; // Using console['warn'] to evade Babel and ESLint
1276
1277 console['warn']('The ReactIs.isAsyncMode() alias has been deprecated, ' + 'and will be removed in React 18+.');
1278 }
1279 }
1280 return false;
1281 }
1282
1283 function isConcurrentMode(object) {
1284 {
1285 if (!hasWarnedAboutDeprecatedIsConcurrentMode) {
1286 hasWarnedAboutDeprecatedIsConcurrentMode = true; // Using console['warn'] to evade Babel and ESLint
1287
1288 console['warn']('The ReactIs.isConcurrentMode() alias has been deprecated, ' + 'and will be removed in React 18+.');
1289 }
1290 }
1291 return false;
1292 }
1293
1294 function isContextConsumer(object) {
1295 return typeOf(object) === REACT_CONTEXT_TYPE;
1296 }
1297
1298 function isContextProvider(object) {
1299 return typeOf(object) === REACT_PROVIDER_TYPE;
1300 }
1301
1302 function isElement(object) {
1303 return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;
1304 }
1305
1306 function isForwardRef(object) {
1307 return typeOf(object) === REACT_FORWARD_REF_TYPE;
1308 }
1309
1310 function isFragment(object) {
1311 return typeOf(object) === REACT_FRAGMENT_TYPE;
1312 }
1313
1314 function isLazy(object) {
1315 return typeOf(object) === REACT_LAZY_TYPE;
1316 }
1317
1318 function isMemo(object) {
1319 return typeOf(object) === REACT_MEMO_TYPE;
1320 }
1321
1322 function isPortal(object) {
1323 return typeOf(object) === REACT_PORTAL_TYPE;
1324 }
1325
1326 function isProfiler(object) {
1327 return typeOf(object) === REACT_PROFILER_TYPE;
1328 }
1329
1330 function isStrictMode(object) {
1331 return typeOf(object) === REACT_STRICT_MODE_TYPE;
1332 }
1333
1334 function isSuspense(object) {
1335 return typeOf(object) === REACT_SUSPENSE_TYPE;
1336 }
1337
1338 exports.ContextConsumer = ContextConsumer;
1339 exports.ContextProvider = ContextProvider;
1340 exports.Element = Element;
1341 exports.ForwardRef = ForwardRef;
1342 exports.Fragment = Fragment;
1343 exports.Lazy = Lazy;
1344 exports.Memo = Memo;
1345 exports.Portal = Portal;
1346 exports.Profiler = Profiler;
1347 exports.StrictMode = StrictMode;
1348 exports.Suspense = Suspense;
1349 exports.isAsyncMode = isAsyncMode;
1350 exports.isConcurrentMode = isConcurrentMode;
1351 exports.isContextConsumer = isContextConsumer;
1352 exports.isContextProvider = isContextProvider;
1353 exports.isElement = isElement;
1354 exports.isForwardRef = isForwardRef;
1355 exports.isFragment = isFragment;
1356 exports.isLazy = isLazy;
1357 exports.isMemo = isMemo;
1358 exports.isPortal = isPortal;
1359 exports.isProfiler = isProfiler;
1360 exports.isStrictMode = isStrictMode;
1361 exports.isSuspense = isSuspense;
1362 exports.isValidElementType = isValidElementType;
1363 exports.typeOf = typeOf;
1364 })();
1365 }
1366 });
1367
1368 var reactIs$1 = createCommonjsModule(function (module) {
1369
1370 {
1371 module.exports = reactIs_development$1;
1372 }
1373 });
1374
1375 function t(t) {
1376 return null != t && "object" == typeof t && 1 === t.nodeType;
1377 }
1378
1379 function e(t, e) {
1380 return (!e || "hidden" !== t) && "visible" !== t && "clip" !== t;
1381 }
1382
1383 function n(t, n) {
1384 if (t.clientHeight < t.scrollHeight || t.clientWidth < t.scrollWidth) {
1385 var r = getComputedStyle(t, null);
1386 return e(r.overflowY, n) || e(r.overflowX, n) || function (t) {
1387 var e = function (t) {
1388 if (!t.ownerDocument || !t.ownerDocument.defaultView) return null;
1389
1390 try {
1391 return t.ownerDocument.defaultView.frameElement;
1392 } catch (t) {
1393 return null;
1394 }
1395 }(t);
1396
1397 return !!e && (e.clientHeight < t.scrollHeight || e.clientWidth < t.scrollWidth);
1398 }(t);
1399 }
1400
1401 return !1;
1402 }
1403
1404 function r(t, e, n, r, i, o, l, d) {
1405 return o < t && l > e || o > t && l < e ? 0 : o <= t && d <= n || l >= e && d >= n ? o - t - r : l > e && d < n || o < t && d > n ? l - e + i : 0;
1406 }
1407
1408 function computeScrollIntoView (e, i) {
1409 var o = window,
1410 l = i.scrollMode,
1411 d = i.block,
1412 u = i.inline,
1413 h = i.boundary,
1414 a = i.skipOverflowHiddenElements,
1415 c = "function" == typeof h ? h : function (t) {
1416 return t !== h;
1417 };
1418 if (!t(e)) throw new TypeError("Invalid target");
1419
1420 for (var f = document.scrollingElement || document.documentElement, s = [], p = e; t(p) && c(p);) {
1421 if ((p = p.parentNode) === f) {
1422 s.push(p);
1423 break;
1424 }
1425
1426 p === document.body && n(p) && !n(document.documentElement) || n(p, a) && s.push(p);
1427 }
1428
1429 for (var g = o.visualViewport ? o.visualViewport.width : innerWidth, m = o.visualViewport ? o.visualViewport.height : innerHeight, w = window.scrollX || pageXOffset, v = window.scrollY || pageYOffset, W = e.getBoundingClientRect(), b = W.height, H = W.width, y = W.top, M = W.right, E = W.bottom, V = W.left, x = "start" === d || "nearest" === d ? y : "end" === d ? E : y + b / 2, I = "center" === u ? V + H / 2 : "end" === u ? M : V, C = [], T = 0; T < s.length; T++) {
1430 var k = s[T],
1431 B = k.getBoundingClientRect(),
1432 D = B.height,
1433 O = B.width,
1434 R = B.top,
1435 X = B.right,
1436 Y = B.bottom,
1437 L = B.left;
1438 if ("if-needed" === l && y >= 0 && V >= 0 && E <= m && M <= g && y >= R && E <= Y && V >= L && M <= X) return C;
1439 var S = getComputedStyle(k),
1440 j = parseInt(S.borderLeftWidth, 10),
1441 N = parseInt(S.borderTopWidth, 10),
1442 q = parseInt(S.borderRightWidth, 10),
1443 z = parseInt(S.borderBottomWidth, 10),
1444 A = 0,
1445 F = 0,
1446 G = "offsetWidth" in k ? k.offsetWidth - k.clientWidth - j - q : 0,
1447 J = "offsetHeight" in k ? k.offsetHeight - k.clientHeight - N - z : 0;
1448 if (f === k) A = "start" === d ? x : "end" === d ? x - m : "nearest" === d ? r(v, v + m, m, N, z, v + x, v + x + b, b) : x - m / 2, F = "start" === u ? I : "center" === u ? I - g / 2 : "end" === u ? I - g : r(w, w + g, g, j, q, w + I, w + I + H, H), A = Math.max(0, A + v), F = Math.max(0, F + w);else {
1449 A = "start" === d ? x - R - N : "end" === d ? x - Y + z + J : "nearest" === d ? r(R, Y, D, N, z + J, x, x + b, b) : x - (R + D / 2) + J / 2, F = "start" === u ? I - L - j : "center" === u ? I - (L + O / 2) + G / 2 : "end" === u ? I - X + q + G : r(L, X, O, j, q + G, I, I + H, H);
1450 var K = k.scrollLeft,
1451 P = k.scrollTop;
1452 x += P - (A = Math.max(0, Math.min(P + A, k.scrollHeight - D + J))), I += K - (F = Math.max(0, Math.min(K + F, k.scrollWidth - O + G)));
1453 }
1454 C.push({
1455 el: k,
1456 top: A,
1457 left: F
1458 });
1459 }
1460
1461 return C;
1462 }
1463
1464 var idCounter = 0;
1465 /**
1466 * Accepts a parameter and returns it if it's a function
1467 * or a noop function if it's not. This allows us to
1468 * accept a callback, but not worry about it if it's not
1469 * passed.
1470 * @param {Function} cb the callback
1471 * @return {Function} a function
1472 */
1473
1474 function cbToCb(cb) {
1475 return typeof cb === 'function' ? cb : noop;
1476 }
1477
1478 function noop() {}
1479 /**
1480 * Scroll node into view if necessary
1481 * @param {HTMLElement} node the element that should scroll into view
1482 * @param {HTMLElement} menuNode the menu element of the component
1483 */
1484
1485
1486 function scrollIntoView(node, menuNode) {
1487 if (!node) {
1488 return;
1489 }
1490
1491 var actions = computeScrollIntoView(node, {
1492 boundary: menuNode,
1493 block: 'nearest',
1494 scrollMode: 'if-needed'
1495 });
1496 actions.forEach(function (_ref) {
1497 var el = _ref.el,
1498 top = _ref.top,
1499 left = _ref.left;
1500 el.scrollTop = top;
1501 el.scrollLeft = left;
1502 });
1503 }
1504 /**
1505 * @param {HTMLElement} parent the parent node
1506 * @param {HTMLElement} child the child node
1507 * @return {Boolean} whether the parent is the child or the child is in the parent
1508 */
1509
1510
1511 function isOrContainsNode(parent, child) {
1512 return parent === child || child instanceof Node && parent.contains && parent.contains(child);
1513 }
1514 /**
1515 * Simple debounce implementation. Will call the given
1516 * function once after the time given has passed since
1517 * it was last called.
1518 * @param {Function} fn the function to call after the time
1519 * @param {Number} time the time to wait
1520 * @return {Function} the debounced function
1521 */
1522
1523
1524 function debounce(fn, time) {
1525 var timeoutId;
1526
1527 function cancel() {
1528 if (timeoutId) {
1529 clearTimeout(timeoutId);
1530 }
1531 }
1532
1533 function wrapper() {
1534 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
1535 args[_key] = arguments[_key];
1536 }
1537
1538 cancel();
1539 timeoutId = setTimeout(function () {
1540 timeoutId = null;
1541 fn.apply(void 0, args);
1542 }, time);
1543 }
1544
1545 wrapper.cancel = cancel;
1546 return wrapper;
1547 }
1548 /**
1549 * This is intended to be used to compose event handlers.
1550 * They are executed in order until one of them sets
1551 * `event.preventDownshiftDefault = true`.
1552 * @param {...Function} fns the event handler functions
1553 * @return {Function} the event handler to add to an element
1554 */
1555
1556
1557 function callAllEventHandlers() {
1558 for (var _len2 = arguments.length, fns = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
1559 fns[_key2] = arguments[_key2];
1560 }
1561
1562 return function (event) {
1563 for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
1564 args[_key3 - 1] = arguments[_key3];
1565 }
1566
1567 return fns.some(function (fn) {
1568 if (fn) {
1569 fn.apply(void 0, [event].concat(args));
1570 }
1571
1572 return event.preventDownshiftDefault || event.hasOwnProperty('nativeEvent') && event.nativeEvent.preventDownshiftDefault;
1573 });
1574 };
1575 }
1576
1577 function handleRefs() {
1578 for (var _len4 = arguments.length, refs = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
1579 refs[_key4] = arguments[_key4];
1580 }
1581
1582 return function (node) {
1583 refs.forEach(function (ref) {
1584 if (typeof ref === 'function') {
1585 ref(node);
1586 } else if (ref) {
1587 ref.current = node;
1588 }
1589 });
1590 };
1591 }
1592 /**
1593 * This generates a unique ID for an instance of Downshift
1594 * @return {String} the unique ID
1595 */
1596
1597
1598 function generateId() {
1599 return String(idCounter++);
1600 }
1601 /**
1602 * Resets idCounter to 0. Used for SSR.
1603 */
1604
1605
1606 function resetIdCounter() {
1607 idCounter = 0;
1608 }
1609 /**
1610 * Default implementation for status message. Only added when menu is open.
1611 * Will specift if there are results in the list, and if so, how many,
1612 * and what keys are relevant.
1613 *
1614 * @param {Object} param the downshift state and other relevant properties
1615 * @return {String} the a11y status message
1616 */
1617
1618
1619 function getA11yStatusMessage(_ref2) {
1620 var isOpen = _ref2.isOpen,
1621 resultCount = _ref2.resultCount,
1622 previousResultCount = _ref2.previousResultCount;
1623
1624 if (!isOpen) {
1625 return '';
1626 }
1627
1628 if (!resultCount) {
1629 return 'No results are available.';
1630 }
1631
1632 if (resultCount !== previousResultCount) {
1633 return resultCount + " result" + (resultCount === 1 ? ' is' : 's are') + " available, use up and down arrow keys to navigate. Press Enter key to select.";
1634 }
1635
1636 return '';
1637 }
1638 /**
1639 * Takes an argument and if it's an array, returns the first item in the array
1640 * otherwise returns the argument
1641 * @param {*} arg the maybe-array
1642 * @param {*} defaultValue the value if arg is falsey not defined
1643 * @return {*} the arg or it's first item
1644 */
1645
1646
1647 function unwrapArray(arg, defaultValue) {
1648 arg = Array.isArray(arg) ?
1649 /* istanbul ignore next (preact) */
1650 arg[0] : arg;
1651
1652 if (!arg && defaultValue) {
1653 return defaultValue;
1654 } else {
1655 return arg;
1656 }
1657 }
1658 /**
1659 * @param {Object} element (P)react element
1660 * @return {Boolean} whether it's a DOM element
1661 */
1662
1663
1664 function isDOMElement(element) {
1665
1666
1667 return typeof element.type === 'string';
1668 }
1669 /**
1670 * @param {Object} element (P)react element
1671 * @return {Object} the props
1672 */
1673
1674
1675 function getElementProps(element) {
1676
1677 return element.props;
1678 }
1679 /**
1680 * Throws a helpful error message for required properties. Useful
1681 * to be used as a default in destructuring or object params.
1682 * @param {String} fnName the function name
1683 * @param {String} propName the prop name
1684 */
1685
1686
1687 function requiredProp(fnName, propName) {
1688 // eslint-disable-next-line no-console
1689 console.error("The property \"" + propName + "\" is required in \"" + fnName + "\"");
1690 }
1691
1692 var stateKeys = ['highlightedIndex', 'inputValue', 'isOpen', 'selectedItem', 'type'];
1693 /**
1694 * @param {Object} state the state object
1695 * @return {Object} state that is relevant to downshift
1696 */
1697
1698 function pickState(state) {
1699 if (state === void 0) {
1700 state = {};
1701 }
1702
1703 var result = {};
1704 stateKeys.forEach(function (k) {
1705 if (state.hasOwnProperty(k)) {
1706 result[k] = state[k];
1707 }
1708 });
1709 return result;
1710 }
1711 /**
1712 * This will perform a shallow merge of the given state object
1713 * with the state coming from props
1714 * (for the controlled component scenario)
1715 * This is used in state updater functions so they're referencing
1716 * the right state regardless of where it comes from.
1717 *
1718 * @param {Object} state The state of the component/hook.
1719 * @param {Object} props The props that may contain controlled values.
1720 * @returns {Object} The merged controlled state.
1721 */
1722
1723
1724 function getState(state, props) {
1725 return Object.keys(state).reduce(function (prevState, key) {
1726 prevState[key] = isControlledProp(props, key) ? props[key] : state[key];
1727 return prevState;
1728 }, {});
1729 }
1730 /**
1731 * This determines whether a prop is a "controlled prop" meaning it is
1732 * state which is controlled by the outside of this component rather
1733 * than within this component.
1734 *
1735 * @param {Object} props The props that may contain controlled values.
1736 * @param {String} key the key to check
1737 * @return {Boolean} whether it is a controlled controlled prop
1738 */
1739
1740
1741 function isControlledProp(props, key) {
1742 return props[key] !== undefined;
1743 }
1744 /**
1745 * Normalizes the 'key' property of a KeyboardEvent in IE/Edge
1746 * @param {Object} event a keyboardEvent object
1747 * @return {String} keyboard key
1748 */
1749
1750
1751 function normalizeArrowKey(event) {
1752 var key = event.key,
1753 keyCode = event.keyCode;
1754 /* istanbul ignore next (ie) */
1755
1756 if (keyCode >= 37 && keyCode <= 40 && key.indexOf('Arrow') !== 0) {
1757 return "Arrow" + key;
1758 }
1759
1760 return key;
1761 }
1762 /**
1763 * Simple check if the value passed is object literal
1764 * @param {*} obj any things
1765 * @return {Boolean} whether it's object literal
1766 */
1767
1768
1769 function isPlainObject(obj) {
1770 return Object.prototype.toString.call(obj) === '[object Object]';
1771 }
1772 /**
1773 * Returns the new index in the list, in a circular way. If next value is out of bonds from the total,
1774 * it will wrap to either 0 or itemCount - 1.
1775 *
1776 * @param {number} moveAmount Number of positions to move. Negative to move backwards, positive forwards.
1777 * @param {number} baseIndex The initial position to move from.
1778 * @param {number} itemCount The total number of items.
1779 * @param {Function} getItemNodeFromIndex Used to check if item is disabled.
1780 * @param {boolean} circular Specify if navigation is circular. Default is true.
1781 * @returns {number} The new index after the move.
1782 */
1783
1784
1785 function getNextWrappingIndex(moveAmount, baseIndex, itemCount, getItemNodeFromIndex, circular) {
1786 if (circular === void 0) {
1787 circular = true;
1788 }
1789
1790 if (itemCount === 0) {
1791 return -1;
1792 }
1793
1794 var itemsLastIndex = itemCount - 1;
1795
1796 if (typeof baseIndex !== 'number' || baseIndex < 0 || baseIndex >= itemCount) {
1797 baseIndex = moveAmount > 0 ? -1 : itemsLastIndex + 1;
1798 }
1799
1800 var newIndex = baseIndex + moveAmount;
1801
1802 if (newIndex < 0) {
1803 newIndex = circular ? itemsLastIndex : 0;
1804 } else if (newIndex > itemsLastIndex) {
1805 newIndex = circular ? 0 : itemsLastIndex;
1806 }
1807
1808 var nonDisabledNewIndex = getNextNonDisabledIndex(moveAmount, newIndex, itemCount, getItemNodeFromIndex, circular);
1809
1810 if (nonDisabledNewIndex === -1) {
1811 return baseIndex >= itemCount ? -1 : baseIndex;
1812 }
1813
1814 return nonDisabledNewIndex;
1815 }
1816 /**
1817 * Returns the next index in the list of an item that is not disabled.
1818 *
1819 * @param {number} moveAmount Number of positions to move. Negative to move backwards, positive forwards.
1820 * @param {number} baseIndex The initial position to move from.
1821 * @param {number} itemCount The total number of items.
1822 * @param {Function} getItemNodeFromIndex Used to check if item is disabled.
1823 * @param {boolean} circular Specify if navigation is circular. Default is true.
1824 * @returns {number} The new index. Returns baseIndex if item is not disabled. Returns next non-disabled item otherwise. If no non-disabled found it will return -1.
1825 */
1826
1827
1828 function getNextNonDisabledIndex(moveAmount, baseIndex, itemCount, getItemNodeFromIndex, circular) {
1829 var currentElementNode = getItemNodeFromIndex(baseIndex);
1830
1831 if (!currentElementNode || !currentElementNode.hasAttribute('disabled')) {
1832 return baseIndex;
1833 }
1834
1835 if (moveAmount > 0) {
1836 for (var index = baseIndex + 1; index < itemCount; index++) {
1837 if (!getItemNodeFromIndex(index).hasAttribute('disabled')) {
1838 return index;
1839 }
1840 }
1841 } else {
1842 for (var _index = baseIndex - 1; _index >= 0; _index--) {
1843 if (!getItemNodeFromIndex(_index).hasAttribute('disabled')) {
1844 return _index;
1845 }
1846 }
1847 }
1848
1849 if (circular) {
1850 return moveAmount > 0 ? getNextNonDisabledIndex(1, 0, itemCount, getItemNodeFromIndex, false) : getNextNonDisabledIndex(-1, itemCount - 1, itemCount, getItemNodeFromIndex, false);
1851 }
1852
1853 return -1;
1854 }
1855 /**
1856 * Checks if event target is within the downshift elements.
1857 *
1858 * @param {EventTarget} target Target to check.
1859 * @param {HTMLElement[]} downshiftElements The elements that form downshift (list, toggle button etc).
1860 * @param {Document} document The document.
1861 * @param {boolean} checkActiveElement Whether to also check activeElement.
1862 *
1863 * @returns {boolean} Whether or not the target is within downshift elements.
1864 */
1865
1866
1867 function targetWithinDownshift(target, downshiftElements, document, checkActiveElement) {
1868 if (checkActiveElement === void 0) {
1869 checkActiveElement = true;
1870 }
1871
1872 return downshiftElements.some(function (contextNode) {
1873 return contextNode && (isOrContainsNode(contextNode, target) || checkActiveElement && isOrContainsNode(contextNode, document.activeElement));
1874 });
1875 }
1876
1877 function validateControlledUnchanged(state, prevProps, nextProps) {
1878
1879 var warningDescription = "This prop should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled Downshift element for the lifetime of the component. More info: https://github.com/downshift-js/downshift#control-props";
1880 Object.keys(state).forEach(function (propKey) {
1881 if (prevProps[propKey] !== undefined && nextProps[propKey] === undefined) {
1882 // eslint-disable-next-line no-console
1883 console.error("downshift: A component has changed the controlled prop \"" + propKey + "\" to be uncontrolled. " + warningDescription);
1884 } else if (prevProps[propKey] === undefined && nextProps[propKey] !== undefined) {
1885 // eslint-disable-next-line no-console
1886 console.error("downshift: A component has changed the uncontrolled prop \"" + propKey + "\" to be controlled. " + warningDescription);
1887 }
1888 });
1889 }
1890
1891 var cleanupStatus = debounce(function (documentProp) {
1892 getStatusDiv(documentProp).textContent = '';
1893 }, 500);
1894 /**
1895 * @param {String} status the status message
1896 * @param {Object} documentProp document passed by the user.
1897 */
1898
1899 function setStatus(status, documentProp) {
1900 var div = getStatusDiv(documentProp);
1901
1902 if (!status) {
1903 return;
1904 }
1905
1906 div.textContent = status;
1907 cleanupStatus(documentProp);
1908 }
1909 /**
1910 * Get the status node or create it if it does not already exist.
1911 * @param {Object} documentProp document passed by the user.
1912 * @return {HTMLElement} the status node.
1913 */
1914
1915
1916 function getStatusDiv(documentProp) {
1917 if (documentProp === void 0) {
1918 documentProp = document;
1919 }
1920
1921 var statusDiv = documentProp.getElementById('a11y-status-message');
1922
1923 if (statusDiv) {
1924 return statusDiv;
1925 }
1926
1927 statusDiv = documentProp.createElement('div');
1928 statusDiv.setAttribute('id', 'a11y-status-message');
1929 statusDiv.setAttribute('role', 'status');
1930 statusDiv.setAttribute('aria-live', 'polite');
1931 statusDiv.setAttribute('aria-relevant', 'additions text');
1932 Object.assign(statusDiv.style, {
1933 border: '0',
1934 clip: 'rect(0 0 0 0)',
1935 height: '1px',
1936 margin: '-1px',
1937 overflow: 'hidden',
1938 padding: '0',
1939 position: 'absolute',
1940 width: '1px'
1941 });
1942 documentProp.body.appendChild(statusDiv);
1943 return statusDiv;
1944 }
1945
1946 var unknown = '__autocomplete_unknown__' ;
1947 var mouseUp = '__autocomplete_mouseup__' ;
1948 var itemMouseEnter = '__autocomplete_item_mouseenter__' ;
1949 var keyDownArrowUp = '__autocomplete_keydown_arrow_up__' ;
1950 var keyDownArrowDown = '__autocomplete_keydown_arrow_down__' ;
1951 var keyDownEscape = '__autocomplete_keydown_escape__' ;
1952 var keyDownEnter = '__autocomplete_keydown_enter__' ;
1953 var keyDownHome = '__autocomplete_keydown_home__' ;
1954 var keyDownEnd = '__autocomplete_keydown_end__' ;
1955 var clickItem = '__autocomplete_click_item__' ;
1956 var blurInput = '__autocomplete_blur_input__' ;
1957 var changeInput = '__autocomplete_change_input__' ;
1958 var keyDownSpaceButton = '__autocomplete_keydown_space_button__' ;
1959 var clickButton = '__autocomplete_click_button__' ;
1960 var blurButton = '__autocomplete_blur_button__' ;
1961 var controlledPropUpdatedSelectedItem = '__autocomplete_controlled_prop_updated_selected_item__' ;
1962 var touchEnd = '__autocomplete_touchend__' ;
1963
1964 var stateChangeTypes = /*#__PURE__*/Object.freeze({
1965 __proto__: null,
1966 unknown: unknown,
1967 mouseUp: mouseUp,
1968 itemMouseEnter: itemMouseEnter,
1969 keyDownArrowUp: keyDownArrowUp,
1970 keyDownArrowDown: keyDownArrowDown,
1971 keyDownEscape: keyDownEscape,
1972 keyDownEnter: keyDownEnter,
1973 keyDownHome: keyDownHome,
1974 keyDownEnd: keyDownEnd,
1975 clickItem: clickItem,
1976 blurInput: blurInput,
1977 changeInput: changeInput,
1978 keyDownSpaceButton: keyDownSpaceButton,
1979 clickButton: clickButton,
1980 blurButton: blurButton,
1981 controlledPropUpdatedSelectedItem: controlledPropUpdatedSelectedItem,
1982 touchEnd: touchEnd
1983 });
1984
1985 var Downshift = /*#__PURE__*/function () {
1986 var Downshift = /*#__PURE__*/function (_Component) {
1987 _inheritsLoose(Downshift, _Component);
1988
1989 function Downshift(_props) {
1990 var _this;
1991
1992 _this = _Component.call(this, _props) || this; // fancy destructuring + defaults + aliases
1993 // this basically says each value of state should either be set to
1994 // the initial value or the default value if the initial value is not provided
1995
1996 _this.id = _this.props.id || "downshift-" + generateId();
1997 _this.menuId = _this.props.menuId || _this.id + "-menu";
1998 _this.labelId = _this.props.labelId || _this.id + "-label";
1999 _this.inputId = _this.props.inputId || _this.id + "-input";
2000
2001 _this.getItemId = _this.props.getItemId || function (index) {
2002 return _this.id + "-item-" + index;
2003 };
2004
2005 _this.input = null;
2006 _this.items = [];
2007 _this.itemCount = null;
2008 _this.previousResultCount = 0;
2009 _this.timeoutIds = [];
2010
2011 _this.internalSetTimeout = function (fn, time) {
2012 var id = setTimeout(function () {
2013 _this.timeoutIds = _this.timeoutIds.filter(function (i) {
2014 return i !== id;
2015 });
2016 fn();
2017 }, time);
2018
2019 _this.timeoutIds.push(id);
2020 };
2021
2022 _this.setItemCount = function (count) {
2023 _this.itemCount = count;
2024 };
2025
2026 _this.unsetItemCount = function () {
2027 _this.itemCount = null;
2028 };
2029
2030 _this.setHighlightedIndex = function (highlightedIndex, otherStateToSet) {
2031 if (highlightedIndex === void 0) {
2032 highlightedIndex = _this.props.defaultHighlightedIndex;
2033 }
2034
2035 if (otherStateToSet === void 0) {
2036 otherStateToSet = {};
2037 }
2038
2039 otherStateToSet = pickState(otherStateToSet);
2040
2041 _this.internalSetState(_extends({
2042 highlightedIndex: highlightedIndex
2043 }, otherStateToSet));
2044 };
2045
2046 _this.clearSelection = function (cb) {
2047 _this.internalSetState({
2048 selectedItem: null,
2049 inputValue: '',
2050 highlightedIndex: _this.props.defaultHighlightedIndex,
2051 isOpen: _this.props.defaultIsOpen
2052 }, cb);
2053 };
2054
2055 _this.selectItem = function (item, otherStateToSet, cb) {
2056 otherStateToSet = pickState(otherStateToSet);
2057
2058 _this.internalSetState(_extends({
2059 isOpen: _this.props.defaultIsOpen,
2060 highlightedIndex: _this.props.defaultHighlightedIndex,
2061 selectedItem: item,
2062 inputValue: _this.props.itemToString(item)
2063 }, otherStateToSet), cb);
2064 };
2065
2066 _this.selectItemAtIndex = function (itemIndex, otherStateToSet, cb) {
2067 var item = _this.items[itemIndex];
2068
2069 if (item == null) {
2070 return;
2071 }
2072
2073 _this.selectItem(item, otherStateToSet, cb);
2074 };
2075
2076 _this.selectHighlightedItem = function (otherStateToSet, cb) {
2077 return _this.selectItemAtIndex(_this.getState().highlightedIndex, otherStateToSet, cb);
2078 };
2079
2080 _this.internalSetState = function (stateToSet, cb) {
2081 var isItemSelected, onChangeArg;
2082 var onStateChangeArg = {};
2083 var isStateToSetFunction = typeof stateToSet === 'function'; // we want to call `onInputValueChange` before the `setState` call
2084 // so someone controlling the `inputValue` state gets notified of
2085 // the input change as soon as possible. This avoids issues with
2086 // preserving the cursor position.
2087 // See https://github.com/downshift-js/downshift/issues/217 for more info.
2088
2089 if (!isStateToSetFunction && stateToSet.hasOwnProperty('inputValue')) {
2090 _this.props.onInputValueChange(stateToSet.inputValue, _extends({}, _this.getStateAndHelpers(), stateToSet));
2091 }
2092
2093 return _this.setState(function (state) {
2094 state = _this.getState(state);
2095 var newStateToSet = isStateToSetFunction ? stateToSet(state) : stateToSet; // Your own function that could modify the state that will be set.
2096
2097 newStateToSet = _this.props.stateReducer(state, newStateToSet); // checks if an item is selected, regardless of if it's different from
2098 // what was selected before
2099 // used to determine if onSelect and onChange callbacks should be called
2100
2101 isItemSelected = newStateToSet.hasOwnProperty('selectedItem'); // this keeps track of the object we want to call with setState
2102
2103 var nextState = {}; // this is just used to tell whether the state changed
2104 // and we're trying to update that state. OR if the selection has changed and we're
2105 // trying to update the selection
2106
2107 if (isItemSelected && newStateToSet.selectedItem !== state.selectedItem) {
2108 onChangeArg = newStateToSet.selectedItem;
2109 }
2110
2111 newStateToSet.type = newStateToSet.type || unknown;
2112 Object.keys(newStateToSet).forEach(function (key) {
2113 // onStateChangeArg should only have the state that is
2114 // actually changing
2115 if (state[key] !== newStateToSet[key]) {
2116 onStateChangeArg[key] = newStateToSet[key];
2117 } // the type is useful for the onStateChangeArg
2118 // but we don't actually want to set it in internal state.
2119 // this is an undocumented feature for now... Not all internalSetState
2120 // calls support it and I'm not certain we want them to yet.
2121 // But it enables users controlling the isOpen state to know when
2122 // the isOpen state changes due to mouseup events which is quite handy.
2123
2124
2125 if (key === 'type') {
2126 return;
2127 }
2128
2129 newStateToSet[key]; // if it's coming from props, then we don't care to set it internally
2130
2131 if (!isControlledProp(_this.props, key)) {
2132 nextState[key] = newStateToSet[key];
2133 }
2134 }); // if stateToSet is a function, then we weren't able to call onInputValueChange
2135 // earlier, so we'll call it now that we know what the inputValue state will be.
2136
2137 if (isStateToSetFunction && newStateToSet.hasOwnProperty('inputValue')) {
2138 _this.props.onInputValueChange(newStateToSet.inputValue, _extends({}, _this.getStateAndHelpers(), newStateToSet));
2139 }
2140
2141 return nextState;
2142 }, function () {
2143 // call the provided callback if it's a function
2144 cbToCb(cb)(); // only call the onStateChange and onChange callbacks if
2145 // we have relevant information to pass them.
2146
2147 var hasMoreStateThanType = Object.keys(onStateChangeArg).length > 1;
2148
2149 if (hasMoreStateThanType) {
2150 _this.props.onStateChange(onStateChangeArg, _this.getStateAndHelpers());
2151 }
2152
2153 if (isItemSelected) {
2154 _this.props.onSelect(stateToSet.selectedItem, _this.getStateAndHelpers());
2155 }
2156
2157 if (onChangeArg !== undefined) {
2158 _this.props.onChange(onChangeArg, _this.getStateAndHelpers());
2159 } // this is currently undocumented and therefore subject to change
2160 // We'll try to not break it, but just be warned.
2161
2162
2163 _this.props.onUserAction(onStateChangeArg, _this.getStateAndHelpers());
2164 });
2165 };
2166
2167 _this.rootRef = function (node) {
2168 return _this._rootNode = node;
2169 };
2170
2171 _this.getRootProps = function (_temp, _temp2) {
2172 var _extends2;
2173
2174 var _ref = _temp === void 0 ? {} : _temp,
2175 _ref$refKey = _ref.refKey,
2176 refKey = _ref$refKey === void 0 ? 'ref' : _ref$refKey,
2177 ref = _ref.ref,
2178 rest = _objectWithoutPropertiesLoose(_ref, ["refKey", "ref"]);
2179
2180 var _ref2 = _temp2 === void 0 ? {} : _temp2,
2181 _ref2$suppressRefErro = _ref2.suppressRefError,
2182 suppressRefError = _ref2$suppressRefErro === void 0 ? false : _ref2$suppressRefErro;
2183
2184 // this is used in the render to know whether the user has called getRootProps.
2185 // It uses that to know whether to apply the props automatically
2186 _this.getRootProps.called = true;
2187 _this.getRootProps.refKey = refKey;
2188 _this.getRootProps.suppressRefError = suppressRefError;
2189
2190 var _this$getState = _this.getState(),
2191 isOpen = _this$getState.isOpen;
2192
2193 return _extends((_extends2 = {}, _extends2[refKey] = handleRefs(ref, _this.rootRef), _extends2.role = 'combobox', _extends2['aria-expanded'] = isOpen, _extends2['aria-haspopup'] = 'listbox', _extends2['aria-owns'] = isOpen ? _this.menuId : null, _extends2['aria-labelledby'] = _this.labelId, _extends2), rest);
2194 };
2195
2196 _this.keyDownHandlers = {
2197 ArrowDown: function ArrowDown(event) {
2198 var _this2 = this;
2199
2200 event.preventDefault();
2201
2202 if (this.getState().isOpen) {
2203 var amount = event.shiftKey ? 5 : 1;
2204 this.moveHighlightedIndex(amount, {
2205 type: keyDownArrowDown
2206 });
2207 } else {
2208 this.internalSetState({
2209 isOpen: true,
2210 type: keyDownArrowDown
2211 }, function () {
2212 var itemCount = _this2.getItemCount();
2213
2214 if (itemCount > 0) {
2215 var _this2$getState = _this2.getState(),
2216 highlightedIndex = _this2$getState.highlightedIndex;
2217
2218 var nextHighlightedIndex = getNextWrappingIndex(1, highlightedIndex, itemCount, function (index) {
2219 return _this2.getItemNodeFromIndex(index);
2220 });
2221
2222 _this2.setHighlightedIndex(nextHighlightedIndex, {
2223 type: keyDownArrowDown
2224 });
2225 }
2226 });
2227 }
2228 },
2229 ArrowUp: function ArrowUp(event) {
2230 var _this3 = this;
2231
2232 event.preventDefault();
2233
2234 if (this.getState().isOpen) {
2235 var amount = event.shiftKey ? -5 : -1;
2236 this.moveHighlightedIndex(amount, {
2237 type: keyDownArrowUp
2238 });
2239 } else {
2240 this.internalSetState({
2241 isOpen: true,
2242 type: keyDownArrowUp
2243 }, function () {
2244 var itemCount = _this3.getItemCount();
2245
2246 if (itemCount > 0) {
2247 var _this3$getState = _this3.getState(),
2248 highlightedIndex = _this3$getState.highlightedIndex;
2249
2250 var nextHighlightedIndex = getNextWrappingIndex(-1, highlightedIndex, itemCount, function (index) {
2251 return _this3.getItemNodeFromIndex(index);
2252 });
2253
2254 _this3.setHighlightedIndex(nextHighlightedIndex, {
2255 type: keyDownArrowUp
2256 });
2257 }
2258 });
2259 }
2260 },
2261 Enter: function Enter(event) {
2262 if (event.which === 229) {
2263 return;
2264 }
2265
2266 var _this$getState2 = this.getState(),
2267 isOpen = _this$getState2.isOpen,
2268 highlightedIndex = _this$getState2.highlightedIndex;
2269
2270 if (isOpen && highlightedIndex != null) {
2271 event.preventDefault();
2272 var item = this.items[highlightedIndex];
2273 var itemNode = this.getItemNodeFromIndex(highlightedIndex);
2274
2275 if (item == null || itemNode && itemNode.hasAttribute('disabled')) {
2276 return;
2277 }
2278
2279 this.selectHighlightedItem({
2280 type: keyDownEnter
2281 });
2282 }
2283 },
2284 Escape: function Escape(event) {
2285 event.preventDefault();
2286 this.reset(_extends({
2287 type: keyDownEscape
2288 }, !this.state.isOpen && {
2289 selectedItem: null,
2290 inputValue: ''
2291 }));
2292 }
2293 };
2294 _this.buttonKeyDownHandlers = _extends({}, _this.keyDownHandlers, {
2295 ' ': function _(event) {
2296 event.preventDefault();
2297 this.toggleMenu({
2298 type: keyDownSpaceButton
2299 });
2300 }
2301 });
2302 _this.inputKeyDownHandlers = _extends({}, _this.keyDownHandlers, {
2303 Home: function Home(event) {
2304 var _this4 = this;
2305
2306 event.preventDefault();
2307 var itemCount = this.getItemCount();
2308
2309 var _this$getState3 = this.getState(),
2310 isOpen = _this$getState3.isOpen;
2311
2312 if (itemCount <= 0 || !isOpen) {
2313 return;
2314 } // get next non-disabled starting downwards from 0 if that's disabled.
2315
2316
2317 var newHighlightedIndex = getNextNonDisabledIndex(1, 0, itemCount, function (index) {
2318 return _this4.getItemNodeFromIndex(index);
2319 }, false);
2320 this.setHighlightedIndex(newHighlightedIndex, {
2321 type: keyDownHome
2322 });
2323 },
2324 End: function End(event) {
2325 var _this5 = this;
2326
2327 event.preventDefault();
2328 var itemCount = this.getItemCount();
2329
2330 var _this$getState4 = this.getState(),
2331 isOpen = _this$getState4.isOpen;
2332
2333 if (itemCount <= 0 || !isOpen) {
2334 return;
2335 } // get next non-disabled starting upwards from last index if that's disabled.
2336
2337
2338 var newHighlightedIndex = getNextNonDisabledIndex(-1, itemCount - 1, itemCount, function (index) {
2339 return _this5.getItemNodeFromIndex(index);
2340 }, false);
2341 this.setHighlightedIndex(newHighlightedIndex, {
2342 type: keyDownEnd
2343 });
2344 }
2345 });
2346
2347 _this.getToggleButtonProps = function (_temp3) {
2348 var _ref3 = _temp3 === void 0 ? {} : _temp3,
2349 onClick = _ref3.onClick,
2350 onPress = _ref3.onPress,
2351 onKeyDown = _ref3.onKeyDown,
2352 onKeyUp = _ref3.onKeyUp,
2353 onBlur = _ref3.onBlur,
2354 rest = _objectWithoutPropertiesLoose(_ref3, ["onClick", "onPress", "onKeyDown", "onKeyUp", "onBlur"]);
2355
2356 var _this$getState5 = _this.getState(),
2357 isOpen = _this$getState5.isOpen;
2358
2359 var enabledEventHandlers = {
2360 onClick: callAllEventHandlers(onClick, _this.buttonHandleClick),
2361 onKeyDown: callAllEventHandlers(onKeyDown, _this.buttonHandleKeyDown),
2362 onKeyUp: callAllEventHandlers(onKeyUp, _this.buttonHandleKeyUp),
2363 onBlur: callAllEventHandlers(onBlur, _this.buttonHandleBlur)
2364 };
2365 var eventHandlers = rest.disabled ? {} : enabledEventHandlers;
2366 return _extends({
2367 type: 'button',
2368 role: 'button',
2369 'aria-label': isOpen ? 'close menu' : 'open menu',
2370 'aria-haspopup': true,
2371 'data-toggle': true
2372 }, eventHandlers, rest);
2373 };
2374
2375 _this.buttonHandleKeyUp = function (event) {
2376 // Prevent click event from emitting in Firefox
2377 event.preventDefault();
2378 };
2379
2380 _this.buttonHandleKeyDown = function (event) {
2381 var key = normalizeArrowKey(event);
2382
2383 if (_this.buttonKeyDownHandlers[key]) {
2384 _this.buttonKeyDownHandlers[key].call(_assertThisInitialized(_this), event);
2385 }
2386 };
2387
2388 _this.buttonHandleClick = function (event) {
2389 event.preventDefault(); // handle odd case for Safari and Firefox which
2390 // don't give the button the focus properly.
2391
2392 /* istanbul ignore if (can't reasonably test this) */
2393
2394 if ( _this.props.environment.document.activeElement === _this.props.environment.document.body) {
2395 event.target.focus();
2396 } // to simplify testing components that use downshift, we'll not wrap this in a setTimeout
2397 // if the NODE_ENV is test. With the proper build system, this should be dead code eliminated
2398 // when building for production and should therefore have no impact on production code.
2399
2400
2401 {
2402 // Ensure that toggle of menu occurs after the potential blur event in iOS
2403 _this.internalSetTimeout(function () {
2404 return _this.toggleMenu({
2405 type: clickButton
2406 });
2407 });
2408 }
2409 };
2410
2411 _this.buttonHandleBlur = function (event) {
2412 var blurTarget = event.target; // Save blur target for comparison with activeElement later
2413 // Need setTimeout, so that when the user presses Tab, the activeElement is the next focused element, not body element
2414
2415 _this.internalSetTimeout(function () {
2416 if (!_this.isMouseDown && (_this.props.environment.document.activeElement == null || _this.props.environment.document.activeElement.id !== _this.inputId) && _this.props.environment.document.activeElement !== blurTarget // Do nothing if we refocus the same element again (to solve issue in Safari on iOS)
2417 ) {
2418 _this.reset({
2419 type: blurButton
2420 });
2421 }
2422 });
2423 };
2424
2425 _this.getLabelProps = function (props) {
2426 return _extends({
2427 htmlFor: _this.inputId,
2428 id: _this.labelId
2429 }, props);
2430 };
2431
2432 _this.getInputProps = function (_temp4) {
2433 var _ref4 = _temp4 === void 0 ? {} : _temp4,
2434 onKeyDown = _ref4.onKeyDown,
2435 onBlur = _ref4.onBlur,
2436 onChange = _ref4.onChange,
2437 onInput = _ref4.onInput,
2438 onChangeText = _ref4.onChangeText,
2439 rest = _objectWithoutPropertiesLoose(_ref4, ["onKeyDown", "onBlur", "onChange", "onInput", "onChangeText"]);
2440
2441 var onChangeKey;
2442 var eventHandlers = {};
2443 /* istanbul ignore next (preact) */
2444
2445 {
2446 onChangeKey = 'onChange';
2447 }
2448
2449 var _this$getState6 = _this.getState(),
2450 inputValue = _this$getState6.inputValue,
2451 isOpen = _this$getState6.isOpen,
2452 highlightedIndex = _this$getState6.highlightedIndex;
2453
2454 if (!rest.disabled) {
2455 var _eventHandlers;
2456
2457 eventHandlers = (_eventHandlers = {}, _eventHandlers[onChangeKey] = callAllEventHandlers(onChange, onInput, _this.inputHandleChange), _eventHandlers.onKeyDown = callAllEventHandlers(onKeyDown, _this.inputHandleKeyDown), _eventHandlers.onBlur = callAllEventHandlers(onBlur, _this.inputHandleBlur), _eventHandlers);
2458 }
2459
2460 return _extends({
2461 'aria-autocomplete': 'list',
2462 'aria-activedescendant': isOpen && typeof highlightedIndex === 'number' && highlightedIndex >= 0 ? _this.getItemId(highlightedIndex) : null,
2463 'aria-controls': isOpen ? _this.menuId : null,
2464 'aria-labelledby': _this.labelId,
2465 // https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion
2466 // revert back since autocomplete="nope" is ignored on latest Chrome and Opera
2467 autoComplete: 'off',
2468 value: inputValue,
2469 id: _this.inputId
2470 }, eventHandlers, rest);
2471 };
2472
2473 _this.inputHandleKeyDown = function (event) {
2474 var key = normalizeArrowKey(event);
2475
2476 if (key && _this.inputKeyDownHandlers[key]) {
2477 _this.inputKeyDownHandlers[key].call(_assertThisInitialized(_this), event);
2478 }
2479 };
2480
2481 _this.inputHandleChange = function (event) {
2482 _this.internalSetState({
2483 type: changeInput,
2484 isOpen: true,
2485 inputValue: event.target.value,
2486 highlightedIndex: _this.props.defaultHighlightedIndex
2487 });
2488 };
2489
2490 _this.inputHandleBlur = function () {
2491 // Need setTimeout, so that when the user presses Tab, the activeElement is the next focused element, not the body element
2492 _this.internalSetTimeout(function () {
2493 var downshiftButtonIsActive = _this.props.environment.document && !!_this.props.environment.document.activeElement && !!_this.props.environment.document.activeElement.dataset && _this.props.environment.document.activeElement.dataset.toggle && _this._rootNode && _this._rootNode.contains(_this.props.environment.document.activeElement);
2494
2495 if (!_this.isMouseDown && !downshiftButtonIsActive) {
2496 _this.reset({
2497 type: blurInput
2498 });
2499 }
2500 });
2501 };
2502
2503 _this.menuRef = function (node) {
2504 _this._menuNode = node;
2505 };
2506
2507 _this.getMenuProps = function (_temp5, _temp6) {
2508 var _extends3;
2509
2510 var _ref5 = _temp5 === void 0 ? {} : _temp5,
2511 _ref5$refKey = _ref5.refKey,
2512 refKey = _ref5$refKey === void 0 ? 'ref' : _ref5$refKey,
2513 ref = _ref5.ref,
2514 props = _objectWithoutPropertiesLoose(_ref5, ["refKey", "ref"]);
2515
2516 var _ref6 = _temp6 === void 0 ? {} : _temp6,
2517 _ref6$suppressRefErro = _ref6.suppressRefError,
2518 suppressRefError = _ref6$suppressRefErro === void 0 ? false : _ref6$suppressRefErro;
2519
2520 _this.getMenuProps.called = true;
2521 _this.getMenuProps.refKey = refKey;
2522 _this.getMenuProps.suppressRefError = suppressRefError;
2523 return _extends((_extends3 = {}, _extends3[refKey] = handleRefs(ref, _this.menuRef), _extends3.role = 'listbox', _extends3['aria-labelledby'] = props && props['aria-label'] ? null : _this.labelId, _extends3.id = _this.menuId, _extends3), props);
2524 };
2525
2526 _this.getItemProps = function (_temp7) {
2527 var _enabledEventHandlers;
2528
2529 var _ref7 = _temp7 === void 0 ? {} : _temp7,
2530 onMouseMove = _ref7.onMouseMove,
2531 onMouseDown = _ref7.onMouseDown,
2532 onClick = _ref7.onClick,
2533 onPress = _ref7.onPress,
2534 index = _ref7.index,
2535 _ref7$item = _ref7.item,
2536 item = _ref7$item === void 0 ? requiredProp('getItemProps', 'item') : _ref7$item,
2537 rest = _objectWithoutPropertiesLoose(_ref7, ["onMouseMove", "onMouseDown", "onClick", "onPress", "index", "item"]);
2538
2539 if (index === undefined) {
2540 _this.items.push(item);
2541
2542 index = _this.items.indexOf(item);
2543 } else {
2544 _this.items[index] = item;
2545 }
2546
2547 var onSelectKey = 'onClick';
2548 var customClickHandler = onClick;
2549 var enabledEventHandlers = (_enabledEventHandlers = {
2550 // onMouseMove is used over onMouseEnter here. onMouseMove
2551 // is only triggered on actual mouse movement while onMouseEnter
2552 // can fire on DOM changes, interrupting keyboard navigation
2553 onMouseMove: callAllEventHandlers(onMouseMove, function () {
2554 if (index === _this.getState().highlightedIndex) {
2555 return;
2556 }
2557
2558 _this.setHighlightedIndex(index, {
2559 type: itemMouseEnter
2560 }); // We never want to manually scroll when changing state based
2561 // on `onMouseMove` because we will be moving the element out
2562 // from under the user which is currently scrolling/moving the
2563 // cursor
2564
2565
2566 _this.avoidScrolling = true;
2567
2568 _this.internalSetTimeout(function () {
2569 return _this.avoidScrolling = false;
2570 }, 250);
2571 }),
2572 onMouseDown: callAllEventHandlers(onMouseDown, function (event) {
2573 // This prevents the activeElement from being changed
2574 // to the item so it can remain with the current activeElement
2575 // which is a more common use case.
2576 event.preventDefault();
2577 })
2578 }, _enabledEventHandlers[onSelectKey] = callAllEventHandlers(customClickHandler, function () {
2579 _this.selectItemAtIndex(index, {
2580 type: clickItem
2581 });
2582 }), _enabledEventHandlers); // Passing down the onMouseDown handler to prevent redirect
2583 // of the activeElement if clicking on disabled items
2584
2585 var eventHandlers = rest.disabled ? {
2586 onMouseDown: enabledEventHandlers.onMouseDown
2587 } : enabledEventHandlers;
2588 return _extends({
2589 id: _this.getItemId(index),
2590 role: 'option',
2591 'aria-selected': _this.getState().highlightedIndex === index
2592 }, eventHandlers, rest);
2593 };
2594
2595 _this.clearItems = function () {
2596 _this.items = [];
2597 };
2598
2599 _this.reset = function (otherStateToSet, cb) {
2600 if (otherStateToSet === void 0) {
2601 otherStateToSet = {};
2602 }
2603
2604 otherStateToSet = pickState(otherStateToSet);
2605
2606 _this.internalSetState(function (_ref8) {
2607 var selectedItem = _ref8.selectedItem;
2608 return _extends({
2609 isOpen: _this.props.defaultIsOpen,
2610 highlightedIndex: _this.props.defaultHighlightedIndex,
2611 inputValue: _this.props.itemToString(selectedItem)
2612 }, otherStateToSet);
2613 }, cb);
2614 };
2615
2616 _this.toggleMenu = function (otherStateToSet, cb) {
2617 if (otherStateToSet === void 0) {
2618 otherStateToSet = {};
2619 }
2620
2621 otherStateToSet = pickState(otherStateToSet);
2622
2623 _this.internalSetState(function (_ref9) {
2624 var isOpen = _ref9.isOpen;
2625 return _extends({
2626 isOpen: !isOpen
2627 }, isOpen && {
2628 highlightedIndex: _this.props.defaultHighlightedIndex
2629 }, otherStateToSet);
2630 }, function () {
2631 var _this$getState7 = _this.getState(),
2632 isOpen = _this$getState7.isOpen,
2633 highlightedIndex = _this$getState7.highlightedIndex;
2634
2635 if (isOpen) {
2636 if (_this.getItemCount() > 0 && typeof highlightedIndex === 'number') {
2637 _this.setHighlightedIndex(highlightedIndex, otherStateToSet);
2638 }
2639 }
2640
2641 cbToCb(cb)();
2642 });
2643 };
2644
2645 _this.openMenu = function (cb) {
2646 _this.internalSetState({
2647 isOpen: true
2648 }, cb);
2649 };
2650
2651 _this.closeMenu = function (cb) {
2652 _this.internalSetState({
2653 isOpen: false
2654 }, cb);
2655 };
2656
2657 _this.updateStatus = debounce(function () {
2658 var state = _this.getState();
2659
2660 var item = _this.items[state.highlightedIndex];
2661
2662 var resultCount = _this.getItemCount();
2663
2664 var status = _this.props.getA11yStatusMessage(_extends({
2665 itemToString: _this.props.itemToString,
2666 previousResultCount: _this.previousResultCount,
2667 resultCount: resultCount,
2668 highlightedItem: item
2669 }, state));
2670
2671 _this.previousResultCount = resultCount;
2672 setStatus(status, _this.props.environment.document);
2673 }, 200);
2674
2675 var _this$props = _this.props,
2676 defaultHighlightedIndex = _this$props.defaultHighlightedIndex,
2677 _this$props$initialHi = _this$props.initialHighlightedIndex,
2678 _highlightedIndex = _this$props$initialHi === void 0 ? defaultHighlightedIndex : _this$props$initialHi,
2679 defaultIsOpen = _this$props.defaultIsOpen,
2680 _this$props$initialIs = _this$props.initialIsOpen,
2681 _isOpen = _this$props$initialIs === void 0 ? defaultIsOpen : _this$props$initialIs,
2682 _this$props$initialIn = _this$props.initialInputValue,
2683 _inputValue = _this$props$initialIn === void 0 ? '' : _this$props$initialIn,
2684 _this$props$initialSe = _this$props.initialSelectedItem,
2685 _selectedItem = _this$props$initialSe === void 0 ? null : _this$props$initialSe;
2686
2687 var _state = _this.getState({
2688 highlightedIndex: _highlightedIndex,
2689 isOpen: _isOpen,
2690 inputValue: _inputValue,
2691 selectedItem: _selectedItem
2692 });
2693
2694 if (_state.selectedItem != null && _this.props.initialInputValue === undefined) {
2695 _state.inputValue = _this.props.itemToString(_state.selectedItem);
2696 }
2697
2698 _this.state = _state;
2699 return _this;
2700 }
2701
2702 var _proto = Downshift.prototype;
2703
2704 /**
2705 * Clear all running timeouts
2706 */
2707 _proto.internalClearTimeouts = function internalClearTimeouts() {
2708 this.timeoutIds.forEach(function (id) {
2709 clearTimeout(id);
2710 });
2711 this.timeoutIds = [];
2712 }
2713 /**
2714 * Gets the state based on internal state or props
2715 * If a state value is passed via props, then that
2716 * is the value given, otherwise it's retrieved from
2717 * stateToMerge
2718 *
2719 * @param {Object} stateToMerge defaults to this.state
2720 * @return {Object} the state
2721 */
2722 ;
2723
2724 _proto.getState = function getState$1(stateToMerge) {
2725 if (stateToMerge === void 0) {
2726 stateToMerge = this.state;
2727 }
2728
2729 return getState(stateToMerge, this.props);
2730 };
2731
2732 _proto.getItemCount = function getItemCount() {
2733 // things read better this way. They're in priority order:
2734 // 1. `this.itemCount`
2735 // 2. `this.props.itemCount`
2736 // 3. `this.items.length`
2737 var itemCount = this.items.length;
2738
2739 if (this.itemCount != null) {
2740 itemCount = this.itemCount;
2741 } else if (this.props.itemCount !== undefined) {
2742 itemCount = this.props.itemCount;
2743 }
2744
2745 return itemCount;
2746 };
2747
2748 _proto.getItemNodeFromIndex = function getItemNodeFromIndex(index) {
2749 return this.props.environment.document.getElementById(this.getItemId(index));
2750 };
2751
2752 _proto.scrollHighlightedItemIntoView = function scrollHighlightedItemIntoView() {
2753 /* istanbul ignore else (react-native) */
2754 {
2755 var node = this.getItemNodeFromIndex(this.getState().highlightedIndex);
2756 this.props.scrollIntoView(node, this._menuNode);
2757 }
2758 };
2759
2760 _proto.moveHighlightedIndex = function moveHighlightedIndex(amount, otherStateToSet) {
2761 var _this6 = this;
2762
2763 var itemCount = this.getItemCount();
2764
2765 var _this$getState8 = this.getState(),
2766 highlightedIndex = _this$getState8.highlightedIndex;
2767
2768 if (itemCount > 0) {
2769 var nextHighlightedIndex = getNextWrappingIndex(amount, highlightedIndex, itemCount, function (index) {
2770 return _this6.getItemNodeFromIndex(index);
2771 });
2772 this.setHighlightedIndex(nextHighlightedIndex, otherStateToSet);
2773 }
2774 };
2775
2776 _proto.getStateAndHelpers = function getStateAndHelpers() {
2777 var _this$getState9 = this.getState(),
2778 highlightedIndex = _this$getState9.highlightedIndex,
2779 inputValue = _this$getState9.inputValue,
2780 selectedItem = _this$getState9.selectedItem,
2781 isOpen = _this$getState9.isOpen;
2782
2783 var itemToString = this.props.itemToString;
2784 var id = this.id;
2785 var getRootProps = this.getRootProps,
2786 getToggleButtonProps = this.getToggleButtonProps,
2787 getLabelProps = this.getLabelProps,
2788 getMenuProps = this.getMenuProps,
2789 getInputProps = this.getInputProps,
2790 getItemProps = this.getItemProps,
2791 openMenu = this.openMenu,
2792 closeMenu = this.closeMenu,
2793 toggleMenu = this.toggleMenu,
2794 selectItem = this.selectItem,
2795 selectItemAtIndex = this.selectItemAtIndex,
2796 selectHighlightedItem = this.selectHighlightedItem,
2797 setHighlightedIndex = this.setHighlightedIndex,
2798 clearSelection = this.clearSelection,
2799 clearItems = this.clearItems,
2800 reset = this.reset,
2801 setItemCount = this.setItemCount,
2802 unsetItemCount = this.unsetItemCount,
2803 setState = this.internalSetState;
2804 return {
2805 // prop getters
2806 getRootProps: getRootProps,
2807 getToggleButtonProps: getToggleButtonProps,
2808 getLabelProps: getLabelProps,
2809 getMenuProps: getMenuProps,
2810 getInputProps: getInputProps,
2811 getItemProps: getItemProps,
2812 // actions
2813 reset: reset,
2814 openMenu: openMenu,
2815 closeMenu: closeMenu,
2816 toggleMenu: toggleMenu,
2817 selectItem: selectItem,
2818 selectItemAtIndex: selectItemAtIndex,
2819 selectHighlightedItem: selectHighlightedItem,
2820 setHighlightedIndex: setHighlightedIndex,
2821 clearSelection: clearSelection,
2822 clearItems: clearItems,
2823 setItemCount: setItemCount,
2824 unsetItemCount: unsetItemCount,
2825 setState: setState,
2826 // props
2827 itemToString: itemToString,
2828 // derived
2829 id: id,
2830 // state
2831 highlightedIndex: highlightedIndex,
2832 inputValue: inputValue,
2833 isOpen: isOpen,
2834 selectedItem: selectedItem
2835 };
2836 } //////////////////////////// ROOT
2837 ;
2838
2839 _proto.componentDidMount = function componentDidMount() {
2840 var _this7 = this;
2841
2842 /* istanbul ignore if (react-native) */
2843 if ( this.getMenuProps.called && !this.getMenuProps.suppressRefError) {
2844 validateGetMenuPropsCalledCorrectly(this._menuNode, this.getMenuProps);
2845 }
2846 /* istanbul ignore if (react-native) */
2847
2848
2849 {
2850 // this.isMouseDown helps us track whether the mouse is currently held down.
2851 // This is useful when the user clicks on an item in the list, but holds the mouse
2852 // down long enough for the list to disappear (because the blur event fires on the input)
2853 // this.isMouseDown is used in the blur handler on the input to determine whether the blur event should
2854 // trigger hiding the menu.
2855 var onMouseDown = function onMouseDown() {
2856 _this7.isMouseDown = true;
2857 };
2858
2859 var onMouseUp = function onMouseUp(event) {
2860 _this7.isMouseDown = false; // if the target element or the activeElement is within a downshift node
2861 // then we don't want to reset downshift
2862
2863 var contextWithinDownshift = targetWithinDownshift(event.target, [_this7._rootNode, _this7._menuNode], _this7.props.environment.document);
2864
2865 if (!contextWithinDownshift && _this7.getState().isOpen) {
2866 _this7.reset({
2867 type: mouseUp
2868 }, function () {
2869 return _this7.props.onOuterClick(_this7.getStateAndHelpers());
2870 });
2871 }
2872 }; // Touching an element in iOS gives focus and hover states, but touching out of
2873 // the element will remove hover, and persist the focus state, resulting in the
2874 // blur event not being triggered.
2875 // this.isTouchMove helps us track whether the user is tapping or swiping on a touch screen.
2876 // If the user taps outside of Downshift, the component should be reset,
2877 // but not if the user is swiping
2878
2879
2880 var onTouchStart = function onTouchStart() {
2881 _this7.isTouchMove = false;
2882 };
2883
2884 var onTouchMove = function onTouchMove() {
2885 _this7.isTouchMove = true;
2886 };
2887
2888 var onTouchEnd = function onTouchEnd(event) {
2889 var contextWithinDownshift = targetWithinDownshift(event.target, [_this7._rootNode, _this7._menuNode], _this7.props.environment.document, false);
2890
2891 if (!_this7.isTouchMove && !contextWithinDownshift && _this7.getState().isOpen) {
2892 _this7.reset({
2893 type: touchEnd
2894 }, function () {
2895 return _this7.props.onOuterClick(_this7.getStateAndHelpers());
2896 });
2897 }
2898 };
2899
2900 var environment = this.props.environment;
2901 environment.addEventListener('mousedown', onMouseDown);
2902 environment.addEventListener('mouseup', onMouseUp);
2903 environment.addEventListener('touchstart', onTouchStart);
2904 environment.addEventListener('touchmove', onTouchMove);
2905 environment.addEventListener('touchend', onTouchEnd);
2906
2907 this.cleanup = function () {
2908 _this7.internalClearTimeouts();
2909
2910 _this7.updateStatus.cancel();
2911
2912 environment.removeEventListener('mousedown', onMouseDown);
2913 environment.removeEventListener('mouseup', onMouseUp);
2914 environment.removeEventListener('touchstart', onTouchStart);
2915 environment.removeEventListener('touchmove', onTouchMove);
2916 environment.removeEventListener('touchend', onTouchEnd);
2917 };
2918 }
2919 };
2920
2921 _proto.shouldScroll = function shouldScroll(prevState, prevProps) {
2922 var _ref10 = this.props.highlightedIndex === undefined ? this.getState() : this.props,
2923 currentHighlightedIndex = _ref10.highlightedIndex;
2924
2925 var _ref11 = prevProps.highlightedIndex === undefined ? prevState : prevProps,
2926 prevHighlightedIndex = _ref11.highlightedIndex;
2927
2928 var scrollWhenOpen = currentHighlightedIndex && this.getState().isOpen && !prevState.isOpen;
2929 var scrollWhenNavigating = currentHighlightedIndex !== prevHighlightedIndex;
2930 return scrollWhenOpen || scrollWhenNavigating;
2931 };
2932
2933 _proto.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {
2934 {
2935 validateControlledUnchanged(this.state, prevProps, this.props);
2936 /* istanbul ignore if (react-native) */
2937
2938 if ( this.getMenuProps.called && !this.getMenuProps.suppressRefError) {
2939 validateGetMenuPropsCalledCorrectly(this._menuNode, this.getMenuProps);
2940 }
2941 }
2942
2943 if (isControlledProp(this.props, 'selectedItem') && this.props.selectedItemChanged(prevProps.selectedItem, this.props.selectedItem)) {
2944 this.internalSetState({
2945 type: controlledPropUpdatedSelectedItem,
2946 inputValue: this.props.itemToString(this.props.selectedItem)
2947 });
2948 }
2949
2950 if (!this.avoidScrolling && this.shouldScroll(prevState, prevProps)) {
2951 this.scrollHighlightedItemIntoView();
2952 }
2953 /* istanbul ignore else (react-native) */
2954
2955
2956 {
2957 this.updateStatus();
2958 }
2959 };
2960
2961 _proto.componentWillUnmount = function componentWillUnmount() {
2962 this.cleanup(); // avoids memory leak
2963 };
2964
2965 _proto.render = function render() {
2966 var children = unwrapArray(this.props.children, noop); // because the items are rerendered every time we call the children
2967 // we clear this out each render and it will be populated again as
2968 // getItemProps is called.
2969
2970 this.clearItems(); // we reset this so we know whether the user calls getRootProps during
2971 // this render. If they do then we don't need to do anything,
2972 // if they don't then we need to clone the element they return and
2973 // apply the props for them.
2974
2975 this.getRootProps.called = false;
2976 this.getRootProps.refKey = undefined;
2977 this.getRootProps.suppressRefError = undefined; // we do something similar for getMenuProps
2978
2979 this.getMenuProps.called = false;
2980 this.getMenuProps.refKey = undefined;
2981 this.getMenuProps.suppressRefError = undefined; // we do something similar for getLabelProps
2982
2983 this.getLabelProps.called = false; // and something similar for getInputProps
2984
2985 this.getInputProps.called = false;
2986 var element = unwrapArray(children(this.getStateAndHelpers()));
2987
2988 if (!element) {
2989 return null;
2990 }
2991
2992 if (this.getRootProps.called || this.props.suppressRefError) {
2993 if ( !this.getRootProps.suppressRefError && !this.props.suppressRefError) {
2994 validateGetRootPropsCalledCorrectly(element, this.getRootProps);
2995 }
2996
2997 return element;
2998 } else if (isDOMElement(element)) {
2999 // they didn't apply the root props, but we can clone
3000 // this and apply the props ourselves
3001 return /*#__PURE__*/react.cloneElement(element, this.getRootProps(getElementProps(element)));
3002 }
3003 /* istanbul ignore else */
3004
3005
3006 {
3007 // they didn't apply the root props, but they need to
3008 // otherwise we can't query around the autocomplete
3009 throw new Error('downshift: If you return a non-DOM element, you must apply the getRootProps function');
3010 }
3011 };
3012
3013 return Downshift;
3014 }(react.Component);
3015
3016 Downshift.defaultProps = {
3017 defaultHighlightedIndex: null,
3018 defaultIsOpen: false,
3019 getA11yStatusMessage: getA11yStatusMessage,
3020 itemToString: function itemToString(i) {
3021 if (i == null) {
3022 return '';
3023 }
3024
3025 if ( isPlainObject(i) && !i.hasOwnProperty('toString')) {
3026 // eslint-disable-next-line no-console
3027 console.warn('downshift: An object was passed to the default implementation of `itemToString`. You should probably provide your own `itemToString` implementation. Please refer to the `itemToString` API documentation.', 'The object that was passed:', i);
3028 }
3029
3030 return String(i);
3031 },
3032 onStateChange: noop,
3033 onInputValueChange: noop,
3034 onUserAction: noop,
3035 onChange: noop,
3036 onSelect: noop,
3037 onOuterClick: noop,
3038 selectedItemChanged: function selectedItemChanged(prevItem, item) {
3039 return prevItem !== item;
3040 },
3041 environment: typeof window === 'undefined'
3042 /* istanbul ignore next (ssr) */
3043 ? {} : window,
3044 stateReducer: function stateReducer(state, stateToSet) {
3045 return stateToSet;
3046 },
3047 suppressRefError: false,
3048 scrollIntoView: scrollIntoView
3049 };
3050 Downshift.stateChangeTypes = stateChangeTypes;
3051 return Downshift;
3052 }();
3053
3054 Downshift.propTypes = {
3055 children: propTypes.func,
3056 defaultHighlightedIndex: propTypes.number,
3057 defaultIsOpen: propTypes.bool,
3058 initialHighlightedIndex: propTypes.number,
3059 initialSelectedItem: propTypes.any,
3060 initialInputValue: propTypes.string,
3061 initialIsOpen: propTypes.bool,
3062 getA11yStatusMessage: propTypes.func,
3063 itemToString: propTypes.func,
3064 onChange: propTypes.func,
3065 onSelect: propTypes.func,
3066 onStateChange: propTypes.func,
3067 onInputValueChange: propTypes.func,
3068 onUserAction: propTypes.func,
3069 onOuterClick: propTypes.func,
3070 selectedItemChanged: propTypes.func,
3071 stateReducer: propTypes.func,
3072 itemCount: propTypes.number,
3073 id: propTypes.string,
3074 environment: propTypes.shape({
3075 addEventListener: propTypes.func,
3076 removeEventListener: propTypes.func,
3077 document: propTypes.shape({
3078 getElementById: propTypes.func,
3079 activeElement: propTypes.any,
3080 body: propTypes.any
3081 })
3082 }),
3083 suppressRefError: propTypes.bool,
3084 scrollIntoView: propTypes.func,
3085 // things we keep in state for uncontrolled components
3086 // but can accept as props for controlled components
3087
3088 /* eslint-disable react/no-unused-prop-types */
3089 selectedItem: propTypes.any,
3090 isOpen: propTypes.bool,
3091 inputValue: propTypes.string,
3092 highlightedIndex: propTypes.number,
3093 labelId: propTypes.string,
3094 inputId: propTypes.string,
3095 menuId: propTypes.string,
3096 getItemId: propTypes.func
3097 /* eslint-enable react/no-unused-prop-types */
3098
3099 } ;
3100
3101 function validateGetMenuPropsCalledCorrectly(node, _ref12) {
3102 var refKey = _ref12.refKey;
3103
3104 if (!node) {
3105 // eslint-disable-next-line no-console
3106 console.error("downshift: The ref prop \"" + refKey + "\" from getMenuProps was not applied correctly on your menu element.");
3107 }
3108 }
3109
3110 function validateGetRootPropsCalledCorrectly(element, _ref13) {
3111 var refKey = _ref13.refKey;
3112 var refKeySpecified = refKey !== 'ref';
3113 var isComposite = !isDOMElement(element);
3114
3115 if (isComposite && !refKeySpecified && !reactIs$1.isForwardRef(element)) {
3116 // eslint-disable-next-line no-console
3117 console.error('downshift: You returned a non-DOM element. You must specify a refKey in getRootProps');
3118 } else if (!isComposite && refKeySpecified) {
3119 // eslint-disable-next-line no-console
3120 console.error("downshift: You returned a DOM element. You should not specify a refKey in getRootProps. You specified \"" + refKey + "\"");
3121 }
3122
3123 if (!reactIs$1.isForwardRef(element) && !getElementProps(element)[refKey]) {
3124 // eslint-disable-next-line no-console
3125 console.error("downshift: You must apply the ref prop \"" + refKey + "\" from getRootProps onto your root element.");
3126 }
3127 }
3128
3129 var dropdownDefaultStateValues = {
3130 highlightedIndex: -1,
3131 isOpen: false,
3132 selectedItem: null,
3133 inputValue: ''
3134 };
3135
3136 function callOnChangeProps(action, state, newState) {
3137 var props = action.props,
3138 type = action.type;
3139 var changes = {};
3140 Object.keys(state).forEach(function (key) {
3141 invokeOnChangeHandler(key, action, state, newState);
3142
3143 if (newState[key] !== state[key]) {
3144 changes[key] = newState[key];
3145 }
3146 });
3147
3148 if (props.onStateChange && Object.keys(changes).length) {
3149 props.onStateChange(_extends({
3150 type: type
3151 }, changes));
3152 }
3153 }
3154
3155 function invokeOnChangeHandler(key, action, state, newState) {
3156 var props = action.props,
3157 type = action.type;
3158 var handler = "on" + capitalizeString(key) + "Change";
3159
3160 if (props[handler] && newState[key] !== undefined && newState[key] !== state[key]) {
3161 props[handler](_extends({
3162 type: type
3163 }, newState));
3164 }
3165 }
3166 /**
3167 * Default state reducer that returns the changes.
3168 *
3169 * @param {Object} s state.
3170 * @param {Object} a action with changes.
3171 * @returns {Object} changes.
3172 */
3173
3174
3175 function stateReducer(s, a) {
3176 return a.changes;
3177 }
3178 /**
3179 * Returns a message to be added to aria-live region when item is selected.
3180 *
3181 * @param {Object} selectionParameters Parameters required to build the message.
3182 * @returns {string} The a11y message.
3183 */
3184
3185
3186 function getA11ySelectionMessage(selectionParameters) {
3187 var selectedItem = selectionParameters.selectedItem,
3188 itemToStringLocal = selectionParameters.itemToString;
3189 return selectedItem ? itemToStringLocal(selectedItem) + " has been selected." : '';
3190 }
3191 /**
3192 * Debounced call for updating the a11y message.
3193 */
3194
3195
3196 var updateA11yStatus = debounce(function (getA11yMessage, document) {
3197 setStatus(getA11yMessage(), document);
3198 }, 200); // istanbul ignore next
3199
3200 var useIsomorphicLayoutEffect = typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined' ? react.useLayoutEffect : react.useEffect;
3201 function getElementIds(_ref) {
3202 var id = _ref.id,
3203 labelId = _ref.labelId,
3204 menuId = _ref.menuId,
3205 getItemId = _ref.getItemId,
3206 toggleButtonId = _ref.toggleButtonId;
3207 var uniqueId = id === undefined ? "downshift-" + generateId() : id;
3208 return {
3209 labelId: labelId || uniqueId + "-label",
3210 menuId: menuId || uniqueId + "-menu",
3211 getItemId: getItemId || function (index) {
3212 return uniqueId + "-item-" + index;
3213 },
3214 toggleButtonId: toggleButtonId || uniqueId + "-toggle-button"
3215 };
3216 }
3217 function getItemIndex(index, item, items) {
3218 if (index !== undefined) {
3219 return index;
3220 }
3221
3222 if (items.length === 0) {
3223 return -1;
3224 }
3225
3226 return items.indexOf(item);
3227 }
3228
3229 function itemToString(item) {
3230 return item ? String(item) : '';
3231 }
3232
3233 function getPropTypesValidator(caller, propTypes$1) {
3234 // istanbul ignore next
3235 return function validate(options) {
3236 if (options === void 0) {
3237 options = {};
3238 }
3239
3240 Object.keys(propTypes$1).forEach(function (key) {
3241 propTypes.checkPropTypes(propTypes$1, options, key, caller.name);
3242 });
3243 };
3244 }
3245 function isAcceptedCharacterKey(key) {
3246 return /^\S{1}$/.test(key);
3247 }
3248 function capitalizeString(string) {
3249 return "" + string.slice(0, 1).toUpperCase() + string.slice(1);
3250 }
3251 function useLatestRef(val) {
3252 var ref = react.useRef(val); // technically this is not "concurrent mode safe" because we're manipulating
3253 // the value during render (so it's not idempotent). However, the places this
3254 // hook is used is to support memoizing callbacks which will be called
3255 // *during* render, so we need the latest values *during* render.
3256 // If not for this, then we'd probably want to use useLayoutEffect instead.
3257
3258 ref.current = val;
3259 return ref;
3260 }
3261 /**
3262 * Computes the controlled state using a the previous state, props,
3263 * two reducers, one from downshift and an optional one from the user.
3264 * Also calls the onChange handlers for state values that have changed.
3265 *
3266 * @param {Function} reducer Reducer function from downshift.
3267 * @param {Object} initialState Initial state of the hook.
3268 * @param {Object} props The hook props.
3269 * @returns {Array} An array with the state and an action dispatcher.
3270 */
3271
3272 function useEnhancedReducer(reducer, initialState, props) {
3273 var prevStateRef = react.useRef();
3274 var actionRef = react.useRef();
3275 var enhancedReducer = react.useCallback(function (state, action) {
3276 actionRef.current = action;
3277 state = getState(state, action.props);
3278 var changes = reducer(state, action);
3279 var newState = action.props.stateReducer(state, _extends({}, action, {
3280 changes: changes
3281 }));
3282 return newState;
3283 }, [reducer]);
3284
3285 var _useReducer = react.useReducer(enhancedReducer, initialState),
3286 state = _useReducer[0],
3287 dispatch = _useReducer[1];
3288
3289 var propsRef = useLatestRef(props);
3290 var dispatchWithProps = react.useCallback(function (action) {
3291 return dispatch(_extends({
3292 props: propsRef.current
3293 }, action));
3294 }, [propsRef]);
3295 var action = actionRef.current;
3296 react.useEffect(function () {
3297 if (action && prevStateRef.current && prevStateRef.current !== state) {
3298 callOnChangeProps(action, getState(prevStateRef.current, action.props), state);
3299 }
3300
3301 prevStateRef.current = state;
3302 }, [state, props, action]);
3303 return [state, dispatchWithProps];
3304 }
3305 /**
3306 * Wraps the useEnhancedReducer and applies the controlled prop values before
3307 * returning the new state.
3308 *
3309 * @param {Function} reducer Reducer function from downshift.
3310 * @param {Object} initialState Initial state of the hook.
3311 * @param {Object} props The hook props.
3312 * @returns {Array} An array with the state and an action dispatcher.
3313 */
3314
3315 function useControlledReducer(reducer, initialState, props) {
3316 var _useEnhancedReducer = useEnhancedReducer(reducer, initialState, props),
3317 state = _useEnhancedReducer[0],
3318 dispatch = _useEnhancedReducer[1];
3319
3320 return [getState(state, props), dispatch];
3321 }
3322 var defaultProps = {
3323 itemToString: itemToString,
3324 stateReducer: stateReducer,
3325 getA11ySelectionMessage: getA11ySelectionMessage,
3326 scrollIntoView: scrollIntoView,
3327 circularNavigation: false,
3328 environment: typeof window === 'undefined'
3329 /* istanbul ignore next (ssr) */
3330 ? {} : window
3331 };
3332 function getDefaultValue(props, propKey, defaultStateValues) {
3333 if (defaultStateValues === void 0) {
3334 defaultStateValues = dropdownDefaultStateValues;
3335 }
3336
3337 var defaultPropKey = "default" + capitalizeString(propKey);
3338
3339 if (defaultPropKey in props) {
3340 return props[defaultPropKey];
3341 }
3342
3343 return defaultStateValues[propKey];
3344 }
3345 function getInitialValue(props, propKey, defaultStateValues) {
3346 if (defaultStateValues === void 0) {
3347 defaultStateValues = dropdownDefaultStateValues;
3348 }
3349
3350 if (propKey in props) {
3351 return props[propKey];
3352 }
3353
3354 var initialPropKey = "initial" + capitalizeString(propKey);
3355
3356 if (initialPropKey in props) {
3357 return props[initialPropKey];
3358 }
3359
3360 return getDefaultValue(props, propKey, defaultStateValues);
3361 }
3362 function getInitialState(props) {
3363 var selectedItem = getInitialValue(props, 'selectedItem');
3364 var isOpen = getInitialValue(props, 'isOpen');
3365 var highlightedIndex = getInitialValue(props, 'highlightedIndex');
3366 var inputValue = getInitialValue(props, 'inputValue');
3367 return {
3368 highlightedIndex: highlightedIndex < 0 && selectedItem && isOpen ? props.items.indexOf(selectedItem) : highlightedIndex,
3369 isOpen: isOpen,
3370 selectedItem: selectedItem,
3371 inputValue: inputValue
3372 };
3373 }
3374 function getHighlightedIndexOnOpen(props, state, offset, getItemNodeFromIndex) {
3375 var items = props.items,
3376 initialHighlightedIndex = props.initialHighlightedIndex,
3377 defaultHighlightedIndex = props.defaultHighlightedIndex;
3378 var selectedItem = state.selectedItem,
3379 highlightedIndex = state.highlightedIndex;
3380
3381 if (items.length === 0) {
3382 return -1;
3383 } // initialHighlightedIndex will give value to highlightedIndex on initial state only.
3384
3385
3386 if (initialHighlightedIndex !== undefined && highlightedIndex === initialHighlightedIndex) {
3387 return initialHighlightedIndex;
3388 }
3389
3390 if (defaultHighlightedIndex !== undefined) {
3391 return defaultHighlightedIndex;
3392 }
3393
3394 if (selectedItem) {
3395 if (offset === 0) {
3396 return items.indexOf(selectedItem);
3397 }
3398
3399 return getNextWrappingIndex(offset, items.indexOf(selectedItem), items.length, getItemNodeFromIndex, false);
3400 }
3401
3402 if (offset === 0) {
3403 return -1;
3404 }
3405
3406 return offset < 0 ? items.length - 1 : 0;
3407 }
3408 /**
3409 * Reuse the movement tracking of mouse and touch events.
3410 *
3411 * @param {boolean} isOpen Whether the dropdown is open or not.
3412 * @param {Array<Object>} downshiftElementRefs Downshift element refs to track movement (toggleButton, menu etc.)
3413 * @param {Object} environment Environment where component/hook exists.
3414 * @param {Function} handleBlur Handler on blur from mouse or touch.
3415 * @returns {Object} Ref containing whether mouseDown or touchMove event is happening
3416 */
3417
3418 function useMouseAndTouchTracker(isOpen, downshiftElementRefs, environment, handleBlur) {
3419 var mouseAndTouchTrackersRef = react.useRef({
3420 isMouseDown: false,
3421 isTouchMove: false
3422 });
3423 react.useEffect(function () {
3424 // The same strategy for checking if a click occurred inside or outside downsift
3425 // as in downshift.js.
3426 var onMouseDown = function onMouseDown() {
3427 mouseAndTouchTrackersRef.current.isMouseDown = true;
3428 };
3429
3430 var onMouseUp = function onMouseUp(event) {
3431 mouseAndTouchTrackersRef.current.isMouseDown = false;
3432
3433 if (isOpen && !targetWithinDownshift(event.target, downshiftElementRefs.map(function (ref) {
3434 return ref.current;
3435 }), environment.document)) {
3436 handleBlur();
3437 }
3438 };
3439
3440 var onTouchStart = function onTouchStart() {
3441 mouseAndTouchTrackersRef.current.isTouchMove = false;
3442 };
3443
3444 var onTouchMove = function onTouchMove() {
3445 mouseAndTouchTrackersRef.current.isTouchMove = true;
3446 };
3447
3448 var onTouchEnd = function onTouchEnd(event) {
3449 if (isOpen && !mouseAndTouchTrackersRef.current.isTouchMove && !targetWithinDownshift(event.target, downshiftElementRefs.map(function (ref) {
3450 return ref.current;
3451 }), environment.document, false)) {
3452 handleBlur();
3453 }
3454 };
3455
3456 environment.addEventListener('mousedown', onMouseDown);
3457 environment.addEventListener('mouseup', onMouseUp);
3458 environment.addEventListener('touchstart', onTouchStart);
3459 environment.addEventListener('touchmove', onTouchMove);
3460 environment.addEventListener('touchend', onTouchEnd);
3461 return function cleanup() {
3462 environment.removeEventListener('mousedown', onMouseDown);
3463 environment.removeEventListener('mouseup', onMouseUp);
3464 environment.removeEventListener('touchstart', onTouchStart);
3465 environment.removeEventListener('touchmove', onTouchMove);
3466 environment.removeEventListener('touchend', onTouchEnd);
3467 }; // eslint-disable-next-line react-hooks/exhaustive-deps
3468 }, [isOpen, environment]);
3469 return mouseAndTouchTrackersRef;
3470 }
3471 /**
3472 * Custom hook that checks if getter props are called correctly.
3473 *
3474 * @param {...any} propKeys Getter prop names to be handled.
3475 * @returns {Function} Setter function called inside getter props to set call information.
3476 */
3477
3478 function useGetterPropsCalledChecker() {
3479 var isInitialMountRef = react.useRef(true);
3480
3481 for (var _len = arguments.length, propKeys = new Array(_len), _key = 0; _key < _len; _key++) {
3482 propKeys[_key] = arguments[_key];
3483 }
3484
3485 var getterPropsCalledRef = react.useRef(propKeys.reduce(function (acc, propKey) {
3486 acc[propKey] = {};
3487 return acc;
3488 }, {}));
3489 react.useEffect(function () {
3490
3491 Object.keys(getterPropsCalledRef.current).forEach(function (propKey) {
3492 var propCallInfo = getterPropsCalledRef.current[propKey];
3493
3494 if (isInitialMountRef.current) {
3495 if (!Object.keys(propCallInfo).length) {
3496 // eslint-disable-next-line no-console
3497 console.error("downshift: You forgot to call the " + propKey + " getter function on your component / element.");
3498 return;
3499 }
3500 }
3501
3502 var suppressRefError = propCallInfo.suppressRefError,
3503 refKey = propCallInfo.refKey,
3504 elementRef = propCallInfo.elementRef;
3505
3506 if ((!elementRef || !elementRef.current) && !suppressRefError) {
3507 // eslint-disable-next-line no-console
3508 console.error("downshift: The ref prop \"" + refKey + "\" from " + propKey + " was not applied correctly on your element.");
3509 }
3510 });
3511 isInitialMountRef.current = false;
3512 });
3513 var setGetterPropCallInfo = react.useCallback(function (propKey, suppressRefError, refKey, elementRef) {
3514 {
3515 getterPropsCalledRef.current[propKey] = {
3516 suppressRefError: suppressRefError,
3517 refKey: refKey,
3518 elementRef: elementRef
3519 };
3520 }
3521 }, []);
3522 return setGetterPropCallInfo;
3523 }
3524 function useA11yMessageSetter(getA11yMessage, dependencyArray, _ref2) {
3525 var isInitialMount = _ref2.isInitialMount,
3526 previousResultCount = _ref2.previousResultCount,
3527 highlightedIndex = _ref2.highlightedIndex,
3528 items = _ref2.items,
3529 environment = _ref2.environment,
3530 rest = _objectWithoutPropertiesLoose(_ref2, ["isInitialMount", "previousResultCount", "highlightedIndex", "items", "environment"]);
3531
3532 // Sets a11y status message on changes in state.
3533 react.useEffect(function () {
3534 if (isInitialMount) {
3535 return;
3536 }
3537
3538 updateA11yStatus(function () {
3539 return getA11yMessage(_extends({
3540 highlightedIndex: highlightedIndex,
3541 highlightedItem: items[highlightedIndex],
3542 resultCount: items.length,
3543 previousResultCount: previousResultCount
3544 }, rest));
3545 }, environment.document); // eslint-disable-next-line react-hooks/exhaustive-deps
3546 }, dependencyArray);
3547 }
3548 function useScrollIntoView(_ref3) {
3549 var highlightedIndex = _ref3.highlightedIndex,
3550 isOpen = _ref3.isOpen,
3551 itemRefs = _ref3.itemRefs,
3552 getItemNodeFromIndex = _ref3.getItemNodeFromIndex,
3553 menuElement = _ref3.menuElement,
3554 scrollIntoViewProp = _ref3.scrollIntoView;
3555 // used not to scroll on highlight by mouse.
3556 var shouldScrollRef = react.useRef(true); // Scroll on highlighted item if change comes from keyboard.
3557
3558 useIsomorphicLayoutEffect(function () {
3559 if (highlightedIndex < 0 || !isOpen || !Object.keys(itemRefs.current).length) {
3560 return;
3561 }
3562
3563 if (shouldScrollRef.current === false) {
3564 shouldScrollRef.current = true;
3565 } else {
3566 scrollIntoViewProp(getItemNodeFromIndex(highlightedIndex), menuElement);
3567 } // eslint-disable-next-line react-hooks/exhaustive-deps
3568
3569 }, [highlightedIndex]);
3570 return shouldScrollRef;
3571 }
3572 function useControlPropsValidator(_ref4) {
3573 var isInitialMount = _ref4.isInitialMount,
3574 props = _ref4.props,
3575 state = _ref4.state;
3576 // used for checking when props are moving from controlled to uncontrolled.
3577 var prevPropsRef = react.useRef(props);
3578 react.useEffect(function () {
3579 if (isInitialMount) {
3580 return;
3581 }
3582
3583 validateControlledUnchanged(state, prevPropsRef.current, props);
3584 prevPropsRef.current = props;
3585 }, [state, props, isInitialMount]);
3586 }
3587
3588 function getItemIndexByCharacterKey(keysSoFar, highlightedIndex, items, itemToStringParam, getItemNodeFromIndex) {
3589 var lowerCasedItemStrings = items.map(function (item) {
3590 return itemToStringParam(item).toLowerCase();
3591 });
3592 var lowerCasedKeysSoFar = keysSoFar.toLowerCase();
3593
3594 var isValid = function isValid(itemString, index) {
3595 var element = getItemNodeFromIndex(index);
3596 return itemString.startsWith(lowerCasedKeysSoFar) && !(element && element.hasAttribute('disabled'));
3597 };
3598
3599 for (var index = highlightedIndex + 1; index < lowerCasedItemStrings.length; index++) {
3600 var itemString = lowerCasedItemStrings[index];
3601
3602 if (isValid(itemString, index)) {
3603 return index;
3604 }
3605 }
3606
3607 for (var _index = 0; _index < highlightedIndex; _index++) {
3608 var _itemString = lowerCasedItemStrings[_index];
3609
3610 if (isValid(_itemString, _index)) {
3611 return _index;
3612 }
3613 }
3614
3615 return highlightedIndex;
3616 }
3617
3618 var propTypes$1 = {
3619 items: propTypes.array.isRequired,
3620 itemToString: propTypes.func,
3621 getA11yStatusMessage: propTypes.func,
3622 getA11ySelectionMessage: propTypes.func,
3623 circularNavigation: propTypes.bool,
3624 highlightedIndex: propTypes.number,
3625 defaultHighlightedIndex: propTypes.number,
3626 initialHighlightedIndex: propTypes.number,
3627 isOpen: propTypes.bool,
3628 defaultIsOpen: propTypes.bool,
3629 initialIsOpen: propTypes.bool,
3630 selectedItem: propTypes.any,
3631 initialSelectedItem: propTypes.any,
3632 defaultSelectedItem: propTypes.any,
3633 id: propTypes.string,
3634 labelId: propTypes.string,
3635 menuId: propTypes.string,
3636 getItemId: propTypes.func,
3637 toggleButtonId: propTypes.string,
3638 stateReducer: propTypes.func,
3639 onSelectedItemChange: propTypes.func,
3640 onHighlightedIndexChange: propTypes.func,
3641 onStateChange: propTypes.func,
3642 onIsOpenChange: propTypes.func,
3643 environment: propTypes.shape({
3644 addEventListener: propTypes.func,
3645 removeEventListener: propTypes.func,
3646 document: propTypes.shape({
3647 getElementById: propTypes.func,
3648 activeElement: propTypes.any,
3649 body: propTypes.any
3650 })
3651 })
3652 };
3653 /**
3654 * Default implementation for status message. Only added when menu is open.
3655 * Will specift if there are results in the list, and if so, how many,
3656 * and what keys are relevant.
3657 *
3658 * @param {Object} param the downshift state and other relevant properties
3659 * @return {String} the a11y status message
3660 */
3661
3662 function getA11yStatusMessage$1(_ref) {
3663 var isOpen = _ref.isOpen,
3664 resultCount = _ref.resultCount,
3665 previousResultCount = _ref.previousResultCount;
3666
3667 if (!isOpen) {
3668 return '';
3669 }
3670
3671 if (!resultCount) {
3672 return 'No results are available.';
3673 }
3674
3675 if (resultCount !== previousResultCount) {
3676 return resultCount + " result" + (resultCount === 1 ? ' is' : 's are') + " available, use up and down arrow keys to navigate. Press Enter or Space Bar keys to select.";
3677 }
3678
3679 return '';
3680 }
3681
3682 var defaultProps$1 = _extends({}, defaultProps, {
3683 getA11yStatusMessage: getA11yStatusMessage$1
3684 });
3685
3686 var MenuKeyDownArrowDown = '__menu_keydown_arrow_down__' ;
3687 var MenuKeyDownArrowUp = '__menu_keydown_arrow_up__' ;
3688 var MenuKeyDownEscape = '__menu_keydown_escape__' ;
3689 var MenuKeyDownHome = '__menu_keydown_home__' ;
3690 var MenuKeyDownEnd = '__menu_keydown_end__' ;
3691 var MenuKeyDownEnter = '__menu_keydown_enter__' ;
3692 var MenuKeyDownSpaceButton = '__menu_keydown_space_button__' ;
3693 var MenuKeyDownCharacter = '__menu_keydown_character__' ;
3694 var MenuBlur = '__menu_blur__' ;
3695 var MenuMouseLeave = '__menu_mouse_leave__' ;
3696 var ItemMouseMove = '__item_mouse_move__' ;
3697 var ItemClick = '__item_click__' ;
3698 var ToggleButtonClick = '__togglebutton_click__' ;
3699 var ToggleButtonKeyDownArrowDown = '__togglebutton_keydown_arrow_down__' ;
3700 var ToggleButtonKeyDownArrowUp = '__togglebutton_keydown_arrow_up__' ;
3701 var ToggleButtonKeyDownCharacter = '__togglebutton_keydown_character__' ;
3702 var FunctionToggleMenu = '__function_toggle_menu__' ;
3703 var FunctionOpenMenu = '__function_open_menu__' ;
3704 var FunctionCloseMenu = '__function_close_menu__' ;
3705 var FunctionSetHighlightedIndex = '__function_set_highlighted_index__' ;
3706 var FunctionSelectItem = '__function_select_item__' ;
3707 var FunctionSetInputValue = '__function_set_input_value__' ;
3708 var FunctionReset = '__function_reset__' ;
3709
3710 var stateChangeTypes$1 = /*#__PURE__*/Object.freeze({
3711 __proto__: null,
3712 MenuKeyDownArrowDown: MenuKeyDownArrowDown,
3713 MenuKeyDownArrowUp: MenuKeyDownArrowUp,
3714 MenuKeyDownEscape: MenuKeyDownEscape,
3715 MenuKeyDownHome: MenuKeyDownHome,
3716 MenuKeyDownEnd: MenuKeyDownEnd,
3717 MenuKeyDownEnter: MenuKeyDownEnter,
3718 MenuKeyDownSpaceButton: MenuKeyDownSpaceButton,
3719 MenuKeyDownCharacter: MenuKeyDownCharacter,
3720 MenuBlur: MenuBlur,
3721 MenuMouseLeave: MenuMouseLeave,
3722 ItemMouseMove: ItemMouseMove,
3723 ItemClick: ItemClick,
3724 ToggleButtonClick: ToggleButtonClick,
3725 ToggleButtonKeyDownArrowDown: ToggleButtonKeyDownArrowDown,
3726 ToggleButtonKeyDownArrowUp: ToggleButtonKeyDownArrowUp,
3727 ToggleButtonKeyDownCharacter: ToggleButtonKeyDownCharacter,
3728 FunctionToggleMenu: FunctionToggleMenu,
3729 FunctionOpenMenu: FunctionOpenMenu,
3730 FunctionCloseMenu: FunctionCloseMenu,
3731 FunctionSetHighlightedIndex: FunctionSetHighlightedIndex,
3732 FunctionSelectItem: FunctionSelectItem,
3733 FunctionSetInputValue: FunctionSetInputValue,
3734 FunctionReset: FunctionReset
3735 });
3736
3737 /* eslint-disable complexity */
3738
3739 function downshiftSelectReducer(state, action) {
3740 var type = action.type,
3741 props = action.props,
3742 shiftKey = action.shiftKey;
3743 var changes;
3744
3745 switch (type) {
3746 case ItemMouseMove:
3747 changes = {
3748 highlightedIndex: action.index
3749 };
3750 break;
3751
3752 case ItemClick:
3753 changes = {
3754 isOpen: getDefaultValue(props, 'isOpen'),
3755 highlightedIndex: getDefaultValue(props, 'highlightedIndex'),
3756 selectedItem: props.items[action.index]
3757 };
3758 break;
3759
3760 case ToggleButtonKeyDownCharacter:
3761 {
3762 var lowercasedKey = action.key;
3763 var inputValue = "" + state.inputValue + lowercasedKey;
3764 var itemIndex = getItemIndexByCharacterKey(inputValue, state.selectedItem ? props.items.indexOf(state.selectedItem) : -1, props.items, props.itemToString, action.getItemNodeFromIndex);
3765 changes = _extends({
3766 inputValue: inputValue
3767 }, itemIndex >= 0 && {
3768 selectedItem: props.items[itemIndex]
3769 });
3770 }
3771 break;
3772
3773 case ToggleButtonKeyDownArrowDown:
3774 changes = {
3775 highlightedIndex: getHighlightedIndexOnOpen(props, state, 1, action.getItemNodeFromIndex),
3776 isOpen: true
3777 };
3778 break;
3779
3780 case ToggleButtonKeyDownArrowUp:
3781 changes = {
3782 highlightedIndex: getHighlightedIndexOnOpen(props, state, -1, action.getItemNodeFromIndex),
3783 isOpen: true
3784 };
3785 break;
3786
3787 case MenuKeyDownEnter:
3788 case MenuKeyDownSpaceButton:
3789 changes = _extends({
3790 isOpen: getDefaultValue(props, 'isOpen'),
3791 highlightedIndex: getDefaultValue(props, 'highlightedIndex')
3792 }, state.highlightedIndex >= 0 && {
3793 selectedItem: props.items[state.highlightedIndex]
3794 });
3795 break;
3796
3797 case MenuKeyDownHome:
3798 changes = {
3799 highlightedIndex: getNextNonDisabledIndex(1, 0, props.items.length, action.getItemNodeFromIndex, false)
3800 };
3801 break;
3802
3803 case MenuKeyDownEnd:
3804 changes = {
3805 highlightedIndex: getNextNonDisabledIndex(-1, props.items.length - 1, props.items.length, action.getItemNodeFromIndex, false)
3806 };
3807 break;
3808
3809 case MenuKeyDownEscape:
3810 changes = {
3811 isOpen: false,
3812 highlightedIndex: -1
3813 };
3814 break;
3815
3816 case MenuBlur:
3817 changes = {
3818 isOpen: false,
3819 highlightedIndex: -1
3820 };
3821 break;
3822
3823 case MenuKeyDownCharacter:
3824 {
3825 var _lowercasedKey = action.key;
3826
3827 var _inputValue = "" + state.inputValue + _lowercasedKey;
3828
3829 var highlightedIndex = getItemIndexByCharacterKey(_inputValue, state.highlightedIndex, props.items, props.itemToString, action.getItemNodeFromIndex);
3830 changes = _extends({
3831 inputValue: _inputValue
3832 }, highlightedIndex >= 0 && {
3833 highlightedIndex: highlightedIndex
3834 });
3835 }
3836 break;
3837
3838 case MenuKeyDownArrowDown:
3839 changes = {
3840 highlightedIndex: getNextWrappingIndex(shiftKey ? 5 : 1, state.highlightedIndex, props.items.length, action.getItemNodeFromIndex, props.circularNavigation)
3841 };
3842 break;
3843
3844 case MenuKeyDownArrowUp:
3845 changes = {
3846 highlightedIndex: getNextWrappingIndex(shiftKey ? -5 : -1, state.highlightedIndex, props.items.length, action.getItemNodeFromIndex, props.circularNavigation)
3847 };
3848 break;
3849
3850 case MenuMouseLeave:
3851 changes = {
3852 highlightedIndex: -1
3853 };
3854 break;
3855
3856 case ToggleButtonClick:
3857 case FunctionToggleMenu:
3858 changes = {
3859 isOpen: !state.isOpen,
3860 highlightedIndex: state.isOpen ? -1 : getHighlightedIndexOnOpen(props, state, 0)
3861 };
3862 break;
3863
3864 case FunctionOpenMenu:
3865 changes = {
3866 isOpen: true,
3867 highlightedIndex: getHighlightedIndexOnOpen(props, state, 0)
3868 };
3869 break;
3870
3871 case FunctionCloseMenu:
3872 changes = {
3873 isOpen: false
3874 };
3875 break;
3876
3877 case FunctionSetHighlightedIndex:
3878 changes = {
3879 highlightedIndex: action.highlightedIndex
3880 };
3881 break;
3882
3883 case FunctionSelectItem:
3884 changes = {
3885 selectedItem: action.selectedItem
3886 };
3887 break;
3888
3889 case FunctionSetInputValue:
3890 changes = {
3891 inputValue: action.inputValue
3892 };
3893 break;
3894
3895 case FunctionReset:
3896 changes = {
3897 highlightedIndex: getDefaultValue(props, 'highlightedIndex'),
3898 isOpen: getDefaultValue(props, 'isOpen'),
3899 selectedItem: getDefaultValue(props, 'selectedItem'),
3900 inputValue: getDefaultValue(props, 'inputValue')
3901 };
3902 break;
3903
3904 default:
3905 throw new Error('Reducer called without proper action type.');
3906 }
3907
3908 return _extends({}, state, changes);
3909 }
3910 /* eslint-enable complexity */
3911
3912 var validatePropTypes = getPropTypesValidator(useSelect, propTypes$1);
3913 useSelect.stateChangeTypes = stateChangeTypes$1;
3914
3915 function useSelect(userProps) {
3916 if (userProps === void 0) {
3917 userProps = {};
3918 }
3919
3920 /* istanbul ignore else */
3921 {
3922 validatePropTypes(userProps);
3923 } // Props defaults and destructuring.
3924
3925
3926 var props = _extends({}, defaultProps$1, userProps);
3927
3928 var items = props.items,
3929 scrollIntoView = props.scrollIntoView,
3930 environment = props.environment,
3931 initialIsOpen = props.initialIsOpen,
3932 defaultIsOpen = props.defaultIsOpen,
3933 itemToString = props.itemToString,
3934 getA11ySelectionMessage = props.getA11ySelectionMessage,
3935 getA11yStatusMessage = props.getA11yStatusMessage; // Initial state depending on controlled props.
3936
3937 var initialState = getInitialState(props);
3938
3939 var _useControlledReducer = useControlledReducer(downshiftSelectReducer, initialState, props),
3940 state = _useControlledReducer[0],
3941 dispatch = _useControlledReducer[1];
3942
3943 var isOpen = state.isOpen,
3944 highlightedIndex = state.highlightedIndex,
3945 selectedItem = state.selectedItem,
3946 inputValue = state.inputValue; // Element efs.
3947
3948 var toggleButtonRef = react.useRef(null);
3949 var menuRef = react.useRef(null);
3950 var itemRefs = react.useRef();
3951 itemRefs.current = {}; // used not to trigger menu blur action in some scenarios.
3952
3953 var shouldBlurRef = react.useRef(true); // used to keep the inputValue clearTimeout object between renders.
3954
3955 var clearTimeoutRef = react.useRef(null); // prevent id re-generation between renders.
3956
3957 var elementIdsRef = react.useRef(getElementIds(props)); // used to keep track of how many items we had on previous cycle.
3958
3959 var previousResultCountRef = react.useRef();
3960 var isInitialMountRef = react.useRef(true); // utility callback to get item element.
3961
3962 var latest = useLatestRef({
3963 state: state,
3964 props: props
3965 }); // Some utils.
3966
3967 var getItemNodeFromIndex = function getItemNodeFromIndex(index) {
3968 return itemRefs.current[elementIdsRef.current.getItemId(index)];
3969 }; // Effects.
3970 // Sets a11y status message on changes in state.
3971
3972
3973 useA11yMessageSetter(getA11yStatusMessage, [isOpen, highlightedIndex, inputValue, items], _extends({
3974 isInitialMount: isInitialMountRef.current,
3975 previousResultCount: previousResultCountRef.current,
3976 items: items,
3977 environment: environment,
3978 itemToString: itemToString
3979 }, state)); // Sets a11y status message on changes in selectedItem.
3980
3981 useA11yMessageSetter(getA11ySelectionMessage, [selectedItem], _extends({
3982 isInitialMount: isInitialMountRef.current,
3983 previousResultCount: previousResultCountRef.current,
3984 items: items,
3985 environment: environment,
3986 itemToString: itemToString
3987 }, state)); // Scroll on highlighted item if change comes from keyboard.
3988
3989 var shouldScrollRef = useScrollIntoView({
3990 menuElement: menuRef.current,
3991 highlightedIndex: highlightedIndex,
3992 isOpen: isOpen,
3993 itemRefs: itemRefs,
3994 scrollIntoView: scrollIntoView,
3995 getItemNodeFromIndex: getItemNodeFromIndex
3996 }); // Sets cleanup for the keysSoFar after 500ms.
3997
3998 react.useEffect(function () {
3999 // init the clean function here as we need access to dispatch.
4000 if (isInitialMountRef.current) {
4001 clearTimeoutRef.current = debounce(function (outerDispatch) {
4002 outerDispatch({
4003 type: FunctionSetInputValue,
4004 inputValue: ''
4005 });
4006 }, 500);
4007 }
4008
4009 if (!inputValue) {
4010 return;
4011 }
4012
4013 clearTimeoutRef.current(dispatch);
4014 }, [dispatch, inputValue]);
4015 useControlPropsValidator({
4016 isInitialMount: isInitialMountRef.current,
4017 props: props,
4018 state: state
4019 });
4020 /* Controls the focus on the menu or the toggle button. */
4021
4022 react.useEffect(function () {
4023 // Don't focus menu on first render.
4024 if (isInitialMountRef.current) {
4025 // Unless it was initialised as open.
4026 if ((initialIsOpen || defaultIsOpen || isOpen) && menuRef.current) {
4027 menuRef.current.focus();
4028 }
4029
4030 return;
4031 } // Focus menu on open.
4032
4033
4034 if (isOpen) {
4035 // istanbul ignore else
4036 if (menuRef.current) {
4037 menuRef.current.focus();
4038 }
4039
4040 return;
4041 } // Focus toggleButton on close, but not if it was closed with (Shift+)Tab.
4042
4043
4044 if (environment.document.activeElement === menuRef.current) {
4045 // istanbul ignore else
4046 if (toggleButtonRef.current) {
4047 shouldBlurRef.current = false;
4048 toggleButtonRef.current.focus();
4049 }
4050 } // eslint-disable-next-line react-hooks/exhaustive-deps
4051
4052 }, [isOpen]);
4053 react.useEffect(function () {
4054 if (isInitialMountRef.current) {
4055 return;
4056 }
4057
4058 previousResultCountRef.current = items.length;
4059 }); // Add mouse/touch events to document.
4060
4061 var mouseAndTouchTrackersRef = useMouseAndTouchTracker(isOpen, [menuRef, toggleButtonRef], environment, function () {
4062 dispatch({
4063 type: MenuBlur
4064 });
4065 });
4066 var setGetterPropCallInfo = useGetterPropsCalledChecker('getMenuProps', 'getToggleButtonProps'); // Make initial ref false.
4067
4068 react.useEffect(function () {
4069 isInitialMountRef.current = false;
4070 }, []); // Event handler functions.
4071
4072 var toggleButtonKeyDownHandlers = react.useMemo(function () {
4073 return {
4074 ArrowDown: function ArrowDown(event) {
4075 event.preventDefault();
4076 dispatch({
4077 type: ToggleButtonKeyDownArrowDown,
4078 getItemNodeFromIndex: getItemNodeFromIndex,
4079 shiftKey: event.shiftKey
4080 });
4081 },
4082 ArrowUp: function ArrowUp(event) {
4083 event.preventDefault();
4084 dispatch({
4085 type: ToggleButtonKeyDownArrowUp,
4086 getItemNodeFromIndex: getItemNodeFromIndex,
4087 shiftKey: event.shiftKey
4088 });
4089 }
4090 };
4091 }, [dispatch]);
4092 var menuKeyDownHandlers = react.useMemo(function () {
4093 return {
4094 ArrowDown: function ArrowDown(event) {
4095 event.preventDefault();
4096 dispatch({
4097 type: MenuKeyDownArrowDown,
4098 getItemNodeFromIndex: getItemNodeFromIndex,
4099 shiftKey: event.shiftKey
4100 });
4101 },
4102 ArrowUp: function ArrowUp(event) {
4103 event.preventDefault();
4104 dispatch({
4105 type: MenuKeyDownArrowUp,
4106 getItemNodeFromIndex: getItemNodeFromIndex,
4107 shiftKey: event.shiftKey
4108 });
4109 },
4110 Home: function Home(event) {
4111 event.preventDefault();
4112 dispatch({
4113 type: MenuKeyDownHome,
4114 getItemNodeFromIndex: getItemNodeFromIndex
4115 });
4116 },
4117 End: function End(event) {
4118 event.preventDefault();
4119 dispatch({
4120 type: MenuKeyDownEnd,
4121 getItemNodeFromIndex: getItemNodeFromIndex
4122 });
4123 },
4124 Escape: function Escape() {
4125 dispatch({
4126 type: MenuKeyDownEscape
4127 });
4128 },
4129 Enter: function Enter(event) {
4130 event.preventDefault();
4131 dispatch({
4132 type: MenuKeyDownEnter
4133 });
4134 },
4135 ' ': function _(event) {
4136 event.preventDefault();
4137 dispatch({
4138 type: MenuKeyDownSpaceButton
4139 });
4140 }
4141 };
4142 }, [dispatch]); // Action functions.
4143
4144 var toggleMenu = react.useCallback(function () {
4145 dispatch({
4146 type: FunctionToggleMenu
4147 });
4148 }, [dispatch]);
4149 var closeMenu = react.useCallback(function () {
4150 dispatch({
4151 type: FunctionCloseMenu
4152 });
4153 }, [dispatch]);
4154 var openMenu = react.useCallback(function () {
4155 dispatch({
4156 type: FunctionOpenMenu
4157 });
4158 }, [dispatch]);
4159 var setHighlightedIndex = react.useCallback(function (newHighlightedIndex) {
4160 dispatch({
4161 type: FunctionSetHighlightedIndex,
4162 highlightedIndex: newHighlightedIndex
4163 });
4164 }, [dispatch]);
4165 var selectItem = react.useCallback(function (newSelectedItem) {
4166 dispatch({
4167 type: FunctionSelectItem,
4168 selectedItem: newSelectedItem
4169 });
4170 }, [dispatch]);
4171 var reset = react.useCallback(function () {
4172 dispatch({
4173 type: FunctionReset
4174 });
4175 }, [dispatch]);
4176 var setInputValue = react.useCallback(function (newInputValue) {
4177 dispatch({
4178 type: FunctionSetInputValue,
4179 inputValue: newInputValue
4180 });
4181 }, [dispatch]); // Getter functions.
4182
4183 var getLabelProps = react.useCallback(function (labelProps) {
4184 return _extends({
4185 id: elementIdsRef.current.labelId,
4186 htmlFor: elementIdsRef.current.toggleButtonId
4187 }, labelProps);
4188 }, []);
4189 var getMenuProps = react.useCallback(function (_temp, _temp2) {
4190 var _extends2;
4191
4192 var _ref = _temp === void 0 ? {} : _temp,
4193 onMouseLeave = _ref.onMouseLeave,
4194 _ref$refKey = _ref.refKey,
4195 refKey = _ref$refKey === void 0 ? 'ref' : _ref$refKey,
4196 onKeyDown = _ref.onKeyDown,
4197 onBlur = _ref.onBlur,
4198 ref = _ref.ref,
4199 rest = _objectWithoutPropertiesLoose(_ref, ["onMouseLeave", "refKey", "onKeyDown", "onBlur", "ref"]);
4200
4201 var _ref2 = _temp2 === void 0 ? {} : _temp2,
4202 _ref2$suppressRefErro = _ref2.suppressRefError,
4203 suppressRefError = _ref2$suppressRefErro === void 0 ? false : _ref2$suppressRefErro;
4204
4205 var latestState = latest.current.state;
4206
4207 var menuHandleKeyDown = function menuHandleKeyDown(event) {
4208 var key = normalizeArrowKey(event);
4209
4210 if (key && menuKeyDownHandlers[key]) {
4211 menuKeyDownHandlers[key](event);
4212 } else if (isAcceptedCharacterKey(key)) {
4213 dispatch({
4214 type: MenuKeyDownCharacter,
4215 key: key,
4216 getItemNodeFromIndex: getItemNodeFromIndex
4217 });
4218 }
4219 };
4220
4221 var menuHandleBlur = function menuHandleBlur() {
4222 // if the blur was a result of selection, we don't trigger this action.
4223 if (shouldBlurRef.current === false) {
4224 shouldBlurRef.current = true;
4225 return;
4226 }
4227
4228 var shouldBlur = !mouseAndTouchTrackersRef.current.isMouseDown;
4229 /* istanbul ignore else */
4230
4231 if (shouldBlur) {
4232 dispatch({
4233 type: MenuBlur
4234 });
4235 }
4236 };
4237
4238 var menuHandleMouseLeave = function menuHandleMouseLeave() {
4239 dispatch({
4240 type: MenuMouseLeave
4241 });
4242 };
4243
4244 setGetterPropCallInfo('getMenuProps', suppressRefError, refKey, menuRef);
4245 return _extends((_extends2 = {}, _extends2[refKey] = handleRefs(ref, function (menuNode) {
4246 menuRef.current = menuNode;
4247 }), _extends2.id = elementIdsRef.current.menuId, _extends2.role = 'listbox', _extends2['aria-labelledby'] = elementIdsRef.current.labelId, _extends2.tabIndex = -1, _extends2), latestState.isOpen && latestState.highlightedIndex > -1 && {
4248 'aria-activedescendant': elementIdsRef.current.getItemId(latestState.highlightedIndex)
4249 }, {
4250 onMouseLeave: callAllEventHandlers(onMouseLeave, menuHandleMouseLeave),
4251 onKeyDown: callAllEventHandlers(onKeyDown, menuHandleKeyDown),
4252 onBlur: callAllEventHandlers(onBlur, menuHandleBlur)
4253 }, rest);
4254 }, [dispatch, latest, menuKeyDownHandlers, mouseAndTouchTrackersRef, setGetterPropCallInfo]);
4255 var getToggleButtonProps = react.useCallback(function (_temp3, _temp4) {
4256 var _extends3;
4257
4258 var _ref3 = _temp3 === void 0 ? {} : _temp3,
4259 onClick = _ref3.onClick,
4260 onKeyDown = _ref3.onKeyDown,
4261 _ref3$refKey = _ref3.refKey,
4262 refKey = _ref3$refKey === void 0 ? 'ref' : _ref3$refKey,
4263 ref = _ref3.ref,
4264 rest = _objectWithoutPropertiesLoose(_ref3, ["onClick", "onKeyDown", "refKey", "ref"]);
4265
4266 var _ref4 = _temp4 === void 0 ? {} : _temp4,
4267 _ref4$suppressRefErro = _ref4.suppressRefError,
4268 suppressRefError = _ref4$suppressRefErro === void 0 ? false : _ref4$suppressRefErro;
4269
4270 var toggleButtonHandleClick = function toggleButtonHandleClick() {
4271 dispatch({
4272 type: ToggleButtonClick
4273 });
4274 };
4275
4276 var toggleButtonHandleKeyDown = function toggleButtonHandleKeyDown(event) {
4277 var key = normalizeArrowKey(event);
4278
4279 if (key && toggleButtonKeyDownHandlers[key]) {
4280 toggleButtonKeyDownHandlers[key](event);
4281 } else if (isAcceptedCharacterKey(key)) {
4282 dispatch({
4283 type: ToggleButtonKeyDownCharacter,
4284 key: key,
4285 getItemNodeFromIndex: getItemNodeFromIndex
4286 });
4287 }
4288 };
4289
4290 var toggleProps = _extends((_extends3 = {}, _extends3[refKey] = handleRefs(ref, function (toggleButtonNode) {
4291 toggleButtonRef.current = toggleButtonNode;
4292 }), _extends3.id = elementIdsRef.current.toggleButtonId, _extends3['aria-haspopup'] = 'listbox', _extends3['aria-expanded'] = latest.current.state.isOpen, _extends3['aria-labelledby'] = elementIdsRef.current.labelId + " " + elementIdsRef.current.toggleButtonId, _extends3), rest);
4293
4294 if (!rest.disabled) {
4295 toggleProps.onClick = callAllEventHandlers(onClick, toggleButtonHandleClick);
4296 toggleProps.onKeyDown = callAllEventHandlers(onKeyDown, toggleButtonHandleKeyDown);
4297 }
4298
4299 setGetterPropCallInfo('getToggleButtonProps', suppressRefError, refKey, toggleButtonRef);
4300 return toggleProps;
4301 }, [dispatch, latest, toggleButtonKeyDownHandlers, setGetterPropCallInfo]);
4302 var getItemProps = react.useCallback(function (_temp5) {
4303 var _extends4;
4304
4305 var _ref5 = _temp5 === void 0 ? {} : _temp5,
4306 item = _ref5.item,
4307 index = _ref5.index,
4308 onMouseMove = _ref5.onMouseMove,
4309 onClick = _ref5.onClick,
4310 _ref5$refKey = _ref5.refKey,
4311 refKey = _ref5$refKey === void 0 ? 'ref' : _ref5$refKey,
4312 ref = _ref5.ref,
4313 rest = _objectWithoutPropertiesLoose(_ref5, ["item", "index", "onMouseMove", "onClick", "refKey", "ref"]);
4314
4315 var _latest$current = latest.current,
4316 latestState = _latest$current.state,
4317 latestProps = _latest$current.props;
4318
4319 var itemHandleMouseMove = function itemHandleMouseMove() {
4320 if (index === latestState.highlightedIndex) {
4321 return;
4322 }
4323
4324 shouldScrollRef.current = false;
4325 dispatch({
4326 type: ItemMouseMove,
4327 index: index
4328 });
4329 };
4330
4331 var itemHandleClick = function itemHandleClick() {
4332 dispatch({
4333 type: ItemClick,
4334 index: index
4335 });
4336 };
4337
4338 var itemIndex = getItemIndex(index, item, latestProps.items);
4339
4340 if (itemIndex < 0) {
4341 throw new Error('Pass either item or item index in getItemProps!');
4342 }
4343
4344 var itemProps = _extends((_extends4 = {
4345 role: 'option',
4346 'aria-selected': "" + (itemIndex === latestState.highlightedIndex),
4347 id: elementIdsRef.current.getItemId(itemIndex)
4348 }, _extends4[refKey] = handleRefs(ref, function (itemNode) {
4349 if (itemNode) {
4350 itemRefs.current[elementIdsRef.current.getItemId(itemIndex)] = itemNode;
4351 }
4352 }), _extends4), rest);
4353
4354 if (!rest.disabled) {
4355 itemProps.onMouseMove = callAllEventHandlers(onMouseMove, itemHandleMouseMove);
4356 itemProps.onClick = callAllEventHandlers(onClick, itemHandleClick);
4357 }
4358
4359 return itemProps;
4360 }, [dispatch, latest, shouldScrollRef]);
4361 return {
4362 // prop getters.
4363 getToggleButtonProps: getToggleButtonProps,
4364 getLabelProps: getLabelProps,
4365 getMenuProps: getMenuProps,
4366 getItemProps: getItemProps,
4367 // actions.
4368 toggleMenu: toggleMenu,
4369 openMenu: openMenu,
4370 closeMenu: closeMenu,
4371 setHighlightedIndex: setHighlightedIndex,
4372 selectItem: selectItem,
4373 reset: reset,
4374 setInputValue: setInputValue,
4375 // state.
4376 highlightedIndex: highlightedIndex,
4377 isOpen: isOpen,
4378 selectedItem: selectedItem,
4379 inputValue: inputValue
4380 };
4381 }
4382
4383 var InputKeyDownArrowDown = '__input_keydown_arrow_down__' ;
4384 var InputKeyDownArrowUp = '__input_keydown_arrow_up__' ;
4385 var InputKeyDownEscape = '__input_keydown_escape__' ;
4386 var InputKeyDownHome = '__input_keydown_home__' ;
4387 var InputKeyDownEnd = '__input_keydown_end__' ;
4388 var InputKeyDownEnter = '__input_keydown_enter__' ;
4389 var InputChange = '__input_change__' ;
4390 var InputBlur = '__input_blur__' ;
4391 var MenuMouseLeave$1 = '__menu_mouse_leave__' ;
4392 var ItemMouseMove$1 = '__item_mouse_move__' ;
4393 var ItemClick$1 = '__item_click__' ;
4394 var ToggleButtonClick$1 = '__togglebutton_click__' ;
4395 var FunctionToggleMenu$1 = '__function_toggle_menu__' ;
4396 var FunctionOpenMenu$1 = '__function_open_menu__' ;
4397 var FunctionCloseMenu$1 = '__function_close_menu__' ;
4398 var FunctionSetHighlightedIndex$1 = '__function_set_highlighted_index__' ;
4399 var FunctionSelectItem$1 = '__function_select_item__' ;
4400 var FunctionSetInputValue$1 = '__function_set_input_value__' ;
4401 var FunctionReset$1 = '__function_reset__' ;
4402 var ControlledPropUpdatedSelectedItem = '__controlled_prop_updated_selected_item__' ;
4403
4404 var stateChangeTypes$2 = /*#__PURE__*/Object.freeze({
4405 __proto__: null,
4406 InputKeyDownArrowDown: InputKeyDownArrowDown,
4407 InputKeyDownArrowUp: InputKeyDownArrowUp,
4408 InputKeyDownEscape: InputKeyDownEscape,
4409 InputKeyDownHome: InputKeyDownHome,
4410 InputKeyDownEnd: InputKeyDownEnd,
4411 InputKeyDownEnter: InputKeyDownEnter,
4412 InputChange: InputChange,
4413 InputBlur: InputBlur,
4414 MenuMouseLeave: MenuMouseLeave$1,
4415 ItemMouseMove: ItemMouseMove$1,
4416 ItemClick: ItemClick$1,
4417 ToggleButtonClick: ToggleButtonClick$1,
4418 FunctionToggleMenu: FunctionToggleMenu$1,
4419 FunctionOpenMenu: FunctionOpenMenu$1,
4420 FunctionCloseMenu: FunctionCloseMenu$1,
4421 FunctionSetHighlightedIndex: FunctionSetHighlightedIndex$1,
4422 FunctionSelectItem: FunctionSelectItem$1,
4423 FunctionSetInputValue: FunctionSetInputValue$1,
4424 FunctionReset: FunctionReset$1,
4425 ControlledPropUpdatedSelectedItem: ControlledPropUpdatedSelectedItem
4426 });
4427
4428 function getElementIds$1(_ref) {
4429 var id = _ref.id,
4430 inputId = _ref.inputId,
4431 rest = _objectWithoutPropertiesLoose(_ref, ["id", "inputId"]);
4432
4433 var uniqueId = id === undefined ? "downshift-" + generateId() : id;
4434 return _extends({
4435 inputId: inputId || uniqueId + "-input"
4436 }, getElementIds(_extends({
4437 id: id
4438 }, rest)));
4439 }
4440 function getInitialState$1(props) {
4441 var initialState = getInitialState(props);
4442 var selectedItem = initialState.selectedItem;
4443 var inputValue = initialState.inputValue;
4444
4445 if (inputValue === '' && selectedItem && props.defaultInputValue === undefined && props.initialInputValue === undefined && props.inputValue === undefined) {
4446 inputValue = props.itemToString(selectedItem);
4447 }
4448
4449 return _extends({}, initialState, {
4450 inputValue: inputValue
4451 });
4452 }
4453 var propTypes$2 = {
4454 items: propTypes.array.isRequired,
4455 itemToString: propTypes.func,
4456 getA11yStatusMessage: propTypes.func,
4457 getA11ySelectionMessage: propTypes.func,
4458 circularNavigation: propTypes.bool,
4459 highlightedIndex: propTypes.number,
4460 defaultHighlightedIndex: propTypes.number,
4461 initialHighlightedIndex: propTypes.number,
4462 isOpen: propTypes.bool,
4463 defaultIsOpen: propTypes.bool,
4464 initialIsOpen: propTypes.bool,
4465 selectedItem: propTypes.any,
4466 initialSelectedItem: propTypes.any,
4467 defaultSelectedItem: propTypes.any,
4468 inputValue: propTypes.string,
4469 defaultInputValue: propTypes.string,
4470 initialInputValue: propTypes.string,
4471 id: propTypes.string,
4472 labelId: propTypes.string,
4473 menuId: propTypes.string,
4474 getItemId: propTypes.func,
4475 inputId: propTypes.string,
4476 toggleButtonId: propTypes.string,
4477 stateReducer: propTypes.func,
4478 onSelectedItemChange: propTypes.func,
4479 onHighlightedIndexChange: propTypes.func,
4480 onStateChange: propTypes.func,
4481 onIsOpenChange: propTypes.func,
4482 onInputValueChange: propTypes.func,
4483 environment: propTypes.shape({
4484 addEventListener: propTypes.func,
4485 removeEventListener: propTypes.func,
4486 document: propTypes.shape({
4487 getElementById: propTypes.func,
4488 activeElement: propTypes.any,
4489 body: propTypes.any
4490 })
4491 })
4492 };
4493 /**
4494 * The useCombobox version of useControlledReducer, which also
4495 * checks if the controlled prop selectedItem changed between
4496 * renders. If so, it will also update inputValue with its
4497 * string equivalent. It uses the common useEnhancedReducer to
4498 * compute the rest of the state.
4499 *
4500 * @param {Function} reducer Reducer function from downshift.
4501 * @param {Object} initialState Initial state of the hook.
4502 * @param {Object} props The hook props.
4503 * @returns {Array} An array with the state and an action dispatcher.
4504 */
4505
4506 function useControlledReducer$1(reducer, initialState, props) {
4507 var previousSelectedItemRef = react.useRef();
4508
4509 var _useEnhancedReducer = useEnhancedReducer(reducer, initialState, props),
4510 state = _useEnhancedReducer[0],
4511 dispatch = _useEnhancedReducer[1]; // ToDo: if needed, make same approach as selectedItemChanged from Downshift.
4512
4513
4514 react.useEffect(function () {
4515 if (isControlledProp(props, 'selectedItem')) {
4516 if (previousSelectedItemRef.current !== props.selectedItem) {
4517 dispatch({
4518 type: ControlledPropUpdatedSelectedItem,
4519 inputValue: props.itemToString(props.selectedItem)
4520 });
4521 }
4522
4523 previousSelectedItemRef.current = state.selectedItem === previousSelectedItemRef.current ? props.selectedItem : state.selectedItem;
4524 }
4525 });
4526 return [getState(state, props), dispatch];
4527 }
4528 var defaultProps$2 = _extends({}, defaultProps, {
4529 getA11yStatusMessage: getA11yStatusMessage,
4530 circularNavigation: true
4531 });
4532
4533 /* eslint-disable complexity */
4534
4535 function downshiftUseComboboxReducer(state, action) {
4536 var type = action.type,
4537 props = action.props,
4538 shiftKey = action.shiftKey;
4539 var changes;
4540
4541 switch (type) {
4542 case ItemMouseMove$1:
4543 changes = {
4544 highlightedIndex: action.index
4545 };
4546 break;
4547
4548 case ItemClick$1:
4549 changes = {
4550 isOpen: getDefaultValue(props, 'isOpen'),
4551 highlightedIndex: getDefaultValue(props, 'highlightedIndex'),
4552 selectedItem: props.items[action.index],
4553 inputValue: props.itemToString(props.items[action.index])
4554 };
4555 break;
4556
4557 case InputKeyDownArrowDown:
4558 if (state.isOpen) {
4559 changes = {
4560 highlightedIndex: getNextWrappingIndex(shiftKey ? 5 : 1, state.highlightedIndex, props.items.length, action.getItemNodeFromIndex, props.circularNavigation)
4561 };
4562 } else {
4563 changes = {
4564 highlightedIndex: getHighlightedIndexOnOpen(props, state, 1, action.getItemNodeFromIndex),
4565 isOpen: true
4566 };
4567 }
4568
4569 break;
4570
4571 case InputKeyDownArrowUp:
4572 if (state.isOpen) {
4573 changes = {
4574 highlightedIndex: getNextWrappingIndex(shiftKey ? -5 : -1, state.highlightedIndex, props.items.length, action.getItemNodeFromIndex, props.circularNavigation)
4575 };
4576 } else {
4577 changes = {
4578 highlightedIndex: getHighlightedIndexOnOpen(props, state, -1, action.getItemNodeFromIndex),
4579 isOpen: true
4580 };
4581 }
4582
4583 break;
4584
4585 case InputKeyDownEnter:
4586 changes = _extends({}, state.isOpen && state.highlightedIndex >= 0 && {
4587 selectedItem: props.items[state.highlightedIndex],
4588 isOpen: getDefaultValue(props, 'isOpen'),
4589 highlightedIndex: getDefaultValue(props, 'highlightedIndex'),
4590 inputValue: props.itemToString(props.items[state.highlightedIndex])
4591 });
4592 break;
4593
4594 case InputKeyDownEscape:
4595 changes = _extends({
4596 isOpen: false,
4597 highlightedIndex: -1
4598 }, !state.isOpen && {
4599 selectedItem: null,
4600 inputValue: ''
4601 });
4602 break;
4603
4604 case InputKeyDownHome:
4605 changes = _extends({}, state.isOpen && {
4606 highlightedIndex: getNextNonDisabledIndex(1, 0, props.items.length, action.getItemNodeFromIndex, false)
4607 });
4608 break;
4609
4610 case InputKeyDownEnd:
4611 changes = _extends({}, state.isOpen && {
4612 highlightedIndex: getNextNonDisabledIndex(-1, props.items.length - 1, props.items.length, action.getItemNodeFromIndex, false)
4613 });
4614 break;
4615
4616 case InputBlur:
4617 if (state.isOpen) {
4618 changes = _extends({
4619 isOpen: false,
4620 highlightedIndex: -1
4621 }, state.highlightedIndex >= 0 && action.selectItem && {
4622 selectedItem: props.items[state.highlightedIndex],
4623 inputValue: props.itemToString(props.items[state.highlightedIndex])
4624 });
4625 }
4626
4627 break;
4628
4629 case InputChange:
4630 changes = {
4631 isOpen: true,
4632 highlightedIndex: getDefaultValue(props, 'highlightedIndex'),
4633 inputValue: action.inputValue
4634 };
4635 break;
4636
4637 case MenuMouseLeave$1:
4638 changes = {
4639 highlightedIndex: -1
4640 };
4641 break;
4642
4643 case ToggleButtonClick$1:
4644 case FunctionToggleMenu$1:
4645 changes = {
4646 isOpen: !state.isOpen,
4647 highlightedIndex: state.isOpen ? -1 : getHighlightedIndexOnOpen(props, state, 0)
4648 };
4649 break;
4650
4651 case FunctionOpenMenu$1:
4652 changes = {
4653 isOpen: true,
4654 highlightedIndex: getHighlightedIndexOnOpen(props, state, 0)
4655 };
4656 break;
4657
4658 case FunctionCloseMenu$1:
4659 changes = {
4660 isOpen: false
4661 };
4662 break;
4663
4664 case FunctionSetHighlightedIndex$1:
4665 changes = {
4666 highlightedIndex: action.highlightedIndex
4667 };
4668 break;
4669
4670 case FunctionSelectItem$1:
4671 changes = {
4672 selectedItem: action.selectedItem,
4673 inputValue: props.itemToString(action.selectedItem)
4674 };
4675 break;
4676
4677 case ControlledPropUpdatedSelectedItem:
4678 case FunctionSetInputValue$1:
4679 changes = {
4680 inputValue: action.inputValue
4681 };
4682 break;
4683
4684 case FunctionReset$1:
4685 changes = {
4686 highlightedIndex: getDefaultValue(props, 'highlightedIndex'),
4687 isOpen: getDefaultValue(props, 'isOpen'),
4688 selectedItem: getDefaultValue(props, 'selectedItem'),
4689 inputValue: getDefaultValue(props, 'inputValue')
4690 };
4691 break;
4692
4693 default:
4694 throw new Error('Reducer called without proper action type.');
4695 }
4696
4697 return _extends({}, state, changes);
4698 }
4699 /* eslint-enable complexity */
4700
4701 var validatePropTypes$1 = getPropTypesValidator(useCombobox, propTypes$2);
4702 useCombobox.stateChangeTypes = stateChangeTypes$2;
4703
4704 function useCombobox(userProps) {
4705 if (userProps === void 0) {
4706 userProps = {};
4707 }
4708
4709 /* istanbul ignore else */
4710 {
4711 validatePropTypes$1(userProps);
4712 } // Props defaults and destructuring.
4713
4714
4715 var props = _extends({}, defaultProps$2, userProps);
4716
4717 var initialIsOpen = props.initialIsOpen,
4718 defaultIsOpen = props.defaultIsOpen,
4719 items = props.items,
4720 scrollIntoView = props.scrollIntoView,
4721 environment = props.environment,
4722 getA11yStatusMessage = props.getA11yStatusMessage,
4723 getA11ySelectionMessage = props.getA11ySelectionMessage,
4724 itemToString = props.itemToString; // Initial state depending on controlled props.
4725
4726 var initialState = getInitialState$1(props);
4727
4728 var _useControlledReducer = useControlledReducer$1(downshiftUseComboboxReducer, initialState, props),
4729 state = _useControlledReducer[0],
4730 dispatch = _useControlledReducer[1];
4731
4732 var isOpen = state.isOpen,
4733 highlightedIndex = state.highlightedIndex,
4734 selectedItem = state.selectedItem,
4735 inputValue = state.inputValue; // Element refs.
4736
4737 var menuRef = react.useRef(null);
4738 var itemRefs = react.useRef();
4739 var inputRef = react.useRef(null);
4740 var toggleButtonRef = react.useRef(null);
4741 var comboboxRef = react.useRef(null);
4742 itemRefs.current = {};
4743 var isInitialMountRef = react.useRef(true); // prevent id re-generation between renders.
4744
4745 var elementIdsRef = react.useRef(getElementIds$1(props)); // used to keep track of how many items we had on previous cycle.
4746
4747 var previousResultCountRef = react.useRef(); // utility callback to get item element.
4748
4749 var latest = useLatestRef({
4750 state: state,
4751 props: props
4752 });
4753
4754 var getItemNodeFromIndex = function getItemNodeFromIndex(index) {
4755 return itemRefs.current[elementIdsRef.current.getItemId(index)];
4756 }; // Effects.
4757 // Sets a11y status message on changes in state.
4758
4759
4760 useA11yMessageSetter(getA11yStatusMessage, [isOpen, highlightedIndex, inputValue, items], _extends({
4761 isInitialMount: isInitialMountRef.current,
4762 previousResultCount: previousResultCountRef.current,
4763 items: items,
4764 environment: environment,
4765 itemToString: itemToString
4766 }, state)); // Sets a11y status message on changes in selectedItem.
4767
4768 useA11yMessageSetter(getA11ySelectionMessage, [selectedItem], _extends({
4769 isInitialMount: isInitialMountRef.current,
4770 previousResultCount: previousResultCountRef.current,
4771 items: items,
4772 environment: environment,
4773 itemToString: itemToString
4774 }, state)); // Scroll on highlighted item if change comes from keyboard.
4775
4776 var shouldScrollRef = useScrollIntoView({
4777 menuElement: menuRef.current,
4778 highlightedIndex: highlightedIndex,
4779 isOpen: isOpen,
4780 itemRefs: itemRefs,
4781 scrollIntoView: scrollIntoView,
4782 getItemNodeFromIndex: getItemNodeFromIndex
4783 });
4784 useControlPropsValidator({
4785 isInitialMount: isInitialMountRef.current,
4786 props: props,
4787 state: state
4788 }); // Controls the focus on the input on open.
4789
4790 react.useEffect(function () {
4791 // Don't focus menu on first render.
4792 if (isInitialMountRef.current) {
4793 // Unless it was initialised as open.
4794 if (initialIsOpen || defaultIsOpen || isOpen) {
4795 if (inputRef.current) {
4796 inputRef.current.focus();
4797 }
4798 }
4799 } // eslint-disable-next-line react-hooks/exhaustive-deps
4800
4801 }, [isOpen]);
4802 react.useEffect(function () {
4803 if (isInitialMountRef.current) {
4804 return;
4805 }
4806
4807 previousResultCountRef.current = items.length;
4808 }); // Add mouse/touch events to document.
4809
4810 var mouseAndTouchTrackersRef = useMouseAndTouchTracker(isOpen, [comboboxRef, menuRef, toggleButtonRef], environment, function () {
4811 dispatch({
4812 type: InputBlur,
4813 selectItem: false
4814 });
4815 });
4816 var setGetterPropCallInfo = useGetterPropsCalledChecker('getInputProps', 'getComboboxProps', 'getMenuProps'); // Make initial ref false.
4817
4818 react.useEffect(function () {
4819 isInitialMountRef.current = false;
4820 }, []);
4821 /* Event handler functions */
4822
4823 var inputKeyDownHandlers = react.useMemo(function () {
4824 return {
4825 ArrowDown: function ArrowDown(event) {
4826 event.preventDefault();
4827 dispatch({
4828 type: InputKeyDownArrowDown,
4829 shiftKey: event.shiftKey,
4830 getItemNodeFromIndex: getItemNodeFromIndex
4831 });
4832 },
4833 ArrowUp: function ArrowUp(event) {
4834 event.preventDefault();
4835 dispatch({
4836 type: InputKeyDownArrowUp,
4837 shiftKey: event.shiftKey,
4838 getItemNodeFromIndex: getItemNodeFromIndex
4839 });
4840 },
4841 Home: function Home(event) {
4842 event.preventDefault();
4843 dispatch({
4844 type: InputKeyDownHome,
4845 getItemNodeFromIndex: getItemNodeFromIndex
4846 });
4847 },
4848 End: function End(event) {
4849 event.preventDefault();
4850 dispatch({
4851 type: InputKeyDownEnd,
4852 getItemNodeFromIndex: getItemNodeFromIndex
4853 });
4854 },
4855 Escape: function Escape() {
4856 dispatch({
4857 type: InputKeyDownEscape
4858 });
4859 },
4860 Enter: function Enter(event) {
4861 // if IME composing, wait for next Enter keydown event.
4862 if (event.which === 229) {
4863 return;
4864 }
4865
4866 var latestState = latest.current.state;
4867
4868 if (latestState.isOpen) {
4869 event.preventDefault();
4870 }
4871
4872 dispatch({
4873 type: InputKeyDownEnter,
4874 getItemNodeFromIndex: getItemNodeFromIndex
4875 });
4876 }
4877 };
4878 }, [dispatch, latest]); // Getter props.
4879
4880 var getLabelProps = react.useCallback(function (labelProps) {
4881 return _extends({
4882 id: elementIdsRef.current.labelId,
4883 htmlFor: elementIdsRef.current.inputId
4884 }, labelProps);
4885 }, []);
4886 var getMenuProps = react.useCallback(function (_temp, _temp2) {
4887 var _extends2;
4888
4889 var _ref = _temp === void 0 ? {} : _temp,
4890 onMouseLeave = _ref.onMouseLeave,
4891 _ref$refKey = _ref.refKey,
4892 refKey = _ref$refKey === void 0 ? 'ref' : _ref$refKey,
4893 ref = _ref.ref,
4894 rest = _objectWithoutPropertiesLoose(_ref, ["onMouseLeave", "refKey", "ref"]);
4895
4896 var _ref2 = _temp2 === void 0 ? {} : _temp2,
4897 _ref2$suppressRefErro = _ref2.suppressRefError,
4898 suppressRefError = _ref2$suppressRefErro === void 0 ? false : _ref2$suppressRefErro;
4899
4900 setGetterPropCallInfo('getMenuProps', suppressRefError, refKey, menuRef);
4901 return _extends((_extends2 = {}, _extends2[refKey] = handleRefs(ref, function (menuNode) {
4902 menuRef.current = menuNode;
4903 }), _extends2.id = elementIdsRef.current.menuId, _extends2.role = 'listbox', _extends2['aria-labelledby'] = elementIdsRef.current.labelId, _extends2.onMouseLeave = callAllEventHandlers(onMouseLeave, function () {
4904 dispatch({
4905 type: MenuMouseLeave$1
4906 });
4907 }), _extends2), rest);
4908 }, [dispatch, setGetterPropCallInfo]);
4909 var getItemProps = react.useCallback(function (_temp3) {
4910 var _extends3, _ref4;
4911
4912 var _ref3 = _temp3 === void 0 ? {} : _temp3,
4913 item = _ref3.item,
4914 index = _ref3.index,
4915 _ref3$refKey = _ref3.refKey,
4916 refKey = _ref3$refKey === void 0 ? 'ref' : _ref3$refKey,
4917 ref = _ref3.ref,
4918 onMouseMove = _ref3.onMouseMove,
4919 onClick = _ref3.onClick,
4920 onPress = _ref3.onPress,
4921 rest = _objectWithoutPropertiesLoose(_ref3, ["item", "index", "refKey", "ref", "onMouseMove", "onClick", "onPress"]);
4922
4923 var _latest$current = latest.current,
4924 latestProps = _latest$current.props,
4925 latestState = _latest$current.state;
4926 var itemIndex = getItemIndex(index, item, latestProps.items);
4927
4928 if (itemIndex < 0) {
4929 throw new Error('Pass either item or item index in getItemProps!');
4930 }
4931
4932 var onSelectKey = 'onClick';
4933 var customClickHandler = onClick;
4934
4935 var itemHandleMouseMove = function itemHandleMouseMove() {
4936 if (index === latestState.highlightedIndex) {
4937 return;
4938 }
4939
4940 shouldScrollRef.current = false;
4941 dispatch({
4942 type: ItemMouseMove$1,
4943 index: index
4944 });
4945 };
4946
4947 var itemHandleClick = function itemHandleClick() {
4948 dispatch({
4949 type: ItemClick$1,
4950 index: index
4951 });
4952
4953 if (inputRef.current) {
4954 inputRef.current.focus();
4955 }
4956 };
4957
4958 return _extends((_extends3 = {}, _extends3[refKey] = handleRefs(ref, function (itemNode) {
4959 if (itemNode) {
4960 itemRefs.current[elementIdsRef.current.getItemId(itemIndex)] = itemNode;
4961 }
4962 }), _extends3.role = 'option', _extends3['aria-selected'] = "" + (itemIndex === latestState.highlightedIndex), _extends3.id = elementIdsRef.current.getItemId(itemIndex), _extends3), !rest.disabled && (_ref4 = {
4963 onMouseMove: callAllEventHandlers(onMouseMove, itemHandleMouseMove)
4964 }, _ref4[onSelectKey] = callAllEventHandlers(customClickHandler, itemHandleClick), _ref4), rest);
4965 }, [dispatch, latest, shouldScrollRef]);
4966 var getToggleButtonProps = react.useCallback(function (_temp4) {
4967 var _extends4;
4968
4969 var _ref5 = _temp4 === void 0 ? {} : _temp4,
4970 onClick = _ref5.onClick,
4971 onPress = _ref5.onPress,
4972 _ref5$refKey = _ref5.refKey,
4973 refKey = _ref5$refKey === void 0 ? 'ref' : _ref5$refKey,
4974 ref = _ref5.ref,
4975 rest = _objectWithoutPropertiesLoose(_ref5, ["onClick", "onPress", "refKey", "ref"]);
4976
4977 var toggleButtonHandleClick = function toggleButtonHandleClick() {
4978 dispatch({
4979 type: ToggleButtonClick$1
4980 });
4981
4982 if (!latest.current.state.isOpen && inputRef.current) {
4983 inputRef.current.focus();
4984 }
4985 };
4986
4987 return _extends((_extends4 = {}, _extends4[refKey] = handleRefs(ref, function (toggleButtonNode) {
4988 toggleButtonRef.current = toggleButtonNode;
4989 }), _extends4.id = elementIdsRef.current.toggleButtonId, _extends4.tabIndex = -1, _extends4), !rest.disabled && _extends({}, {
4990 onClick: callAllEventHandlers(onClick, toggleButtonHandleClick)
4991 }), rest);
4992 }, [dispatch, latest]);
4993 var getInputProps = react.useCallback(function (_temp5, _temp6) {
4994 var _extends5;
4995
4996 var _ref6 = _temp5 === void 0 ? {} : _temp5,
4997 onKeyDown = _ref6.onKeyDown,
4998 onChange = _ref6.onChange,
4999 onInput = _ref6.onInput,
5000 onBlur = _ref6.onBlur,
5001 onChangeText = _ref6.onChangeText,
5002 _ref6$refKey = _ref6.refKey,
5003 refKey = _ref6$refKey === void 0 ? 'ref' : _ref6$refKey,
5004 ref = _ref6.ref,
5005 rest = _objectWithoutPropertiesLoose(_ref6, ["onKeyDown", "onChange", "onInput", "onBlur", "onChangeText", "refKey", "ref"]);
5006
5007 var _ref7 = _temp6 === void 0 ? {} : _temp6,
5008 _ref7$suppressRefErro = _ref7.suppressRefError,
5009 suppressRefError = _ref7$suppressRefErro === void 0 ? false : _ref7$suppressRefErro;
5010
5011 setGetterPropCallInfo('getInputProps', suppressRefError, refKey, inputRef);
5012 var latestState = latest.current.state;
5013
5014 var inputHandleKeyDown = function inputHandleKeyDown(event) {
5015 var key = normalizeArrowKey(event);
5016
5017 if (key && inputKeyDownHandlers[key]) {
5018 inputKeyDownHandlers[key](event);
5019 }
5020 };
5021
5022 var inputHandleChange = function inputHandleChange(event) {
5023 dispatch({
5024 type: InputChange,
5025 inputValue: event.target.value
5026 });
5027 };
5028
5029 var inputHandleBlur = function inputHandleBlur() {
5030 /* istanbul ignore else */
5031 if (!mouseAndTouchTrackersRef.current.isMouseDown) {
5032 dispatch({
5033 type: InputBlur,
5034 selectItem: true
5035 });
5036 }
5037 };
5038 /* istanbul ignore next (preact) */
5039
5040
5041 var onChangeKey = 'onChange';
5042 var eventHandlers = {};
5043
5044 if (!rest.disabled) {
5045 var _eventHandlers;
5046
5047 eventHandlers = (_eventHandlers = {}, _eventHandlers[onChangeKey] = callAllEventHandlers(onChange, onInput, inputHandleChange), _eventHandlers.onKeyDown = callAllEventHandlers(onKeyDown, inputHandleKeyDown), _eventHandlers.onBlur = callAllEventHandlers(onBlur, inputHandleBlur), _eventHandlers);
5048 }
5049
5050 return _extends((_extends5 = {}, _extends5[refKey] = handleRefs(ref, function (inputNode) {
5051 inputRef.current = inputNode;
5052 }), _extends5.id = elementIdsRef.current.inputId, _extends5['aria-autocomplete'] = 'list', _extends5['aria-controls'] = elementIdsRef.current.menuId, _extends5), latestState.isOpen && latestState.highlightedIndex > -1 && {
5053 'aria-activedescendant': elementIdsRef.current.getItemId(latestState.highlightedIndex)
5054 }, {
5055 'aria-labelledby': elementIdsRef.current.labelId,
5056 // https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion
5057 // revert back since autocomplete="nope" is ignored on latest Chrome and Opera
5058 autoComplete: 'off',
5059 value: latestState.inputValue
5060 }, eventHandlers, rest);
5061 }, [dispatch, inputKeyDownHandlers, latest, mouseAndTouchTrackersRef, setGetterPropCallInfo]);
5062 var getComboboxProps = react.useCallback(function (_temp7, _temp8) {
5063 var _extends6;
5064
5065 var _ref8 = _temp7 === void 0 ? {} : _temp7,
5066 _ref8$refKey = _ref8.refKey,
5067 refKey = _ref8$refKey === void 0 ? 'ref' : _ref8$refKey,
5068 ref = _ref8.ref,
5069 rest = _objectWithoutPropertiesLoose(_ref8, ["refKey", "ref"]);
5070
5071 var _ref9 = _temp8 === void 0 ? {} : _temp8,
5072 _ref9$suppressRefErro = _ref9.suppressRefError,
5073 suppressRefError = _ref9$suppressRefErro === void 0 ? false : _ref9$suppressRefErro;
5074
5075 setGetterPropCallInfo('getComboboxProps', suppressRefError, refKey, comboboxRef);
5076 return _extends((_extends6 = {}, _extends6[refKey] = handleRefs(ref, function (comboboxNode) {
5077 comboboxRef.current = comboboxNode;
5078 }), _extends6.role = 'combobox', _extends6['aria-haspopup'] = 'listbox', _extends6['aria-owns'] = elementIdsRef.current.menuId, _extends6['aria-expanded'] = latest.current.state.isOpen, _extends6), rest);
5079 }, [latest, setGetterPropCallInfo]); // returns
5080
5081 var toggleMenu = react.useCallback(function () {
5082 dispatch({
5083 type: FunctionToggleMenu$1
5084 });
5085 }, [dispatch]);
5086 var closeMenu = react.useCallback(function () {
5087 dispatch({
5088 type: FunctionCloseMenu$1
5089 });
5090 }, [dispatch]);
5091 var openMenu = react.useCallback(function () {
5092 dispatch({
5093 type: FunctionOpenMenu$1
5094 });
5095 }, [dispatch]);
5096 var setHighlightedIndex = react.useCallback(function (newHighlightedIndex) {
5097 dispatch({
5098 type: FunctionSetHighlightedIndex$1,
5099 highlightedIndex: newHighlightedIndex
5100 });
5101 }, [dispatch]);
5102 var selectItem = react.useCallback(function (newSelectedItem) {
5103 dispatch({
5104 type: FunctionSelectItem$1,
5105 selectedItem: newSelectedItem
5106 });
5107 }, [dispatch]);
5108 var setInputValue = react.useCallback(function (newInputValue) {
5109 dispatch({
5110 type: FunctionSetInputValue$1,
5111 inputValue: newInputValue
5112 });
5113 }, [dispatch]);
5114 var reset = react.useCallback(function () {
5115 dispatch({
5116 type: FunctionReset$1
5117 });
5118 }, [dispatch]);
5119 return {
5120 // prop getters.
5121 getItemProps: getItemProps,
5122 getLabelProps: getLabelProps,
5123 getMenuProps: getMenuProps,
5124 getInputProps: getInputProps,
5125 getComboboxProps: getComboboxProps,
5126 getToggleButtonProps: getToggleButtonProps,
5127 // actions.
5128 toggleMenu: toggleMenu,
5129 openMenu: openMenu,
5130 closeMenu: closeMenu,
5131 setHighlightedIndex: setHighlightedIndex,
5132 setInputValue: setInputValue,
5133 selectItem: selectItem,
5134 reset: reset,
5135 // state.
5136 highlightedIndex: highlightedIndex,
5137 isOpen: isOpen,
5138 selectedItem: selectedItem,
5139 inputValue: inputValue
5140 };
5141 }
5142
5143 var defaultStateValues = {
5144 activeIndex: -1,
5145 selectedItems: []
5146 };
5147 /**
5148 * Returns the initial value for a state key in the following order:
5149 * 1. controlled prop, 2. initial prop, 3. default prop, 4. default
5150 * value from Downshift.
5151 *
5152 * @param {Object} props Props passed to the hook.
5153 * @param {string} propKey Props key to generate the value for.
5154 * @returns {any} The initial value for that prop.
5155 */
5156
5157 function getInitialValue$1(props, propKey) {
5158 return getInitialValue(props, propKey, defaultStateValues);
5159 }
5160 /**
5161 * Returns the default value for a state key in the following order:
5162 * 1. controlled prop, 2. default prop, 3. default value from Downshift.
5163 *
5164 * @param {Object} props Props passed to the hook.
5165 * @param {string} propKey Props key to generate the value for.
5166 * @returns {any} The initial value for that prop.
5167 */
5168
5169
5170 function getDefaultValue$1(props, propKey) {
5171 return getDefaultValue(props, propKey, defaultStateValues);
5172 }
5173 /**
5174 * Gets the initial state based on the provided props. It uses initial, default
5175 * and controlled props related to state in order to compute the initial value.
5176 *
5177 * @param {Object} props Props passed to the hook.
5178 * @returns {Object} The initial state.
5179 */
5180
5181 function getInitialState$2(props) {
5182 var activeIndex = getInitialValue$1(props, 'activeIndex');
5183 var selectedItems = getInitialValue$1(props, 'selectedItems');
5184 return {
5185 activeIndex: activeIndex,
5186 selectedItems: selectedItems
5187 };
5188 }
5189 /**
5190 * Returns true if dropdown keydown operation is permitted. Should not be
5191 * allowed on keydown with modifier keys (ctrl, alt, shift, meta), on
5192 * input element with text content that is either highlighted or selection
5193 * cursor is not at the starting position.
5194 *
5195 * @param {KeyboardEvent} event The event from keydown.
5196 * @returns {boolean} Whether the operation is allowed.
5197 */
5198
5199 function isKeyDownOperationPermitted(event) {
5200 if (event.shiftKey || event.metaKey || event.ctrlKey || event.altKey) {
5201 return false;
5202 }
5203
5204 var element = event.target;
5205
5206 if (element instanceof HTMLInputElement && // if element is a text input
5207 element.value !== '' && ( // and we have text in it
5208 // and cursor is either not at the start or is currently highlighting text.
5209 element.selectionStart !== 0 || element.selectionEnd !== 0)) {
5210 return false;
5211 }
5212
5213 return true;
5214 }
5215 /**
5216 * Returns a message to be added to aria-live region when item is removed.
5217 *
5218 * @param {Object} selectionParameters Parameters required to build the message.
5219 * @returns {string} The a11y message.
5220 */
5221
5222 function getA11yRemovalMessage(selectionParameters) {
5223 var removedSelectedItem = selectionParameters.removedSelectedItem,
5224 itemToStringLocal = selectionParameters.itemToString;
5225 return itemToStringLocal(removedSelectedItem) + " has been removed.";
5226 }
5227
5228 var propTypes$3 = {
5229 selectedItems: propTypes.array,
5230 initialSelectedItems: propTypes.array,
5231 defaultSelectedItems: propTypes.array,
5232 itemToString: propTypes.func,
5233 getA11yRemovalMessage: propTypes.func,
5234 stateReducer: propTypes.func,
5235 activeIndex: propTypes.number,
5236 initialActiveIndex: propTypes.number,
5237 defaultActiveIndex: propTypes.number,
5238 onActiveIndexChange: propTypes.func,
5239 onSelectedItemsChange: propTypes.func,
5240 keyNavigationNext: propTypes.string,
5241 keyNavigationPrevious: propTypes.string,
5242 environment: propTypes.shape({
5243 addEventListener: propTypes.func,
5244 removeEventListener: propTypes.func,
5245 document: propTypes.shape({
5246 getElementById: propTypes.func,
5247 activeElement: propTypes.any,
5248 body: propTypes.any
5249 })
5250 })
5251 };
5252 var defaultProps$3 = {
5253 itemToString: defaultProps.itemToString,
5254 stateReducer: defaultProps.stateReducer,
5255 environment: defaultProps.environment,
5256 getA11yRemovalMessage: getA11yRemovalMessage,
5257 keyNavigationNext: 'ArrowRight',
5258 keyNavigationPrevious: 'ArrowLeft'
5259 };
5260
5261 var SelectedItemClick = '__selected_item_click__' ;
5262 var SelectedItemKeyDownDelete = '__selected_item_keydown_delete__' ;
5263 var SelectedItemKeyDownBackspace = '__selected_item_keydown_backspace__' ;
5264 var SelectedItemKeyDownNavigationNext = '__selected_item_keydown_navigation_next__' ;
5265 var SelectedItemKeyDownNavigationPrevious = '__selected_item_keydown_navigation_previous__' ;
5266 var DropdownKeyDownNavigationPrevious = '__dropdown_keydown_navigation_previous__' ;
5267 var DropdownKeyDownBackspace = '__dropdown_keydown_backspace__' ;
5268 var DropdownClick = '__dropdown_click__' ;
5269 var FunctionAddSelectedItem = '__function_add_selected_item__' ;
5270 var FunctionRemoveSelectedItem = '__function_remove_selected_item__' ;
5271 var FunctionSetSelectedItems = '__function_set_selected_items__' ;
5272 var FunctionSetActiveIndex = '__function_set_active_index__' ;
5273 var FunctionReset$2 = '__function_reset__' ;
5274
5275 var stateChangeTypes$3 = /*#__PURE__*/Object.freeze({
5276 __proto__: null,
5277 SelectedItemClick: SelectedItemClick,
5278 SelectedItemKeyDownDelete: SelectedItemKeyDownDelete,
5279 SelectedItemKeyDownBackspace: SelectedItemKeyDownBackspace,
5280 SelectedItemKeyDownNavigationNext: SelectedItemKeyDownNavigationNext,
5281 SelectedItemKeyDownNavigationPrevious: SelectedItemKeyDownNavigationPrevious,
5282 DropdownKeyDownNavigationPrevious: DropdownKeyDownNavigationPrevious,
5283 DropdownKeyDownBackspace: DropdownKeyDownBackspace,
5284 DropdownClick: DropdownClick,
5285 FunctionAddSelectedItem: FunctionAddSelectedItem,
5286 FunctionRemoveSelectedItem: FunctionRemoveSelectedItem,
5287 FunctionSetSelectedItems: FunctionSetSelectedItems,
5288 FunctionSetActiveIndex: FunctionSetActiveIndex,
5289 FunctionReset: FunctionReset$2
5290 });
5291
5292 /* eslint-disable complexity */
5293
5294 function downshiftMultipleSelectionReducer(state, action) {
5295 var type = action.type,
5296 index = action.index,
5297 props = action.props,
5298 selectedItem = action.selectedItem;
5299 var activeIndex = state.activeIndex,
5300 selectedItems = state.selectedItems;
5301 var changes;
5302
5303 switch (type) {
5304 case SelectedItemClick:
5305 changes = {
5306 activeIndex: index
5307 };
5308 break;
5309
5310 case SelectedItemKeyDownNavigationPrevious:
5311 changes = {
5312 activeIndex: activeIndex - 1 < 0 ? 0 : activeIndex - 1
5313 };
5314 break;
5315
5316 case SelectedItemKeyDownNavigationNext:
5317 changes = {
5318 activeIndex: activeIndex + 1 >= selectedItems.length ? -1 : activeIndex + 1
5319 };
5320 break;
5321
5322 case SelectedItemKeyDownBackspace:
5323 case SelectedItemKeyDownDelete:
5324 {
5325 var newActiveIndex = activeIndex;
5326
5327 if (selectedItems.length === 1) {
5328 newActiveIndex = -1;
5329 } else if (activeIndex === selectedItems.length - 1) {
5330 newActiveIndex = selectedItems.length - 2;
5331 }
5332
5333 changes = _extends({
5334 selectedItems: [].concat(selectedItems.slice(0, activeIndex), selectedItems.slice(activeIndex + 1))
5335 }, {
5336 activeIndex: newActiveIndex
5337 });
5338 break;
5339 }
5340
5341 case DropdownKeyDownNavigationPrevious:
5342 changes = {
5343 activeIndex: selectedItems.length - 1
5344 };
5345 break;
5346
5347 case DropdownKeyDownBackspace:
5348 changes = {
5349 selectedItems: selectedItems.slice(0, selectedItems.length - 1)
5350 };
5351 break;
5352
5353 case FunctionAddSelectedItem:
5354 changes = {
5355 selectedItems: [].concat(selectedItems, [selectedItem])
5356 };
5357 break;
5358
5359 case DropdownClick:
5360 changes = {
5361 activeIndex: -1
5362 };
5363 break;
5364
5365 case FunctionRemoveSelectedItem:
5366 {
5367 var _newActiveIndex = activeIndex;
5368 var selectedItemIndex = selectedItems.indexOf(selectedItem);
5369
5370 if (selectedItems.length === 1) {
5371 _newActiveIndex = -1;
5372 } else if (selectedItemIndex === selectedItems.length - 1) {
5373 _newActiveIndex = selectedItems.length - 2;
5374 }
5375
5376 changes = _extends({
5377 selectedItems: [].concat(selectedItems.slice(0, selectedItemIndex), selectedItems.slice(selectedItemIndex + 1))
5378 }, {
5379 activeIndex: _newActiveIndex
5380 });
5381 break;
5382 }
5383
5384 case FunctionSetSelectedItems:
5385 {
5386 var newSelectedItems = action.selectedItems;
5387 changes = {
5388 selectedItems: newSelectedItems
5389 };
5390 break;
5391 }
5392
5393 case FunctionSetActiveIndex:
5394 {
5395 var _newActiveIndex2 = action.activeIndex;
5396 changes = {
5397 activeIndex: _newActiveIndex2
5398 };
5399 break;
5400 }
5401
5402 case FunctionReset$2:
5403 changes = {
5404 activeIndex: getDefaultValue$1(props, 'activeIndex'),
5405 selectedItems: getDefaultValue$1(props, 'selectedItems')
5406 };
5407 break;
5408
5409 default:
5410 throw new Error('Reducer called without proper action type.');
5411 }
5412
5413 return _extends({}, state, changes);
5414 }
5415
5416 useMultipleSelection.stateChangeTypes = stateChangeTypes$3;
5417
5418 function useMultipleSelection(userProps) {
5419 if (userProps === void 0) {
5420 userProps = {};
5421 }
5422
5423 // Props defaults and destructuring.
5424 var props = _extends({}, defaultProps$3, userProps);
5425
5426 var getA11yRemovalMessage = props.getA11yRemovalMessage,
5427 itemToString = props.itemToString,
5428 environment = props.environment,
5429 keyNavigationNext = props.keyNavigationNext,
5430 keyNavigationPrevious = props.keyNavigationPrevious; // Reducer init.
5431
5432 var _useControlledReducer = useControlledReducer(downshiftMultipleSelectionReducer, getInitialState$2(props), props),
5433 state = _useControlledReducer[0],
5434 dispatch = _useControlledReducer[1];
5435
5436 var activeIndex = state.activeIndex,
5437 selectedItems = state.selectedItems; // Refs.
5438
5439 var isInitialMountRef = react.useRef(true);
5440 var dropdownRef = react.useRef(null);
5441 var previousSelectedItemsRef = react.useRef(selectedItems);
5442 var selectedItemRefs = react.useRef();
5443 selectedItemRefs.current = [];
5444 var latest = useLatestRef({
5445 state: state,
5446 props: props
5447 }); // Effects.
5448
5449 /* Sets a11y status message on changes in selectedItem. */
5450
5451 react.useEffect(function () {
5452 if (isInitialMountRef.current) {
5453 return;
5454 }
5455
5456 if (selectedItems.length < previousSelectedItemsRef.current.length) {
5457 var removedSelectedItem = previousSelectedItemsRef.current.find(function (item) {
5458 return selectedItems.indexOf(item) < 0;
5459 });
5460 setStatus(getA11yRemovalMessage({
5461 itemToString: itemToString,
5462 resultCount: selectedItems.length,
5463 removedSelectedItem: removedSelectedItem,
5464 activeIndex: activeIndex,
5465 activeSelectedItem: selectedItems[activeIndex]
5466 }), environment.document);
5467 }
5468
5469 previousSelectedItemsRef.current = selectedItems; // eslint-disable-next-line react-hooks/exhaustive-deps
5470 }, [selectedItems.length]); // Sets focus on active item.
5471
5472 react.useEffect(function () {
5473 if (isInitialMountRef.current) {
5474 return;
5475 }
5476
5477 if (activeIndex === -1 && dropdownRef.current) {
5478 dropdownRef.current.focus();
5479 } else if (selectedItemRefs.current[activeIndex]) {
5480 selectedItemRefs.current[activeIndex].focus();
5481 }
5482 }, [activeIndex]);
5483 useControlPropsValidator({
5484 isInitialMount: isInitialMountRef.current,
5485 props: props,
5486 state: state
5487 });
5488 var setGetterPropCallInfo = useGetterPropsCalledChecker('getDropdownProps'); // Make initial ref false.
5489
5490 react.useEffect(function () {
5491 isInitialMountRef.current = false;
5492 }, []); // Event handler functions.
5493
5494 var selectedItemKeyDownHandlers = react.useMemo(function () {
5495 var _ref;
5496
5497 return _ref = {}, _ref[keyNavigationPrevious] = function () {
5498 dispatch({
5499 type: SelectedItemKeyDownNavigationPrevious
5500 });
5501 }, _ref[keyNavigationNext] = function () {
5502 dispatch({
5503 type: SelectedItemKeyDownNavigationNext
5504 });
5505 }, _ref.Delete = function Delete() {
5506 dispatch({
5507 type: SelectedItemKeyDownDelete
5508 });
5509 }, _ref.Backspace = function Backspace() {
5510 dispatch({
5511 type: SelectedItemKeyDownBackspace
5512 });
5513 }, _ref;
5514 }, [dispatch, keyNavigationNext, keyNavigationPrevious]);
5515 var dropdownKeyDownHandlers = react.useMemo(function () {
5516 var _ref2;
5517
5518 return _ref2 = {}, _ref2[keyNavigationPrevious] = function (event) {
5519 if (isKeyDownOperationPermitted(event)) {
5520 dispatch({
5521 type: DropdownKeyDownNavigationPrevious
5522 });
5523 }
5524 }, _ref2.Backspace = function Backspace(event) {
5525 if (isKeyDownOperationPermitted(event)) {
5526 dispatch({
5527 type: DropdownKeyDownBackspace
5528 });
5529 }
5530 }, _ref2;
5531 }, [dispatch, keyNavigationPrevious]); // Getter props.
5532
5533 var getSelectedItemProps = react.useCallback(function (_temp) {
5534 var _extends2;
5535
5536 var _ref3 = _temp === void 0 ? {} : _temp,
5537 _ref3$refKey = _ref3.refKey,
5538 refKey = _ref3$refKey === void 0 ? 'ref' : _ref3$refKey,
5539 ref = _ref3.ref,
5540 onClick = _ref3.onClick,
5541 onKeyDown = _ref3.onKeyDown,
5542 selectedItem = _ref3.selectedItem,
5543 index = _ref3.index,
5544 rest = _objectWithoutPropertiesLoose(_ref3, ["refKey", "ref", "onClick", "onKeyDown", "selectedItem", "index"]);
5545
5546 var latestState = latest.current.state;
5547 var itemIndex = getItemIndex(index, selectedItem, latestState.selectedItems);
5548
5549 if (itemIndex < 0) {
5550 throw new Error('Pass either selectedItem or index in getSelectedItemProps!');
5551 }
5552
5553 var selectedItemHandleClick = function selectedItemHandleClick() {
5554 dispatch({
5555 type: SelectedItemClick,
5556 index: index
5557 });
5558 };
5559
5560 var selectedItemHandleKeyDown = function selectedItemHandleKeyDown(event) {
5561 var key = normalizeArrowKey(event);
5562
5563 if (key && selectedItemKeyDownHandlers[key]) {
5564 selectedItemKeyDownHandlers[key](event);
5565 }
5566 };
5567
5568 return _extends((_extends2 = {}, _extends2[refKey] = handleRefs(ref, function (selectedItemNode) {
5569 if (selectedItemNode) {
5570 selectedItemRefs.current.push(selectedItemNode);
5571 }
5572 }), _extends2.tabIndex = index === latestState.activeIndex ? 0 : -1, _extends2.onClick = callAllEventHandlers(onClick, selectedItemHandleClick), _extends2.onKeyDown = callAllEventHandlers(onKeyDown, selectedItemHandleKeyDown), _extends2), rest);
5573 }, [dispatch, latest, selectedItemKeyDownHandlers]);
5574 var getDropdownProps = react.useCallback(function (_temp2, _temp3) {
5575 var _extends3;
5576
5577 var _ref4 = _temp2 === void 0 ? {} : _temp2,
5578 _ref4$refKey = _ref4.refKey,
5579 refKey = _ref4$refKey === void 0 ? 'ref' : _ref4$refKey,
5580 ref = _ref4.ref,
5581 onKeyDown = _ref4.onKeyDown,
5582 onClick = _ref4.onClick,
5583 _ref4$preventKeyActio = _ref4.preventKeyAction,
5584 preventKeyAction = _ref4$preventKeyActio === void 0 ? false : _ref4$preventKeyActio,
5585 rest = _objectWithoutPropertiesLoose(_ref4, ["refKey", "ref", "onKeyDown", "onClick", "preventKeyAction"]);
5586
5587 var _ref5 = _temp3 === void 0 ? {} : _temp3,
5588 _ref5$suppressRefErro = _ref5.suppressRefError,
5589 suppressRefError = _ref5$suppressRefErro === void 0 ? false : _ref5$suppressRefErro;
5590
5591 setGetterPropCallInfo('getDropdownProps', suppressRefError, refKey, dropdownRef);
5592
5593 var dropdownHandleKeyDown = function dropdownHandleKeyDown(event) {
5594 var key = normalizeArrowKey(event);
5595
5596 if (key && dropdownKeyDownHandlers[key]) {
5597 dropdownKeyDownHandlers[key](event);
5598 }
5599 };
5600
5601 var dropdownHandleClick = function dropdownHandleClick() {
5602 dispatch({
5603 type: DropdownClick
5604 });
5605 };
5606
5607 return _extends((_extends3 = {}, _extends3[refKey] = handleRefs(ref, function (dropdownNode) {
5608 if (dropdownNode) {
5609 dropdownRef.current = dropdownNode;
5610 }
5611 }), _extends3), !preventKeyAction && {
5612 onKeyDown: callAllEventHandlers(onKeyDown, dropdownHandleKeyDown),
5613 onClick: callAllEventHandlers(onClick, dropdownHandleClick)
5614 }, rest);
5615 }, [dispatch, dropdownKeyDownHandlers, setGetterPropCallInfo]); // returns
5616
5617 var addSelectedItem = react.useCallback(function (selectedItem) {
5618 dispatch({
5619 type: FunctionAddSelectedItem,
5620 selectedItem: selectedItem
5621 });
5622 }, [dispatch]);
5623 var removeSelectedItem = react.useCallback(function (selectedItem) {
5624 dispatch({
5625 type: FunctionRemoveSelectedItem,
5626 selectedItem: selectedItem
5627 });
5628 }, [dispatch]);
5629 var setSelectedItems = react.useCallback(function (newSelectedItems) {
5630 dispatch({
5631 type: FunctionSetSelectedItems,
5632 selectedItems: newSelectedItems
5633 });
5634 }, [dispatch]);
5635 var setActiveIndex = react.useCallback(function (newActiveIndex) {
5636 dispatch({
5637 type: FunctionSetActiveIndex,
5638 activeIndex: newActiveIndex
5639 });
5640 }, [dispatch]);
5641 var reset = react.useCallback(function () {
5642 dispatch({
5643 type: FunctionReset$2
5644 });
5645 }, [dispatch]);
5646 return {
5647 getSelectedItemProps: getSelectedItemProps,
5648 getDropdownProps: getDropdownProps,
5649 addSelectedItem: addSelectedItem,
5650 removeSelectedItem: removeSelectedItem,
5651 setSelectedItems: setSelectedItems,
5652 setActiveIndex: setActiveIndex,
5653 reset: reset,
5654 selectedItems: selectedItems,
5655 activeIndex: activeIndex
5656 };
5657 }
5658
5659 exports.default = Downshift;
5660 exports.resetIdCounter = resetIdCounter;
5661 exports.useCombobox = useCombobox;
5662 exports.useMultipleSelection = useMultipleSelection;
5663 exports.useSelect = useSelect;
5664
5665 Object.defineProperty(exports, '__esModule', { value: true });
5666
5667})));
5668//# sourceMappingURL=downshift.umd.js.map