(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('preact/compat'), require('prop-types')) :
  typeof define === 'function' && define.amd ? define(['exports', 'preact/compat', 'prop-types'], factory) :
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Downshift = {}, global.React, global.PropTypes));
})(this, (function (exports, React, PropTypes) { 'use strict';

  function _interopNamespaceDefault(e) {
    var n = Object.create(null);
    if (e) {
      Object.keys(e).forEach(function (k) {
        if (k !== 'default') {
          var d = Object.getOwnPropertyDescriptor(e, k);
          Object.defineProperty(n, k, d.get ? d : {
            enumerable: true,
            get: function () { return e[k]; }
          });
        }
      });
    }
    n.default = e;
    return Object.freeze(n);
  }

  var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);

  function _objectWithoutPropertiesLoose(r, e) {
    if (null == r) return {};
    var t = {};
    for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
      if (-1 !== e.indexOf(n)) continue;
      t[n] = r[n];
    }
    return t;
  }

  function _extends() {
    return _extends = Object.assign ? Object.assign.bind() : function (n) {
      for (var e = 1; e < arguments.length; e++) {
        var t = arguments[e];
        for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
      }
      return n;
    }, _extends.apply(null, arguments);
  }

  function _setPrototypeOf(t, e) {
    return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) {
      return t.__proto__ = e, t;
    }, _setPrototypeOf(t, e);
  }

  function _inheritsLoose(t, o) {
    t.prototype = Object.create(o.prototype), t.prototype.constructor = t, _setPrototypeOf(t, o);
  }

  var reactIs = {exports: {}};

  var reactIs_development = {};

  /**
   * @license React
   * react-is.development.js
   *
   * Copyright (c) Facebook, Inc. and its affiliates.
   *
   * This source code is licensed under the MIT license found in the
   * LICENSE file in the root directory of this source tree.
   */

  var hasRequiredReactIs_development;

  function requireReactIs_development () {
  	if (hasRequiredReactIs_development) return reactIs_development;
  	hasRequiredReactIs_development = 1;

  	{
  	  (function() {

  	// ATTENTION
  	// When adding new symbols to this file,
  	// Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
  	// The Symbol used to tag the ReactElement-like types.
  	var REACT_ELEMENT_TYPE = Symbol.for('react.element');
  	var REACT_PORTAL_TYPE = Symbol.for('react.portal');
  	var REACT_FRAGMENT_TYPE = Symbol.for('react.fragment');
  	var REACT_STRICT_MODE_TYPE = Symbol.for('react.strict_mode');
  	var REACT_PROFILER_TYPE = Symbol.for('react.profiler');
  	var REACT_PROVIDER_TYPE = Symbol.for('react.provider');
  	var REACT_CONTEXT_TYPE = Symbol.for('react.context');
  	var REACT_SERVER_CONTEXT_TYPE = Symbol.for('react.server_context');
  	var REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref');
  	var REACT_SUSPENSE_TYPE = Symbol.for('react.suspense');
  	var REACT_SUSPENSE_LIST_TYPE = Symbol.for('react.suspense_list');
  	var REACT_MEMO_TYPE = Symbol.for('react.memo');
  	var REACT_LAZY_TYPE = Symbol.for('react.lazy');
  	var REACT_OFFSCREEN_TYPE = Symbol.for('react.offscreen');

  	// -----------------------------------------------------------------------------

  	var enableScopeAPI = false; // Experimental Create Event Handle API.
  	var enableCacheElement = false;
  	var enableTransitionTracing = false; // No known bugs, but needs performance testing

  	var enableLegacyHidden = false; // Enables unstable_avoidThisFallback feature in Fiber
  	// stuff. Intended to enable React core members to more easily debug scheduling
  	// issues in DEV builds.

  	var enableDebugTracing = false; // Track which Fiber(s) schedule render work.

  	var REACT_MODULE_REFERENCE;

  	{
  	  REACT_MODULE_REFERENCE = Symbol.for('react.module.reference');
  	}

  	function isValidElementType(type) {
  	  if (typeof type === 'string' || typeof type === 'function') {
  	    return true;
  	  } // Note: typeof might be other than 'symbol' or 'number' (e.g. if it's a polyfill).


  	  if (type === REACT_FRAGMENT_TYPE || type === REACT_PROFILER_TYPE || enableDebugTracing  || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || enableLegacyHidden  || type === REACT_OFFSCREEN_TYPE || enableScopeAPI  || enableCacheElement  || enableTransitionTracing ) {
  	    return true;
  	  }

  	  if (typeof type === 'object' && type !== null) {
  	    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 || // This needs to include all possible module reference object
  	    // types supported by any Flight configuration anywhere since
  	    // we don't know which Flight build this will end up being used
  	    // with.
  	    type.$$typeof === REACT_MODULE_REFERENCE || type.getModuleId !== undefined) {
  	      return true;
  	    }
  	  }

  	  return false;
  	}

  	function typeOf(object) {
  	  if (typeof object === 'object' && object !== null) {
  	    var $$typeof = object.$$typeof;

  	    switch ($$typeof) {
  	      case REACT_ELEMENT_TYPE:
  	        var type = object.type;

  	        switch (type) {
  	          case REACT_FRAGMENT_TYPE:
  	          case REACT_PROFILER_TYPE:
  	          case REACT_STRICT_MODE_TYPE:
  	          case REACT_SUSPENSE_TYPE:
  	          case REACT_SUSPENSE_LIST_TYPE:
  	            return type;

  	          default:
  	            var $$typeofType = type && type.$$typeof;

  	            switch ($$typeofType) {
  	              case REACT_SERVER_CONTEXT_TYPE:
  	              case REACT_CONTEXT_TYPE:
  	              case REACT_FORWARD_REF_TYPE:
  	              case REACT_LAZY_TYPE:
  	              case REACT_MEMO_TYPE:
  	              case REACT_PROVIDER_TYPE:
  	                return $$typeofType;

  	              default:
  	                return $$typeof;
  	            }

  	        }

  	      case REACT_PORTAL_TYPE:
  	        return $$typeof;
  	    }
  	  }

  	  return undefined;
  	}
  	var ContextConsumer = REACT_CONTEXT_TYPE;
  	var ContextProvider = REACT_PROVIDER_TYPE;
  	var Element = REACT_ELEMENT_TYPE;
  	var ForwardRef = REACT_FORWARD_REF_TYPE;
  	var Fragment = REACT_FRAGMENT_TYPE;
  	var Lazy = REACT_LAZY_TYPE;
  	var Memo = REACT_MEMO_TYPE;
  	var Portal = REACT_PORTAL_TYPE;
  	var Profiler = REACT_PROFILER_TYPE;
  	var StrictMode = REACT_STRICT_MODE_TYPE;
  	var Suspense = REACT_SUSPENSE_TYPE;
  	var SuspenseList = REACT_SUSPENSE_LIST_TYPE;
  	var hasWarnedAboutDeprecatedIsAsyncMode = false;
  	var hasWarnedAboutDeprecatedIsConcurrentMode = false; // AsyncMode should be deprecated

  	function isAsyncMode(object) {
  	  {
  	    if (!hasWarnedAboutDeprecatedIsAsyncMode) {
  	      hasWarnedAboutDeprecatedIsAsyncMode = true; // Using console['warn'] to evade Babel and ESLint

  	      console['warn']('The ReactIs.isAsyncMode() alias has been deprecated, ' + 'and will be removed in React 18+.');
  	    }
  	  }

  	  return false;
  	}
  	function isConcurrentMode(object) {
  	  {
  	    if (!hasWarnedAboutDeprecatedIsConcurrentMode) {
  	      hasWarnedAboutDeprecatedIsConcurrentMode = true; // Using console['warn'] to evade Babel and ESLint

  	      console['warn']('The ReactIs.isConcurrentMode() alias has been deprecated, ' + 'and will be removed in React 18+.');
  	    }
  	  }

  	  return false;
  	}
  	function isContextConsumer(object) {
  	  return typeOf(object) === REACT_CONTEXT_TYPE;
  	}
  	function isContextProvider(object) {
  	  return typeOf(object) === REACT_PROVIDER_TYPE;
  	}
  	function isElement(object) {
  	  return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;
  	}
  	function isForwardRef(object) {
  	  return typeOf(object) === REACT_FORWARD_REF_TYPE;
  	}
  	function isFragment(object) {
  	  return typeOf(object) === REACT_FRAGMENT_TYPE;
  	}
  	function isLazy(object) {
  	  return typeOf(object) === REACT_LAZY_TYPE;
  	}
  	function isMemo(object) {
  	  return typeOf(object) === REACT_MEMO_TYPE;
  	}
  	function isPortal(object) {
  	  return typeOf(object) === REACT_PORTAL_TYPE;
  	}
  	function isProfiler(object) {
  	  return typeOf(object) === REACT_PROFILER_TYPE;
  	}
  	function isStrictMode(object) {
  	  return typeOf(object) === REACT_STRICT_MODE_TYPE;
  	}
  	function isSuspense(object) {
  	  return typeOf(object) === REACT_SUSPENSE_TYPE;
  	}
  	function isSuspenseList(object) {
  	  return typeOf(object) === REACT_SUSPENSE_LIST_TYPE;
  	}

  	reactIs_development.ContextConsumer = ContextConsumer;
  	reactIs_development.ContextProvider = ContextProvider;
  	reactIs_development.Element = Element;
  	reactIs_development.ForwardRef = ForwardRef;
  	reactIs_development.Fragment = Fragment;
  	reactIs_development.Lazy = Lazy;
  	reactIs_development.Memo = Memo;
  	reactIs_development.Portal = Portal;
  	reactIs_development.Profiler = Profiler;
  	reactIs_development.StrictMode = StrictMode;
  	reactIs_development.Suspense = Suspense;
  	reactIs_development.SuspenseList = SuspenseList;
  	reactIs_development.isAsyncMode = isAsyncMode;
  	reactIs_development.isConcurrentMode = isConcurrentMode;
  	reactIs_development.isContextConsumer = isContextConsumer;
  	reactIs_development.isContextProvider = isContextProvider;
  	reactIs_development.isElement = isElement;
  	reactIs_development.isForwardRef = isForwardRef;
  	reactIs_development.isFragment = isFragment;
  	reactIs_development.isLazy = isLazy;
  	reactIs_development.isMemo = isMemo;
  	reactIs_development.isPortal = isPortal;
  	reactIs_development.isProfiler = isProfiler;
  	reactIs_development.isStrictMode = isStrictMode;
  	reactIs_development.isSuspense = isSuspense;
  	reactIs_development.isSuspenseList = isSuspenseList;
  	reactIs_development.isValidElementType = isValidElementType;
  	reactIs_development.typeOf = typeOf;
  	  })();
  	}
  	return reactIs_development;
  }

  var hasRequiredReactIs;

  function requireReactIs () {
  	if (hasRequiredReactIs) return reactIs.exports;
  	hasRequiredReactIs = 1;

  	{
  	  reactIs.exports = requireReactIs_development();
  	}
  	return reactIs.exports;
  }

  var reactIsExports = requireReactIs();

  var unknown = '__autocomplete_unknown__' ;
  var mouseUp = '__autocomplete_mouseup__' ;
  var itemMouseEnter = '__autocomplete_item_mouseenter__' ;
  var keyDownArrowUp = '__autocomplete_keydown_arrow_up__' ;
  var keyDownArrowDown = '__autocomplete_keydown_arrow_down__' ;
  var keyDownEscape = '__autocomplete_keydown_escape__' ;
  var keyDownEnter = '__autocomplete_keydown_enter__' ;
  var keyDownHome = '__autocomplete_keydown_home__' ;
  var keyDownEnd = '__autocomplete_keydown_end__' ;
  var clickItem = '__autocomplete_click_item__' ;
  var blurInput = '__autocomplete_blur_input__' ;
  var changeInput = '__autocomplete_change_input__' ;
  var keyDownSpaceButton = '__autocomplete_keydown_space_button__' ;
  var clickButton = '__autocomplete_click_button__' ;
  var blurButton = '__autocomplete_blur_button__' ;
  var controlledPropUpdatedSelectedItem = '__autocomplete_controlled_prop_updated_selected_item__' ;
  var touchEnd = '__autocomplete_touchend__' ;

  var stateChangeTypes$4 = /*#__PURE__*/Object.freeze({
    __proto__: null,
    blurButton: blurButton,
    blurInput: blurInput,
    changeInput: changeInput,
    clickButton: clickButton,
    clickItem: clickItem,
    controlledPropUpdatedSelectedItem: controlledPropUpdatedSelectedItem,
    itemMouseEnter: itemMouseEnter,
    keyDownArrowDown: keyDownArrowDown,
    keyDownArrowUp: keyDownArrowUp,
    keyDownEnd: keyDownEnd,
    keyDownEnter: keyDownEnter,
    keyDownEscape: keyDownEscape,
    keyDownHome: keyDownHome,
    keyDownSpaceButton: keyDownSpaceButton,
    mouseUp: mouseUp,
    touchEnd: touchEnd,
    unknown: unknown
  });

  var idCounter = 0;

  /**
   * This generates a unique ID for an instance of Downshift
   * @return {string} the unique ID
   */
  function generateId() {
    return String(idCounter++);
  }

  /**
   * Resets idCounter to 0. Used for SSR.
   */
  function resetIdCounter() {
    // istanbul ignore next
    if ('useId' in React__namespace) {
      console.warn("It is not necessary to call resetIdCounter when using React 18+");
      return;
    }
    idCounter = 0;
  }

  function useLatestRef(val) {
    var ref = React__namespace.useRef(val);
    // technically this is not "concurrent mode safe" because we're manipulating
    // the value during render (so it's not idempotent). However, the places this
    // hook is used is to support memoizing callbacks which will be called
    // *during* render, so we need the latest values *during* render.
    // If not for this, then we'd probably want to use useLayoutEffect instead.
    ref.current = val;
    return ref;
  }

  function handleRefs$1() {
    for (var _len = arguments.length, refs = new Array(_len), _key = 0; _key < _len; _key++) {
      refs[_key] = arguments[_key];
    }
    return function (node) {
      refs.forEach(function (ref) {
        if (typeof ref === 'function') {
          ref(node);
        } else if (ref) {
          ref.current = node;
        }
      });
    };
  }

  /**
   * This is intended to be used to compose event handlers.
   * They are executed in order until one of them sets
   * `event.preventDownshiftDefault = true`.
   * @param fns the event handler functions
   * @return the event handler to add to an element
   */
  function callAllEventHandlers$1() {
    for (var _len = arguments.length, fns = new Array(_len), _key = 0; _key < _len; _key++) {
      fns[_key] = arguments[_key];
    }
    return function (event) {
      for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
        args[_key2 - 1] = arguments[_key2];
      }
      return fns.some(function (fn) {
        if (fn) {
          fn.apply(void 0, [event].concat(args));
        }
        return event.preventDownshiftDefault || event.hasOwnProperty('nativeEvent') && event.nativeEvent.preventDownshiftDefault;
      });
    };
  }

  /**
   * Simple debounce implementation. Will call the given
   * function once after the time given has passed since
   * it was last called.
   */
  function debounce$1(fn, time) {
    var timeoutId;
    function cancel() {
      if (timeoutId) {
        clearTimeout(timeoutId);
      }
    }
    function wrapper() {
      for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
        args[_key] = arguments[_key];
      }
      cancel();
      timeoutId = setTimeout(function () {
        timeoutId = null;
        fn.apply(void 0, args);
      }, time);
    }
    wrapper.cancel = cancel;
    return wrapper;
  }

  var cleanupStatus = debounce$1(function (document) {
    getStatusDiv(document).textContent = '';
  }, 500);

  /**
   * Get the status node or create it if it does not already exist.
   */
  function getStatusDiv(document) {
    var statusDiv = document.getElementById('a11y-status-message');
    if (statusDiv) {
      return statusDiv;
    }
    statusDiv = document.createElement('div');
    statusDiv.setAttribute('id', 'a11y-status-message');
    statusDiv.setAttribute('role', 'status');
    statusDiv.setAttribute('aria-live', 'polite');
    statusDiv.setAttribute('aria-relevant', 'additions text');
    Object.assign(statusDiv.style, {
      border: '0',
      clip: 'rect(0 0 0 0)',
      height: '1px',
      margin: '-1px',
      overflow: 'hidden',
      padding: '0',
      position: 'absolute',
      width: '1px'
    });
    document.body.appendChild(statusDiv);
    return statusDiv;
  }

  /**
   * Sets aria live status to a div element that's visually hidden.
   */
  function setStatus(status, document) {
    if (!status || !document) {
      return;
    }
    var div = getStatusDiv(document);
    div.textContent = status;
    cleanupStatus(document);
  }

  /**
   * Removes the status element from the DOM
   */
  function cleanupStatusDiv(document) {
    var statusDiv = document == null ? void 0 : document.getElementById('a11y-status-message');
    if (statusDiv) {
      statusDiv.remove();
    }
  }

  function noop() {}

  // eslint-disable-next-line import/no-mutable-exports
  var validatePropTypes$1 = noop;
  /* istanbul ignore next */
  {
    validatePropTypes$1 = function validatePropTypes(options, caller, propTypes) {
      PropTypes.checkPropTypes(propTypes, options, 'prop', caller.name);
    };
  }

  /**
   * This will perform a shallow merge of the given state object
   * with the state coming from props
   * (for the controlled component scenario)
   * This is used in state updater functions so they're referencing
   * the right state regardless of where it comes from.
   *
   * @param state The state of the component/hook.
   * @param props The props that may contain controlled values.
   * @returns The merged controlled state.
   */
  function getState(state, props) {
    if (!props) {
      return state;
    }
    var keys = Object.keys(state);
    return keys.reduce(function (newState, key) {
      if (props[key] !== undefined) {
        newState[key] = props[key];
      }
      return newState;
    }, _extends({}, state));
  }

  const t=t=>"object"==typeof t&&null!=t&&1===t.nodeType,e=(t,e)=>(!e||"hidden"!==t)&&("visible"!==t&&"clip"!==t),n=(t,n)=>{if(t.clientHeight<t.scrollHeight||t.clientWidth<t.scrollWidth){const o=getComputedStyle(t,null);return e(o.overflowY,n)||e(o.overflowX,n)||(t=>{const e=(t=>{if(!t.ownerDocument||!t.ownerDocument.defaultView)return null;try{return t.ownerDocument.defaultView.frameElement}catch(t){return null}})(t);return !!e&&(e.clientHeight<t.scrollHeight||e.clientWidth<t.scrollWidth)})(t)}return  false},o=(t,e,n,o,l,r,i,s)=>r<t&&i>e||r>t&&i<e?0:r<=t&&s<=n||i>=e&&s>=n?r-t-o:i>e&&s<n||r<t&&s>n?i-e+l:0,l=t=>{const e=t.parentElement;return null==e?t.getRootNode().host||null:e},r=(e,r)=>{var i,s,d,h;if("undefined"==typeof document)return [];const{inline:u,boundary:a,skipOverflowHiddenElements:g}=r,p="function"==typeof a?a:t=>t!==a;if(!t(e))throw new TypeError("Invalid target");const m=document.scrollingElement||document.documentElement,w=[];let W=e;for(;t(W)&&p(W);){if(W=l(W),W===m){w.push(W);break}null!=W&&W===document.body&&n(W)&&!n(document.documentElement)||null!=W&&n(W,g)&&w.push(W);}const b=null!=(s=null==(i=window.visualViewport)?void 0:i.width)?s:innerWidth,H=null!=(h=null==(d=window.visualViewport)?void 0:d.height)?h:innerHeight,{scrollX:y,scrollY:M}=window,{height:v,width:E,top:x,right:C,bottom:I,left:R}=e.getBoundingClientRect(),{top:T,right:B,left:V}=(t=>{const e=window.getComputedStyle(t);return {top:parseFloat(e.scrollMarginTop)||0,right:parseFloat(e.scrollMarginRight)||0,bottom:parseFloat(e.scrollMarginBottom)||0,left:parseFloat(e.scrollMarginLeft)||0}})(e);let k=x-T,D="center"===u?R+E/2-V+B:"end"===u?C+B:R-V;const L=[];for(let t=0;t<w.length;t++){const e=w[t],{height:l,width:r,top:i,right:s,bottom:d,left:h}=e.getBoundingClientRect();if(x>=0&&R>=0&&I<=H&&C<=b&&(e===m&&!n(e)||x>=i&&I<=d&&R>=h&&C<=s))return L;const a=getComputedStyle(e),g=parseInt(a.borderLeftWidth,10),p=parseInt(a.borderTopWidth,10),W=parseInt(a.borderRightWidth,10),T=parseInt(a.borderBottomWidth,10);let B=0,F=0;const V="offsetWidth"in e?e.offsetWidth-e.clientWidth-g-W:0,S="offsetHeight"in e?e.offsetHeight-e.clientHeight-p-T:0,X="offsetWidth"in e?0===e.offsetWidth?0:r/e.offsetWidth:0,Y="offsetHeight"in e?0===e.offsetHeight?0:l/e.offsetHeight:0;if(m===e)B=o(M,M+H,H,p,T,M+k,M+k+v,v),F="start"===u?D:"center"===u?D-b/2:"end"===u?D-b:o(y,y+b,b,g,W,y+D,y+D+E,E),B=Math.max(0,B+M),F=Math.max(0,F+y);else {B=o(i,d,l,p,T+S,k,k+v,v),F="start"===u?D-h-g:"center"===u?D-(h+r/2)+V/2:"end"===u?D-s+W+V:o(h,s,r,g,W+V,D,D+E,E);const{scrollLeft:t,scrollTop:n}=e;B=0===Y?0:Math.max(0,Math.min(n+B/Y,e.scrollHeight-l/Y+S)),F=0===X?0:Math.max(0,Math.min(t+F/X,e.scrollWidth-r/X+V)),k+=n-B,D+=t-F;}L.push({el:e,top:B,left:F});}return L};

  /**
   * Scroll node into view if necessary
   * @param {HTMLElement} node the element that should scroll into view
   * @param {HTMLElement} menuNode the menu element of the component
   */
  function scrollIntoView(node, menuNode) {
    if (!node) {
      return;
    }
    var actions = r(node, {
      boundary: menuNode});
    actions.forEach(function (_ref) {
      var el = _ref.el,
        top = _ref.top,
        left = _ref.left;
      el.scrollTop = top;
      el.scrollLeft = left;
    });
  }

  /**
   * Accepts a parameter and returns it if it's a function
   * or a noop function if it's not. This allows us to
   * accept a callback, but not worry about it if it's not
   * passed.
   * @param {Function} cb the callback
   * @return {Function} a function
   */
  function cbToCb(cb) {
    return typeof cb === 'function' ? cb : noop;
  }

  /**
   * @param {HTMLElement} parent the parent node
   * @param {HTMLElement} child the child node
   * @param {Window} environment The window context where downshift renders.
   * @return {Boolean} whether the parent is the child or the child is in the parent
   */
  function isOrContainsNode(parent, child, environment) {
    var result = parent === child || child instanceof environment.Node && parent.contains && parent.contains(child);
    return result;
  }

  /**
   * Simple debounce implementation. Will call the given
   * function once after the time given has passed since
   * it was last called.
   * @param {Function} fn the function to call after the time
   * @param {Number} time the time to wait
   * @return {Function} the debounced function
   */
  function debounce(fn, time) {
    var timeoutId;
    function cancel() {
      if (timeoutId) {
        clearTimeout(timeoutId);
      }
    }
    function wrapper() {
      for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
        args[_key] = arguments[_key];
      }
      cancel();
      timeoutId = setTimeout(function () {
        timeoutId = null;
        fn.apply(void 0, args);
      }, time);
    }
    wrapper.cancel = cancel;
    return wrapper;
  }

  /**
   * This is intended to be used to compose event handlers.
   * They are executed in order until one of them sets
   * `event.preventDownshiftDefault = true`.
   * @param {...Function} fns the event handler functions
   * @return {Function} the event handler to add to an element
   */
  function callAllEventHandlers() {
    for (var _len2 = arguments.length, fns = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
      fns[_key2] = arguments[_key2];
    }
    return function (event) {
      for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
        args[_key3 - 1] = arguments[_key3];
      }
      return fns.some(function (fn) {
        if (fn) {
          fn.apply(void 0, [event].concat(args));
        }
        return event.preventDownshiftDefault || event.hasOwnProperty('nativeEvent') && event.nativeEvent.preventDownshiftDefault;
      });
    };
  }
  function handleRefs() {
    for (var _len4 = arguments.length, refs = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
      refs[_key4] = arguments[_key4];
    }
    return function (node) {
      refs.forEach(function (ref) {
        if (typeof ref === 'function') {
          ref(node);
        } else if (ref) {
          ref.current = node;
        }
      });
    };
  }

  /**
   * Default implementation for status message. Only added when menu is open.
   * Will specify if there are results in the list, and if so, how many,
   * and what keys are relevant.
   *
   * @param {Object} param the downshift state and other relevant properties
   * @return {String} the a11y status message
   */
  function getA11yStatusMessage(_ref) {
    var isOpen = _ref.isOpen,
      resultCount = _ref.resultCount,
      previousResultCount = _ref.previousResultCount;
    if (!isOpen) {
      return '';
    }
    if (!resultCount) {
      return 'No results are available.';
    }
    if (resultCount !== previousResultCount) {
      return resultCount + " result" + (resultCount === 1 ? ' is' : 's are') + " available, use up and down arrow keys to navigate. Press Enter key to select.";
    }
    return '';
  }

  /**
   * Takes an argument and if it's an array, returns the first item in the array
   * otherwise returns the argument
   * @param {*} arg the maybe-array
   * @param {*} defaultValue the value if arg is falsey not defined
   * @return {*} the arg or it's first item
   */
  function unwrapArray(arg, defaultValue) {
    arg = Array.isArray(arg) ? /* istanbul ignore next (preact) */arg[0] : arg;
    if (!arg && defaultValue) {
      return defaultValue;
    } else {
      return arg;
    }
  }

  /**
   * @param {Object} element (P)react element
   * @return {Boolean} whether it's a DOM element
   */
  function isDOMElement(element) {
    /* istanbul ignore if */
    {
      // then this is preact or preact X
      return typeof element.type === 'string' || typeof element.nodeName === 'string';
    }
  }

  /**
   * @param {Object} element (P)react element
   * @return {Object} the props
   */
  function getElementProps(element) {
    // props for react, attributes for preact

    /* istanbul ignore if */
    {
      return element.props || element.attributes;
    }
  }

  /**
   * Throws a helpful error message for required properties. Useful
   * to be used as a default in destructuring or object params.
   * @param {String} fnName the function name
   * @param {String} propName the prop name
   */
  function requiredProp(fnName, propName) {
    // eslint-disable-next-line no-console
    console.error("The property \"" + propName + "\" is required in \"" + fnName + "\"");
  }
  var stateKeys = ['highlightedIndex', 'inputValue', 'isOpen', 'selectedItem', 'type'];
  /**
   * @param {Object} state the state object
   * @return {Object} state that is relevant to downshift
   */
  function pickState(state) {
    if (state === void 0) {
      state = {};
    }
    var result = {};
    stateKeys.forEach(function (k) {
      if (state.hasOwnProperty(k)) {
        result[k] = state[k];
      }
    });
    return result;
  }

  /**
   * This determines whether a prop is a "controlled prop" meaning it is
   * state which is controlled by the outside of this component rather
   * than within this component.
   *
   * @param {Object} props The props that may contain controlled values.
   * @param {String} key the key to check
   * @return {Boolean} whether it is a controlled controlled prop
   */
  function isControlledProp(props, key) {
    return props[key] !== undefined;
  }

  /**
   * Normalizes the 'key' property of a KeyboardEvent in IE/Edge
   * @param {Object} event a keyboardEvent object
   * @return {String} keyboard key
   */
  function normalizeArrowKey(event) {
    var key = event.key,
      keyCode = event.keyCode;
    /* istanbul ignore next (ie) */
    if (keyCode >= 37 && keyCode <= 40 && key.indexOf('Arrow') !== 0) {
      return "Arrow" + key;
    }
    return key;
  }

  /**
   * Simple check if the value passed is object literal
   * @param {*} obj any things
   * @return {Boolean} whether it's object literal
   */
  function isPlainObject(obj) {
    return Object.prototype.toString.call(obj) === '[object Object]';
  }

  /**
   * Returns the next non-disabled highlightedIndex value.
   *
   * @param {number} start The current highlightedIndex.
   * @param {number} offset The offset from the current highlightedIndex to start searching.
   * @param {unknown[]} items The items array.
   * @param {(item: unknown, index: number) => boolean} isItemDisabled Function that tells if an item is disabled or not.
   * @param {boolean?} circular If the search reaches the end, if it can search again starting from the other end.
   * @returns {number} The next highlightedIndex.
   */
  function getHighlightedIndex(start, offset, items, isItemDisabled, circular) {
    if (circular === void 0) {
      circular = false;
    }
    var count = items.length;
    if (count === 0) {
      return -1;
    }
    var itemsLastIndex = count - 1;
    if (typeof start !== 'number' || start < 0 || start > itemsLastIndex) {
      start = offset > 0 ? -1 : itemsLastIndex + 1;
    }
    var current = start + offset;
    if (current < 0) {
      current = circular ? itemsLastIndex : 0;
    } else if (current > itemsLastIndex) {
      current = circular ? 0 : itemsLastIndex;
    }
    var highlightedIndex = getNonDisabledIndex(current, offset < 0, items, isItemDisabled, circular);
    if (highlightedIndex === -1) {
      return start >= count ? -1 : start;
    }
    return highlightedIndex;
  }

  /**
   * Returns the next non-disabled highlightedIndex value.
   *
   * @param {number} start The current highlightedIndex.
   * @param {boolean} backwards If true, it will search backwards from the start.
   * @param {unknown[]} items The items array.
   * @param {(item: unknown, index: number) => boolean} isItemDisabled Function that tells if an item is disabled or not.
   * @param {boolean} circular If the search reaches the end, if it can search again starting from the other end.
   * @returns {number} The next non-disabled index.
   */
  function getNonDisabledIndex(start, backwards, items, isItemDisabled, circular) {
    if (circular === void 0) {
      circular = false;
    }
    var count = items.length;
    if (backwards) {
      for (var index = start; index >= 0; index--) {
        if (!isItemDisabled(items[index], index)) {
          return index;
        }
      }
    } else {
      for (var _index = start; _index < count; _index++) {
        if (!isItemDisabled(items[_index], _index)) {
          return _index;
        }
      }
    }
    if (circular) {
      return getNonDisabledIndex(backwards ? count - 1 : 0, backwards, items, isItemDisabled);
    }
    return -1;
  }

  /**
   * Checks if event target is within the downshift elements.
   *
   * @param {EventTarget} target Target to check.
   * @param {HTMLElement[]} downshiftElements The elements that form downshift (list, toggle button etc).
   * @param {Window} environment The window context where downshift renders.
   * @param {boolean} checkActiveElement Whether to also check activeElement.
   *
   * @returns {boolean} Whether or not the target is within downshift elements.
   */
  function targetWithinDownshift(target, downshiftElements, environment, checkActiveElement) {
    if (checkActiveElement === void 0) {
      checkActiveElement = true;
    }
    return environment && downshiftElements.some(function (contextNode) {
      return contextNode && (isOrContainsNode(contextNode, target, environment) || checkActiveElement && isOrContainsNode(contextNode, environment.document.activeElement, environment));
    });
  }

  // eslint-disable-next-line import/no-mutable-exports
  var validateControlledUnchanged = noop;
  /* istanbul ignore next */
  {
    validateControlledUnchanged = function validateControlledUnchanged(state, prevProps, nextProps) {
      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";
      Object.keys(state).forEach(function (propKey) {
        if (prevProps[propKey] !== undefined && nextProps[propKey] === undefined) {
          // eslint-disable-next-line no-console
          console.error("downshift: A component has changed the controlled prop \"" + propKey + "\" to be uncontrolled. " + warningDescription);
        } else if (prevProps[propKey] === undefined && nextProps[propKey] !== undefined) {
          // eslint-disable-next-line no-console
          console.error("downshift: A component has changed the uncontrolled prop \"" + propKey + "\" to be controlled. " + warningDescription);
        }
      });
    };
  }

  var _excluded$4 = ["refKey", "ref"],
    _excluded2$4 = ["onClick", "onPress", "onKeyDown", "onKeyUp", "onBlur"],
    _excluded3$3 = ["onKeyDown", "onBlur", "onChange", "onInput", "onChangeText"],
    _excluded4$2 = ["refKey", "ref"],
    _excluded5 = ["onMouseMove", "onMouseDown", "onClick", "onPress", "index", "item"];
  var Downshift = /*#__PURE__*/function () {
    var Downshift = /*#__PURE__*/function (_Component) {
      function Downshift(_props) {
        var _this;
        _this = _Component.call(this, _props) || this;
        // fancy destructuring + defaults + aliases
        // this basically says each value of state should either be set to
        // the initial value or the default value if the initial value is not provided
        _this.id = _this.props.id || "downshift-" + generateId();
        _this.menuId = _this.props.menuId || _this.id + "-menu";
        _this.labelId = _this.props.labelId || _this.id + "-label";
        _this.inputId = _this.props.inputId || _this.id + "-input";
        _this.getItemId = _this.props.getItemId || function (index) {
          return _this.id + "-item-" + index;
        };
        _this.items = [];
        // itemCount can be changed asynchronously
        // from within downshift (so it can't come from a prop)
        // this is why we store it as an instance and use
        // getItemCount rather than just use items.length
        // (to support windowing + async)
        _this.itemCount = null;
        _this.previousResultCount = 0;
        _this.timeoutIds = [];
        /**
         * @param {Function} fn the function to call after the time
         * @param {Number} time the time to wait
         */
        _this.internalSetTimeout = function (fn, time) {
          var id = setTimeout(function () {
            _this.timeoutIds = _this.timeoutIds.filter(function (i) {
              return i !== id;
            });
            fn();
          }, time);
          _this.timeoutIds.push(id);
        };
        _this.setItemCount = function (count) {
          _this.itemCount = count;
        };
        _this.unsetItemCount = function () {
          _this.itemCount = null;
        };
        _this.isItemDisabled = function (_item, index) {
          var currentElementNode = _this.getItemNodeFromIndex(index);
          return currentElementNode && currentElementNode.hasAttribute('disabled');
        };
        _this.setHighlightedIndex = function (highlightedIndex, otherStateToSet) {
          if (highlightedIndex === void 0) {
            highlightedIndex = _this.props.defaultHighlightedIndex;
          }
          if (otherStateToSet === void 0) {
            otherStateToSet = {};
          }
          otherStateToSet = pickState(otherStateToSet);
          _this.internalSetState(_extends({
            highlightedIndex: highlightedIndex
          }, otherStateToSet));
        };
        _this.clearSelection = function (cb) {
          _this.internalSetState({
            selectedItem: null,
            inputValue: '',
            highlightedIndex: _this.props.defaultHighlightedIndex,
            isOpen: _this.props.defaultIsOpen
          }, cb);
        };
        _this.selectItem = function (item, otherStateToSet, cb) {
          otherStateToSet = pickState(otherStateToSet);
          _this.internalSetState(_extends({
            isOpen: _this.props.defaultIsOpen,
            highlightedIndex: _this.props.defaultHighlightedIndex,
            selectedItem: item,
            inputValue: _this.props.itemToString(item)
          }, otherStateToSet), cb);
        };
        _this.selectItemAtIndex = function (itemIndex, otherStateToSet, cb) {
          var item = _this.items[itemIndex];
          if (item == null) {
            return;
          }
          _this.selectItem(item, otherStateToSet, cb);
        };
        _this.selectHighlightedItem = function (otherStateToSet, cb) {
          return _this.selectItemAtIndex(_this.getState().highlightedIndex, otherStateToSet, cb);
        };
        // any piece of our state can live in two places:
        // 1. Uncontrolled: it's internal (this.state)
        //    We will call this.setState to update that state
        // 2. Controlled: it's external (this.props)
        //    We will call this.props.onStateChange to update that state
        //
        // In addition, we'll call this.props.onChange if the
        // selectedItem is changed.
        _this.internalSetState = function (stateToSet, cb) {
          var isItemSelected, onChangeArg;
          var onStateChangeArg = {};
          var isStateToSetFunction = typeof stateToSet === 'function';

          // we want to call `onInputValueChange` before the `setState` call
          // so someone controlling the `inputValue` state gets notified of
          // the input change as soon as possible. This avoids issues with
          // preserving the cursor position.
          // See https://github.com/downshift-js/downshift/issues/217 for more info.
          if (!isStateToSetFunction && stateToSet.hasOwnProperty('inputValue')) {
            _this.props.onInputValueChange(stateToSet.inputValue, _extends({}, _this.getStateAndHelpers(), stateToSet));
          }
          return _this.setState(function (state) {
            var _newStateToSet;
            state = _this.getState(state);
            var newStateToSet = isStateToSetFunction ? stateToSet(state) : stateToSet;

            // Your own function that could modify the state that will be set.
            newStateToSet = _this.props.stateReducer(state, newStateToSet);

            // checks if an item is selected, regardless of if it's different from
            // what was selected before
            // used to determine if onSelect and onChange callbacks should be called
            isItemSelected = newStateToSet.hasOwnProperty('selectedItem');
            // this keeps track of the object we want to call with setState
            var nextState = {};
            // we need to call on change if the outside world is controlling any of our state
            // and we're trying to update that state. OR if the selection has changed and we're
            // trying to update the selection
            if (isItemSelected && newStateToSet.selectedItem !== state.selectedItem) {
              onChangeArg = newStateToSet.selectedItem;
            }
            (_newStateToSet = newStateToSet).type || (_newStateToSet.type = unknown);
            Object.keys(newStateToSet).forEach(function (key) {
              // onStateChangeArg should only have the state that is
              // actually changing
              if (state[key] !== newStateToSet[key]) {
                onStateChangeArg[key] = newStateToSet[key];
              }
              // the type is useful for the onStateChangeArg
              // but we don't actually want to set it in internal state.
              // this is an undocumented feature for now... Not all internalSetState
              // calls support it and I'm not certain we want them to yet.
              // But it enables users controlling the isOpen state to know when
              // the isOpen state changes due to mouseup events which is quite handy.
              if (key === 'type') {
                return;
              }
              newStateToSet[key];
              // if it's coming from props, then we don't care to set it internally
              if (!isControlledProp(_this.props, key)) {
                nextState[key] = newStateToSet[key];
              }
            });

            // if stateToSet is a function, then we weren't able to call onInputValueChange
            // earlier, so we'll call it now that we know what the inputValue state will be.
            if (isStateToSetFunction && newStateToSet.hasOwnProperty('inputValue')) {
              _this.props.onInputValueChange(newStateToSet.inputValue, _extends({}, _this.getStateAndHelpers(), newStateToSet));
            }
            return nextState;
          }, function () {
            // call the provided callback if it's a function
            cbToCb(cb)();

            // only call the onStateChange and onChange callbacks if
            // we have relevant information to pass them.
            var hasMoreStateThanType = Object.keys(onStateChangeArg).length > 1;
            if (hasMoreStateThanType) {
              _this.props.onStateChange(onStateChangeArg, _this.getStateAndHelpers());
            }
            if (isItemSelected) {
              _this.props.onSelect(stateToSet.selectedItem, _this.getStateAndHelpers());
            }
            if (onChangeArg !== undefined) {
              _this.props.onChange(onChangeArg, _this.getStateAndHelpers());
            }
            // this is currently undocumented and therefore subject to change
            // We'll try to not break it, but just be warned.
            _this.props.onUserAction(onStateChangeArg, _this.getStateAndHelpers());
          });
        };
        //////////////////////////// ROOT
        _this.rootRef = function (node) {
          return _this._rootNode = node;
        };
        _this.getRootProps = function (_temp, _temp2) {
          var _extends2;
          var _ref = _temp === void 0 ? {} : _temp,
            _ref$refKey = _ref.refKey,
            refKey = _ref$refKey === void 0 ? 'ref' : _ref$refKey,
            ref = _ref.ref,
            rest = _objectWithoutPropertiesLoose(_ref, _excluded$4);
          var _ref2 = _temp2 === void 0 ? {} : _temp2,
            _ref2$suppressRefErro = _ref2.suppressRefError,
            suppressRefError = _ref2$suppressRefErro === void 0 ? false : _ref2$suppressRefErro;
          // this is used in the render to know whether the user has called getRootProps.
          // It uses that to know whether to apply the props automatically
          _this.getRootProps.called = true;
          _this.getRootProps.refKey = refKey;
          _this.getRootProps.suppressRefError = suppressRefError;
          var _this$getState = _this.getState(),
            isOpen = _this$getState.isOpen;
          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 : undefined, _extends2['aria-labelledby'] = _this.labelId, _extends2), rest);
        };
        //\\\\\\\\\\\\\\\\\\\\\\\\\\ ROOT
        _this.keyDownHandlers = {
          ArrowDown: function ArrowDown(event) {
            var _this2 = this;
            event.preventDefault();
            if (this.getState().isOpen) {
              var amount = event.shiftKey ? 5 : 1;
              this.moveHighlightedIndex(amount, {
                type: keyDownArrowDown
              });
            } else {
              this.internalSetState({
                isOpen: true,
                type: keyDownArrowDown
              }, function () {
                var itemCount = _this2.getItemCount();
                if (itemCount > 0) {
                  var _this2$getState = _this2.getState(),
                    highlightedIndex = _this2$getState.highlightedIndex;
                  var nextHighlightedIndex = getHighlightedIndex(highlightedIndex, 1, {
                    length: itemCount
                  }, _this2.isItemDisabled, true);
                  _this2.setHighlightedIndex(nextHighlightedIndex, {
                    type: keyDownArrowDown
                  });
                }
              });
            }
          },
          ArrowUp: function ArrowUp(event) {
            var _this3 = this;
            event.preventDefault();
            if (this.getState().isOpen) {
              var amount = event.shiftKey ? -5 : -1;
              this.moveHighlightedIndex(amount, {
                type: keyDownArrowUp
              });
            } else {
              this.internalSetState({
                isOpen: true,
                type: keyDownArrowUp
              }, function () {
                var itemCount = _this3.getItemCount();
                if (itemCount > 0) {
                  var _this3$getState = _this3.getState(),
                    highlightedIndex = _this3$getState.highlightedIndex;
                  var nextHighlightedIndex = getHighlightedIndex(highlightedIndex, -1, {
                    length: itemCount
                  }, _this3.isItemDisabled, true);
                  _this3.setHighlightedIndex(nextHighlightedIndex, {
                    type: keyDownArrowUp
                  });
                }
              });
            }
          },
          Enter: function Enter(event) {
            if (event.which === 229) {
              return;
            }
            var _this$getState2 = this.getState(),
              isOpen = _this$getState2.isOpen,
              highlightedIndex = _this$getState2.highlightedIndex;
            if (isOpen && highlightedIndex != null) {
              event.preventDefault();
              var item = this.items[highlightedIndex];
              var itemNode = this.getItemNodeFromIndex(highlightedIndex);
              if (item == null || itemNode && itemNode.hasAttribute('disabled')) {
                return;
              }
              this.selectHighlightedItem({
                type: keyDownEnter
              });
            }
          },
          Escape: function Escape(event) {
            event.preventDefault();
            this.reset(_extends({
              type: keyDownEscape
            }, !this.state.isOpen && {
              selectedItem: null,
              inputValue: ''
            }));
          }
        };
        //////////////////////////// BUTTON
        _this.buttonKeyDownHandlers = _extends({}, _this.keyDownHandlers, {
          ' ': function _(event) {
            event.preventDefault();
            this.toggleMenu({
              type: keyDownSpaceButton
            });
          }
        });
        _this.inputKeyDownHandlers = _extends({}, _this.keyDownHandlers, {
          Home: function Home(event) {
            var _this$getState3 = this.getState(),
              isOpen = _this$getState3.isOpen;
            if (!isOpen) {
              return;
            }
            event.preventDefault();
            var itemCount = this.getItemCount();
            if (itemCount <= 0 || !isOpen) {
              return;
            }

            // get next non-disabled starting downwards from 0 if that's disabled.
            var newHighlightedIndex = getNonDisabledIndex(0, false, {
              length: itemCount
            }, this.isItemDisabled);
            this.setHighlightedIndex(newHighlightedIndex, {
              type: keyDownHome
            });
          },
          End: function End(event) {
            var _this$getState4 = this.getState(),
              isOpen = _this$getState4.isOpen;
            if (!isOpen) {
              return;
            }
            event.preventDefault();
            var itemCount = this.getItemCount();
            if (itemCount <= 0 || !isOpen) {
              return;
            }

            // get next non-disabled starting upwards from last index if that's disabled.
            var newHighlightedIndex = getNonDisabledIndex(itemCount - 1, true, {
              length: itemCount
            }, this.isItemDisabled);
            this.setHighlightedIndex(newHighlightedIndex, {
              type: keyDownEnd
            });
          }
        });
        _this.getToggleButtonProps = function (_temp3) {
          var _ref3 = _temp3 === void 0 ? {} : _temp3,
            onClick = _ref3.onClick;
            _ref3.onPress;
            var onKeyDown = _ref3.onKeyDown,
            onKeyUp = _ref3.onKeyUp,
            onBlur = _ref3.onBlur,
            rest = _objectWithoutPropertiesLoose(_ref3, _excluded2$4);
          var _this$getState5 = _this.getState(),
            isOpen = _this$getState5.isOpen;
          var enabledEventHandlers = {
            onClick: callAllEventHandlers(onClick, _this.buttonHandleClick),
            onKeyDown: callAllEventHandlers(onKeyDown, _this.buttonHandleKeyDown),
            onKeyUp: callAllEventHandlers(onKeyUp, _this.buttonHandleKeyUp),
            onBlur: callAllEventHandlers(onBlur, _this.buttonHandleBlur)
          };
          var eventHandlers = rest.disabled ? {} : enabledEventHandlers;
          return _extends({
            type: 'button',
            role: 'button',
            'aria-label': isOpen ? 'close menu' : 'open menu',
            'aria-haspopup': true,
            'data-toggle': true
          }, eventHandlers, rest);
        };
        _this.buttonHandleKeyUp = function (event) {
          // Prevent click event from emitting in Firefox
          event.preventDefault();
        };
        _this.buttonHandleKeyDown = function (event) {
          var key = normalizeArrowKey(event);
          if (_this.buttonKeyDownHandlers[key]) {
            _this.buttonKeyDownHandlers[key].call(_this, event);
          }
        };
        _this.buttonHandleClick = function (event) {
          event.preventDefault();
          // handle odd case for Safari and Firefox which
          // don't give the button the focus properly.
          /* istanbul ignore if (can't reasonably test this) */
          if (_this.props.environment) {
            var _this$props$environme = _this.props.environment.document,
              body = _this$props$environme.body,
              activeElement = _this$props$environme.activeElement;
            if (body && body === activeElement) {
              event.target.focus();
            }
          }
          // to simplify testing components that use downshift, we'll not wrap this in a setTimeout
          // if the NODE_ENV is test. With the proper build system, this should be dead code eliminated
          // when building for production and should therefore have no impact on production code.
          {
            // Ensure that toggle of menu occurs after the potential blur event in iOS
            _this.internalSetTimeout(function () {
              return _this.toggleMenu({
                type: clickButton
              });
            });
          }
        };
        _this.buttonHandleBlur = function (event) {
          var blurTarget = event.target; // Save blur target for comparison with activeElement later
          // Need setTimeout, so that when the user presses Tab, the activeElement is the next focused element, not body element
          _this.internalSetTimeout(function () {
            if (_this.isMouseDown || !_this.props.environment) {
              return;
            }
            var activeElement = _this.props.environment.document.activeElement;
            if ((activeElement == null || activeElement.id !== _this.inputId) && activeElement !== blurTarget // Do nothing if we refocus the same element again (to solve issue in Safari on iOS)
            ) {
              _this.reset({
                type: blurButton
              });
            }
          });
        };
        //\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ BUTTON
        /////////////////////////////// LABEL
        _this.getLabelProps = function (props) {
          return _extends({
            htmlFor: _this.inputId,
            id: _this.labelId
          }, props);
        };
        //\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ LABEL
        /////////////////////////////// INPUT
        _this.getInputProps = function (_temp4) {
          var _ref4 = _temp4 === void 0 ? {} : _temp4,
            onKeyDown = _ref4.onKeyDown,
            onBlur = _ref4.onBlur,
            onChange = _ref4.onChange,
            onInput = _ref4.onInput;
            _ref4.onChangeText;
            var rest = _objectWithoutPropertiesLoose(_ref4, _excluded3$3);
          var onChangeKey;
          var eventHandlers = {};

          /* istanbul ignore next (preact) */
          {
            onChangeKey = 'onInput';
          }
          var _this$getState6 = _this.getState(),
            inputValue = _this$getState6.inputValue,
            isOpen = _this$getState6.isOpen,
            highlightedIndex = _this$getState6.highlightedIndex;
          if (!rest.disabled) {
            var _eventHandlers;
            eventHandlers = (_eventHandlers = {}, _eventHandlers[onChangeKey] = callAllEventHandlers(onChange, onInput, _this.inputHandleChange), _eventHandlers.onKeyDown = callAllEventHandlers(onKeyDown, _this.inputHandleKeyDown), _eventHandlers.onBlur = callAllEventHandlers(onBlur, _this.inputHandleBlur), _eventHandlers);
          }
          return _extends({
            'aria-autocomplete': 'list',
            'aria-activedescendant': isOpen && typeof highlightedIndex === 'number' && highlightedIndex >= 0 ? _this.getItemId(highlightedIndex) : undefined,
            'aria-controls': isOpen ? _this.menuId : undefined,
            'aria-labelledby': rest && rest['aria-label'] ? undefined : _this.labelId,
            // https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion
            // revert back since autocomplete="nope" is ignored on latest Chrome and Opera
            autoComplete: 'off',
            value: inputValue,
            id: _this.inputId
          }, eventHandlers, rest);
        };
        _this.inputHandleKeyDown = function (event) {
          var key = normalizeArrowKey(event);
          if (key && _this.inputKeyDownHandlers[key]) {
            _this.inputKeyDownHandlers[key].call(_this, event);
          }
        };
        _this.inputHandleChange = function (event) {
          _this.internalSetState({
            type: changeInput,
            isOpen: true,
            inputValue: event.target.value,
            highlightedIndex: _this.props.defaultHighlightedIndex
          });
        };
        _this.inputHandleBlur = function () {
          // Need setTimeout, so that when the user presses Tab, the activeElement is the next focused element, not the body element
          _this.internalSetTimeout(function () {
            var _activeElement$datase;
            if (_this.isMouseDown || !_this.props.environment) {
              return;
            }
            var activeElement = _this.props.environment.document.activeElement;
            var downshiftButtonIsActive = (activeElement == null || (_activeElement$datase = activeElement.dataset) == null ? void 0 : _activeElement$datase.toggle) && _this._rootNode && _this._rootNode.contains(activeElement);
            if (!downshiftButtonIsActive) {
              _this.reset({
                type: blurInput
              });
            }
          });
        };
        //\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ INPUT
        /////////////////////////////// MENU
        _this.menuRef = function (node) {
          _this._menuNode = node;
        };
        _this.getMenuProps = function (_temp5, _temp6) {
          var _extends3;
          var _ref5 = _temp5 === void 0 ? {} : _temp5,
            _ref5$refKey = _ref5.refKey,
            refKey = _ref5$refKey === void 0 ? 'ref' : _ref5$refKey,
            ref = _ref5.ref,
            props = _objectWithoutPropertiesLoose(_ref5, _excluded4$2);
          var _ref6 = _temp6 === void 0 ? {} : _temp6,
            _ref6$suppressRefErro = _ref6.suppressRefError,
            suppressRefError = _ref6$suppressRefErro === void 0 ? false : _ref6$suppressRefErro;
          _this.getMenuProps.called = true;
          _this.getMenuProps.refKey = refKey;
          _this.getMenuProps.suppressRefError = suppressRefError;
          return _extends((_extends3 = {}, _extends3[refKey] = handleRefs(ref, _this.menuRef), _extends3.role = 'listbox', _extends3['aria-labelledby'] = props && props['aria-label'] ? undefined : _this.labelId, _extends3.id = _this.menuId, _extends3), props);
        };
        //\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ MENU
        /////////////////////////////// ITEM
        _this.getItemProps = function (_temp7) {
          var _enabledEventHandlers;
          var _ref7 = _temp7 === void 0 ? {} : _temp7,
            onMouseMove = _ref7.onMouseMove,
            onMouseDown = _ref7.onMouseDown,
            onClick = _ref7.onClick;
            _ref7.onPress;
            var index = _ref7.index,
            _ref7$item = _ref7.item,
            item = _ref7$item === void 0 ? requiredProp('getItemProps', 'item') : _ref7$item,
            rest = _objectWithoutPropertiesLoose(_ref7, _excluded5);
          if (index === undefined) {
            _this.items.push(item);
            index = _this.items.indexOf(item);
          } else {
            _this.items[index] = item;
          }
          var onSelectKey = 'onClick';
          var customClickHandler = onClick;
          var enabledEventHandlers = (_enabledEventHandlers = {
            // onMouseMove is used over onMouseEnter here. onMouseMove
            // is only triggered on actual mouse movement while onMouseEnter
            // can fire on DOM changes, interrupting keyboard navigation
            onMouseMove: callAllEventHandlers(onMouseMove, function () {
              if (index === _this.getState().highlightedIndex) {
                return;
              }
              _this.setHighlightedIndex(index, {
                type: itemMouseEnter
              });

              // We never want to manually scroll when changing state based
              // on `onMouseMove` because we will be moving the element out
              // from under the user which is currently scrolling/moving the
              // cursor
              _this.avoidScrolling = true;
              _this.internalSetTimeout(function () {
                return _this.avoidScrolling = false;
              }, 250);
            }),
            onMouseDown: callAllEventHandlers(onMouseDown, function (event) {
              // This prevents the activeElement from being changed
              // to the item so it can remain with the current activeElement
              // which is a more common use case.
              event.preventDefault();
            })
          }, _enabledEventHandlers[onSelectKey] = callAllEventHandlers(customClickHandler, function () {
            _this.selectItemAtIndex(index, {
              type: clickItem
            });
          }), _enabledEventHandlers);

          // Passing down the onMouseDown handler to prevent redirect
          // of the activeElement if clicking on disabled items
          var eventHandlers = rest.disabled ? {
            onMouseDown: enabledEventHandlers.onMouseDown
          } : enabledEventHandlers;
          return _extends({
            id: _this.getItemId(index),
            role: 'option',
            'aria-selected': _this.getState().highlightedIndex === index
          }, eventHandlers, rest);
        };
        //\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ITEM
        _this.clearItems = function () {
          _this.items = [];
        };
        _this.reset = function (otherStateToSet, cb) {
          if (otherStateToSet === void 0) {
            otherStateToSet = {};
          }
          otherStateToSet = pickState(otherStateToSet);
          _this.internalSetState(function (_ref8) {
            var selectedItem = _ref8.selectedItem;
            return _extends({
              isOpen: _this.props.defaultIsOpen,
              highlightedIndex: _this.props.defaultHighlightedIndex,
              inputValue: _this.props.itemToString(selectedItem)
            }, otherStateToSet);
          }, cb);
        };
        _this.toggleMenu = function (otherStateToSet, cb) {
          if (otherStateToSet === void 0) {
            otherStateToSet = {};
          }
          otherStateToSet = pickState(otherStateToSet);
          _this.internalSetState(function (_ref9) {
            var isOpen = _ref9.isOpen;
            return _extends({
              isOpen: !isOpen
            }, isOpen && {
              highlightedIndex: _this.props.defaultHighlightedIndex
            }, otherStateToSet);
          }, function () {
            var _this$getState7 = _this.getState(),
              isOpen = _this$getState7.isOpen,
              highlightedIndex = _this$getState7.highlightedIndex;
            if (isOpen) {
              if (_this.getItemCount() > 0 && typeof highlightedIndex === 'number') {
                _this.setHighlightedIndex(highlightedIndex, otherStateToSet);
              }
            }
            cbToCb(cb)();
          });
        };
        _this.openMenu = function (cb) {
          _this.internalSetState({
            isOpen: true
          }, cb);
        };
        _this.closeMenu = function (cb) {
          _this.internalSetState({
            isOpen: false
          }, cb);
        };
        _this.updateStatus = debounce(function () {
          var _this$props;
          if (!((_this$props = _this.props) != null && (_this$props = _this$props.environment) != null && _this$props.document)) {
            return;
          }
          var state = _this.getState();
          var item = _this.items[state.highlightedIndex];
          var resultCount = _this.getItemCount();
          var status = _this.props.getA11yStatusMessage(_extends({
            itemToString: _this.props.itemToString,
            previousResultCount: _this.previousResultCount,
            resultCount: resultCount,
            highlightedItem: item
          }, state));
          _this.previousResultCount = resultCount;
          setStatus(status, _this.props.environment.document);
        }, 200);
        var _this$props2 = _this.props,
          defaultHighlightedIndex = _this$props2.defaultHighlightedIndex,
          _this$props2$initialH = _this$props2.initialHighlightedIndex,
          _highlightedIndex = _this$props2$initialH === void 0 ? defaultHighlightedIndex : _this$props2$initialH,
          defaultIsOpen = _this$props2.defaultIsOpen,
          _this$props2$initialI = _this$props2.initialIsOpen,
          _isOpen = _this$props2$initialI === void 0 ? defaultIsOpen : _this$props2$initialI,
          _this$props2$initialI2 = _this$props2.initialInputValue,
          _inputValue = _this$props2$initialI2 === void 0 ? '' : _this$props2$initialI2,
          _this$props2$initialS = _this$props2.initialSelectedItem,
          _selectedItem = _this$props2$initialS === void 0 ? null : _this$props2$initialS;
        var _state = _this.getState({
          highlightedIndex: _highlightedIndex,
          isOpen: _isOpen,
          inputValue: _inputValue,
          selectedItem: _selectedItem
        });
        if (_state.selectedItem != null && _this.props.initialInputValue === undefined) {
          _state.inputValue = _this.props.itemToString(_state.selectedItem);
        }
        _this.state = _state;
        return _this;
      }
      _inheritsLoose(Downshift, _Component);
      var _proto = Downshift.prototype;
      /**
       * Clear all running timeouts
       */
      _proto.internalClearTimeouts = function internalClearTimeouts() {
        this.timeoutIds.forEach(function (id) {
          clearTimeout(id);
        });
        this.timeoutIds = [];
      }

      /**
       * Gets the state based on internal state or props
       * If a state value is passed via props, then that
       * is the value given, otherwise it's retrieved from
       * stateToMerge
       *
       * @param {Object} stateToMerge defaults to this.state
       * @return {Object} the state
       */;
      _proto.getState = function getState$1(stateToMerge) {
        if (stateToMerge === void 0) {
          stateToMerge = this.state;
        }
        return getState(stateToMerge, this.props);
      };
      _proto.getItemCount = function getItemCount() {
        // things read better this way. They're in priority order:
        // 1. `this.itemCount`
        // 2. `this.props.itemCount`
        // 3. `this.items.length`
        var itemCount = this.items.length;
        if (this.itemCount != null) {
          itemCount = this.itemCount;
        } else if (this.props.itemCount !== undefined) {
          itemCount = this.props.itemCount;
        }
        return itemCount;
      };
      _proto.getItemNodeFromIndex = function getItemNodeFromIndex(index) {
        return this.props.environment ? this.props.environment.document.getElementById(this.getItemId(index)) : null;
      };
      _proto.scrollHighlightedItemIntoView = function scrollHighlightedItemIntoView() {
        /* istanbul ignore else (react-native) */
        {
          var node = this.getItemNodeFromIndex(this.getState().highlightedIndex);
          this.props.scrollIntoView(node, this._menuNode);
        }
      };
      _proto.moveHighlightedIndex = function moveHighlightedIndex(amount, otherStateToSet) {
        var itemCount = this.getItemCount();
        var _this$getState8 = this.getState(),
          highlightedIndex = _this$getState8.highlightedIndex;
        if (itemCount > 0) {
          var nextHighlightedIndex = getHighlightedIndex(highlightedIndex, amount, {
            length: itemCount
          }, this.isItemDisabled, true);
          this.setHighlightedIndex(nextHighlightedIndex, otherStateToSet);
        }
      };
      _proto.getStateAndHelpers = function getStateAndHelpers() {
        var _this$getState9 = this.getState(),
          highlightedIndex = _this$getState9.highlightedIndex,
          inputValue = _this$getState9.inputValue,
          selectedItem = _this$getState9.selectedItem,
          isOpen = _this$getState9.isOpen;
        var itemToString = this.props.itemToString;
        var id = this.id;
        var getRootProps = this.getRootProps,
          getToggleButtonProps = this.getToggleButtonProps,
          getLabelProps = this.getLabelProps,
          getMenuProps = this.getMenuProps,
          getInputProps = this.getInputProps,
          getItemProps = this.getItemProps,
          openMenu = this.openMenu,
          closeMenu = this.closeMenu,
          toggleMenu = this.toggleMenu,
          selectItem = this.selectItem,
          selectItemAtIndex = this.selectItemAtIndex,
          selectHighlightedItem = this.selectHighlightedItem,
          setHighlightedIndex = this.setHighlightedIndex,
          clearSelection = this.clearSelection,
          clearItems = this.clearItems,
          reset = this.reset,
          setItemCount = this.setItemCount,
          unsetItemCount = this.unsetItemCount,
          setState = this.internalSetState;
        return {
          // prop getters
          getRootProps: getRootProps,
          getToggleButtonProps: getToggleButtonProps,
          getLabelProps: getLabelProps,
          getMenuProps: getMenuProps,
          getInputProps: getInputProps,
          getItemProps: getItemProps,
          // actions
          reset: reset,
          openMenu: openMenu,
          closeMenu: closeMenu,
          toggleMenu: toggleMenu,
          selectItem: selectItem,
          selectItemAtIndex: selectItemAtIndex,
          selectHighlightedItem: selectHighlightedItem,
          setHighlightedIndex: setHighlightedIndex,
          clearSelection: clearSelection,
          clearItems: clearItems,
          setItemCount: setItemCount,
          unsetItemCount: unsetItemCount,
          setState: setState,
          // props
          itemToString: itemToString,
          // derived
          id: id,
          // state
          highlightedIndex: highlightedIndex,
          inputValue: inputValue,
          isOpen: isOpen,
          selectedItem: selectedItem
        };
      };
      _proto.componentDidMount = function componentDidMount() {
        var _this4 = this;
        /* istanbul ignore if (react-native) */
        if (this.getMenuProps.called && !this.getMenuProps.suppressRefError) {
          validateGetMenuPropsCalledCorrectly(this._menuNode, this.getMenuProps);
        }

        /* istanbul ignore if (react-native or SSR) */
        if (!this.props.environment) {
          this.cleanup = function () {
            _this4.internalClearTimeouts();
          };
        } else {
          // this.isMouseDown helps us track whether the mouse is currently held down.
          // This is useful when the user clicks on an item in the list, but holds the mouse
          // down long enough for the list to disappear (because the blur event fires on the input)
          // this.isMouseDown is used in the blur handler on the input to determine whether the blur event should
          // trigger hiding the menu.
          var onMouseDown = function onMouseDown() {
            _this4.isMouseDown = true;
          };
          var onMouseUp = function onMouseUp(event) {
            _this4.isMouseDown = false;
            // if the target element or the activeElement is within a downshift node
            // then we don't want to reset downshift
            var contextWithinDownshift = targetWithinDownshift(event.target, [_this4._rootNode, _this4._menuNode], _this4.props.environment);
            if (!contextWithinDownshift && _this4.getState().isOpen) {
              _this4.reset({
                type: mouseUp
              }, function () {
                return _this4.props.onOuterClick(_this4.getStateAndHelpers());
              });
            }
          };
          // Touching an element in iOS gives focus and hover states, but touching out of
          // the element will remove hover, and persist the focus state, resulting in the
          // blur event not being triggered.
          // this.isTouchMove helps us track whether the user is tapping or swiping on a touch screen.
          // If the user taps outside of Downshift, the component should be reset,
          // but not if the user is swiping
          var onTouchStart = function onTouchStart() {
            _this4.isTouchMove = false;
          };
          var onTouchMove = function onTouchMove() {
            _this4.isTouchMove = true;
          };
          var onTouchEnd = function onTouchEnd(event) {
            var contextWithinDownshift = targetWithinDownshift(event.target, [_this4._rootNode, _this4._menuNode], _this4.props.environment, false);
            if (!_this4.isTouchMove && !contextWithinDownshift && _this4.getState().isOpen) {
              _this4.reset({
                type: touchEnd
              }, function () {
                return _this4.props.onOuterClick(_this4.getStateAndHelpers());
              });
            }
          };
          var environment = this.props.environment;
          environment.addEventListener('mousedown', onMouseDown);
          environment.addEventListener('mouseup', onMouseUp);
          environment.addEventListener('touchstart', onTouchStart);
          environment.addEventListener('touchmove', onTouchMove);
          environment.addEventListener('touchend', onTouchEnd);
          this.cleanup = function () {
            _this4.internalClearTimeouts();
            _this4.updateStatus.cancel();
            environment.removeEventListener('mousedown', onMouseDown);
            environment.removeEventListener('mouseup', onMouseUp);
            environment.removeEventListener('touchstart', onTouchStart);
            environment.removeEventListener('touchmove', onTouchMove);
            environment.removeEventListener('touchend', onTouchEnd);
          };
        }
      };
      _proto.shouldScroll = function shouldScroll(prevState, prevProps) {
        var _ref0 = this.props.highlightedIndex === undefined ? this.getState() : this.props,
          currentHighlightedIndex = _ref0.highlightedIndex;
        var _ref1 = prevProps.highlightedIndex === undefined ? prevState : prevProps,
          prevHighlightedIndex = _ref1.highlightedIndex;
        var scrollWhenOpen = currentHighlightedIndex && this.getState().isOpen && !prevState.isOpen;
        var scrollWhenNavigating = currentHighlightedIndex !== prevHighlightedIndex;
        return scrollWhenOpen || scrollWhenNavigating;
      };
      _proto.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {
        {
          validateControlledUnchanged(this.state, prevProps, this.props);
          /* istanbul ignore if (react-native) */
          if (this.getMenuProps.called && !this.getMenuProps.suppressRefError) {
            validateGetMenuPropsCalledCorrectly(this._menuNode, this.getMenuProps);
          }
        }
        if (isControlledProp(this.props, 'selectedItem') && this.props.selectedItemChanged(prevProps.selectedItem, this.props.selectedItem)) {
          this.internalSetState({
            type: controlledPropUpdatedSelectedItem,
            inputValue: this.props.itemToString(this.props.selectedItem)
          });
        }
        if (!this.avoidScrolling && this.shouldScroll(prevState, prevProps)) {
          this.scrollHighlightedItemIntoView();
        }

        /* istanbul ignore else (react-native) */
        {
          this.updateStatus();
        }
      };
      _proto.componentWillUnmount = function componentWillUnmount() {
        this.cleanup(); // avoids memory leak
      };
      _proto.render = function render() {
        var children = unwrapArray(this.props.children, noop);
        // because the items are rerendered every time we call the children
        // we clear this out each render and it will be populated again as
        // getItemProps is called.
        this.clearItems();
        // we reset this so we know whether the user calls getRootProps during
        // this render. If they do then we don't need to do anything,
        // if they don't then we need to clone the element they return and
        // apply the props for them.
        this.getRootProps.called = false;
        this.getRootProps.refKey = undefined;
        this.getRootProps.suppressRefError = undefined;
        // we do something similar for getMenuProps
        this.getMenuProps.called = false;
        this.getMenuProps.refKey = undefined;
        this.getMenuProps.suppressRefError = undefined;
        // we do something similar for getLabelProps
        this.getLabelProps.called = false;
        // and something similar for getInputProps
        this.getInputProps.called = false;
        var element = unwrapArray(children(this.getStateAndHelpers()));
        if (!element) {
          return null;
        }
        if (this.getRootProps.called || this.props.suppressRefError) {
          if (!this.getRootProps.suppressRefError && !this.props.suppressRefError) {
            validateGetRootPropsCalledCorrectly(element, this.getRootProps);
          }
          return element;
        } else if (isDOMElement(element)) {
          // they didn't apply the root props, but we can clone
          // this and apply the props ourselves
          return React.cloneElement(element, this.getRootProps(getElementProps(element)));
        }

        /* istanbul ignore else */
        {
          // they didn't apply the root props, but they need to
          // otherwise we can't query around the autocomplete

          throw new Error('downshift: If you return a non-DOM element, you must apply the getRootProps function');
        }
      };
      return Downshift;
    }(React.Component);
    Downshift.defaultProps = {
      defaultHighlightedIndex: null,
      defaultIsOpen: false,
      getA11yStatusMessage: getA11yStatusMessage,
      itemToString: function itemToString(i) {
        if (i == null) {
          return '';
        }
        if (isPlainObject(i) && !i.hasOwnProperty('toString')) {
          // eslint-disable-next-line no-console
          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);
        }
        return String(i);
      },
      onStateChange: noop,
      onInputValueChange: noop,
      onUserAction: noop,
      onChange: noop,
      onSelect: noop,
      onOuterClick: noop,
      selectedItemChanged: function selectedItemChanged(prevItem, item) {
        return prevItem !== item;
      },
      environment: /* istanbul ignore next (ssr) */
      typeof window === 'undefined' || false ? undefined : window,
      stateReducer: function stateReducer(state, stateToSet) {
        return stateToSet;
      },
      suppressRefError: false,
      scrollIntoView: scrollIntoView
    };
    Downshift.stateChangeTypes = stateChangeTypes$4;
    return Downshift;
  }();
  function validateGetMenuPropsCalledCorrectly(node, _ref10) {
    var refKey = _ref10.refKey;
    if (!node) {
      // eslint-disable-next-line no-console
      console.error("downshift: The ref prop \"" + refKey + "\" from getMenuProps was not applied correctly on your menu element.");
    }
  }
  function validateGetRootPropsCalledCorrectly(element, _ref11) {
    var refKey = _ref11.refKey;
    var refKeySpecified = refKey !== 'ref';
    var isComposite = !isDOMElement(element);
    if (isComposite && !refKeySpecified && !reactIsExports.isForwardRef(element)) {
      // eslint-disable-next-line no-console
      console.error('downshift: You returned a non-DOM element. You must specify a refKey in getRootProps');
    } else if (!isComposite && refKeySpecified) {
      // eslint-disable-next-line no-console
      console.error("downshift: You returned a DOM element. You should not specify a refKey in getRootProps. You specified \"" + refKey + "\"");
    }
    if (!reactIsExports.isForwardRef(element) && !getElementProps(element)[refKey]) {
      // eslint-disable-next-line no-console
      console.error("downshift: You must apply the ref prop \"" + refKey + "\" from getRootProps onto your root element.");
    }
  }

  function capitalizeString(string) {
    return "" + string.slice(0, 1).toUpperCase() + string.slice(1);
  }

  function callOnChangeProps(action, props, state, newState) {
    var type = action.type;
    var changes = {};
    var keys = Object.keys(state);
    for (var _i = 0, _keys = keys; _i < _keys.length; _i++) {
      var key = _keys[_i];
      invokeOnChangeHandler(key, action, props, state, newState);
      if (newState[key] !== state[key]) {
        changes[key] = newState[key];
      }
    }
    if (props.onStateChange && Object.keys(changes).length) {
      props.onStateChange(_extends({
        type: type
      }, changes));
    }
  }
  function invokeOnChangeHandler(key, action, props, state, newState) {
    if (newState[key] === state[key]) {
      return;
    }
    var handlerKey = "on" + capitalizeString(key) + "Change";
    var handler = props[handlerKey];
    if (typeof handler !== 'function') {
      return;
    }
    var type = action.type;
    handler(_extends({
      type: type
    }, newState));
  }

  /**
   * Computes the controlled state using a the previous state, props,
   * two reducers, one from downshift and an optional one from the user.
   * Also calls the onChange handlers for state values that have changed.
   *
   * @param {Function} reducer Reducer function from downshift.
   * @param {Object} props The hook props, also passed to createInitialState.
   * @param {Function} createInitialState Function that returns the initial state.
   * @param {Function} isStateEqual Function that checks if a previous state is equal to the next.
   * @returns {Array} An array with the state and an action dispatcher.
   */
  function useEnhancedReducer(reducer, props, createInitialState, isStateEqual) {
    var prevStateRef = React__namespace.useRef(null);
    var actionRef = React__namespace.useRef(undefined);
    var propsRef = useLatestRef(props);
    var enhancedReducer = React__namespace.useCallback(function (state, action) {
      actionRef.current = action;
      state = getState(state, propsRef.current);
      var changes = reducer(state, propsRef.current, action);
      var newState = propsRef.current.stateReducer(state, _extends({}, action, {
        changes: changes
      }));
      return _extends({}, state, newState);
    }, [propsRef, reducer]);
    var _React$useReducer = React__namespace.useReducer(enhancedReducer, props, createInitialState),
      state = _React$useReducer[0],
      dispatch = _React$useReducer[1];
    var action = actionRef.current;
    React__namespace.useEffect(function () {
      var _prevStateRef$current;
      var prevState = getState((_prevStateRef$current = prevStateRef.current) != null ? _prevStateRef$current : {}, propsRef.current);
      var shouldCallOnChangeProps = action && prevStateRef.current && !isStateEqual(prevState, state);
      if (shouldCallOnChangeProps) {
        callOnChangeProps(action, propsRef.current, prevState, state);
      }
      prevStateRef.current = state;
    }, [state, action, isStateEqual, propsRef]);
    return [state, dispatch];
  }

  /**
   * Wraps the useEnhancedReducer and applies the controlled prop values before
   * returning the new state.
   *
   * @param {Function} reducer Reducer function from downshift.
   * @param {Object} props The hook props, also passed to createInitialState.
   * @param {Function} createInitialState Function that returns the initial state.
   * @param {Function} isStateEqual Function that checks if a previous state is equal to the next.
   * @returns {Array} An array with the state and an action dispatcher.
   */
  function useControlledReducer$1(reducer, props, createInitialState, isStateEqual) {
    var _useEnhancedReducer = useEnhancedReducer(reducer, props, createInitialState, isStateEqual),
      state = _useEnhancedReducer[0],
      dispatch = _useEnhancedReducer[1];
    return [getState(state, props), dispatch];
  }

  /**
   * Returns both the item and index when both or either is passed.
   *
   * @param itemProp The item which could be undefined.
   * @param indexProp The index which could be undefined.
   * @param items The array of items to get the item based on index.
   * @param errorMessage The error to be thrown if index and item could not be returned for any reason.
   * @returns An array with item and index.
   */
  function getItemAndIndex(itemProp, indexProp, items, errorMessage) {
    if (itemProp !== undefined && indexProp !== undefined) {
      return [itemProp, indexProp];
    }
    if (itemProp !== undefined) {
      var index = items.indexOf(itemProp);
      if (index < 0) {
        throw new Error(errorMessage);
      }
      return [itemProp, items.indexOf(itemProp)];
    }
    if (indexProp !== undefined) {
      var item = items[indexProp];
      if (item === undefined) {
        throw new Error(errorMessage);
      }
      return [item, indexProp];
    }
    throw new Error(errorMessage);
  }

  /**
   * Tracks if it's the first render.
   */
  function useIsInitialMount() {
    var isInitialMountRef = React__namespace.useRef(true);
    React__namespace.useEffect(function () {
      isInitialMountRef.current = false;
      return function () {
        isInitialMountRef.current = true;
      };
    }, []);
    return isInitialMountRef.current;
  }

  /**
   * Default state reducer that returns the changes.
   *
   */
  function stateReducer(_s, a) {
    return a.changes;
  }

  // Shared between all exports.
  var propTypes$5 = {
    environment: PropTypes.shape({
      addEventListener: PropTypes.func.isRequired,
      removeEventListener: PropTypes.func.isRequired,
      document: PropTypes.shape({
        createElement: PropTypes.func.isRequired,
        getElementById: PropTypes.func.isRequired,
        activeElement: PropTypes.any.isRequired,
        body: PropTypes.any.isRequired
      }).isRequired,
      Node: PropTypes.func.isRequired
    }),
    itemToKey: PropTypes.func,
    stateReducer: PropTypes.func
  };

  function getDefaultValue$1(props, propKey, defaultStateValues) {
    var defaultValue = props["default" + capitalizeString(propKey)];
    if (defaultValue !== undefined) {
      return defaultValue;
    }
    return defaultStateValues[propKey];
  }

  function getInitialValue$1(props, propKey, defaultStateValues) {
    var value = props[propKey];
    if (value !== undefined) {
      return value;
    }
    var initialValue = props["initial" + capitalizeString(propKey)];
    if (initialValue !== undefined) {
      return initialValue;
    }
    return getDefaultValue$1(props, propKey, defaultStateValues);
  }

  /**
   * Debounced call for updating the a11y message.
   */
  var updateA11yStatus = debounce$1(function (status, document) {
    setStatus(status, document);
  }, 200);

  /**
   * Adds an a11y aria live status message if getA11yStatusMessage is passed.
   * @param getA11yStatusMessage The function that builds the status message.
   * @param options The options to be passed to getA11yStatusMessage if called.
   * @param dependencyArray The dependency array that triggers the status message setter via useEffect.
   * @param environment The environment object containing the document.
   */
  function useA11yMessageStatus(getA11yStatusMessage, options, dependencyArray, environment) {
    var document = environment == null ? void 0 : environment.document;
    var isInitialMount = useIsInitialMount();

    // Adds an a11y aria live status message if getA11yStatusMessage is passed.
    React__namespace.useEffect(function () {
      if (!getA11yStatusMessage || isInitialMount || false || !document) {
        return;
      }
      var status = getA11yStatusMessage(options);
      updateA11yStatus(status, document);

      // eslint-disable-next-line react-hooks/exhaustive-deps
    }, dependencyArray);

    // Cleanup the status message container.
    React__namespace.useEffect(function () {
      return function () {
        updateA11yStatus.cancel();
        cleanupStatusDiv(document);
      };
    }, [document]);
  }

  // Shared between useSelect, useCombobox, Downshift.
  var propTypes$4 = _extends({}, propTypes$5, {
    getA11yStatusMessage: PropTypes.func,
    highlightedIndex: PropTypes.number,
    defaultHighlightedIndex: PropTypes.number,
    initialHighlightedIndex: PropTypes.number,
    isOpen: PropTypes.bool,
    defaultIsOpen: PropTypes.bool,
    initialIsOpen: PropTypes.bool,
    selectedItem: PropTypes.any,
    initialSelectedItem: PropTypes.any,
    defaultSelectedItem: PropTypes.any,
    id: PropTypes.string,
    labelId: PropTypes.string,
    menuId: PropTypes.string,
    getItemId: PropTypes.func,
    toggleButtonId: PropTypes.string,
    onSelectedItemChange: PropTypes.func,
    onHighlightedIndexChange: PropTypes.func,
    onStateChange: PropTypes.func,
    onIsOpenChange: PropTypes.func,
    scrollIntoView: PropTypes.func
  });

  var defaultProps$3 = {
    itemToString: function itemToString(item) {
      return item ? String(item) : '';
    },
    itemToKey: function itemToKey(item) {
      return item;
    },
    stateReducer: stateReducer,
    scrollIntoView: scrollIntoView,
    environment: /* istanbul ignore next (ssr) */
    typeof window === 'undefined' || false ? undefined : window
  };

  var defaultStateValues$1 = {
    highlightedIndex: -1,
    isOpen: false,
    selectedItem: null,
    inputValue: ''
  };

  // istanbul ignore next
  var useIsomorphicLayoutEffect = typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined' ? React__namespace.useLayoutEffect : React__namespace.useEffect;
  function isAcceptedCharacterKey(key) {
    return /^\S{1}$/.test(key);
  }
  function getInitialState$3(props) {
    var selectedItem = getInitialValue$1(props, 'selectedItem', defaultStateValues$1);
    var isOpen = getInitialValue$1(props, 'isOpen', defaultStateValues$1);
    var highlightedIndex = getInitialHighlightedIndex(props);
    var inputValue = getInitialValue$1(props, 'inputValue', defaultStateValues$1);
    return {
      highlightedIndex: highlightedIndex < 0 && selectedItem && isOpen ? props.items.findIndex(function (item) {
        return props.itemToKey(item) === props.itemToKey(selectedItem);
      }) : highlightedIndex,
      isOpen: isOpen,
      selectedItem: selectedItem,
      inputValue: inputValue
    };
  }
  function getHighlightedIndexOnOpen(props, state, offset) {
    var items = props.items,
      initialHighlightedIndex = props.initialHighlightedIndex,
      defaultHighlightedIndex = props.defaultHighlightedIndex,
      isItemDisabled = props.isItemDisabled,
      itemToKey = props.itemToKey;
    var selectedItem = state.selectedItem,
      highlightedIndex = state.highlightedIndex;
    if (items.length === 0) {
      return -1;
    }

    // initialHighlightedIndex will give value to highlightedIndex on initial state only.
    if (initialHighlightedIndex !== undefined && highlightedIndex === initialHighlightedIndex && !isItemDisabled(items[initialHighlightedIndex], initialHighlightedIndex)) {
      return initialHighlightedIndex;
    }
    if (defaultHighlightedIndex !== undefined && !isItemDisabled(items[defaultHighlightedIndex], defaultHighlightedIndex)) {
      return defaultHighlightedIndex;
    }
    if (selectedItem) {
      return items.findIndex(function (item) {
        return itemToKey(selectedItem) === itemToKey(item);
      });
    }
    if (offset < 0 && !isItemDisabled(items[items.length - 1], items.length - 1)) {
      return items.length - 1;
    }
    if (offset > 0 && !isItemDisabled(items[0], 0)) {
      return 0;
    }
    return -1;
  }
  /**
   * Tracks mouse and touch events, such as mouseDown, touchMove and touchEnd.
   *
   * @param {Window} environment The environment to add the event listeners to, for instance window.
   * @param {() => void} handleBlur The function that is called if mouseDown or touchEnd occured outside the downshiftElements.
   * @param {Array<{current: HTMLElement}>} downshiftElementsRefs The refs for the elements that should not trigger a blur action from mouseDown or touchEnd.
   * @returns {{isMouseDown: boolean, isTouchMove: boolean, isTouchEnd: boolean}} The mouse and touch events information, if any of are happening.
   */
  function useMouseAndTouchTracker(environment, handleBlur, downshiftRefs) {
    var mouseAndTouchTrackersRef = React__namespace.useRef({
      isMouseDown: false,
      isTouchMove: false,
      isTouchEnd: false
    });
    var getDownshiftElements = React__namespace.useCallback(function () {
      return downshiftRefs.map(function (ref) {
        return ref.current;
      });
    }, [downshiftRefs]);
    React__namespace.useEffect(function () {
      if (!environment) {
        return noop;
      }
      function onMouseDown() {
        mouseAndTouchTrackersRef.current.isTouchEnd = false; // reset this one.
        mouseAndTouchTrackersRef.current.isMouseDown = true;
      }
      function onMouseUp(event) {
        mouseAndTouchTrackersRef.current.isMouseDown = false;
        if (!targetWithinDownshift(event.target, getDownshiftElements(), environment)) {
          handleBlur();
        }
      }
      function onTouchStart() {
        mouseAndTouchTrackersRef.current.isTouchEnd = false;
        mouseAndTouchTrackersRef.current.isTouchMove = false;
      }
      function onTouchMove() {
        mouseAndTouchTrackersRef.current.isTouchMove = true;
      }
      function onTouchEnd(event) {
        mouseAndTouchTrackersRef.current.isTouchEnd = true;
        if (!mouseAndTouchTrackersRef.current.isTouchMove && !targetWithinDownshift(event.target, getDownshiftElements(), environment, false)) {
          handleBlur();
        }
      }
      environment.addEventListener('mousedown', onMouseDown);
      environment.addEventListener('mouseup', onMouseUp);
      environment.addEventListener('touchstart', onTouchStart);
      environment.addEventListener('touchmove', onTouchMove);
      environment.addEventListener('touchend', onTouchEnd);
      return function cleanup() {
        environment.removeEventListener('mousedown', onMouseDown);
        environment.removeEventListener('mouseup', onMouseUp);
        environment.removeEventListener('touchstart', onTouchStart);
        environment.removeEventListener('touchmove', onTouchMove);
        environment.removeEventListener('touchend', onTouchEnd);
      };
    }, [environment, getDownshiftElements, handleBlur]);
    return mouseAndTouchTrackersRef.current;
  }

  /* istanbul ignore next */
  // eslint-disable-next-line import/no-mutable-exports
  var useGetterPropsCalledChecker = function useGetterPropsCalledChecker() {
    return noop;
  };
  /**
   * Custom hook that checks if getter props are called correctly.
   *
   * @param  {...any} propKeys Getter prop names to be handled.
   * @returns {Function} Setter function called inside getter props to set call information.
   */
  /* istanbul ignore next */
  {
    useGetterPropsCalledChecker = function useGetterPropsCalledChecker() {
      for (var _len = arguments.length, propKeys = new Array(_len), _key = 0; _key < _len; _key++) {
        propKeys[_key] = arguments[_key];
      }
      var getterPropsCalledRef = React__namespace.useRef(propKeys.reduce(function (acc, propKey) {
        acc[propKey] = {};
        return acc;
      }, {}));
      React__namespace.useEffect(function () {
        Object.keys(getterPropsCalledRef.current).forEach(function (propKey) {
          var propCallInfo = getterPropsCalledRef.current[propKey];
          if (!Object.keys(propCallInfo).length) {
            // eslint-disable-next-line no-console
            console.error("downshift: You forgot to call the " + propKey + " getter function on your component / element.");
            return;
          }
          var suppressRefError = propCallInfo.suppressRefError,
            refKey = propCallInfo.refKey,
            elementRef = propCallInfo.elementRef;
          if (suppressRefError) {
            return;
          }
          if (!(elementRef != null && elementRef.current)) {
            // eslint-disable-next-line no-console
            console.error("downshift: The ref prop \"" + refKey + "\" from " + propKey + " was not applied correctly on your element.");
          }
        });
      }, []);
      var setGetterPropCallInfo = React__namespace.useCallback(function (propKey, suppressRefError, refKey, elementRef) {
        getterPropsCalledRef.current[propKey] = {
          suppressRefError: suppressRefError,
          refKey: refKey,
          elementRef: elementRef
        };
      }, []);
      return setGetterPropCallInfo;
    };
  }
  function useScrollIntoView(_ref) {
    var highlightedIndex = _ref.highlightedIndex,
      isOpen = _ref.isOpen,
      itemRefs = _ref.itemRefs,
      getItemNodeFromIndex = _ref.getItemNodeFromIndex,
      menuElement = _ref.menuElement,
      scrollIntoViewProp = _ref.scrollIntoView;
    // used not to scroll on highlight by mouse.
    var shouldScrollRef = React__namespace.useRef(true);
    // Scroll on highlighted item if change comes from keyboard.
    useIsomorphicLayoutEffect(function () {
      if (highlightedIndex < 0 || !isOpen || !Object.keys(itemRefs.current).length) {
        return;
      }
      if (shouldScrollRef.current === false) {
        shouldScrollRef.current = true;
      } else {
        scrollIntoViewProp(getItemNodeFromIndex(highlightedIndex), menuElement);
      }
      // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [highlightedIndex]);
    return shouldScrollRef;
  }

  // eslint-disable-next-line import/no-mutable-exports
  var useControlPropsValidator = noop;
  /* istanbul ignore next */
  {
    useControlPropsValidator = function useControlPropsValidator(_ref2) {
      var props = _ref2.props,
        state = _ref2.state;
      // used for checking when props are moving from controlled to uncontrolled.
      var prevPropsRef = React__namespace.useRef(props);
      var isInitialMount = useIsInitialMount();
      React__namespace.useEffect(function () {
        if (isInitialMount) {
          return;
        }
        validateControlledUnchanged(state, prevPropsRef.current, props);
        prevPropsRef.current = props;
      }, [state, props, isInitialMount]);
    };
  }

  /**
   * Handles selection on Enter / Alt + ArrowUp. Closes the menu and resets the highlighted index, unless there is a highlighted.
   * In that case, selects the item and resets to defaults for open state and highlighted idex.
   * @param {Object} props The useCombobox props.
   * @param {number} highlightedIndex The index from the state.
   * @param {boolean} inputValue Also return the input value for state.
   * @returns The changes for the state.
   */
  function getChangesOnSelection(props, highlightedIndex, inputValue) {
    var _props$items;
    if (inputValue === void 0) {
      inputValue = true;
    }
    var shouldSelect = ((_props$items = props.items) == null ? void 0 : _props$items.length) && highlightedIndex >= 0;
    return _extends({
      isOpen: false,
      highlightedIndex: -1
    }, shouldSelect && _extends({
      selectedItem: props.items[highlightedIndex],
      isOpen: getDefaultValue$1(props, 'isOpen', defaultStateValues$1),
      highlightedIndex: getDefaultValue$1(props, 'highlightedIndex', defaultStateValues$1)
    }, inputValue && {
      inputValue: props.itemToString(props.items[highlightedIndex])
    }));
  }

  /**
   * Check if a state is equal for dropdowns, by comparing isOpen, inputValue, highlightedIndex and selected item.
   * Used by useSelect and useCombobox.
   *
   * @param {Object} prevState
   * @param {Object} newState
   * @returns {boolean} Wheather the states are deeply equal.
   */
  function isDropdownsStateEqual(prevState, newState) {
    return prevState.isOpen === newState.isOpen && prevState.inputValue === newState.inputValue && prevState.highlightedIndex === newState.highlightedIndex && prevState.selectedItem === newState.selectedItem;
  }

  /**
   * Returns the new highlightedIndex based on the defaultHighlightedIndex prop, if it's not disabled.
   *
   * @param {Object} props Props from useCombobox or useSelect.
   * @returns {number} The highlighted index.
   */
  function getDefaultHighlightedIndex(props) {
    var highlightedIndex = getDefaultValue$1(props, 'highlightedIndex', defaultStateValues$1);
    if (highlightedIndex > -1 && props.isItemDisabled(props.items[highlightedIndex], highlightedIndex)) {
      return -1;
    }
    return highlightedIndex;
  }

  /**
   * Returns the new highlightedIndex based on the initialHighlightedIndex prop, if not disabled.
   *
   * @param {Object} props Props from useCombobox or useSelect.
   * @returns {number} The highlighted index.
   */
  function getInitialHighlightedIndex(props) {
    var highlightedIndex = getInitialValue$1(props, 'highlightedIndex', defaultStateValues$1);
    if (highlightedIndex > -1 && props.isItemDisabled(props.items[highlightedIndex], highlightedIndex)) {
      return -1;
    }
    return highlightedIndex;
  }

  function downshiftCommonReducer(state, props, action, stateChangeTypes) {
    var type = action.type;
    var changes;
    switch (type) {
      case stateChangeTypes.ItemMouseMove:
        changes = {
          highlightedIndex: action.disabled ? -1 : action.index
        };
        break;
      case stateChangeTypes.MenuMouseLeave:
        changes = {
          highlightedIndex: -1
        };
        break;
      case stateChangeTypes.ToggleButtonClick:
      case stateChangeTypes.FunctionToggleMenu:
        changes = {
          isOpen: !state.isOpen,
          highlightedIndex: state.isOpen ? -1 : getHighlightedIndexOnOpen(props, state, 0)
        };
        break;
      case stateChangeTypes.FunctionOpenMenu:
        changes = {
          isOpen: true,
          highlightedIndex: getHighlightedIndexOnOpen(props, state, 0)
        };
        break;
      case stateChangeTypes.FunctionCloseMenu:
        changes = {
          isOpen: false
        };
        break;
      case stateChangeTypes.FunctionSetHighlightedIndex:
        changes = {
          highlightedIndex: props.isItemDisabled(props.items[action.highlightedIndex], action.highlightedIndex) ? -1 : action.highlightedIndex
        };
        break;
      case stateChangeTypes.FunctionSetInputValue:
        changes = {
          inputValue: action.inputValue
        };
        break;
      case stateChangeTypes.FunctionReset:
        changes = {
          highlightedIndex: getDefaultHighlightedIndex(props),
          isOpen: getDefaultValue$1(props, 'isOpen', defaultStateValues$1),
          selectedItem: getDefaultValue$1(props, 'selectedItem', defaultStateValues$1),
          inputValue: getDefaultValue$1(props, 'inputValue', defaultStateValues$1)
        };
        break;
      default:
        throw new Error('Reducer called without proper action type.');
    }
    return _extends({}, state, changes);
  }
  /* eslint-enable complexity */

  var propTypes$3 = _extends({}, propTypes$4, {
    items: PropTypes.array.isRequired,
    isItemDisabled: PropTypes.func
  });

  var defaultProps$2 = _extends({}, defaultProps$3, {
    isItemDisabled: function isItemDisabled() {
      return false;
    }
  });

  function getItemIndexByCharacterKey(_ref) {
    var keysSoFar = _ref.keysSoFar,
      highlightedIndex = _ref.highlightedIndex,
      items = _ref.items,
      itemToString = _ref.itemToString,
      isItemDisabled = _ref.isItemDisabled;
    var lowerCasedKeysSoFar = keysSoFar.toLowerCase();
    for (var _index = 0; _index < items.length; _index++) {
      // if we already have a search query in progress, we also consider the current highlighted item.
      var offsetIndex = (_index + highlightedIndex + (keysSoFar.length < 2 ? 1 : 0)) % items.length;
      var _item = items[offsetIndex];
      if (_item !== undefined && itemToString(_item).toLowerCase().startsWith(lowerCasedKeysSoFar) && !isItemDisabled(_item, offsetIndex)) {
        return offsetIndex;
      }
    }
    return highlightedIndex;
  }

  var ToggleButtonClick$1 = '__togglebutton_click__' ;
  var ToggleButtonKeyDownArrowDown = '__togglebutton_keydown_arrow_down__' ;
  var ToggleButtonKeyDownArrowUp = '__togglebutton_keydown_arrow_up__' ;
  var ToggleButtonKeyDownCharacter = '__togglebutton_keydown_character__' ;
  var ToggleButtonKeyDownEscape = '__togglebutton_keydown_escape__' ;
  var ToggleButtonKeyDownHome = '__togglebutton_keydown_home__' ;
  var ToggleButtonKeyDownEnd = '__togglebutton_keydown_end__' ;
  var ToggleButtonKeyDownEnter = '__togglebutton_keydown_enter__' ;
  var ToggleButtonKeyDownSpaceButton = '__togglebutton_keydown_space_button__' ;
  var ToggleButtonKeyDownPageUp = '__togglebutton_keydown_page_up__' ;
  var ToggleButtonKeyDownPageDown = '__togglebutton_keydown_page_down__' ;
  var ToggleButtonBlur = '__togglebutton_blur__' ;
  var MenuMouseLeave$1 = '__menu_mouse_leave__' ;
  var ItemMouseMove$1 = '__item_mouse_move__' ;
  var ItemClick$1 = '__item_click__' ;
  var FunctionToggleMenu$1 = '__function_toggle_menu__' ;
  var FunctionOpenMenu$1 = '__function_open_menu__' ;
  var FunctionCloseMenu$1 = '__function_close_menu__' ;
  var FunctionSetHighlightedIndex$1 = '__function_set_highlighted_index__' ;
  var FunctionSelectItem$1 = '__function_select_item__' ;
  var FunctionSetInputValue$1 = '__function_set_input_value__' ;
  var FunctionReset$2 = '__function_reset__' ;

  var stateChangeTypes$3 = /*#__PURE__*/Object.freeze({
    __proto__: null,
    FunctionCloseMenu: FunctionCloseMenu$1,
    FunctionOpenMenu: FunctionOpenMenu$1,
    FunctionReset: FunctionReset$2,
    FunctionSelectItem: FunctionSelectItem$1,
    FunctionSetHighlightedIndex: FunctionSetHighlightedIndex$1,
    FunctionSetInputValue: FunctionSetInputValue$1,
    FunctionToggleMenu: FunctionToggleMenu$1,
    ItemClick: ItemClick$1,
    ItemMouseMove: ItemMouseMove$1,
    MenuMouseLeave: MenuMouseLeave$1,
    ToggleButtonBlur: ToggleButtonBlur,
    ToggleButtonClick: ToggleButtonClick$1,
    ToggleButtonKeyDownArrowDown: ToggleButtonKeyDownArrowDown,
    ToggleButtonKeyDownArrowUp: ToggleButtonKeyDownArrowUp,
    ToggleButtonKeyDownCharacter: ToggleButtonKeyDownCharacter,
    ToggleButtonKeyDownEnd: ToggleButtonKeyDownEnd,
    ToggleButtonKeyDownEnter: ToggleButtonKeyDownEnter,
    ToggleButtonKeyDownEscape: ToggleButtonKeyDownEscape,
    ToggleButtonKeyDownHome: ToggleButtonKeyDownHome,
    ToggleButtonKeyDownPageDown: ToggleButtonKeyDownPageDown,
    ToggleButtonKeyDownPageUp: ToggleButtonKeyDownPageUp,
    ToggleButtonKeyDownSpaceButton: ToggleButtonKeyDownSpaceButton
  });

  /* eslint-disable complexity */
  function downshiftSelectReducer(state, props, action) {
    var _props$items;
    var type = action.type,
      altKey = action.altKey;
    var changes;
    switch (type) {
      case ItemClick$1:
        changes = {
          isOpen: getDefaultValue$1(props, 'isOpen', defaultStateValues$1),
          highlightedIndex: getDefaultHighlightedIndex(props),
          selectedItem: props.items[action.index]
        };
        break;
      case ToggleButtonKeyDownCharacter:
        {
          var lowercasedKey = action.key;
          var inputValue = "" + state.inputValue + lowercasedKey;
          var prevHighlightedIndex = !state.isOpen && state.selectedItem ? props.items.findIndex(function (item) {
            return props.itemToKey(item) === props.itemToKey(state.selectedItem);
          }) : state.highlightedIndex;
          var highlightedIndex = getItemIndexByCharacterKey({
            keysSoFar: inputValue,
            highlightedIndex: prevHighlightedIndex,
            items: props.items,
            itemToString: props.itemToString,
            isItemDisabled: props.isItemDisabled
          });
          changes = {
            inputValue: inputValue,
            highlightedIndex: highlightedIndex,
            isOpen: true
          };
        }
        break;
      case ToggleButtonKeyDownArrowDown:
        {
          var _highlightedIndex = state.isOpen ? getHighlightedIndex(state.highlightedIndex, 1, props.items, props.isItemDisabled) : altKey && state.selectedItem == null ? -1 : getHighlightedIndexOnOpen(props, state, 1);
          changes = {
            highlightedIndex: _highlightedIndex,
            isOpen: true
          };
        }
        break;
      case ToggleButtonKeyDownArrowUp:
        if (state.isOpen && altKey) {
          changes = getChangesOnSelection(props, state.highlightedIndex, false);
        } else {
          var _highlightedIndex2 = state.isOpen ? getHighlightedIndex(state.highlightedIndex, -1, props.items, props.isItemDisabled) : getHighlightedIndexOnOpen(props, state, -1);
          changes = {
            highlightedIndex: _highlightedIndex2,
            isOpen: true
          };
        }
        break;
      // only triggered when menu is open.
      case ToggleButtonKeyDownEnter:
      case ToggleButtonKeyDownSpaceButton:
        changes = getChangesOnSelection(props, state.highlightedIndex, false);
        break;
      case ToggleButtonKeyDownHome:
        changes = {
          highlightedIndex: getNonDisabledIndex(0, false, props.items, props.isItemDisabled),
          isOpen: true
        };
        break;
      case ToggleButtonKeyDownEnd:
        changes = {
          highlightedIndex: getNonDisabledIndex(props.items.length - 1, true, props.items, props.isItemDisabled),
          isOpen: true
        };
        break;
      case ToggleButtonKeyDownPageUp:
        changes = {
          highlightedIndex: getHighlightedIndex(state.highlightedIndex, -10, props.items, props.isItemDisabled)
        };
        break;
      case ToggleButtonKeyDownPageDown:
        changes = {
          highlightedIndex: getHighlightedIndex(state.highlightedIndex, 10, props.items, props.isItemDisabled)
        };
        break;
      case ToggleButtonKeyDownEscape:
        changes = {
          isOpen: false,
          highlightedIndex: -1
        };
        break;
      case ToggleButtonBlur:
        changes = _extends({
          isOpen: false,
          highlightedIndex: -1
        }, state.highlightedIndex >= 0 && ((_props$items = props.items) == null ? void 0 : _props$items.length) && {
          selectedItem: props.items[state.highlightedIndex]
        });
        break;
      case FunctionSelectItem$1:
        changes = {
          selectedItem: action.selectedItem
        };
        break;
      default:
        return downshiftCommonReducer(state, props, action, stateChangeTypes$3);
    }
    return _extends({}, state, changes);
  }
  /* eslint-enable complexity */

  // eslint-disable-next-line @typescript-eslint/dot-notation
  var reactUseId$1 = React__namespace['useId'];
  var useElementIds$1 = typeof reactUseId$1 === 'function' ? useElementIdsR18$1 : useElementIdsLegacy$1;
  function useElementIdsR18$1(_ref) {
    var id = _ref.id,
      labelId = _ref.labelId,
      menuId = _ref.menuId,
      getItemId = _ref.getItemId,
      toggleButtonId = _ref.toggleButtonId,
      inputId = _ref.inputId;
    var reactId = "downshift-" + reactUseId$1();
    if (!id) {
      id = reactId;
    }
    var elementIds = React__namespace.useMemo(function () {
      return {
        labelId: labelId != null ? labelId : id + "-label",
        menuId: menuId != null ? menuId : id + "-menu",
        getItemId: getItemId != null ? getItemId : function (index) {
          return id + "-item-" + index;
        },
        toggleButtonId: toggleButtonId != null ? toggleButtonId : id + "-toggle-button",
        inputId: inputId != null ? inputId : id + "-input"
      };
    }, [getItemId, id, inputId, labelId, menuId, toggleButtonId]);
    return elementIds;
  }
  function useElementIdsLegacy$1(_ref2) {
    var id = _ref2.id,
      labelId = _ref2.labelId,
      menuId = _ref2.menuId,
      getItemId = _ref2.getItemId,
      toggleButtonId = _ref2.toggleButtonId,
      inputId = _ref2.inputId;
    var baseIdRef = React__namespace.useRef(id != null ? id : "downshift-" + generateId());
    var baseId = baseIdRef.current;
    var elementIds = React__namespace.useMemo(function () {
      return {
        labelId: labelId != null ? labelId : baseId + "-label",
        menuId: menuId != null ? menuId : baseId + "-menu",
        getItemId: getItemId != null ? getItemId : function (index) {
          return baseId + "-item-" + index;
        },
        toggleButtonId: toggleButtonId != null ? toggleButtonId : baseId + "-toggle-button",
        inputId: inputId != null ? inputId : baseId + "-input"
      };
    }, [getItemId, inputId, labelId, menuId, toggleButtonId, baseId]);
    return elementIds;
  }

  var _excluded$3 = ["onClick"],
    _excluded2$3 = ["onMouseLeave", "refKey", "ref"],
    _excluded3$2 = ["onBlur", "onClick", "onPress", "onKeyDown", "refKey", "ref"],
    _excluded4$1 = ["item", "index", "onMouseMove", "onClick", "onMouseDown", "onPress", "refKey", "disabled", "ref"];
  useSelect.stateChangeTypes = stateChangeTypes$3;
  function useSelect(userProps) {
    if (userProps === void 0) {
      userProps = {};
    }
    validatePropTypes$1(userProps, useSelect, propTypes$3);
    // Props defaults and destructuring.
    var props = _extends({}, defaultProps$2, userProps);
    var scrollIntoView = props.scrollIntoView,
      environment = props.environment,
      getA11yStatusMessage = props.getA11yStatusMessage;
    // Initial state depending on controlled props.
    var _useControlledReducer = useControlledReducer$1(downshiftSelectReducer, props, getInitialState$3, isDropdownsStateEqual),
      state = _useControlledReducer[0],
      dispatch = _useControlledReducer[1];
    var isOpen = state.isOpen,
      highlightedIndex = state.highlightedIndex,
      selectedItem = state.selectedItem,
      inputValue = state.inputValue;
    // Element efs.
    var toggleButtonRef = React.useRef(null);
    var menuRef = React.useRef(null);
    var itemRefs = React.useRef({});

    // used to keep the inputValue clearTimeout object between renders.
    var clearTimeoutRef = React.useRef(null);
    // prevent id re-generation between renders.
    var elementIds = useElementIds$1(props);
    // utility callback to get item element.
    var latest = useLatestRef({
      state: state,
      props: props
    });

    // Some utils.
    var getItemNodeFromIndex = React.useCallback(function (index) {
      return itemRefs.current[elementIds.getItemId(index)];
    }, [elementIds]);

    // Effects.
    // Adds an a11y aria live status message if getA11yStatusMessage is passed.
    useA11yMessageStatus(getA11yStatusMessage, state, [isOpen, highlightedIndex, selectedItem, inputValue], environment);
    // Scroll on highlighted item if change comes from keyboard.
    var shouldScrollRef = useScrollIntoView({
      menuElement: menuRef.current,
      highlightedIndex: highlightedIndex,
      isOpen: isOpen,
      itemRefs: itemRefs,
      scrollIntoView: scrollIntoView,
      getItemNodeFromIndex: getItemNodeFromIndex
    });
    // Sets cleanup for the keysSoFar callback, debounded after 500ms.
    React.useEffect(function () {
      // init the clean function here as we need access to dispatch.
      clearTimeoutRef.current = debounce(function (outerDispatch) {
        outerDispatch({
          type: FunctionSetInputValue$1,
          inputValue: ''
        });
      }, 500);

      // Cancel any pending debounced calls on mount
      return function () {
        clearTimeoutRef.current.cancel();
      };
    }, []);
    // Invokes the keysSoFar callback set up above.
    React.useEffect(function () {
      if (!inputValue) {
        return;
      }
      clearTimeoutRef.current(dispatch);
    }, [dispatch, inputValue]);
    useControlPropsValidator({
      props: props,
      state: state
    });
    // Focus the toggle button on first render if required.
    React.useEffect(function () {
      var focusOnOpen = getInitialValue$1(props, 'isOpen', defaultStateValues$1);
      if (focusOnOpen && toggleButtonRef.current) {
        toggleButtonRef.current.focus();
      }
      // eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);
    var handleBlurInTracker = React.useCallback(function handleBlur() {
      if (latest.current.state.isOpen) {
        dispatch({
          type: ToggleButtonBlur
        });
      }
    }, [dispatch, latest]);
    var downshiftRefs = React.useMemo(function () {
      return [menuRef, toggleButtonRef];
    }, []);
    var mouseAndTouchTrackers = useMouseAndTouchTracker(environment, handleBlurInTracker, downshiftRefs);
    var setGetterPropCallInfo = useGetterPropsCalledChecker('getMenuProps', 'getToggleButtonProps');
    // Reset itemRefs on close.
    React.useEffect(function () {
      if (!isOpen) {
        itemRefs.current = {};
      }
    }, [isOpen]);

    // Event handler functions.
    var toggleButtonKeyDownHandlers = React.useMemo(function () {
      return {
        ArrowDown: function ArrowDown(event) {
          event.preventDefault();
          dispatch({
            type: ToggleButtonKeyDownArrowDown,
            altKey: event.altKey
          });
        },
        ArrowUp: function ArrowUp(event) {
          event.preventDefault();
          dispatch({
            type: ToggleButtonKeyDownArrowUp,
            altKey: event.altKey
          });
        },
        Home: function Home(event) {
          event.preventDefault();
          dispatch({
            type: ToggleButtonKeyDownHome
          });
        },
        End: function End(event) {
          event.preventDefault();
          dispatch({
            type: ToggleButtonKeyDownEnd
          });
        },
        Escape: function Escape() {
          if (latest.current.state.isOpen) {
            dispatch({
              type: ToggleButtonKeyDownEscape
            });
          }
        },
        Enter: function Enter(event) {
          event.preventDefault();
          dispatch({
            type: latest.current.state.isOpen ? ToggleButtonKeyDownEnter : ToggleButtonClick$1
          });
        },
        PageUp: function PageUp(event) {
          if (latest.current.state.isOpen) {
            event.preventDefault();
            dispatch({
              type: ToggleButtonKeyDownPageUp
            });
          }
        },
        PageDown: function PageDown(event) {
          if (latest.current.state.isOpen) {
            event.preventDefault();
            dispatch({
              type: ToggleButtonKeyDownPageDown
            });
          }
        },
        ' ': function _(event) {
          event.preventDefault();
          var currentState = latest.current.state;
          if (!currentState.isOpen) {
            dispatch({
              type: ToggleButtonClick$1
            });
            return;
          }
          if (currentState.inputValue) {
            dispatch({
              type: ToggleButtonKeyDownCharacter,
              key: ' '
            });
          } else {
            dispatch({
              type: ToggleButtonKeyDownSpaceButton
            });
          }
        }
      };
    }, [dispatch, latest]);

    // Action functions.
    var toggleMenu = React.useCallback(function () {
      dispatch({
        type: FunctionToggleMenu$1
      });
    }, [dispatch]);
    var closeMenu = React.useCallback(function () {
      dispatch({
        type: FunctionCloseMenu$1
      });
    }, [dispatch]);
    var openMenu = React.useCallback(function () {
      dispatch({
        type: FunctionOpenMenu$1
      });
    }, [dispatch]);
    var setHighlightedIndex = React.useCallback(function (newHighlightedIndex) {
      dispatch({
        type: FunctionSetHighlightedIndex$1,
        highlightedIndex: newHighlightedIndex
      });
    }, [dispatch]);
    var selectItem = React.useCallback(function (newSelectedItem) {
      dispatch({
        type: FunctionSelectItem$1,
        selectedItem: newSelectedItem
      });
    }, [dispatch]);
    var reset = React.useCallback(function () {
      dispatch({
        type: FunctionReset$2
      });
    }, [dispatch]);
    var setInputValue = React.useCallback(function (newInputValue) {
      dispatch({
        type: FunctionSetInputValue$1,
        inputValue: newInputValue
      });
    }, [dispatch]);
    // Getter functions.
    var getLabelProps = React.useCallback(function (_temp) {
      var _ref = _temp === void 0 ? {} : _temp,
        onClick = _ref.onClick,
        labelProps = _objectWithoutPropertiesLoose(_ref, _excluded$3);
      var labelHandleClick = function labelHandleClick() {
        var _toggleButtonRef$curr;
        (_toggleButtonRef$curr = toggleButtonRef.current) == null || _toggleButtonRef$curr.focus();
      };
      return _extends({
        id: elementIds.labelId,
        htmlFor: elementIds.toggleButtonId,
        onClick: callAllEventHandlers(onClick, labelHandleClick)
      }, labelProps);
    }, [elementIds]);
    var getMenuProps = React.useCallback(function (_temp2, _temp3) {
      var _extends2;
      var _ref2 = _temp2 === void 0 ? {} : _temp2,
        onMouseLeave = _ref2.onMouseLeave,
        _ref2$refKey = _ref2.refKey,
        refKey = _ref2$refKey === void 0 ? 'ref' : _ref2$refKey,
        ref = _ref2.ref,
        rest = _objectWithoutPropertiesLoose(_ref2, _excluded2$3);
      var _ref3 = _temp3 === void 0 ? {} : _temp3,
        _ref3$suppressRefErro = _ref3.suppressRefError,
        suppressRefError = _ref3$suppressRefErro === void 0 ? false : _ref3$suppressRefErro;
      var menuHandleMouseLeave = function menuHandleMouseLeave() {
        dispatch({
          type: MenuMouseLeave$1
        });
      };
      setGetterPropCallInfo('getMenuProps', suppressRefError, refKey, menuRef);
      return _extends((_extends2 = {}, _extends2[refKey] = handleRefs(ref, function (menuNode) {
        menuRef.current = menuNode;
      }), _extends2.id = elementIds.menuId, _extends2.role = 'listbox', _extends2['aria-labelledby'] = rest && rest['aria-label'] ? undefined : "" + elementIds.labelId, _extends2.onMouseLeave = callAllEventHandlers(onMouseLeave, menuHandleMouseLeave), _extends2), rest);
    }, [dispatch, setGetterPropCallInfo, elementIds]);
    var getToggleButtonProps = React.useCallback(function (_temp4, _temp5) {
      var _extends3;
      var _ref4 = _temp4 === void 0 ? {} : _temp4,
        onBlur = _ref4.onBlur,
        onClick = _ref4.onClick;
        _ref4.onPress;
        var onKeyDown = _ref4.onKeyDown,
        _ref4$refKey = _ref4.refKey,
        refKey = _ref4$refKey === void 0 ? 'ref' : _ref4$refKey,
        ref = _ref4.ref,
        rest = _objectWithoutPropertiesLoose(_ref4, _excluded3$2);
      var _ref5 = _temp5 === void 0 ? {} : _temp5,
        _ref5$suppressRefErro = _ref5.suppressRefError,
        suppressRefError = _ref5$suppressRefErro === void 0 ? false : _ref5$suppressRefErro;
      var latestState = latest.current.state;
      var toggleButtonHandleClick = function toggleButtonHandleClick() {
        dispatch({
          type: ToggleButtonClick$1
        });
      };
      var toggleButtonHandleBlur = function toggleButtonHandleBlur() {
        if (latestState.isOpen && !mouseAndTouchTrackers.isMouseDown) {
          dispatch({
            type: ToggleButtonBlur
          });
        }
      };
      var toggleButtonHandleKeyDown = function toggleButtonHandleKeyDown(event) {
        var key = normalizeArrowKey(event);
        if (key && toggleButtonKeyDownHandlers[key]) {
          toggleButtonKeyDownHandlers[key](event);
        } else if (isAcceptedCharacterKey(key)) {
          dispatch({
            type: ToggleButtonKeyDownCharacter,
            key: key
          });
        }
      };
      var toggleProps = _extends((_extends3 = {}, _extends3[refKey] = handleRefs(ref, function (toggleButtonNode) {
        toggleButtonRef.current = toggleButtonNode;
      }), _extends3['aria-activedescendant'] = latestState.isOpen && latestState.highlightedIndex > -1 ? elementIds.getItemId(latestState.highlightedIndex) : '', _extends3['aria-controls'] = elementIds.menuId, _extends3['aria-expanded'] = latest.current.state.isOpen, _extends3['aria-haspopup'] = 'listbox', _extends3['aria-labelledby'] = rest && rest['aria-label'] ? undefined : "" + elementIds.labelId, _extends3.id = elementIds.toggleButtonId, _extends3.role = 'combobox', _extends3.tabIndex = 0, _extends3.onBlur = callAllEventHandlers(onBlur, toggleButtonHandleBlur), _extends3), rest);
      if (!rest.disabled) {
        /* istanbul ignore if (react-native) */
        {
          toggleProps.onClick = callAllEventHandlers(onClick, toggleButtonHandleClick);
          toggleProps.onKeyDown = callAllEventHandlers(onKeyDown, toggleButtonHandleKeyDown);
        }
      }
      setGetterPropCallInfo('getToggleButtonProps', suppressRefError, refKey, toggleButtonRef);
      return toggleProps;
    }, [dispatch, elementIds, latest, mouseAndTouchTrackers, setGetterPropCallInfo, toggleButtonKeyDownHandlers]);
    var getItemProps = React.useCallback(function (_temp6) {
      var _extends4;
      var _ref6 = _temp6 === void 0 ? {} : _temp6,
        itemProp = _ref6.item,
        indexProp = _ref6.index,
        onMouseMove = _ref6.onMouseMove,
        onClick = _ref6.onClick,
        onMouseDown = _ref6.onMouseDown;
        _ref6.onPress;
        var _ref6$refKey = _ref6.refKey,
        refKey = _ref6$refKey === void 0 ? 'ref' : _ref6$refKey,
        disabledProp = _ref6.disabled,
        ref = _ref6.ref,
        rest = _objectWithoutPropertiesLoose(_ref6, _excluded4$1);
      if (disabledProp !== undefined) {
        console.warn('Passing "disabled" as an argument to getItemProps is not supported anymore. Please use the isItemDisabled prop from useSelect.');
      }
      var _latest$current = latest.current,
        latestState = _latest$current.state,
        latestProps = _latest$current.props;
      var _getItemAndIndex = getItemAndIndex(itemProp, indexProp, latestProps.items, 'Pass either item or index to getItemProps!'),
        item = _getItemAndIndex[0],
        index = _getItemAndIndex[1];
      var disabled = latestProps.isItemDisabled(item, index);
      var itemHandleMouseMove = function itemHandleMouseMove() {
        if (mouseAndTouchTrackers.isTouchEnd || index === latestState.highlightedIndex) {
          return;
        }
        shouldScrollRef.current = false;
        dispatch({
          type: ItemMouseMove$1,
          index: index,
          disabled: disabled
        });
      };
      var itemHandleClick = function itemHandleClick() {
        dispatch({
          type: ItemClick$1,
          index: index
        });
      };
      var itemHandleMouseDown = function itemHandleMouseDown(e) {
        return e.preventDefault();
      }; // keep focus on the toggle after item click select.

      var itemProps = _extends((_extends4 = {}, _extends4[refKey] = handleRefs(ref, function (itemNode) {
        if (itemNode) {
          itemRefs.current[elementIds.getItemId(index)] = itemNode;
        }
      }), _extends4['aria-disabled'] = disabled, _extends4['aria-selected'] = item === latestState.selectedItem, _extends4.id = elementIds.getItemId(index), _extends4.role = 'option', _extends4), rest);
      if (!disabled) {
        /* istanbul ignore next (react-native) */
        {
          itemProps.onClick = callAllEventHandlers(onClick, itemHandleClick);
        }
      }
      itemProps.onMouseMove = callAllEventHandlers(onMouseMove, itemHandleMouseMove);
      itemProps.onMouseDown = callAllEventHandlers(onMouseDown, itemHandleMouseDown);
      return itemProps;
    }, [latest, elementIds, mouseAndTouchTrackers, shouldScrollRef, dispatch]);
    return {
      // prop getters.
      getToggleButtonProps: getToggleButtonProps,
      getLabelProps: getLabelProps,
      getMenuProps: getMenuProps,
      getItemProps: getItemProps,
      // actions.
      toggleMenu: toggleMenu,
      openMenu: openMenu,
      closeMenu: closeMenu,
      setHighlightedIndex: setHighlightedIndex,
      selectItem: selectItem,
      reset: reset,
      setInputValue: setInputValue,
      // state.
      highlightedIndex: highlightedIndex,
      isOpen: isOpen,
      selectedItem: selectedItem,
      inputValue: inputValue
    };
  }

  var InputKeyDownArrowDown = '__input_keydown_arrow_down__' ;
  var InputKeyDownArrowUp = '__input_keydown_arrow_up__' ;
  var InputKeyDownEscape = '__input_keydown_escape__' ;
  var InputKeyDownHome = '__input_keydown_home__' ;
  var InputKeyDownEnd = '__input_keydown_end__' ;
  var InputKeyDownPageUp = '__input_keydown_page_up__' ;
  var InputKeyDownPageDown = '__input_keydown_page_down__' ;
  var InputKeyDownEnter = '__input_keydown_enter__' ;
  var InputChange = '__input_change__' ;
  var InputBlur = '__input_blur__' ;
  var InputClick = '__input_click__' ;
  var MenuMouseLeave = '__menu_mouse_leave__' ;
  var ItemMouseMove = '__item_mouse_move__' ;
  var ItemClick = '__item_click__' ;
  var ToggleButtonClick = '__togglebutton_click__' ;
  var FunctionToggleMenu = '__function_toggle_menu__' ;
  var FunctionOpenMenu = '__function_open_menu__' ;
  var FunctionCloseMenu = '__function_close_menu__' ;
  var FunctionSetHighlightedIndex = '__function_set_highlighted_index__' ;
  var FunctionSelectItem = '__function_select_item__' ;
  var FunctionSetInputValue = '__function_set_input_value__' ;
  var FunctionReset$1 = '__function_reset__' ;
  var ControlledPropUpdatedSelectedItem = '__controlled_prop_updated_selected_item__' ;

  var stateChangeTypes$2 = /*#__PURE__*/Object.freeze({
    __proto__: null,
    ControlledPropUpdatedSelectedItem: ControlledPropUpdatedSelectedItem,
    FunctionCloseMenu: FunctionCloseMenu,
    FunctionOpenMenu: FunctionOpenMenu,
    FunctionReset: FunctionReset$1,
    FunctionSelectItem: FunctionSelectItem,
    FunctionSetHighlightedIndex: FunctionSetHighlightedIndex,
    FunctionSetInputValue: FunctionSetInputValue,
    FunctionToggleMenu: FunctionToggleMenu,
    InputBlur: InputBlur,
    InputChange: InputChange,
    InputClick: InputClick,
    InputKeyDownArrowDown: InputKeyDownArrowDown,
    InputKeyDownArrowUp: InputKeyDownArrowUp,
    InputKeyDownEnd: InputKeyDownEnd,
    InputKeyDownEnter: InputKeyDownEnter,
    InputKeyDownEscape: InputKeyDownEscape,
    InputKeyDownHome: InputKeyDownHome,
    InputKeyDownPageDown: InputKeyDownPageDown,
    InputKeyDownPageUp: InputKeyDownPageUp,
    ItemClick: ItemClick,
    ItemMouseMove: ItemMouseMove,
    MenuMouseLeave: MenuMouseLeave,
    ToggleButtonClick: ToggleButtonClick
  });

  function getInitialState$2(props) {
    var initialState = getInitialState$3(props);
    var selectedItem = initialState.selectedItem;
    var inputValue = initialState.inputValue;
    if (inputValue === '' && selectedItem && props.defaultInputValue === undefined && props.initialInputValue === undefined && props.inputValue === undefined) {
      inputValue = props.itemToString(selectedItem);
    }
    return _extends({}, initialState, {
      inputValue: inputValue
    });
  }
  var propTypes$2 = _extends({}, propTypes$4, {
    items: PropTypes.array.isRequired,
    isItemDisabled: PropTypes.func,
    inputValue: PropTypes.string,
    defaultInputValue: PropTypes.string,
    initialInputValue: PropTypes.string,
    inputId: PropTypes.string,
    onInputValueChange: PropTypes.func
  });

  /**
   * The useCombobox version of useControlledReducer, which also
   * checks if the controlled prop selectedItem changed between
   * renders. If so, it will also update inputValue with its
   * string equivalent. It uses the common useEnhancedReducer to
   * compute the rest of the state.
   *
   * @param {Function} reducer Reducer function from downshift.
   * @param {Object} props The hook props, also passed to createInitialState.
   * @param {Function} createInitialState Function that returns the initial state.
   * @param {Function} isStateEqual Function that checks if a previous state is equal to the next.
   * @returns {Array} An array with the state and an action dispatcher.
   */
  function useControlledReducer(reducer, props, createInitialState, isStateEqual) {
    var previousSelectedItemRef = React.useRef();
    var _useEnhancedReducer = useEnhancedReducer(reducer, props, createInitialState, isStateEqual),
      state = _useEnhancedReducer[0],
      dispatch = _useEnhancedReducer[1];
    var isInitialMount = useIsInitialMount();
    React.useEffect(function () {
      if (!isControlledProp(props, 'selectedItem')) {
        return;
      }
      if (!isInitialMount // on first mount we already have the proper inputValue for a initial selected item.
      ) {
        var shouldCallDispatch = props.itemToKey(props.selectedItem) !== props.itemToKey(previousSelectedItemRef.current);
        if (shouldCallDispatch) {
          dispatch({
            type: ControlledPropUpdatedSelectedItem,
            inputValue: props.itemToString(props.selectedItem)
          });
        }
      }
      previousSelectedItemRef.current = state.selectedItem === previousSelectedItemRef.current ? props.selectedItem : state.selectedItem;
      // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [state.selectedItem, props.selectedItem]);
    return [getState(state, props), dispatch];
  }
  var defaultProps$1 = _extends({}, defaultProps$3, {
    isItemDisabled: function isItemDisabled() {
      return false;
    }
  });

  /* eslint-disable complexity */
  function downshiftUseComboboxReducer(state, props, action) {
    var _props$items;
    var type = action.type,
      altKey = action.altKey;
    var changes;
    switch (type) {
      case ItemClick:
        changes = {
          isOpen: getDefaultValue$1(props, 'isOpen', defaultStateValues$1),
          highlightedIndex: getDefaultHighlightedIndex(props),
          selectedItem: props.items[action.index],
          inputValue: props.itemToString(props.items[action.index])
        };
        break;
      case InputKeyDownArrowDown:
        if (state.isOpen) {
          changes = {
            highlightedIndex: getHighlightedIndex(state.highlightedIndex, 1, props.items, props.isItemDisabled, true)
          };
        } else {
          changes = {
            highlightedIndex: altKey && state.selectedItem == null ? -1 : getHighlightedIndexOnOpen(props, state, 1),
            isOpen: props.items.length >= 0
          };
        }
        break;
      case InputKeyDownArrowUp:
        if (state.isOpen) {
          if (altKey) {
            changes = getChangesOnSelection(props, state.highlightedIndex);
          } else {
            changes = {
              highlightedIndex: getHighlightedIndex(state.highlightedIndex, -1, props.items, props.isItemDisabled, true)
            };
          }
        } else {
          changes = {
            highlightedIndex: getHighlightedIndexOnOpen(props, state, -1),
            isOpen: props.items.length >= 0
          };
        }
        break;
      case InputKeyDownEnter:
        changes = getChangesOnSelection(props, state.highlightedIndex);
        break;
      case InputKeyDownEscape:
        changes = _extends({
          isOpen: false,
          highlightedIndex: -1
        }, !state.isOpen && {
          selectedItem: null,
          inputValue: ''
        });
        break;
      case InputKeyDownPageUp:
        changes = {
          highlightedIndex: getHighlightedIndex(state.highlightedIndex, -10, props.items, props.isItemDisabled, true)
        };
        break;
      case InputKeyDownPageDown:
        changes = {
          highlightedIndex: getHighlightedIndex(state.highlightedIndex, 10, props.items, props.isItemDisabled, true)
        };
        break;
      case InputKeyDownHome:
        changes = {
          highlightedIndex: getNonDisabledIndex(0, false, props.items, props.isItemDisabled)
        };
        break;
      case InputKeyDownEnd:
        changes = {
          highlightedIndex: getNonDisabledIndex(props.items.length - 1, true, props.items, props.isItemDisabled)
        };
        break;
      case InputBlur:
        changes = _extends({
          isOpen: false,
          highlightedIndex: -1
        }, state.highlightedIndex >= 0 && ((_props$items = props.items) == null ? void 0 : _props$items.length) && action.selectItem && {
          selectedItem: props.items[state.highlightedIndex],
          inputValue: props.itemToString(props.items[state.highlightedIndex])
        });
        break;
      case InputChange:
        changes = {
          isOpen: true,
          highlightedIndex: getDefaultHighlightedIndex(props),
          inputValue: action.inputValue
        };
        break;
      case InputClick:
        changes = {
          isOpen: !state.isOpen,
          highlightedIndex: state.isOpen ? -1 : getHighlightedIndexOnOpen(props, state, 0)
        };
        break;
      case FunctionSelectItem:
        changes = {
          selectedItem: action.selectedItem,
          inputValue: props.itemToString(action.selectedItem)
        };
        break;
      case ControlledPropUpdatedSelectedItem:
        changes = {
          inputValue: action.inputValue
        };
        break;
      default:
        return downshiftCommonReducer(state, props, action, stateChangeTypes$2);
    }
    return _extends({}, state, changes);
  }
  /* eslint-enable complexity */

  var _excluded$2 = ["onMouseLeave", "refKey", "ref"],
    _excluded2$2 = ["item", "index", "refKey", "ref", "onMouseMove", "onMouseDown", "onClick", "onPress", "disabled"],
    _excluded3$1 = ["onClick", "onPress", "refKey", "ref"],
    _excluded4 = ["onKeyDown", "onChange", "onInput", "onBlur", "onChangeText", "onClick", "refKey", "ref"];
  useCombobox.stateChangeTypes = stateChangeTypes$2;
  function useCombobox(userProps) {
    if (userProps === void 0) {
      userProps = {};
    }
    validatePropTypes$1(userProps, useCombobox, propTypes$2);
    // Props defaults and destructuring.
    var props = _extends({}, defaultProps$1, userProps);
    var items = props.items,
      scrollIntoView = props.scrollIntoView,
      environment = props.environment,
      getA11yStatusMessage = props.getA11yStatusMessage;
    // Initial state depending on controlled props.
    var _useControlledReducer = useControlledReducer(downshiftUseComboboxReducer, props, getInitialState$2, isDropdownsStateEqual),
      state = _useControlledReducer[0],
      dispatch = _useControlledReducer[1];
    var isOpen = state.isOpen,
      highlightedIndex = state.highlightedIndex,
      selectedItem = state.selectedItem,
      inputValue = state.inputValue;

    // Element refs.
    var menuRef = React.useRef(null);
    var itemRefs = React.useRef({});
    var inputRef = React.useRef(null);
    var toggleButtonRef = React.useRef(null);
    var isInitialMount = useIsInitialMount();

    // prevent id re-generation between renders.
    var elementIds = useElementIds$1(props);
    // used to keep track of how many items we had on previous cycle.
    var previousResultCountRef = React.useRef();
    // utility callback to get item element.
    var latest = useLatestRef({
      state: state,
      props: props
    });
    var getItemNodeFromIndex = React.useCallback(function (index) {
      return itemRefs.current[elementIds.getItemId(index)];
    }, [elementIds]);

    // Effects.
    // Adds an a11y aria live status message if getA11yStatusMessage is passed.
    useA11yMessageStatus(getA11yStatusMessage, state, [isOpen, highlightedIndex, selectedItem, inputValue], environment);
    // Scroll on highlighted item if change comes from keyboard.
    var shouldScrollRef = useScrollIntoView({
      menuElement: menuRef.current,
      highlightedIndex: highlightedIndex,
      isOpen: isOpen,
      itemRefs: itemRefs,
      scrollIntoView: scrollIntoView,
      getItemNodeFromIndex: getItemNodeFromIndex
    });
    useControlPropsValidator({
      props: props,
      state: state
    });
    // Focus the input on first render if required.
    React.useEffect(function () {
      var focusOnOpen = getInitialValue$1(props, 'isOpen', defaultStateValues$1);
      if (focusOnOpen && inputRef.current) {
        inputRef.current.focus();
      }
      // eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);
    React.useEffect(function () {
      if (!isInitialMount) {
        previousResultCountRef.current = items.length;
      }
    });
    var handleBlurInTracker = React.useCallback(function handleBlur() {
      if (latest.current.state.isOpen) {
        dispatch({
          type: InputBlur
        });
      }
    }, [dispatch, latest]);
    var downshiftRefs = React.useMemo(function () {
      return [menuRef, toggleButtonRef, inputRef];
    }, []);
    var mouseAndTouchTrackers = useMouseAndTouchTracker(environment, handleBlurInTracker, downshiftRefs);
    var setGetterPropCallInfo = useGetterPropsCalledChecker('getInputProps', 'getMenuProps');
    // Reset itemRefs on close.
    React.useEffect(function () {
      if (!isOpen) {
        itemRefs.current = {};
      }
    }, [isOpen]);
    // Reset itemRefs on close.
    React.useEffect(function () {
      var _inputRef$current;
      if (!isOpen || !(environment != null && environment.document) || !(inputRef != null && (_inputRef$current = inputRef.current) != null && _inputRef$current.focus)) {
        return;
      }
      if (environment.document.activeElement !== inputRef.current) {
        inputRef.current.focus();
      }
    }, [isOpen, environment]);

    /* Event handler functions */
    var inputKeyDownHandlers = React.useMemo(function () {
      return {
        ArrowDown: function ArrowDown(event) {
          event.preventDefault();
          dispatch({
            type: InputKeyDownArrowDown,
            altKey: event.altKey
          });
        },
        ArrowUp: function ArrowUp(event) {
          event.preventDefault();
          dispatch({
            type: InputKeyDownArrowUp,
            altKey: event.altKey
          });
        },
        Home: function Home(event) {
          if (!latest.current.state.isOpen) {
            return;
          }
          event.preventDefault();
          dispatch({
            type: InputKeyDownHome
          });
        },
        End: function End(event) {
          if (!latest.current.state.isOpen) {
            return;
          }
          event.preventDefault();
          dispatch({
            type: InputKeyDownEnd
          });
        },
        Escape: function Escape(event) {
          var latestState = latest.current.state;
          if (latestState.isOpen || latestState.inputValue || latestState.selectedItem || latestState.highlightedIndex > -1) {
            event.preventDefault();
            dispatch({
              type: InputKeyDownEscape
            });
          }
        },
        Enter: function Enter(event) {
          var latestState = latest.current.state;
          // if closed or no highlighted index, do nothing.
          if (!latestState.isOpen || event.which === 229 // if IME composing, wait for next Enter keydown event.
          ) {
            return;
          }
          event.preventDefault();
          dispatch({
            type: InputKeyDownEnter
          });
        },
        PageUp: function PageUp(event) {
          if (latest.current.state.isOpen) {
            event.preventDefault();
            dispatch({
              type: InputKeyDownPageUp
            });
          }
        },
        PageDown: function PageDown(event) {
          if (latest.current.state.isOpen) {
            event.preventDefault();
            dispatch({
              type: InputKeyDownPageDown
            });
          }
        }
      };
    }, [dispatch, latest]);

    // Getter props.
    var getLabelProps = React.useCallback(function (labelProps) {
      return _extends({
        id: elementIds.labelId,
        htmlFor: elementIds.inputId
      }, labelProps);
    }, [elementIds]);
    var getMenuProps = React.useCallback(function (_temp, _temp2) {
      var _extends2;
      var _ref = _temp === void 0 ? {} : _temp,
        onMouseLeave = _ref.onMouseLeave,
        _ref$refKey = _ref.refKey,
        refKey = _ref$refKey === void 0 ? 'ref' : _ref$refKey,
        ref = _ref.ref,
        rest = _objectWithoutPropertiesLoose(_ref, _excluded$2);
      var _ref2 = _temp2 === void 0 ? {} : _temp2,
        _ref2$suppressRefErro = _ref2.suppressRefError,
        suppressRefError = _ref2$suppressRefErro === void 0 ? false : _ref2$suppressRefErro;
      setGetterPropCallInfo('getMenuProps', suppressRefError, refKey, menuRef);
      return _extends((_extends2 = {}, _extends2[refKey] = handleRefs(ref, function (menuNode) {
        menuRef.current = menuNode;
      }), _extends2.id = elementIds.menuId, _extends2.role = 'listbox', _extends2['aria-labelledby'] = rest && rest['aria-label'] ? undefined : "" + elementIds.labelId, _extends2.onMouseLeave = callAllEventHandlers(onMouseLeave, function () {
        dispatch({
          type: MenuMouseLeave
        });
      }), _extends2), rest);
    }, [dispatch, setGetterPropCallInfo, elementIds]);
    var getItemProps = React.useCallback(function (_temp3) {
      var _extends3, _ref4;
      var _ref3 = _temp3 === void 0 ? {} : _temp3,
        itemProp = _ref3.item,
        indexProp = _ref3.index,
        _ref3$refKey = _ref3.refKey,
        refKey = _ref3$refKey === void 0 ? 'ref' : _ref3$refKey,
        ref = _ref3.ref,
        onMouseMove = _ref3.onMouseMove,
        onMouseDown = _ref3.onMouseDown,
        onClick = _ref3.onClick;
        _ref3.onPress;
        var disabledProp = _ref3.disabled,
        rest = _objectWithoutPropertiesLoose(_ref3, _excluded2$2);
      if (disabledProp !== undefined) {
        console.warn('Passing "disabled" as an argument to getItemProps is not supported anymore. Please use the isItemDisabled prop from useCombobox.');
      }
      var _latest$current = latest.current,
        latestProps = _latest$current.props,
        latestState = _latest$current.state;
      var _getItemAndIndex = getItemAndIndex(itemProp, indexProp, latestProps.items, 'Pass either item or index to getItemProps!'),
        item = _getItemAndIndex[0],
        index = _getItemAndIndex[1];
      var disabled = latestProps.isItemDisabled(item, index);
      var onSelectKey = 'onClick';
      var customClickHandler = onClick;
      var itemHandleMouseMove = function itemHandleMouseMove() {
        if (mouseAndTouchTrackers.isTouchEnd || index === latestState.highlightedIndex) {
          return;
        }
        shouldScrollRef.current = false;
        dispatch({
          type: ItemMouseMove,
          index: index,
          disabled: disabled
        });
      };
      var itemHandleClick = function itemHandleClick() {
        dispatch({
          type: ItemClick,
          index: index
        });
      };
      var itemHandleMouseDown = function itemHandleMouseDown(e) {
        return e.preventDefault();
      }; // keep focus on the input after item click select.

      return _extends((_extends3 = {}, _extends3[refKey] = handleRefs(ref, function (itemNode) {
        if (itemNode) {
          itemRefs.current[elementIds.getItemId(index)] = itemNode;
        }
      }), _extends3['aria-disabled'] = disabled, _extends3['aria-selected'] = index === latestState.highlightedIndex, _extends3.id = elementIds.getItemId(index), _extends3.role = 'option', _extends3), !disabled && (_ref4 = {}, _ref4[onSelectKey] = callAllEventHandlers(customClickHandler, itemHandleClick), _ref4), {
        onMouseMove: callAllEventHandlers(onMouseMove, itemHandleMouseMove),
        onMouseDown: callAllEventHandlers(onMouseDown, itemHandleMouseDown)
      }, rest);
    }, [dispatch, elementIds, latest, mouseAndTouchTrackers, shouldScrollRef]);
    var getToggleButtonProps = React.useCallback(function (_temp4) {
      var _extends4;
      var _ref5 = _temp4 === void 0 ? {} : _temp4,
        onClick = _ref5.onClick;
        _ref5.onPress;
        var _ref5$refKey = _ref5.refKey,
        refKey = _ref5$refKey === void 0 ? 'ref' : _ref5$refKey,
        ref = _ref5.ref,
        rest = _objectWithoutPropertiesLoose(_ref5, _excluded3$1);
      var latestState = latest.current.state;
      var toggleButtonHandleClick = function toggleButtonHandleClick() {
        dispatch({
          type: ToggleButtonClick
        });
      };
      return _extends((_extends4 = {}, _extends4[refKey] = handleRefs(ref, function (toggleButtonNode) {
        toggleButtonRef.current = toggleButtonNode;
      }), _extends4['aria-controls'] = elementIds.menuId, _extends4['aria-expanded'] = latestState.isOpen, _extends4.id = elementIds.toggleButtonId, _extends4.tabIndex = -1, _extends4), !rest.disabled && _extends({}, {
        onClick: callAllEventHandlers(onClick, toggleButtonHandleClick)
      }), rest);
    }, [dispatch, latest, elementIds]);
    var getInputProps = React.useCallback(function (_temp5, _temp6) {
      var _extends5;
      var _ref6 = _temp5 === void 0 ? {} : _temp5,
        onKeyDown = _ref6.onKeyDown,
        onChange = _ref6.onChange,
        onInput = _ref6.onInput,
        onBlur = _ref6.onBlur;
        _ref6.onChangeText;
        var onClick = _ref6.onClick,
        _ref6$refKey = _ref6.refKey,
        refKey = _ref6$refKey === void 0 ? 'ref' : _ref6$refKey,
        ref = _ref6.ref,
        rest = _objectWithoutPropertiesLoose(_ref6, _excluded4);
      var _ref7 = _temp6 === void 0 ? {} : _temp6,
        _ref7$suppressRefErro = _ref7.suppressRefError,
        suppressRefError = _ref7$suppressRefErro === void 0 ? false : _ref7$suppressRefErro;
      setGetterPropCallInfo('getInputProps', suppressRefError, refKey, inputRef);
      var latestState = latest.current.state;
      var inputHandleKeyDown = function inputHandleKeyDown(event) {
        var key = normalizeArrowKey(event);
        if (key && inputKeyDownHandlers[key]) {
          inputKeyDownHandlers[key](event);
        }
      };
      var inputHandleChange = function inputHandleChange(event) {
        dispatch({
          type: InputChange,
          inputValue: event.target.value
        });
      };
      var inputHandleBlur = function inputHandleBlur(event) {
        /* istanbul ignore else */
        if (environment != null && environment.document && latestState.isOpen && !mouseAndTouchTrackers.isMouseDown) {
          var isBlurByTabChange = event.relatedTarget === null && environment.document.activeElement !== environment.document.body;
          dispatch({
            type: InputBlur,
            selectItem: !isBlurByTabChange
          });
        }
      };
      var inputHandleClick = function inputHandleClick() {
        dispatch({
          type: InputClick
        });
      };

      /* istanbul ignore next (preact) */
      var onChangeKey = 'onInput' ;
      var eventHandlers = {};
      if (!rest.disabled) {
        var _eventHandlers;
        eventHandlers = (_eventHandlers = {}, _eventHandlers[onChangeKey] = callAllEventHandlers(onChange, onInput, inputHandleChange), _eventHandlers.onKeyDown = callAllEventHandlers(onKeyDown, inputHandleKeyDown), _eventHandlers.onBlur = callAllEventHandlers(onBlur, inputHandleBlur), _eventHandlers.onClick = callAllEventHandlers(onClick, inputHandleClick), _eventHandlers);
      }
      return _extends((_extends5 = {}, _extends5[refKey] = handleRefs(ref, function (inputNode) {
        inputRef.current = inputNode;
      }), _extends5['aria-activedescendant'] = latestState.isOpen && latestState.highlightedIndex > -1 ? elementIds.getItemId(latestState.highlightedIndex) : '', _extends5['aria-autocomplete'] = 'list', _extends5['aria-controls'] = elementIds.menuId, _extends5['aria-expanded'] = latestState.isOpen, _extends5['aria-labelledby'] = rest && rest['aria-label'] ? undefined : elementIds.labelId, _extends5.autoComplete = 'off', _extends5.id = elementIds.inputId, _extends5.role = 'combobox', _extends5.value = latestState.inputValue, _extends5), eventHandlers, rest);
    }, [dispatch, elementIds, environment, inputKeyDownHandlers, latest, mouseAndTouchTrackers, setGetterPropCallInfo]);

    // returns
    var toggleMenu = React.useCallback(function () {
      dispatch({
        type: FunctionToggleMenu
      });
    }, [dispatch]);
    var closeMenu = React.useCallback(function () {
      dispatch({
        type: FunctionCloseMenu
      });
    }, [dispatch]);
    var openMenu = React.useCallback(function () {
      dispatch({
        type: FunctionOpenMenu
      });
    }, [dispatch]);
    var setHighlightedIndex = React.useCallback(function (newHighlightedIndex) {
      dispatch({
        type: FunctionSetHighlightedIndex,
        highlightedIndex: newHighlightedIndex
      });
    }, [dispatch]);
    var selectItem = React.useCallback(function (newSelectedItem) {
      dispatch({
        type: FunctionSelectItem,
        selectedItem: newSelectedItem
      });
    }, [dispatch]);
    var setInputValue = React.useCallback(function (newInputValue) {
      dispatch({
        type: FunctionSetInputValue,
        inputValue: newInputValue
      });
    }, [dispatch]);
    var reset = React.useCallback(function () {
      dispatch({
        type: FunctionReset$1
      });
    }, [dispatch]);
    return {
      // prop getters.
      getItemProps: getItemProps,
      getLabelProps: getLabelProps,
      getMenuProps: getMenuProps,
      getInputProps: getInputProps,
      getToggleButtonProps: getToggleButtonProps,
      // actions.
      toggleMenu: toggleMenu,
      openMenu: openMenu,
      closeMenu: closeMenu,
      setHighlightedIndex: setHighlightedIndex,
      setInputValue: setInputValue,
      selectItem: selectItem,
      reset: reset,
      // state.
      highlightedIndex: highlightedIndex,
      isOpen: isOpen,
      selectedItem: selectedItem,
      inputValue: inputValue
    };
  }

  var defaultStateValues = {
    activeIndex: -1,
    selectedItems: []
  };

  /**
   * Returns the initial value for a state key in the following order:
   * 1. controlled prop, 2. initial prop, 3. default prop, 4. default
   * value from Downshift.
   *
   * @param {Object} props Props passed to the hook.
   * @param {string} propKey Props key to generate the value for.
   * @returns {any} The initial value for that prop.
   */
  function getInitialValue(props, propKey) {
    return getInitialValue$1(props, propKey, defaultStateValues);
  }

  /**
   * Returns the default value for a state key in the following order:
   * 1. controlled prop, 2. default prop, 3. default value from Downshift.
   *
   * @param {Object} props Props passed to the hook.
   * @param {string} propKey Props key to generate the value for.
   * @returns {any} The initial value for that prop.
   */
  function getDefaultValue(props, propKey) {
    return getDefaultValue$1(props, propKey, defaultStateValues);
  }

  /**
   * Gets the initial state based on the provided props. It uses initial, default
   * and controlled props related to state in order to compute the initial value.
   *
   * @param {Object} props Props passed to the hook.
   * @returns {Object} The initial state.
   */
  function getInitialState$1(props) {
    var activeIndex = getInitialValue(props, 'activeIndex');
    var selectedItems = getInitialValue(props, 'selectedItems');
    return {
      activeIndex: activeIndex,
      selectedItems: selectedItems
    };
  }

  /**
   * Returns true if dropdown keydown operation is permitted. Should not be
   * allowed on keydown with modifier keys (ctrl, alt, shift, meta), on
   * input element with text content that is either highlighted or selection
   * cursor is not at the starting position.
   *
   * @param {KeyboardEvent} event The event from keydown.
   * @returns {boolean} Whether the operation is allowed.
   */
  function isKeyDownOperationPermitted(event) {
    if (event.shiftKey || event.metaKey || event.ctrlKey || event.altKey) {
      return false;
    }
    var element = event.target;
    if (element instanceof HTMLInputElement &&
    // if element is a text input
    element.value !== '' && (
    // and we have text in it
    // and cursor is either not at the start or is currently highlighting text.
    element.selectionStart !== 0 || element.selectionEnd !== 0)) {
      return false;
    }
    return true;
  }

  /**
   * Check if a state is equal for taglist, by comparing active index and selected items.
   * Used by useSelect and useCombobox.
   *
   * @param {Object} prevState
   * @param {Object} newState
   * @returns {boolean} Wheather the states are deeply equal.
   */
  function isStateEqual$1(prevState, newState) {
    return prevState.selectedItems === newState.selectedItems && prevState.activeIndex === newState.activeIndex;
  }
  var propTypes$1 = {
    stateReducer: propTypes$4.stateReducer,
    itemToKey: propTypes$4.itemToKey,
    environment: propTypes$4.environment,
    selectedItems: PropTypes.array,
    initialSelectedItems: PropTypes.array,
    defaultSelectedItems: PropTypes.array,
    getA11yStatusMessage: PropTypes.func,
    activeIndex: PropTypes.number,
    initialActiveIndex: PropTypes.number,
    defaultActiveIndex: PropTypes.number,
    onActiveIndexChange: PropTypes.func,
    onSelectedItemsChange: PropTypes.func,
    keyNavigationNext: PropTypes.string,
    keyNavigationPrevious: PropTypes.string
  };
  var defaultProps = {
    itemToKey: defaultProps$3.itemToKey,
    stateReducer: defaultProps$3.stateReducer,
    environment: defaultProps$3.environment,
    keyNavigationNext: 'ArrowRight',
    keyNavigationPrevious: 'ArrowLeft'
  };

  // eslint-disable-next-line import/no-mutable-exports
  var validatePropTypes = noop;
  /* istanbul ignore next */
  {
    validatePropTypes = function validatePropTypes(options, caller) {
      PropTypes.checkPropTypes(propTypes$1, options, 'prop', caller.name);
    };
  }

  var SelectedItemClick = '__selected_item_click__' ;
  var SelectedItemKeyDownDelete = '__selected_item_keydown_delete__' ;
  var SelectedItemKeyDownBackspace = '__selected_item_keydown_backspace__' ;
  var SelectedItemKeyDownNavigationNext = '__selected_item_keydown_navigation_next__' ;
  var SelectedItemKeyDownNavigationPrevious = '__selected_item_keydown_navigation_previous__' ;
  var DropdownKeyDownNavigationPrevious = '__dropdown_keydown_navigation_previous__' ;
  var DropdownKeyDownBackspace = '__dropdown_keydown_backspace__' ;
  var DropdownClick = '__dropdown_click__' ;
  var FunctionAddSelectedItem = '__function_add_selected_item__' ;
  var FunctionRemoveSelectedItem = '__function_remove_selected_item__' ;
  var FunctionSetSelectedItems = '__function_set_selected_items__' ;
  var FunctionSetActiveIndex = '__function_set_active_index__' ;
  var FunctionReset = '__function_reset__' ;

  var stateChangeTypes$1 = /*#__PURE__*/Object.freeze({
    __proto__: null,
    DropdownClick: DropdownClick,
    DropdownKeyDownBackspace: DropdownKeyDownBackspace,
    DropdownKeyDownNavigationPrevious: DropdownKeyDownNavigationPrevious,
    FunctionAddSelectedItem: FunctionAddSelectedItem,
    FunctionRemoveSelectedItem: FunctionRemoveSelectedItem,
    FunctionReset: FunctionReset,
    FunctionSetActiveIndex: FunctionSetActiveIndex,
    FunctionSetSelectedItems: FunctionSetSelectedItems,
    SelectedItemClick: SelectedItemClick,
    SelectedItemKeyDownBackspace: SelectedItemKeyDownBackspace,
    SelectedItemKeyDownDelete: SelectedItemKeyDownDelete,
    SelectedItemKeyDownNavigationNext: SelectedItemKeyDownNavigationNext,
    SelectedItemKeyDownNavigationPrevious: SelectedItemKeyDownNavigationPrevious
  });

  /* eslint-disable complexity */
  function downshiftMultipleSelectionReducer(state, props, action) {
    var type = action.type,
      index = action.index,
      selectedItem = action.selectedItem;
    var activeIndex = state.activeIndex,
      selectedItems = state.selectedItems;
    var changes;
    switch (type) {
      case SelectedItemClick:
        changes = {
          activeIndex: index
        };
        break;
      case SelectedItemKeyDownNavigationPrevious:
        changes = {
          activeIndex: activeIndex - 1 < 0 ? 0 : activeIndex - 1
        };
        break;
      case SelectedItemKeyDownNavigationNext:
        changes = {
          activeIndex: activeIndex + 1 >= selectedItems.length ? -1 : activeIndex + 1
        };
        break;
      case SelectedItemKeyDownBackspace:
      case SelectedItemKeyDownDelete:
        {
          if (activeIndex < 0) {
            break;
          }
          var newActiveIndex = activeIndex;
          if (selectedItems.length === 1) {
            newActiveIndex = -1;
          } else if (activeIndex === selectedItems.length - 1) {
            newActiveIndex = selectedItems.length - 2;
          }
          changes = _extends({
            selectedItems: [].concat(selectedItems.slice(0, activeIndex), selectedItems.slice(activeIndex + 1))
          }, {
            activeIndex: newActiveIndex
          });
          break;
        }
      case DropdownKeyDownNavigationPrevious:
        changes = {
          activeIndex: selectedItems.length - 1
        };
        break;
      case DropdownKeyDownBackspace:
        changes = {
          selectedItems: selectedItems.slice(0, selectedItems.length - 1)
        };
        break;
      case FunctionAddSelectedItem:
        changes = {
          selectedItems: [].concat(selectedItems, [selectedItem])
        };
        break;
      case DropdownClick:
        changes = {
          activeIndex: -1
        };
        break;
      case FunctionRemoveSelectedItem:
        {
          var _newActiveIndex = activeIndex;
          var selectedItemIndex = selectedItems.findIndex(function (item) {
            return props.itemToKey(item) === props.itemToKey(selectedItem);
          });
          if (selectedItemIndex < 0) {
            break;
          }
          if (selectedItems.length === 1) {
            _newActiveIndex = -1;
          } else if (selectedItemIndex === selectedItems.length - 1) {
            _newActiveIndex = selectedItems.length - 2;
          }
          changes = {
            selectedItems: [].concat(selectedItems.slice(0, selectedItemIndex), selectedItems.slice(selectedItemIndex + 1)),
            activeIndex: _newActiveIndex
          };
          break;
        }
      case FunctionSetSelectedItems:
        {
          var newSelectedItems = action.selectedItems;
          changes = {
            selectedItems: newSelectedItems
          };
          break;
        }
      case FunctionSetActiveIndex:
        {
          var _newActiveIndex2 = action.activeIndex;
          changes = {
            activeIndex: _newActiveIndex2
          };
          break;
        }
      case FunctionReset:
        changes = {
          activeIndex: getDefaultValue(props, 'activeIndex'),
          selectedItems: getDefaultValue(props, 'selectedItems')
        };
        break;
      default:
        throw new Error('Reducer called without proper action type.');
    }
    return _extends({}, state, changes);
  }

  var _excluded$1 = ["refKey", "ref", "onClick", "onKeyDown", "selectedItem", "index"],
    _excluded2$1 = ["refKey", "ref", "onKeyDown", "onClick", "preventKeyAction"];
  useMultipleSelection.stateChangeTypes = stateChangeTypes$1;
  function useMultipleSelection(userProps) {
    if (userProps === void 0) {
      userProps = {};
    }
    validatePropTypes(userProps, useMultipleSelection);
    // Props defaults and destructuring.
    var props = _extends({}, defaultProps, userProps);
    var getA11yStatusMessage = props.getA11yStatusMessage,
      environment = props.environment,
      keyNavigationNext = props.keyNavigationNext,
      keyNavigationPrevious = props.keyNavigationPrevious;

    // Reducer init.
    var _useControlledReducer = useControlledReducer$1(downshiftMultipleSelectionReducer, props, getInitialState$1, isStateEqual$1),
      state = _useControlledReducer[0],
      dispatch = _useControlledReducer[1];
    var activeIndex = state.activeIndex,
      selectedItems = state.selectedItems;

    // Refs.
    var isInitialMount = useIsInitialMount();
    var dropdownRef = React.useRef(null);
    var selectedItemRefs = React.useRef();
    selectedItemRefs.current = [];
    var latest = useLatestRef({
      state: state,
      props: props
    });

    // Effects.
    // Adds an a11y aria live status message if getA11yStatusMessage is passed.
    useA11yMessageStatus(getA11yStatusMessage, state, [activeIndex, selectedItems], environment);
    // Sets focus on active item.
    React.useEffect(function () {
      if (isInitialMount) {
        return;
      }
      if (activeIndex === -1 && dropdownRef.current) {
        dropdownRef.current.focus();
      } else if (selectedItemRefs.current[activeIndex]) {
        selectedItemRefs.current[activeIndex].focus();
      }
      // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [activeIndex]);
    useControlPropsValidator({
      props: props,
      state: state
    });
    var setGetterPropCallInfo = useGetterPropsCalledChecker('getDropdownProps');

    // Event handler functions.
    var selectedItemKeyDownHandlers = React.useMemo(function () {
      var _ref;
      return _ref = {}, _ref[keyNavigationPrevious] = function () {
        dispatch({
          type: SelectedItemKeyDownNavigationPrevious
        });
      }, _ref[keyNavigationNext] = function () {
        dispatch({
          type: SelectedItemKeyDownNavigationNext
        });
      }, _ref.Delete = function Delete() {
        dispatch({
          type: SelectedItemKeyDownDelete
        });
      }, _ref.Backspace = function Backspace() {
        dispatch({
          type: SelectedItemKeyDownBackspace
        });
      }, _ref;
    }, [dispatch, keyNavigationNext, keyNavigationPrevious]);
    var dropdownKeyDownHandlers = React.useMemo(function () {
      var _ref2;
      return _ref2 = {}, _ref2[keyNavigationPrevious] = function (event) {
        if (isKeyDownOperationPermitted(event)) {
          dispatch({
            type: DropdownKeyDownNavigationPrevious
          });
        }
      }, _ref2.Backspace = function Backspace(event) {
        if (isKeyDownOperationPermitted(event)) {
          dispatch({
            type: DropdownKeyDownBackspace
          });
        }
      }, _ref2;
    }, [dispatch, keyNavigationPrevious]);

    // Getter props.
    var getSelectedItemProps = React.useCallback(function (_temp) {
      var _extends2;
      var _ref3 = _temp === void 0 ? {} : _temp,
        _ref3$refKey = _ref3.refKey,
        refKey = _ref3$refKey === void 0 ? 'ref' : _ref3$refKey,
        ref = _ref3.ref,
        onClick = _ref3.onClick,
        onKeyDown = _ref3.onKeyDown,
        selectedItemProp = _ref3.selectedItem,
        indexProp = _ref3.index,
        rest = _objectWithoutPropertiesLoose(_ref3, _excluded$1);
      var latestState = latest.current.state;
      var _getItemAndIndex = getItemAndIndex(selectedItemProp, indexProp, latestState.selectedItems, 'Pass either item or index to getSelectedItemProps!'),
        index = _getItemAndIndex[1];
      var isFocusable = index > -1 && index === latestState.activeIndex;
      var selectedItemHandleClick = function selectedItemHandleClick() {
        dispatch({
          type: SelectedItemClick,
          index: index
        });
      };
      var selectedItemHandleKeyDown = function selectedItemHandleKeyDown(event) {
        var key = normalizeArrowKey(event);
        if (key && selectedItemKeyDownHandlers[key]) {
          selectedItemKeyDownHandlers[key](event);
        }
      };
      return _extends((_extends2 = {}, _extends2[refKey] = handleRefs(ref, function (selectedItemNode) {
        if (selectedItemNode) {
          selectedItemRefs.current.push(selectedItemNode);
        }
      }), _extends2.tabIndex = isFocusable ? 0 : -1, _extends2.onClick = callAllEventHandlers(onClick, selectedItemHandleClick), _extends2.onKeyDown = callAllEventHandlers(onKeyDown, selectedItemHandleKeyDown), _extends2), rest);
    }, [dispatch, latest, selectedItemKeyDownHandlers]);
    var getDropdownProps = React.useCallback(function (_temp2, _temp3) {
      var _extends3;
      var _ref4 = _temp2 === void 0 ? {} : _temp2,
        _ref4$refKey = _ref4.refKey,
        refKey = _ref4$refKey === void 0 ? 'ref' : _ref4$refKey,
        ref = _ref4.ref,
        onKeyDown = _ref4.onKeyDown,
        onClick = _ref4.onClick,
        _ref4$preventKeyActio = _ref4.preventKeyAction,
        preventKeyAction = _ref4$preventKeyActio === void 0 ? false : _ref4$preventKeyActio,
        rest = _objectWithoutPropertiesLoose(_ref4, _excluded2$1);
      var _ref5 = _temp3 === void 0 ? {} : _temp3,
        _ref5$suppressRefErro = _ref5.suppressRefError,
        suppressRefError = _ref5$suppressRefErro === void 0 ? false : _ref5$suppressRefErro;
      setGetterPropCallInfo('getDropdownProps', suppressRefError, refKey, dropdownRef);
      var dropdownHandleKeyDown = function dropdownHandleKeyDown(event) {
        var key = normalizeArrowKey(event);
        if (key && dropdownKeyDownHandlers[key]) {
          dropdownKeyDownHandlers[key](event);
        }
      };
      var dropdownHandleClick = function dropdownHandleClick() {
        dispatch({
          type: DropdownClick
        });
      };
      return _extends((_extends3 = {}, _extends3[refKey] = handleRefs(ref, function (dropdownNode) {
        if (dropdownNode) {
          dropdownRef.current = dropdownNode;
        }
      }), _extends3), !preventKeyAction && {
        onKeyDown: callAllEventHandlers(onKeyDown, dropdownHandleKeyDown),
        onClick: callAllEventHandlers(onClick, dropdownHandleClick)
      }, rest);
    }, [dispatch, dropdownKeyDownHandlers, setGetterPropCallInfo]);

    // returns
    var addSelectedItem = React.useCallback(function (selectedItem) {
      dispatch({
        type: FunctionAddSelectedItem,
        selectedItem: selectedItem
      });
    }, [dispatch]);
    var removeSelectedItem = React.useCallback(function (selectedItem) {
      dispatch({
        type: FunctionRemoveSelectedItem,
        selectedItem: selectedItem
      });
    }, [dispatch]);
    var setSelectedItems = React.useCallback(function (newSelectedItems) {
      dispatch({
        type: FunctionSetSelectedItems,
        selectedItems: newSelectedItems
      });
    }, [dispatch]);
    var setActiveIndex = React.useCallback(function (newActiveIndex) {
      dispatch({
        type: FunctionSetActiveIndex,
        activeIndex: newActiveIndex
      });
    }, [dispatch]);
    var reset = React.useCallback(function () {
      dispatch({
        type: FunctionReset
      });
    }, [dispatch]);
    return {
      getSelectedItemProps: getSelectedItemProps,
      getDropdownProps: getDropdownProps,
      addSelectedItem: addSelectedItem,
      removeSelectedItem: removeSelectedItem,
      setSelectedItems: setSelectedItems,
      setActiveIndex: setActiveIndex,
      reset: reset,
      selectedItems: selectedItems,
      activeIndex: activeIndex
    };
  }

  var TagClick = '__tag_click__' ;
  var TagGroupKeyDownArrowLeft = '__taggroup_keydown_arrowleft__' ;
  var TagGroupKeyDownArrowRight = '__taggroup_keydown_arrowright__' ;
  var TagGroupKeyDownDelete = '__taggroup_keydown_delete__' ;
  var TagGroupKeyDownBackspace = '__taggroup_keydown_backspace__' ;
  var TagRemoveClick = '__tagremove_click__' ;
  var FunctionAddItem = '__function_add_item__' ;

  var stateChangeTypes = /*#__PURE__*/Object.freeze({
    __proto__: null,
    FunctionAddItem: FunctionAddItem,
    TagClick: TagClick,
    TagGroupKeyDownArrowLeft: TagGroupKeyDownArrowLeft,
    TagGroupKeyDownArrowRight: TagGroupKeyDownArrowRight,
    TagGroupKeyDownBackspace: TagGroupKeyDownBackspace,
    TagGroupKeyDownDelete: TagGroupKeyDownDelete,
    TagRemoveClick: TagRemoveClick
  });

  function useTagGroupReducer(state, _props, action) {
    var type = action.type;
    var changes;
    switch (type) {
      case TagClick:
        changes = {
          activeIndex: action.index
        };
        break;
      case TagGroupKeyDownArrowLeft:
        changes = {
          activeIndex: state.activeIndex === 0 ? state.items.length - 1 : state.activeIndex - 1
        };
        break;
      case TagGroupKeyDownArrowRight:
        changes = {
          activeIndex: state.activeIndex === state.items.length - 1 ? 0 : state.activeIndex + 1
        };
        break;
      case TagGroupKeyDownBackspace:
      case TagGroupKeyDownDelete:
        {
          var newItems = [].concat(state.items.slice(0, state.activeIndex), state.items.slice(state.activeIndex + 1));
          var newActiveIndex = newItems.length === 0 ? -1 : newItems.length === state.activeIndex ? state.activeIndex - 1 : state.activeIndex;
          changes = {
            items: [].concat(state.items.slice(0, state.activeIndex), state.items.slice(state.activeIndex + 1)),
            activeIndex: newActiveIndex
          };
          break;
        }
      case TagRemoveClick:
        {
          var _newItems = [].concat(state.items.slice(0, action.index), state.items.slice(action.index + 1));
          var _newActiveIndex = _newItems.length === 0 ? -1 : _newItems.length === action.index ? action.index - 1 : action.index;
          changes = {
            items: _newItems,
            activeIndex: _newActiveIndex
          };
        }
        break;
      case FunctionAddItem:
        {
          var _newItems2 = [];
          if (action.index === undefined) {
            _newItems2 = [].concat(state.items, [action.item]);
          } else {
            _newItems2 = [].concat(state.items.slice(0, action.index), [action.item], state.items.slice(action.index));
          }
          var _newActiveIndex2 = state.activeIndex === -1 ? _newItems2.length - 1 : state.activeIndex;
          changes = {
            items: _newItems2,
            activeIndex: _newActiveIndex2
          };
          break;
        }
      default:
        throw new Error('Invalid useTagGroup reducer action.');
    }
    return _extends({}, state, changes);
  }

  // eslint-disable-next-line @typescript-eslint/dot-notation
  var reactUseId = React__namespace['useId'];

  // istanbul ignore next
  var useElementIds = typeof reactUseId === 'function' ? useElementIdsR18 : useElementIdsLegacy;
  function useElementIdsR18(_ref) {
    var id = _ref.id,
      tagGroupId = _ref.tagGroupId,
      getTagId = _ref.getTagId;
    var reactId = "downshift-" + reactUseId();
    if (!id) {
      id = reactId;
    }
    var elementIds = React__namespace.useMemo(function () {
      return {
        tagGroupId: tagGroupId != null ? tagGroupId : id + "-tag-group",
        getTagId: getTagId != null ? getTagId : function (index) {
          return id + "-tag-" + index;
        }
      };
    }, [getTagId, id, tagGroupId]);
    return elementIds;
  }
  function useElementIdsLegacy(_ref2) {
    var id = _ref2.id,
      getTagId = _ref2.getTagId,
      tagGroupId = _ref2.tagGroupId;
    var baseIdRef = React__namespace.useRef(id != null ? id : "downshift-" + generateId());
    var baseId = baseIdRef.current;
    var elementIds = React__namespace.useMemo(function () {
      return {
        tagGroupId: tagGroupId != null ? tagGroupId : baseId + "-tag-group",
        getTagId: getTagId != null ? getTagId : function (index) {
          return baseId + "-tag-" + index;
        }
      };
    }, [getTagId, baseId, tagGroupId]);
    return elementIds;
  }

  function getInitialState(props) {
    var _ref, _props$items, _ref2, _props$activeIndex;
    var items = (_ref = (_props$items = props.items) != null ? _props$items : props.initialItems) != null ? _ref : [];
    var activeIndex = (_ref2 = (_props$activeIndex = props.activeIndex) != null ? _props$activeIndex : props.initialActiveIndex) != null ? _ref2 : items.length === 0 ? -1 : 0;
    return {
      activeIndex: activeIndex,
      items: items
    };
  }

  function isStateEqual(oldState, newState) {
    return oldState.activeIndex === newState.activeIndex && oldState.items === newState.items;
  }

  var A11Y_DESCRIPTION_ELEMENT_ID = 'tag-group-a11y-description';
  function useAccessibleDescription(document, description) {
    React__namespace.useEffect(function () {
      if (!document) {
        return;
      }
      var accessibleDescriptionElement = document.createElement('div');
      accessibleDescriptionElement.setAttribute('id', A11Y_DESCRIPTION_ELEMENT_ID);
      accessibleDescriptionElement.style.display = 'none';
      accessibleDescriptionElement.textContent = description;
      document.body.appendChild(accessibleDescriptionElement);
      return function () {
        accessibleDescriptionElement.remove();
      };
    }, [description, document]);
  }

  function getMergedProps(userProps) {
    return _extends({
      stateReducer: function stateReducer(_s, _ref) {
        var changes = _ref.changes;
        return changes;
      },
      environment: /* istanbul ignore next (ssr) */
      typeof window === 'undefined' || false ? undefined : window,
      removeElementDescription: 'Press Delete or Backspace to remove tag.'
    }, userProps);
  }

  /**
   * Focuses the tag at activeIndex when it changes or when an item is removed.
   */
  function useRovingTagFocus(activeIndex, itemsLength, getTagId) {
    var itemRefs = React__namespace.useRef({});
    var previousActiveIndexRef = React__namespace.useRef(activeIndex);
    var previousItemsLengthRef = React__namespace.useRef(itemsLength);
    React__namespace.useEffect(function () {
      if (activeIndex !== -1 && previousActiveIndexRef.current !== -1 && activeIndex !== previousActiveIndexRef.current || previousItemsLengthRef.current === itemsLength + 1) {
        var _itemRefs$current$get;
        (_itemRefs$current$get = itemRefs.current[getTagId(activeIndex)]) == null || _itemRefs$current$get.focus();
      }
      previousActiveIndexRef.current = activeIndex;
      previousItemsLengthRef.current = itemsLength;
    }, [activeIndex, getTagId, itemsLength]);
    return itemRefs;
  }

  var propTypes = {
    isItemDisabled: PropTypes.func
  };

  var _excluded = ["onKeyDown"],
    _excluded2 = ["index", "refKey", "ref", "onClick"],
    _excluded3 = ["index", "onClick"];
  var _useTagGroup = function useTagGroup(userProps) {
    var _props$environment;
    if (userProps === void 0) {
      userProps = {};
    }
    /* State and Props */

    validatePropTypes$1(userProps, _useTagGroup, propTypes);
    var props = getMergedProps(userProps);
    var _useControlledReducer = useControlledReducer$1(useTagGroupReducer, props, getInitialState, isStateEqual),
      state = _useControlledReducer[0],
      dispatch = _useControlledReducer[1];
    var activeIndex = state.activeIndex,
      items = state.items;

    /* Refs */

    var latest = useLatestRef({
      state: state,
      props: props
    });
    var elementIds = useElementIds({
      getTagId: props.getTagId,
      id: props.id,
      tagGroupId: props.tagGroupId
    });

    /* Effects */

    useAccessibleDescription((_props$environment = props.environment) == null ? void 0 : _props$environment.document, props.removeElementDescription);
    var itemRefs = useRovingTagFocus(activeIndex, items.length, elementIds.getTagId);

    /* Getter functions */

    var getTagGroupProps = React.useCallback(function (options) {
      var _ref = options != null ? options : {},
        onKeyDown = _ref.onKeyDown,
        rest = _objectWithoutPropertiesLoose(_ref, _excluded);
      var handleKeyDown = function handleKeyDown(e) {
        switch (e.key) {
          case 'ArrowLeft':
            dispatch({
              type: TagGroupKeyDownArrowLeft
            });
            break;
          case 'ArrowRight':
            dispatch({
              type: TagGroupKeyDownArrowRight
            });
            break;
          case 'Delete':
            dispatch({
              type: TagGroupKeyDownDelete
            });
            break;
          case 'Backspace':
            dispatch({
              type: TagGroupKeyDownBackspace
            });
            break;
        }
      };
      var tagGroupProps = _extends({
        id: elementIds.tagGroupId,
        'aria-live': 'polite',
        'aria-atomic': 'false',
        'aria-relevant': 'additions',
        role: 'listbox',
        onKeyDown: callAllEventHandlers$1(onKeyDown, handleKeyDown)
      }, rest);
      return tagGroupProps;
    }, [dispatch, elementIds.tagGroupId]);
    var getTagProps = React.useCallback(function (options) {
      var _extends2;
      var index = options.index,
        _options$refKey = options.refKey,
        refKey = _options$refKey === void 0 ? 'ref' : _options$refKey,
        ref = options.ref,
        onClick = options.onClick,
        rest = _objectWithoutPropertiesLoose(options, _excluded2);
      if (!Number.isInteger(index) || index < 0) {
        throw new Error('Pass correct item index to getTagProps!');
      }
      var latestState = latest.current.state;
      var handleClick = function handleClick() {
        dispatch({
          type: TagClick,
          index: index
        });
      };
      var tagId = elementIds.getTagId(index);
      return _extends((_extends2 = {
        'aria-describedby': A11Y_DESCRIPTION_ELEMENT_ID
      }, _extends2[refKey] = handleRefs$1(ref, function (itemNode) {
        if (itemNode) {
          itemRefs.current[tagId] = itemNode;
        }
      }), _extends2['aria-labelledby'] = tagId, _extends2.role = 'option', _extends2.id = tagId, _extends2.onClick = callAllEventHandlers$1(onClick, handleClick), _extends2.tabIndex = latestState.activeIndex === index ? 0 : -1, _extends2), rest);
    }, [dispatch, elementIds, latest, itemRefs]);
    var getTagRemoveProps = React.useCallback(function (options) {
      var index = options.index,
        onClick = options.onClick,
        rest = _objectWithoutPropertiesLoose(options, _excluded3);
      if (!Number.isInteger(index) || index < 0) {
        throw new Error('Pass correct item index to getTagRemoveProps!');
      }
      var handleClick = function handleClick(event) {
        event.stopPropagation();
        dispatch({
          type: TagRemoveClick,
          index: index
        });
      };
      var tagId = elementIds.getTagId(index);
      var tagRemoveId = tagId + "-remove";
      return _extends({
        id: tagRemoveId,
        tabIndex: -1,
        'aria-labelledby': tagRemoveId + " " + tagId,
        onClick: callAllEventHandlers$1(onClick, handleClick)
      }, rest);
    }, [elementIds, dispatch]);

    /* Imperative Functions */

    var addItem = React.useCallback(function (item, index) {
      dispatch({
        type: FunctionAddItem,
        item: item,
        index: index
      });
    }, [dispatch]);
    return {
      activeIndex: activeIndex,
      addItem: addItem,
      getTagGroupProps: getTagGroupProps,
      getTagProps: getTagProps,
      getTagRemoveProps: getTagRemoveProps,
      items: items
    };
  };
  _useTagGroup.stateChangeTypes = stateChangeTypes;

  exports.default = Downshift;
  exports.resetIdCounter = resetIdCounter;
  exports.useCombobox = useCombobox;
  exports.useMultipleSelection = useMultipleSelection;
  exports.useSelect = useSelect;
  exports.useTagGroup = _useTagGroup;

  Object.defineProperty(exports, '__esModule', { value: true });

}));
//# sourceMappingURL=downshift.umd.js.map
