downshift 6.0.14 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,7 @@ import _objectWithoutPropertiesLoose from '@babel/runtime/helpers/esm/objectWith
2
2
  import _extends from '@babel/runtime/helpers/esm/extends';
3
3
  import _assertThisInitialized from '@babel/runtime/helpers/esm/assertThisInitialized';
4
4
  import _inheritsLoose from '@babel/runtime/helpers/esm/inheritsLoose';
5
- import { cloneElement, Component, useRef, useEffect, useCallback, useLayoutEffect, useReducer, useMemo } from 'preact';
5
+ import { cloneElement, Component, useRef, useEffect, useLayoutEffect, useCallback, useReducer, useMemo } from 'preact';
6
6
  import { isForwardRef } from 'react-is';
7
7
  import computeScrollIntoView from 'compute-scroll-into-view';
8
8
  import PropTypes from 'prop-types';
@@ -424,23 +424,25 @@ function targetWithinDownshift(target, downshiftElements, document, checkActiveE
424
424
  return downshiftElements.some(function (contextNode) {
425
425
  return contextNode && (isOrContainsNode(contextNode, target) || checkActiveElement && isOrContainsNode(contextNode, document.activeElement));
426
426
  });
427
- }
427
+ } // eslint-disable-next-line import/no-mutable-exports
428
428
 
429
- function validateControlledUnchanged(state, prevProps, nextProps) {
430
- if (process.env.NODE_ENV === 'production') {
431
- return;
432
- }
433
429
 
434
- 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";
435
- Object.keys(state).forEach(function (propKey) {
436
- if (prevProps[propKey] !== undefined && nextProps[propKey] === undefined) {
437
- // eslint-disable-next-line no-console
438
- console.error("downshift: A component has changed the controlled prop \"" + propKey + "\" to be uncontrolled. " + warningDescription);
439
- } else if (prevProps[propKey] === undefined && nextProps[propKey] !== undefined) {
440
- // eslint-disable-next-line no-console
441
- console.error("downshift: A component has changed the uncontrolled prop \"" + propKey + "\" to be controlled. " + warningDescription);
442
- }
443
- });
430
+ var validateControlledUnchanged = noop;
431
+ /* istanbul ignore next */
432
+
433
+ if (process.env.NODE_ENV !== 'production') {
434
+ validateControlledUnchanged = function validateControlledUnchanged(state, prevProps, nextProps) {
435
+ 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";
436
+ Object.keys(state).forEach(function (propKey) {
437
+ if (prevProps[propKey] !== undefined && nextProps[propKey] === undefined) {
438
+ // eslint-disable-next-line no-console
439
+ console.error("downshift: A component has changed the controlled prop \"" + propKey + "\" to be uncontrolled. " + warningDescription);
440
+ } else if (prevProps[propKey] === undefined && nextProps[propKey] !== undefined) {
441
+ // eslint-disable-next-line no-console
442
+ console.error("downshift: A component has changed the uncontrolled prop \"" + propKey + "\" to be controlled. " + warningDescription);
443
+ }
444
+ });
445
+ };
444
446
  }
445
447
 
446
448
  var cleanupStatus = debounce(function (documentProp) {
@@ -858,12 +860,16 @@ var Downshift = /*#__PURE__*/function () {
858
860
  Home: function Home(event) {
859
861
  var _this4 = this;
860
862
 
861
- event.preventDefault();
862
- var itemCount = this.getItemCount();
863
-
864
863
  var _this$getState3 = this.getState(),
865
864
  isOpen = _this$getState3.isOpen;
866
865
 
866
+ if (!isOpen) {
867
+ return;
868
+ }
869
+
870
+ event.preventDefault();
871
+ var itemCount = this.getItemCount();
872
+
867
873
  if (itemCount <= 0 || !isOpen) {
868
874
  return;
869
875
  } // get next non-disabled starting downwards from 0 if that's disabled.
@@ -879,12 +885,16 @@ var Downshift = /*#__PURE__*/function () {
879
885
  End: function End(event) {
880
886
  var _this5 = this;
881
887
 
882
- event.preventDefault();
883
- var itemCount = this.getItemCount();
884
-
885
888
  var _this$getState4 = this.getState(),
886
889
  isOpen = _this$getState4.isOpen;
887
890
 
891
+ if (!isOpen) {
892
+ return;
893
+ }
894
+
895
+ event.preventDefault();
896
+ var itemCount = this.getItemCount();
897
+
888
898
  if (itemCount <= 0 || !isOpen) {
889
899
  return;
890
900
  } // get next non-disabled starting upwards from last index if that's disabled.
@@ -1716,22 +1726,27 @@ var updateA11yStatus = debounce(function (getA11yMessage, document) {
1716
1726
  }, 200); // istanbul ignore next
1717
1727
 
1718
1728
  var useIsomorphicLayoutEffect = typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined' ? useLayoutEffect : useEffect;
1719
- function getElementIds(_ref) {
1720
- var id = _ref.id,
1729
+
1730
+ function useElementIds(_ref) {
1731
+ var _ref$id = _ref.id,
1732
+ id = _ref$id === void 0 ? "downshift-" + generateId() : _ref$id,
1721
1733
  labelId = _ref.labelId,
1722
1734
  menuId = _ref.menuId,
1723
1735
  getItemId = _ref.getItemId,
1724
- toggleButtonId = _ref.toggleButtonId;
1725
- var uniqueId = id === undefined ? "downshift-" + generateId() : id;
1726
- return {
1727
- labelId: labelId || uniqueId + "-label",
1728
- menuId: menuId || uniqueId + "-menu",
1736
+ toggleButtonId = _ref.toggleButtonId,
1737
+ inputId = _ref.inputId;
1738
+ var elementIdsRef = useRef({
1739
+ labelId: labelId || id + "-label",
1740
+ menuId: menuId || id + "-menu",
1729
1741
  getItemId: getItemId || function (index) {
1730
- return uniqueId + "-item-" + index;
1742
+ return id + "-item-" + index;
1731
1743
  },
1732
- toggleButtonId: toggleButtonId || uniqueId + "-toggle-button"
1733
- };
1744
+ toggleButtonId: toggleButtonId || id + "-toggle-button",
1745
+ inputId: inputId || id + "-input"
1746
+ });
1747
+ return elementIdsRef.current;
1734
1748
  }
1749
+
1735
1750
  function getItemIndex(index, item, items) {
1736
1751
  if (index !== undefined) {
1737
1752
  return index;
@@ -1748,24 +1763,14 @@ function itemToString(item) {
1748
1763
  return item ? String(item) : '';
1749
1764
  }
1750
1765
 
1751
- function getPropTypesValidator(caller, propTypes) {
1752
- // istanbul ignore next
1753
- return function validate(options) {
1754
- if (options === void 0) {
1755
- options = {};
1756
- }
1757
-
1758
- Object.keys(propTypes).forEach(function (key) {
1759
- PropTypes.checkPropTypes(propTypes, options, key, caller.name);
1760
- });
1761
- };
1762
- }
1763
1766
  function isAcceptedCharacterKey(key) {
1764
1767
  return /^\S{1}$/.test(key);
1765
1768
  }
1769
+
1766
1770
  function capitalizeString(string) {
1767
1771
  return "" + string.slice(0, 1).toUpperCase() + string.slice(1);
1768
1772
  }
1773
+
1769
1774
  function useLatestRef(val) {
1770
1775
  var ref = useRef(val); // technically this is not "concurrent mode safe" because we're manipulating
1771
1776
  // the value during render (so it's not idempotent). However, the places this
@@ -1787,6 +1792,7 @@ function useLatestRef(val) {
1787
1792
  * @returns {Array} An array with the state and an action dispatcher.
1788
1793
  */
1789
1794
 
1795
+
1790
1796
  function useEnhancedReducer(reducer, initialState, props) {
1791
1797
  var prevStateRef = useRef();
1792
1798
  var actionRef = useRef();
@@ -1830,6 +1836,7 @@ function useEnhancedReducer(reducer, initialState, props) {
1830
1836
  * @returns {Array} An array with the state and an action dispatcher.
1831
1837
  */
1832
1838
 
1839
+
1833
1840
  function useControlledReducer(reducer, initialState, props) {
1834
1841
  var _useEnhancedReducer = useEnhancedReducer(reducer, initialState, props),
1835
1842
  state = _useEnhancedReducer[0],
@@ -1837,6 +1844,7 @@ function useControlledReducer(reducer, initialState, props) {
1837
1844
 
1838
1845
  return [getState(state, props), dispatch];
1839
1846
  }
1847
+
1840
1848
  var defaultProps = {
1841
1849
  itemToString: itemToString,
1842
1850
  stateReducer: stateReducer,
@@ -1847,6 +1855,7 @@ var defaultProps = {
1847
1855
  /* istanbul ignore next (ssr) */
1848
1856
  ? {} : window
1849
1857
  };
1858
+
1850
1859
  function getDefaultValue(props, propKey, defaultStateValues) {
1851
1860
  if (defaultStateValues === void 0) {
1852
1861
  defaultStateValues = dropdownDefaultStateValues;
@@ -1860,6 +1869,7 @@ function getDefaultValue(props, propKey, defaultStateValues) {
1860
1869
 
1861
1870
  return defaultStateValues[propKey];
1862
1871
  }
1872
+
1863
1873
  function getInitialValue(props, propKey, defaultStateValues) {
1864
1874
  if (defaultStateValues === void 0) {
1865
1875
  defaultStateValues = dropdownDefaultStateValues;
@@ -1877,6 +1887,7 @@ function getInitialValue(props, propKey, defaultStateValues) {
1877
1887
 
1878
1888
  return getDefaultValue(props, propKey, defaultStateValues);
1879
1889
  }
1890
+
1880
1891
  function getInitialState(props) {
1881
1892
  var selectedItem = getInitialValue(props, 'selectedItem');
1882
1893
  var isOpen = getInitialValue(props, 'isOpen');
@@ -1889,6 +1900,7 @@ function getInitialState(props) {
1889
1900
  inputValue: inputValue
1890
1901
  };
1891
1902
  }
1903
+
1892
1904
  function getHighlightedIndexOnOpen(props, state, offset, getItemNodeFromIndex) {
1893
1905
  var items = props.items,
1894
1906
  initialHighlightedIndex = props.initialHighlightedIndex,
@@ -1933,6 +1945,7 @@ function getHighlightedIndexOnOpen(props, state, offset, getItemNodeFromIndex) {
1933
1945
  * @returns {Object} Ref containing whether mouseDown or touchMove event is happening
1934
1946
  */
1935
1947
 
1948
+
1936
1949
  function useMouseAndTouchTracker(isOpen, downshiftElementRefs, environment, handleBlur) {
1937
1950
  var mouseAndTouchTrackersRef = useRef({
1938
1951
  isMouseDown: false,
@@ -1986,6 +1999,13 @@ function useMouseAndTouchTracker(isOpen, downshiftElementRefs, environment, hand
1986
1999
  }, [isOpen, environment]);
1987
2000
  return mouseAndTouchTrackersRef;
1988
2001
  }
2002
+ /* istanbul ignore next */
2003
+ // eslint-disable-next-line import/no-mutable-exports
2004
+
2005
+
2006
+ var useGetterPropsCalledChecker = function useGetterPropsCalledChecker() {
2007
+ return noop;
2008
+ };
1989
2009
  /**
1990
2010
  * Custom hook that checks if getter props are called correctly.
1991
2011
  *
@@ -1993,63 +2013,61 @@ function useMouseAndTouchTracker(isOpen, downshiftElementRefs, environment, hand
1993
2013
  * @returns {Function} Setter function called inside getter props to set call information.
1994
2014
  */
1995
2015
 
1996
- function useGetterPropsCalledChecker() {
1997
- var isNotProduction = process.env.NODE_ENV !== 'production';
1998
- var isInitialMountRef = useRef(true);
2016
+ /* istanbul ignore next */
1999
2017
 
2000
- for (var _len = arguments.length, propKeys = new Array(_len), _key = 0; _key < _len; _key++) {
2001
- propKeys[_key] = arguments[_key];
2002
- }
2003
2018
 
2004
- var getterPropsCalledRef = useRef(propKeys.reduce(function (acc, propKey) {
2005
- acc[propKey] = {};
2006
- return acc;
2007
- }, {}));
2008
- useEffect(function () {
2009
- if (!isNotProduction) {
2010
- return;
2011
- }
2019
+ if (process.env.NODE_ENV !== 'production') {
2020
+ useGetterPropsCalledChecker = function useGetterPropsCalledChecker() {
2021
+ var isInitialMountRef = useRef(true);
2012
2022
 
2013
- Object.keys(getterPropsCalledRef.current).forEach(function (propKey) {
2014
- var propCallInfo = getterPropsCalledRef.current[propKey];
2023
+ for (var _len = arguments.length, propKeys = new Array(_len), _key = 0; _key < _len; _key++) {
2024
+ propKeys[_key] = arguments[_key];
2025
+ }
2015
2026
 
2016
- if (isInitialMountRef.current) {
2017
- if (!Object.keys(propCallInfo).length) {
2018
- // eslint-disable-next-line no-console
2019
- console.error("downshift: You forgot to call the " + propKey + " getter function on your component / element.");
2020
- return;
2027
+ var getterPropsCalledRef = useRef(propKeys.reduce(function (acc, propKey) {
2028
+ acc[propKey] = {};
2029
+ return acc;
2030
+ }, {}));
2031
+ useEffect(function () {
2032
+ Object.keys(getterPropsCalledRef.current).forEach(function (propKey) {
2033
+ var propCallInfo = getterPropsCalledRef.current[propKey];
2034
+
2035
+ if (isInitialMountRef.current) {
2036
+ if (!Object.keys(propCallInfo).length) {
2037
+ // eslint-disable-next-line no-console
2038
+ console.error("downshift: You forgot to call the " + propKey + " getter function on your component / element.");
2039
+ return;
2040
+ }
2021
2041
  }
2022
- }
2023
2042
 
2024
- var suppressRefError = propCallInfo.suppressRefError,
2025
- refKey = propCallInfo.refKey,
2026
- elementRef = propCallInfo.elementRef;
2043
+ var suppressRefError = propCallInfo.suppressRefError,
2044
+ refKey = propCallInfo.refKey,
2045
+ elementRef = propCallInfo.elementRef;
2027
2046
 
2028
- if ((!elementRef || !elementRef.current) && !suppressRefError) {
2029
- // eslint-disable-next-line no-console
2030
- console.error("downshift: The ref prop \"" + refKey + "\" from " + propKey + " was not applied correctly on your element.");
2031
- }
2047
+ if ((!elementRef || !elementRef.current) && !suppressRefError) {
2048
+ // eslint-disable-next-line no-console
2049
+ console.error("downshift: The ref prop \"" + refKey + "\" from " + propKey + " was not applied correctly on your element.");
2050
+ }
2051
+ });
2052
+ isInitialMountRef.current = false;
2032
2053
  });
2033
- isInitialMountRef.current = false;
2034
- });
2035
- var setGetterPropCallInfo = useCallback(function (propKey, suppressRefError, refKey, elementRef) {
2036
- if (process.env.NODE_ENV !== 'production') {
2054
+ var setGetterPropCallInfo = useCallback(function (propKey, suppressRefError, refKey, elementRef) {
2037
2055
  getterPropsCalledRef.current[propKey] = {
2038
2056
  suppressRefError: suppressRefError,
2039
2057
  refKey: refKey,
2040
2058
  elementRef: elementRef
2041
2059
  };
2042
- }
2043
- }, []);
2044
- return setGetterPropCallInfo;
2060
+ }, []);
2061
+ return setGetterPropCallInfo;
2062
+ };
2045
2063
  }
2064
+
2046
2065
  function useA11yMessageSetter(getA11yMessage, dependencyArray, _ref2) {
2047
2066
  var isInitialMount = _ref2.isInitialMount,
2048
- previousResultCount = _ref2.previousResultCount,
2049
2067
  highlightedIndex = _ref2.highlightedIndex,
2050
2068
  items = _ref2.items,
2051
2069
  environment = _ref2.environment,
2052
- rest = _objectWithoutPropertiesLoose(_ref2, ["isInitialMount", "previousResultCount", "highlightedIndex", "items", "environment"]);
2070
+ rest = _objectWithoutPropertiesLoose(_ref2, ["isInitialMount", "highlightedIndex", "items", "environment"]);
2053
2071
 
2054
2072
  // Sets a11y status message on changes in state.
2055
2073
  useEffect(function () {
@@ -2061,12 +2079,12 @@ function useA11yMessageSetter(getA11yMessage, dependencyArray, _ref2) {
2061
2079
  return getA11yMessage(_extends({
2062
2080
  highlightedIndex: highlightedIndex,
2063
2081
  highlightedItem: items[highlightedIndex],
2064
- resultCount: items.length,
2065
- previousResultCount: previousResultCount
2082
+ resultCount: items.length
2066
2083
  }, rest));
2067
2084
  }, environment.document); // eslint-disable-next-line react-hooks/exhaustive-deps
2068
2085
  }, dependencyArray);
2069
2086
  }
2087
+
2070
2088
  function useScrollIntoView(_ref3) {
2071
2089
  var highlightedIndex = _ref3.highlightedIndex,
2072
2090
  isOpen = _ref3.isOpen,
@@ -2090,47 +2108,112 @@ function useScrollIntoView(_ref3) {
2090
2108
 
2091
2109
  }, [highlightedIndex]);
2092
2110
  return shouldScrollRef;
2093
- }
2094
- function useControlPropsValidator(_ref4) {
2095
- var isInitialMount = _ref4.isInitialMount,
2096
- props = _ref4.props,
2097
- state = _ref4.state;
2098
- // used for checking when props are moving from controlled to uncontrolled.
2099
- var prevPropsRef = useRef(props);
2100
- useEffect(function () {
2101
- if (isInitialMount) {
2102
- return;
2103
- }
2111
+ } // eslint-disable-next-line import/no-mutable-exports
2104
2112
 
2105
- validateControlledUnchanged(state, prevPropsRef.current, props);
2106
- prevPropsRef.current = props;
2107
- }, [state, props, isInitialMount]);
2108
- }
2109
2113
 
2110
- function getItemIndexByCharacterKey(keysSoFar, highlightedIndex, items, itemToStringParam, getItemNodeFromIndex) {
2111
- var lowerCasedItemStrings = items.map(function (item) {
2112
- return itemToStringParam(item).toLowerCase();
2113
- });
2114
- var lowerCasedKeysSoFar = keysSoFar.toLowerCase();
2114
+ var useControlPropsValidator = noop;
2115
+ /* istanbul ignore next */
2115
2116
 
2116
- var isValid = function isValid(itemString, index) {
2117
- var element = getItemNodeFromIndex(index);
2118
- return itemString.startsWith(lowerCasedKeysSoFar) && !(element && element.hasAttribute('disabled'));
2117
+ if (process.env.NODE_ENV !== 'production') {
2118
+ useControlPropsValidator = function useControlPropsValidator(_ref4) {
2119
+ var isInitialMount = _ref4.isInitialMount,
2120
+ props = _ref4.props,
2121
+ state = _ref4.state;
2122
+ // used for checking when props are moving from controlled to uncontrolled.
2123
+ var prevPropsRef = useRef(props);
2124
+ useEffect(function () {
2125
+ if (isInitialMount) {
2126
+ return;
2127
+ }
2128
+
2129
+ validateControlledUnchanged(state, prevPropsRef.current, props);
2130
+ prevPropsRef.current = props;
2131
+ }, [state, props, isInitialMount]);
2119
2132
  };
2133
+ }
2120
2134
 
2121
- for (var index = highlightedIndex + 1; index < lowerCasedItemStrings.length; index++) {
2122
- var itemString = lowerCasedItemStrings[index];
2135
+ /* eslint-disable complexity */
2123
2136
 
2124
- if (isValid(itemString, index)) {
2125
- return index;
2126
- }
2137
+ function downshiftCommonReducer(state, action, stateChangeTypes) {
2138
+ var type = action.type,
2139
+ props = action.props;
2140
+ var changes;
2141
+
2142
+ switch (type) {
2143
+ case stateChangeTypes.ItemMouseMove:
2144
+ changes = {
2145
+ highlightedIndex: action.index
2146
+ };
2147
+ break;
2148
+
2149
+ case stateChangeTypes.MenuMouseLeave:
2150
+ changes = {
2151
+ highlightedIndex: -1
2152
+ };
2153
+ break;
2154
+
2155
+ case stateChangeTypes.ToggleButtonClick:
2156
+ case stateChangeTypes.FunctionToggleMenu:
2157
+ changes = {
2158
+ isOpen: !state.isOpen,
2159
+ highlightedIndex: state.isOpen ? -1 : getHighlightedIndexOnOpen(props, state, 0)
2160
+ };
2161
+ break;
2162
+
2163
+ case stateChangeTypes.FunctionOpenMenu:
2164
+ changes = {
2165
+ isOpen: true,
2166
+ highlightedIndex: getHighlightedIndexOnOpen(props, state, 0)
2167
+ };
2168
+ break;
2169
+
2170
+ case stateChangeTypes.FunctionCloseMenu:
2171
+ changes = {
2172
+ isOpen: false
2173
+ };
2174
+ break;
2175
+
2176
+ case stateChangeTypes.FunctionSetHighlightedIndex:
2177
+ changes = {
2178
+ highlightedIndex: action.highlightedIndex
2179
+ };
2180
+ break;
2181
+
2182
+ case stateChangeTypes.FunctionSetInputValue:
2183
+ changes = {
2184
+ inputValue: action.inputValue
2185
+ };
2186
+ break;
2187
+
2188
+ case stateChangeTypes.FunctionReset:
2189
+ changes = {
2190
+ highlightedIndex: getDefaultValue(props, 'highlightedIndex'),
2191
+ isOpen: getDefaultValue(props, 'isOpen'),
2192
+ selectedItem: getDefaultValue(props, 'selectedItem'),
2193
+ inputValue: getDefaultValue(props, 'inputValue')
2194
+ };
2195
+ break;
2196
+
2197
+ default:
2198
+ throw new Error('Reducer called without proper action type.');
2127
2199
  }
2128
2200
 
2129
- for (var _index = 0; _index < highlightedIndex; _index++) {
2130
- var _itemString = lowerCasedItemStrings[_index];
2201
+ return _extends({}, state, changes);
2202
+ }
2203
+ /* eslint-enable complexity */
2204
+
2205
+ function getItemIndexByCharacterKey(keysSoFar, highlightedIndex, items, itemToString, getItemNodeFromIndex) {
2206
+ var lowerCasedKeysSoFar = keysSoFar.toLowerCase();
2207
+
2208
+ for (var index = 0; index < items.length; index++) {
2209
+ var offsetIndex = (index + highlightedIndex + 1) % items.length;
2210
+
2211
+ if (itemToString(items[offsetIndex]).toLowerCase().startsWith(lowerCasedKeysSoFar)) {
2212
+ var element = getItemNodeFromIndex(offsetIndex);
2131
2213
 
2132
- if (isValid(_itemString, _index)) {
2133
- return _index;
2214
+ if (!(element && element.hasAttribute('disabled'))) {
2215
+ return offsetIndex;
2216
+ }
2134
2217
  }
2135
2218
  }
2136
2219
 
@@ -2203,7 +2286,17 @@ function getA11yStatusMessage$1(_ref) {
2203
2286
 
2204
2287
  var defaultProps$1 = _extends({}, defaultProps, {
2205
2288
  getA11yStatusMessage: getA11yStatusMessage$1
2206
- });
2289
+ }); // eslint-disable-next-line import/no-mutable-exports
2290
+
2291
+
2292
+ var validatePropTypes = noop;
2293
+ /* istanbul ignore next */
2294
+
2295
+ if (process.env.NODE_ENV !== 'production') {
2296
+ validatePropTypes = function validatePropTypes(options, caller) {
2297
+ PropTypes.checkPropTypes(propTypes, options, 'prop', caller.name);
2298
+ };
2299
+ }
2207
2300
 
2208
2301
  var MenuKeyDownArrowDown = process.env.NODE_ENV !== "production" ? '__menu_keydown_arrow_down__' : 0;
2209
2302
  var MenuKeyDownArrowUp = process.env.NODE_ENV !== "production" ? '__menu_keydown_arrow_up__' : 1;
@@ -2265,12 +2358,6 @@ function downshiftSelectReducer(state, action) {
2265
2358
  var changes;
2266
2359
 
2267
2360
  switch (type) {
2268
- case ItemMouseMove:
2269
- changes = {
2270
- highlightedIndex: action.index
2271
- };
2272
- break;
2273
-
2274
2361
  case ItemClick:
2275
2362
  changes = {
2276
2363
  isOpen: getDefaultValue(props, 'isOpen'),
@@ -2369,71 +2456,20 @@ function downshiftSelectReducer(state, action) {
2369
2456
  };
2370
2457
  break;
2371
2458
 
2372
- case MenuMouseLeave:
2373
- changes = {
2374
- highlightedIndex: -1
2375
- };
2376
- break;
2377
-
2378
- case ToggleButtonClick:
2379
- case FunctionToggleMenu:
2380
- changes = {
2381
- isOpen: !state.isOpen,
2382
- highlightedIndex: state.isOpen ? -1 : getHighlightedIndexOnOpen(props, state, 0)
2383
- };
2384
- break;
2385
-
2386
- case FunctionOpenMenu:
2387
- changes = {
2388
- isOpen: true,
2389
- highlightedIndex: getHighlightedIndexOnOpen(props, state, 0)
2390
- };
2391
- break;
2392
-
2393
- case FunctionCloseMenu:
2394
- changes = {
2395
- isOpen: false
2396
- };
2397
- break;
2398
-
2399
- case FunctionSetHighlightedIndex:
2400
- changes = {
2401
- highlightedIndex: action.highlightedIndex
2402
- };
2403
- break;
2404
-
2405
2459
  case FunctionSelectItem:
2406
2460
  changes = {
2407
2461
  selectedItem: action.selectedItem
2408
2462
  };
2409
2463
  break;
2410
2464
 
2411
- case FunctionSetInputValue:
2412
- changes = {
2413
- inputValue: action.inputValue
2414
- };
2415
- break;
2416
-
2417
- case FunctionReset:
2418
- changes = {
2419
- highlightedIndex: getDefaultValue(props, 'highlightedIndex'),
2420
- isOpen: getDefaultValue(props, 'isOpen'),
2421
- selectedItem: getDefaultValue(props, 'selectedItem'),
2422
- inputValue: getDefaultValue(props, 'inputValue')
2423
- };
2424
- break;
2425
-
2426
2465
  default:
2427
- throw new Error('Reducer called without proper action type.');
2466
+ return downshiftCommonReducer(state, action, stateChangeTypes$1);
2428
2467
  }
2429
2468
 
2430
2469
  return _extends({}, state, changes);
2431
2470
  }
2432
2471
  /* eslint-enable complexity */
2433
2472
 
2434
- var validatePropTypes = process.env.NODE_ENV === 'production' ?
2435
- /* istanbul ignore next */
2436
- null : getPropTypesValidator(useSelect, propTypes);
2437
2473
  useSelect.stateChangeTypes = stateChangeTypes$1;
2438
2474
 
2439
2475
  function useSelect(userProps) {
@@ -2441,11 +2477,7 @@ function useSelect(userProps) {
2441
2477
  userProps = {};
2442
2478
  }
2443
2479
 
2444
- /* istanbul ignore else */
2445
- if (process.env.NODE_ENV !== 'production') {
2446
- validatePropTypes(userProps);
2447
- } // Props defaults and destructuring.
2448
-
2480
+ validatePropTypes(userProps, useSelect); // Props defaults and destructuring.
2449
2481
 
2450
2482
  var props = _extends({}, defaultProps$1, userProps);
2451
2483
 
@@ -2471,14 +2503,13 @@ function useSelect(userProps) {
2471
2503
 
2472
2504
  var toggleButtonRef = useRef(null);
2473
2505
  var menuRef = useRef(null);
2474
- var itemRefs = useRef();
2475
- itemRefs.current = {}; // used not to trigger menu blur action in some scenarios.
2506
+ var itemRefs = useRef({}); // used not to trigger menu blur action in some scenarios.
2476
2507
 
2477
2508
  var shouldBlurRef = useRef(true); // used to keep the inputValue clearTimeout object between renders.
2478
2509
 
2479
2510
  var clearTimeoutRef = useRef(null); // prevent id re-generation between renders.
2480
2511
 
2481
- var elementIdsRef = useRef(getElementIds(props)); // used to keep track of how many items we had on previous cycle.
2512
+ var elementIds = useElementIds(props); // used to keep track of how many items we had on previous cycle.
2482
2513
 
2483
2514
  var previousResultCountRef = useRef();
2484
2515
  var isInitialMountRef = useRef(true); // utility callback to get item element.
@@ -2488,12 +2519,11 @@ function useSelect(userProps) {
2488
2519
  props: props
2489
2520
  }); // Some utils.
2490
2521
 
2491
- var getItemNodeFromIndex = function getItemNodeFromIndex(index) {
2492
- return itemRefs.current[elementIdsRef.current.getItemId(index)];
2493
- }; // Effects.
2522
+ var getItemNodeFromIndex = useCallback(function (index) {
2523
+ return itemRefs.current[elementIds.getItemId(index)];
2524
+ }, [elementIds]); // Effects.
2494
2525
  // Sets a11y status message on changes in state.
2495
2526
 
2496
-
2497
2527
  useA11yMessageSetter(getA11yStatusMessage, [isOpen, highlightedIndex, inputValue, items], _extends({
2498
2528
  isInitialMount: isInitialMountRef.current,
2499
2529
  previousResultCount: previousResultCountRef.current,
@@ -2591,7 +2621,13 @@ function useSelect(userProps) {
2591
2621
 
2592
2622
  useEffect(function () {
2593
2623
  isInitialMountRef.current = false;
2594
- }, []); // Event handler functions.
2624
+ }, []); // Reset itemRefs on close.
2625
+
2626
+ useEffect(function () {
2627
+ if (!isOpen) {
2628
+ itemRefs.current = {};
2629
+ }
2630
+ }, [isOpen]); // Event handler functions.
2595
2631
 
2596
2632
  var toggleButtonKeyDownHandlers = useMemo(function () {
2597
2633
  return {
@@ -2612,7 +2648,7 @@ function useSelect(userProps) {
2612
2648
  });
2613
2649
  }
2614
2650
  };
2615
- }, [dispatch]);
2651
+ }, [dispatch, getItemNodeFromIndex]);
2616
2652
  var menuKeyDownHandlers = useMemo(function () {
2617
2653
  return {
2618
2654
  ArrowDown: function ArrowDown(event) {
@@ -2663,7 +2699,7 @@ function useSelect(userProps) {
2663
2699
  });
2664
2700
  }
2665
2701
  };
2666
- }, [dispatch]); // Action functions.
2702
+ }, [dispatch, getItemNodeFromIndex]); // Action functions.
2667
2703
 
2668
2704
  var toggleMenu = useCallback(function () {
2669
2705
  dispatch({
@@ -2706,10 +2742,10 @@ function useSelect(userProps) {
2706
2742
 
2707
2743
  var getLabelProps = useCallback(function (labelProps) {
2708
2744
  return _extends({
2709
- id: elementIdsRef.current.labelId,
2710
- htmlFor: elementIdsRef.current.toggleButtonId
2745
+ id: elementIds.labelId,
2746
+ htmlFor: elementIds.toggleButtonId
2711
2747
  }, labelProps);
2712
- }, []);
2748
+ }, [elementIds]);
2713
2749
  var getMenuProps = useCallback(function (_temp, _temp2) {
2714
2750
  var _extends2;
2715
2751
 
@@ -2768,14 +2804,14 @@ function useSelect(userProps) {
2768
2804
  setGetterPropCallInfo('getMenuProps', suppressRefError, refKey, menuRef);
2769
2805
  return _extends((_extends2 = {}, _extends2[refKey] = handleRefs(ref, function (menuNode) {
2770
2806
  menuRef.current = menuNode;
2771
- }), _extends2.id = elementIdsRef.current.menuId, _extends2.role = 'listbox', _extends2['aria-labelledby'] = elementIdsRef.current.labelId, _extends2.tabIndex = -1, _extends2), latestState.isOpen && latestState.highlightedIndex > -1 && {
2772
- 'aria-activedescendant': elementIdsRef.current.getItemId(latestState.highlightedIndex)
2807
+ }), _extends2.id = elementIds.menuId, _extends2.role = 'listbox', _extends2['aria-labelledby'] = elementIds.labelId, _extends2.tabIndex = -1, _extends2), latestState.isOpen && latestState.highlightedIndex > -1 && {
2808
+ 'aria-activedescendant': elementIds.getItemId(latestState.highlightedIndex)
2773
2809
  }, {
2774
2810
  onMouseLeave: callAllEventHandlers(onMouseLeave, menuHandleMouseLeave),
2775
2811
  onKeyDown: callAllEventHandlers(onKeyDown, menuHandleKeyDown),
2776
2812
  onBlur: callAllEventHandlers(onBlur, menuHandleBlur)
2777
2813
  }, rest);
2778
- }, [dispatch, latest, menuKeyDownHandlers, mouseAndTouchTrackersRef, setGetterPropCallInfo]);
2814
+ }, [dispatch, latest, menuKeyDownHandlers, mouseAndTouchTrackersRef, setGetterPropCallInfo, elementIds, getItemNodeFromIndex]);
2779
2815
  var getToggleButtonProps = useCallback(function (_temp3, _temp4) {
2780
2816
  var _extends3;
2781
2817
 
@@ -2813,7 +2849,7 @@ function useSelect(userProps) {
2813
2849
 
2814
2850
  var toggleProps = _extends((_extends3 = {}, _extends3[refKey] = handleRefs(ref, function (toggleButtonNode) {
2815
2851
  toggleButtonRef.current = toggleButtonNode;
2816
- }), _extends3.id = elementIdsRef.current.toggleButtonId, _extends3['aria-haspopup'] = 'listbox', _extends3['aria-expanded'] = latest.current.state.isOpen, _extends3['aria-labelledby'] = elementIdsRef.current.labelId + " " + elementIdsRef.current.toggleButtonId, _extends3), rest);
2852
+ }), _extends3.id = elementIds.toggleButtonId, _extends3['aria-haspopup'] = 'listbox', _extends3['aria-expanded'] = latest.current.state.isOpen, _extends3['aria-labelledby'] = elementIds.labelId + " " + elementIds.toggleButtonId, _extends3), rest);
2817
2853
 
2818
2854
  if (!rest.disabled) {
2819
2855
  toggleProps.onClick = callAllEventHandlers(onClick, toggleButtonHandleClick);
@@ -2822,7 +2858,7 @@ function useSelect(userProps) {
2822
2858
 
2823
2859
  setGetterPropCallInfo('getToggleButtonProps', suppressRefError, refKey, toggleButtonRef);
2824
2860
  return toggleProps;
2825
- }, [dispatch, latest, toggleButtonKeyDownHandlers, setGetterPropCallInfo]);
2861
+ }, [dispatch, latest, toggleButtonKeyDownHandlers, setGetterPropCallInfo, elementIds, getItemNodeFromIndex]);
2826
2862
  var getItemProps = useCallback(function (_temp5) {
2827
2863
  var _extends4;
2828
2864
 
@@ -2868,10 +2904,10 @@ function useSelect(userProps) {
2868
2904
  var itemProps = _extends((_extends4 = {
2869
2905
  role: 'option',
2870
2906
  'aria-selected': "" + (itemIndex === latestState.highlightedIndex),
2871
- id: elementIdsRef.current.getItemId(itemIndex)
2907
+ id: elementIds.getItemId(itemIndex)
2872
2908
  }, _extends4[refKey] = handleRefs(ref, function (itemNode) {
2873
2909
  if (itemNode) {
2874
- itemRefs.current[elementIdsRef.current.getItemId(itemIndex)] = itemNode;
2910
+ itemRefs.current[elementIds.getItemId(itemIndex)] = itemNode;
2875
2911
  }
2876
2912
  }), _extends4), rest);
2877
2913
 
@@ -2881,7 +2917,7 @@ function useSelect(userProps) {
2881
2917
  }
2882
2918
 
2883
2919
  return itemProps;
2884
- }, [dispatch, latest, shouldScrollRef]);
2920
+ }, [dispatch, latest, shouldScrollRef, elementIds]);
2885
2921
  return {
2886
2922
  // prop getters.
2887
2923
  getToggleButtonProps: getToggleButtonProps,
@@ -2949,18 +2985,6 @@ var stateChangeTypes$2 = /*#__PURE__*/Object.freeze({
2949
2985
  ControlledPropUpdatedSelectedItem: ControlledPropUpdatedSelectedItem
2950
2986
  });
2951
2987
 
2952
- function getElementIds$1(_ref) {
2953
- var id = _ref.id,
2954
- inputId = _ref.inputId,
2955
- rest = _objectWithoutPropertiesLoose(_ref, ["id", "inputId"]);
2956
-
2957
- var uniqueId = id === undefined ? "downshift-" + generateId() : id;
2958
- return _extends({
2959
- inputId: inputId || uniqueId + "-input"
2960
- }, getElementIds(_extends({
2961
- id: id
2962
- }, rest)));
2963
- }
2964
2988
  function getInitialState$1(props) {
2965
2989
  var initialState = getInitialState(props);
2966
2990
  var selectedItem = initialState.selectedItem;
@@ -2974,6 +2998,7 @@ function getInitialState$1(props) {
2974
2998
  inputValue: inputValue
2975
2999
  });
2976
3000
  }
3001
+
2977
3002
  var propTypes$1 = {
2978
3003
  items: PropTypes.array.isRequired,
2979
3004
  itemToString: PropTypes.func,
@@ -3048,7 +3073,18 @@ function useControlledReducer$1(reducer, initialState, props) {
3048
3073
  }
3049
3074
  });
3050
3075
  return [getState(state, props), dispatch];
3076
+ } // eslint-disable-next-line import/no-mutable-exports
3077
+
3078
+
3079
+ var validatePropTypes$1 = noop;
3080
+ /* istanbul ignore next */
3081
+
3082
+ if (process.env.NODE_ENV !== 'production') {
3083
+ validatePropTypes$1 = function validatePropTypes(options, caller) {
3084
+ PropTypes.checkPropTypes(propTypes$1, options, 'prop', caller.name);
3085
+ };
3051
3086
  }
3087
+
3052
3088
  var defaultProps$2 = _extends({}, defaultProps, {
3053
3089
  getA11yStatusMessage: getA11yStatusMessage,
3054
3090
  circularNavigation: true
@@ -3063,12 +3099,6 @@ function downshiftUseComboboxReducer(state, action) {
3063
3099
  var changes;
3064
3100
 
3065
3101
  switch (type) {
3066
- case ItemMouseMove$1:
3067
- changes = {
3068
- highlightedIndex: action.index
3069
- };
3070
- break;
3071
-
3072
3102
  case ItemClick$1:
3073
3103
  changes = {
3074
3104
  isOpen: getDefaultValue(props, 'isOpen'),
@@ -3086,7 +3116,7 @@ function downshiftUseComboboxReducer(state, action) {
3086
3116
  } else {
3087
3117
  changes = {
3088
3118
  highlightedIndex: getHighlightedIndexOnOpen(props, state, 1, action.getItemNodeFromIndex),
3089
- isOpen: true
3119
+ isOpen: props.items.length >= 0
3090
3120
  };
3091
3121
  }
3092
3122
 
@@ -3100,7 +3130,7 @@ function downshiftUseComboboxReducer(state, action) {
3100
3130
  } else {
3101
3131
  changes = {
3102
3132
  highlightedIndex: getHighlightedIndexOnOpen(props, state, -1, action.getItemNodeFromIndex),
3103
- isOpen: true
3133
+ isOpen: props.items.length >= 0
3104
3134
  };
3105
3135
  }
3106
3136
 
@@ -3126,28 +3156,25 @@ function downshiftUseComboboxReducer(state, action) {
3126
3156
  break;
3127
3157
 
3128
3158
  case InputKeyDownHome:
3129
- changes = _extends({}, state.isOpen && {
3159
+ changes = {
3130
3160
  highlightedIndex: getNextNonDisabledIndex(1, 0, props.items.length, action.getItemNodeFromIndex, false)
3131
- });
3161
+ };
3132
3162
  break;
3133
3163
 
3134
3164
  case InputKeyDownEnd:
3135
- changes = _extends({}, state.isOpen && {
3165
+ changes = {
3136
3166
  highlightedIndex: getNextNonDisabledIndex(-1, props.items.length - 1, props.items.length, action.getItemNodeFromIndex, false)
3137
- });
3167
+ };
3138
3168
  break;
3139
3169
 
3140
3170
  case InputBlur:
3141
- if (state.isOpen) {
3142
- changes = _extends({
3143
- isOpen: false,
3144
- highlightedIndex: -1
3145
- }, state.highlightedIndex >= 0 && action.selectItem && {
3146
- selectedItem: props.items[state.highlightedIndex],
3147
- inputValue: props.itemToString(props.items[state.highlightedIndex])
3148
- });
3149
- }
3150
-
3171
+ changes = _extends({
3172
+ isOpen: false,
3173
+ highlightedIndex: -1
3174
+ }, state.highlightedIndex >= 0 && action.selectItem && {
3175
+ selectedItem: props.items[state.highlightedIndex],
3176
+ inputValue: props.itemToString(props.items[state.highlightedIndex])
3177
+ });
3151
3178
  break;
3152
3179
 
3153
3180
  case InputChange:
@@ -3158,39 +3185,6 @@ function downshiftUseComboboxReducer(state, action) {
3158
3185
  };
3159
3186
  break;
3160
3187
 
3161
- case MenuMouseLeave$1:
3162
- changes = {
3163
- highlightedIndex: -1
3164
- };
3165
- break;
3166
-
3167
- case ToggleButtonClick$1:
3168
- case FunctionToggleMenu$1:
3169
- changes = {
3170
- isOpen: !state.isOpen,
3171
- highlightedIndex: state.isOpen ? -1 : getHighlightedIndexOnOpen(props, state, 0)
3172
- };
3173
- break;
3174
-
3175
- case FunctionOpenMenu$1:
3176
- changes = {
3177
- isOpen: true,
3178
- highlightedIndex: getHighlightedIndexOnOpen(props, state, 0)
3179
- };
3180
- break;
3181
-
3182
- case FunctionCloseMenu$1:
3183
- changes = {
3184
- isOpen: false
3185
- };
3186
- break;
3187
-
3188
- case FunctionSetHighlightedIndex$1:
3189
- changes = {
3190
- highlightedIndex: action.highlightedIndex
3191
- };
3192
- break;
3193
-
3194
3188
  case FunctionSelectItem$1:
3195
3189
  changes = {
3196
3190
  selectedItem: action.selectedItem,
@@ -3199,32 +3193,19 @@ function downshiftUseComboboxReducer(state, action) {
3199
3193
  break;
3200
3194
 
3201
3195
  case ControlledPropUpdatedSelectedItem:
3202
- case FunctionSetInputValue$1:
3203
3196
  changes = {
3204
3197
  inputValue: action.inputValue
3205
3198
  };
3206
3199
  break;
3207
3200
 
3208
- case FunctionReset$1:
3209
- changes = {
3210
- highlightedIndex: getDefaultValue(props, 'highlightedIndex'),
3211
- isOpen: getDefaultValue(props, 'isOpen'),
3212
- selectedItem: getDefaultValue(props, 'selectedItem'),
3213
- inputValue: getDefaultValue(props, 'inputValue')
3214
- };
3215
- break;
3216
-
3217
3201
  default:
3218
- throw new Error('Reducer called without proper action type.');
3202
+ return downshiftCommonReducer(state, action, stateChangeTypes$2);
3219
3203
  }
3220
3204
 
3221
3205
  return _extends({}, state, changes);
3222
3206
  }
3223
3207
  /* eslint-enable complexity */
3224
3208
 
3225
- var validatePropTypes$1 = process.env.NODE_ENV === 'production' ?
3226
- /* istanbul ignore next */
3227
- null : getPropTypesValidator(useCombobox, propTypes$1);
3228
3209
  useCombobox.stateChangeTypes = stateChangeTypes$2;
3229
3210
 
3230
3211
  function useCombobox(userProps) {
@@ -3232,11 +3213,7 @@ function useCombobox(userProps) {
3232
3213
  userProps = {};
3233
3214
  }
3234
3215
 
3235
- /* istanbul ignore else */
3236
- if (process.env.NODE_ENV !== 'production') {
3237
- validatePropTypes$1(userProps);
3238
- } // Props defaults and destructuring.
3239
-
3216
+ validatePropTypes$1(userProps, useCombobox); // Props defaults and destructuring.
3240
3217
 
3241
3218
  var props = _extends({}, defaultProps$2, userProps);
3242
3219
 
@@ -3261,14 +3238,13 @@ function useCombobox(userProps) {
3261
3238
  inputValue = state.inputValue; // Element refs.
3262
3239
 
3263
3240
  var menuRef = useRef(null);
3264
- var itemRefs = useRef();
3241
+ var itemRefs = useRef({});
3265
3242
  var inputRef = useRef(null);
3266
3243
  var toggleButtonRef = useRef(null);
3267
3244
  var comboboxRef = useRef(null);
3268
- itemRefs.current = {};
3269
3245
  var isInitialMountRef = useRef(true); // prevent id re-generation between renders.
3270
3246
 
3271
- var elementIdsRef = useRef(getElementIds$1(props)); // used to keep track of how many items we had on previous cycle.
3247
+ var elementIds = useElementIds(props); // used to keep track of how many items we had on previous cycle.
3272
3248
 
3273
3249
  var previousResultCountRef = useRef(); // utility callback to get item element.
3274
3250
 
@@ -3276,13 +3252,11 @@ function useCombobox(userProps) {
3276
3252
  state: state,
3277
3253
  props: props
3278
3254
  });
3279
-
3280
- var getItemNodeFromIndex = function getItemNodeFromIndex(index) {
3281
- return itemRefs.current[elementIdsRef.current.getItemId(index)];
3282
- }; // Effects.
3255
+ var getItemNodeFromIndex = useCallback(function (index) {
3256
+ return itemRefs.current[elementIds.getItemId(index)];
3257
+ }, [elementIds]); // Effects.
3283
3258
  // Sets a11y status message on changes in state.
3284
3259
 
3285
-
3286
3260
  useA11yMessageSetter(getA11yStatusMessage, [isOpen, highlightedIndex, inputValue, items], _extends({
3287
3261
  isInitialMount: isInitialMountRef.current,
3288
3262
  previousResultCount: previousResultCountRef.current,
@@ -3311,20 +3285,16 @@ function useCombobox(userProps) {
3311
3285
  isInitialMount: isInitialMountRef.current,
3312
3286
  props: props,
3313
3287
  state: state
3314
- }); // Controls the focus on the input on open.
3288
+ }); // Focus the input on first render if required.
3315
3289
 
3316
3290
  useEffect(function () {
3317
- // Don't focus menu on first render.
3318
- if (isInitialMountRef.current) {
3319
- // Unless it was initialised as open.
3320
- if (initialIsOpen || defaultIsOpen || isOpen) {
3321
- if (inputRef.current) {
3322
- inputRef.current.focus();
3323
- }
3324
- }
3291
+ var focusOnOpen = initialIsOpen || defaultIsOpen || isOpen;
3292
+
3293
+ if (focusOnOpen && inputRef.current) {
3294
+ inputRef.current.focus();
3325
3295
  } // eslint-disable-next-line react-hooks/exhaustive-deps
3326
3296
 
3327
- }, [isOpen]);
3297
+ }, []);
3328
3298
  useEffect(function () {
3329
3299
  if (isInitialMountRef.current) {
3330
3300
  return;
@@ -3343,7 +3313,13 @@ function useCombobox(userProps) {
3343
3313
 
3344
3314
  useEffect(function () {
3345
3315
  isInitialMountRef.current = false;
3346
- }, []);
3316
+ }, []); // Reset itemRefs on close.
3317
+
3318
+ useEffect(function () {
3319
+ if (!isOpen) {
3320
+ itemRefs.current = {};
3321
+ }
3322
+ }, [isOpen]);
3347
3323
  /* Event handler functions */
3348
3324
 
3349
3325
  var inputKeyDownHandlers = useMemo(function () {
@@ -3365,6 +3341,10 @@ function useCombobox(userProps) {
3365
3341
  });
3366
3342
  },
3367
3343
  Home: function Home(event) {
3344
+ if (!latest.current.state.isOpen) {
3345
+ return;
3346
+ }
3347
+
3368
3348
  event.preventDefault();
3369
3349
  dispatch({
3370
3350
  type: InputKeyDownHome,
@@ -3372,6 +3352,10 @@ function useCombobox(userProps) {
3372
3352
  });
3373
3353
  },
3374
3354
  End: function End(event) {
3355
+ if (!latest.current.state.isOpen) {
3356
+ return;
3357
+ }
3358
+
3375
3359
  event.preventDefault();
3376
3360
  dispatch({
3377
3361
  type: InputKeyDownEnd,
@@ -3379,36 +3363,37 @@ function useCombobox(userProps) {
3379
3363
  });
3380
3364
  },
3381
3365
  Escape: function Escape() {
3382
- dispatch({
3383
- type: InputKeyDownEscape
3384
- });
3385
- },
3386
- Enter: function Enter(event) {
3387
- // if IME composing, wait for next Enter keydown event.
3388
- if (event.which === 229) {
3389
- return;
3390
- }
3391
-
3392
3366
  var latestState = latest.current.state;
3393
3367
 
3394
- if (latestState.isOpen) {
3395
- event.preventDefault();
3368
+ if (latestState.isOpen || latestState.inputValue || latestState.selectedItem || latestState.highlightedIndex > -1) {
3369
+ dispatch({
3370
+ type: InputKeyDownEscape
3371
+ });
3396
3372
  }
3373
+ },
3374
+ Enter: function Enter(event) {
3375
+ var latestState = latest.current.state; // if closed or no highlighted index, do nothing.
3397
3376
 
3377
+ if (!latestState.isOpen || latestState.highlightedIndex < 0 || event.which === 229 // if IME composing, wait for next Enter keydown event.
3378
+ ) {
3379
+ return;
3380
+ }
3381
+
3382
+ event.preventDefault();
3398
3383
  dispatch({
3399
3384
  type: InputKeyDownEnter,
3400
3385
  getItemNodeFromIndex: getItemNodeFromIndex
3401
3386
  });
3402
3387
  }
3403
3388
  };
3404
- }, [dispatch, latest]); // Getter props.
3389
+ }, [dispatch, latest, getItemNodeFromIndex]); // Getter props.
3405
3390
 
3406
3391
  var getLabelProps = useCallback(function (labelProps) {
3407
3392
  return _extends({
3408
- id: elementIdsRef.current.labelId,
3409
- htmlFor: elementIdsRef.current.inputId
3393
+ id: elementIds.labelId,
3394
+ htmlFor: elementIds.inputId
3410
3395
  }, labelProps);
3411
- }, []);
3396
+ }, [elementIds]);
3412
3397
  var getMenuProps = useCallback(function (_temp, _temp2) {
3413
3398
  var _extends2;
3414
3399
 
@@ -3426,12 +3411,12 @@ function useCombobox(userProps) {
3426
3411
  setGetterPropCallInfo('getMenuProps', suppressRefError, refKey, menuRef);
3427
3412
  return _extends((_extends2 = {}, _extends2[refKey] = handleRefs(ref, function (menuNode) {
3428
3413
  menuRef.current = menuNode;
3429
- }), _extends2.id = elementIdsRef.current.menuId, _extends2.role = 'listbox', _extends2['aria-labelledby'] = elementIdsRef.current.labelId, _extends2.onMouseLeave = callAllEventHandlers(onMouseLeave, function () {
3414
+ }), _extends2.id = elementIds.menuId, _extends2.role = 'listbox', _extends2['aria-labelledby'] = elementIds.labelId, _extends2.onMouseLeave = callAllEventHandlers(onMouseLeave, function () {
3430
3415
  dispatch({
3431
3416
  type: MenuMouseLeave$1
3432
3417
  });
3433
3418
  }), _extends2), rest);
3434
- }, [dispatch, setGetterPropCallInfo]);
3419
+ }, [dispatch, setGetterPropCallInfo, elementIds]);
3435
3420
  var getItemProps = useCallback(function (_temp3) {
3436
3421
  var _extends3, _ref4;
3437
3422
 
@@ -3483,12 +3468,12 @@ function useCombobox(userProps) {
3483
3468
 
3484
3469
  return _extends((_extends3 = {}, _extends3[refKey] = handleRefs(ref, function (itemNode) {
3485
3470
  if (itemNode) {
3486
- itemRefs.current[elementIdsRef.current.getItemId(itemIndex)] = itemNode;
3471
+ itemRefs.current[elementIds.getItemId(itemIndex)] = itemNode;
3487
3472
  }
3488
- }), _extends3.role = 'option', _extends3['aria-selected'] = "" + (itemIndex === latestState.highlightedIndex), _extends3.id = elementIdsRef.current.getItemId(itemIndex), _extends3), !rest.disabled && (_ref4 = {
3473
+ }), _extends3.role = 'option', _extends3['aria-selected'] = "" + (itemIndex === latestState.highlightedIndex), _extends3.id = elementIds.getItemId(itemIndex), _extends3), !rest.disabled && (_ref4 = {
3489
3474
  onMouseMove: callAllEventHandlers(onMouseMove, itemHandleMouseMove)
3490
3475
  }, _ref4[onSelectKey] = callAllEventHandlers(customClickHandler, itemHandleClick), _ref4), rest);
3491
- }, [dispatch, latest, shouldScrollRef]);
3476
+ }, [dispatch, latest, shouldScrollRef, elementIds]);
3492
3477
  var getToggleButtonProps = useCallback(function (_temp4) {
3493
3478
  var _extends4;
3494
3479
 
@@ -3512,10 +3497,10 @@ function useCombobox(userProps) {
3512
3497
 
3513
3498
  return _extends((_extends4 = {}, _extends4[refKey] = handleRefs(ref, function (toggleButtonNode) {
3514
3499
  toggleButtonRef.current = toggleButtonNode;
3515
- }), _extends4.id = elementIdsRef.current.toggleButtonId, _extends4.tabIndex = -1, _extends4), !rest.disabled && _extends({}, {
3500
+ }), _extends4.id = elementIds.toggleButtonId, _extends4.tabIndex = -1, _extends4), !rest.disabled && _extends({}, {
3516
3501
  onClick: callAllEventHandlers(onClick, toggleButtonHandleClick)
3517
3502
  }), rest);
3518
- }, [dispatch, latest]);
3503
+ }, [dispatch, latest, elementIds]);
3519
3504
  var getInputProps = useCallback(function (_temp5, _temp6) {
3520
3505
  var _extends5;
3521
3506
 
@@ -3554,7 +3539,7 @@ function useCombobox(userProps) {
3554
3539
 
3555
3540
  var inputHandleBlur = function inputHandleBlur() {
3556
3541
  /* istanbul ignore else */
3557
- if (!mouseAndTouchTrackersRef.current.isMouseDown) {
3542
+ if (latestState.isOpen && !mouseAndTouchTrackersRef.current.isMouseDown) {
3558
3543
  dispatch({
3559
3544
  type: InputBlur,
3560
3545
  selectItem: true
@@ -3575,16 +3560,16 @@ function useCombobox(userProps) {
3575
3560
 
3576
3561
  return _extends((_extends5 = {}, _extends5[refKey] = handleRefs(ref, function (inputNode) {
3577
3562
  inputRef.current = inputNode;
3578
- }), _extends5.id = elementIdsRef.current.inputId, _extends5['aria-autocomplete'] = 'list', _extends5['aria-controls'] = elementIdsRef.current.menuId, _extends5), latestState.isOpen && latestState.highlightedIndex > -1 && {
3579
- 'aria-activedescendant': elementIdsRef.current.getItemId(latestState.highlightedIndex)
3563
+ }), _extends5.id = elementIds.inputId, _extends5['aria-autocomplete'] = 'list', _extends5['aria-controls'] = elementIds.menuId, _extends5), latestState.isOpen && latestState.highlightedIndex > -1 && {
3564
+ 'aria-activedescendant': elementIds.getItemId(latestState.highlightedIndex)
3580
3565
  }, {
3581
- 'aria-labelledby': elementIdsRef.current.labelId,
3566
+ 'aria-labelledby': elementIds.labelId,
3582
3567
  // https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion
3583
3568
  // revert back since autocomplete="nope" is ignored on latest Chrome and Opera
3584
3569
  autoComplete: 'off',
3585
3570
  value: latestState.inputValue
3586
3571
  }, eventHandlers, rest);
3587
- }, [dispatch, inputKeyDownHandlers, latest, mouseAndTouchTrackersRef, setGetterPropCallInfo]);
3572
+ }, [dispatch, inputKeyDownHandlers, latest, mouseAndTouchTrackersRef, setGetterPropCallInfo, elementIds]);
3588
3573
  var getComboboxProps = useCallback(function (_temp7, _temp8) {
3589
3574
  var _extends6;
3590
3575
 
@@ -3601,8 +3586,8 @@ function useCombobox(userProps) {
3601
3586
  setGetterPropCallInfo('getComboboxProps', suppressRefError, refKey, comboboxRef);
3602
3587
  return _extends((_extends6 = {}, _extends6[refKey] = handleRefs(ref, function (comboboxNode) {
3603
3588
  comboboxRef.current = comboboxNode;
3604
- }), _extends6.role = 'combobox', _extends6['aria-haspopup'] = 'listbox', _extends6['aria-owns'] = elementIdsRef.current.menuId, _extends6['aria-expanded'] = latest.current.state.isOpen, _extends6), rest);
3605
- }, [latest, setGetterPropCallInfo]); // returns
3589
+ }), _extends6.role = 'combobox', _extends6['aria-haspopup'] = 'listbox', _extends6['aria-owns'] = elementIds.menuId, _extends6['aria-expanded'] = latest.current.state.isOpen, _extends6), rest);
3590
+ }, [latest, setGetterPropCallInfo, elementIds]); // returns
3606
3591
 
3607
3592
  var toggleMenu = useCallback(function () {
3608
3593
  dispatch({
@@ -3704,6 +3689,7 @@ function getDefaultValue$1(props, propKey) {
3704
3689
  * @returns {Object} The initial state.
3705
3690
  */
3706
3691
 
3692
+
3707
3693
  function getInitialState$2(props) {
3708
3694
  var activeIndex = getInitialValue$1(props, 'activeIndex');
3709
3695
  var selectedItems = getInitialValue$1(props, 'selectedItems');
@@ -3722,6 +3708,7 @@ function getInitialState$2(props) {
3722
3708
  * @returns {boolean} Whether the operation is allowed.
3723
3709
  */
3724
3710
 
3711
+
3725
3712
  function isKeyDownOperationPermitted(event) {
3726
3713
  if (event.shiftKey || event.metaKey || event.ctrlKey || event.altKey) {
3727
3714
  return false;
@@ -3745,6 +3732,7 @@ function isKeyDownOperationPermitted(event) {
3745
3732
  * @returns {string} The a11y message.
3746
3733
  */
3747
3734
 
3735
+
3748
3736
  function getA11yRemovalMessage(selectionParameters) {
3749
3737
  var removedSelectedItem = selectionParameters.removedSelectedItem,
3750
3738
  itemToStringLocal = selectionParameters.itemToString;
@@ -3782,7 +3770,16 @@ var defaultProps$3 = {
3782
3770
  getA11yRemovalMessage: getA11yRemovalMessage,
3783
3771
  keyNavigationNext: 'ArrowRight',
3784
3772
  keyNavigationPrevious: 'ArrowLeft'
3785
- };
3773
+ }; // eslint-disable-next-line import/no-mutable-exports
3774
+
3775
+ var validatePropTypes$2 = noop;
3776
+ /* istanbul ignore next */
3777
+
3778
+ if (process.env.NODE_ENV !== 'production') {
3779
+ validatePropTypes$2 = function validatePropTypes(options, caller) {
3780
+ PropTypes.checkPropTypes(propTypes$2, options, 'prop', caller.name);
3781
+ };
3782
+ }
3786
3783
 
3787
3784
  var SelectedItemClick = process.env.NODE_ENV !== "production" ? '__selected_item_click__' : 0;
3788
3785
  var SelectedItemKeyDownDelete = process.env.NODE_ENV !== "production" ? '__selected_item_keydown_delete__' : 1;
@@ -3946,7 +3943,8 @@ function useMultipleSelection(userProps) {
3946
3943
  userProps = {};
3947
3944
  }
3948
3945
 
3949
- // Props defaults and destructuring.
3946
+ validatePropTypes$2(userProps, useMultipleSelection); // Props defaults and destructuring.
3947
+
3950
3948
  var props = _extends({}, defaultProps$3, userProps);
3951
3949
 
3952
3950
  var getA11yRemovalMessage = props.getA11yRemovalMessage,