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.
@@ -431,23 +431,25 @@ function targetWithinDownshift(target, downshiftElements, document, checkActiveE
431
431
  return downshiftElements.some(function (contextNode) {
432
432
  return contextNode && (isOrContainsNode(contextNode, target) || checkActiveElement && isOrContainsNode(contextNode, document.activeElement));
433
433
  });
434
- }
434
+ } // eslint-disable-next-line import/no-mutable-exports
435
435
 
436
- function validateControlledUnchanged(state, prevProps, nextProps) {
437
- if (process.env.NODE_ENV === 'production') {
438
- return;
439
- }
440
436
 
441
- 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";
442
- Object.keys(state).forEach(function (propKey) {
443
- if (prevProps[propKey] !== undefined && nextProps[propKey] === undefined) {
444
- // eslint-disable-next-line no-console
445
- console.error("downshift: A component has changed the controlled prop \"" + propKey + "\" to be uncontrolled. " + warningDescription);
446
- } else if (prevProps[propKey] === undefined && nextProps[propKey] !== undefined) {
447
- // eslint-disable-next-line no-console
448
- console.error("downshift: A component has changed the uncontrolled prop \"" + propKey + "\" to be controlled. " + warningDescription);
449
- }
450
- });
437
+ var validateControlledUnchanged = noop;
438
+ /* istanbul ignore next */
439
+
440
+ if (process.env.NODE_ENV !== 'production') {
441
+ validateControlledUnchanged = function validateControlledUnchanged(state, prevProps, nextProps) {
442
+ 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";
443
+ Object.keys(state).forEach(function (propKey) {
444
+ if (prevProps[propKey] !== undefined && nextProps[propKey] === undefined) {
445
+ // eslint-disable-next-line no-console
446
+ console.error("downshift: A component has changed the controlled prop \"" + propKey + "\" to be uncontrolled. " + warningDescription);
447
+ } else if (prevProps[propKey] === undefined && nextProps[propKey] !== undefined) {
448
+ // eslint-disable-next-line no-console
449
+ console.error("downshift: A component has changed the uncontrolled prop \"" + propKey + "\" to be controlled. " + warningDescription);
450
+ }
451
+ });
452
+ };
451
453
  }
452
454
 
453
455
  var cleanupStatus = debounce(function (documentProp) {
@@ -865,12 +867,16 @@ var Downshift = /*#__PURE__*/function () {
865
867
  Home: function Home(event) {
866
868
  var _this4 = this;
867
869
 
868
- event.preventDefault();
869
- var itemCount = this.getItemCount();
870
-
871
870
  var _this$getState3 = this.getState(),
872
871
  isOpen = _this$getState3.isOpen;
873
872
 
873
+ if (!isOpen) {
874
+ return;
875
+ }
876
+
877
+ event.preventDefault();
878
+ var itemCount = this.getItemCount();
879
+
874
880
  if (itemCount <= 0 || !isOpen) {
875
881
  return;
876
882
  } // get next non-disabled starting downwards from 0 if that's disabled.
@@ -886,12 +892,16 @@ var Downshift = /*#__PURE__*/function () {
886
892
  End: function End(event) {
887
893
  var _this5 = this;
888
894
 
889
- event.preventDefault();
890
- var itemCount = this.getItemCount();
891
-
892
895
  var _this$getState4 = this.getState(),
893
896
  isOpen = _this$getState4.isOpen;
894
897
 
898
+ if (!isOpen) {
899
+ return;
900
+ }
901
+
902
+ event.preventDefault();
903
+ var itemCount = this.getItemCount();
904
+
895
905
  if (itemCount <= 0 || !isOpen) {
896
906
  return;
897
907
  } // get next non-disabled starting upwards from last index if that's disabled.
@@ -1703,22 +1713,27 @@ var updateA11yStatus = debounce(function (getA11yMessage, document) {
1703
1713
  }, 200); // istanbul ignore next
1704
1714
 
1705
1715
  var useIsomorphicLayoutEffect = typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined' ? react.useLayoutEffect : react.useEffect;
1706
- function getElementIds(_ref) {
1707
- var id = _ref.id,
1716
+
1717
+ function useElementIds(_ref) {
1718
+ var _ref$id = _ref.id,
1719
+ id = _ref$id === void 0 ? "downshift-" + generateId() : _ref$id,
1708
1720
  labelId = _ref.labelId,
1709
1721
  menuId = _ref.menuId,
1710
1722
  getItemId = _ref.getItemId,
1711
- toggleButtonId = _ref.toggleButtonId;
1712
- var uniqueId = id === undefined ? "downshift-" + generateId() : id;
1713
- return {
1714
- labelId: labelId || uniqueId + "-label",
1715
- menuId: menuId || uniqueId + "-menu",
1723
+ toggleButtonId = _ref.toggleButtonId,
1724
+ inputId = _ref.inputId;
1725
+ var elementIdsRef = react.useRef({
1726
+ labelId: labelId || id + "-label",
1727
+ menuId: menuId || id + "-menu",
1716
1728
  getItemId: getItemId || function (index) {
1717
- return uniqueId + "-item-" + index;
1729
+ return id + "-item-" + index;
1718
1730
  },
1719
- toggleButtonId: toggleButtonId || uniqueId + "-toggle-button"
1720
- };
1731
+ toggleButtonId: toggleButtonId || id + "-toggle-button",
1732
+ inputId: inputId || id + "-input"
1733
+ });
1734
+ return elementIdsRef.current;
1721
1735
  }
1736
+
1722
1737
  function getItemIndex(index, item, items) {
1723
1738
  if (index !== undefined) {
1724
1739
  return index;
@@ -1735,24 +1750,14 @@ function itemToString(item) {
1735
1750
  return item ? String(item) : '';
1736
1751
  }
1737
1752
 
1738
- function getPropTypesValidator(caller, propTypes) {
1739
- // istanbul ignore next
1740
- return function validate(options) {
1741
- if (options === void 0) {
1742
- options = {};
1743
- }
1744
-
1745
- Object.keys(propTypes).forEach(function (key) {
1746
- PropTypes__default['default'].checkPropTypes(propTypes, options, key, caller.name);
1747
- });
1748
- };
1749
- }
1750
1753
  function isAcceptedCharacterKey(key) {
1751
1754
  return /^\S{1}$/.test(key);
1752
1755
  }
1756
+
1753
1757
  function capitalizeString(string) {
1754
1758
  return "" + string.slice(0, 1).toUpperCase() + string.slice(1);
1755
1759
  }
1760
+
1756
1761
  function useLatestRef(val) {
1757
1762
  var ref = react.useRef(val); // technically this is not "concurrent mode safe" because we're manipulating
1758
1763
  // the value during render (so it's not idempotent). However, the places this
@@ -1774,6 +1779,7 @@ function useLatestRef(val) {
1774
1779
  * @returns {Array} An array with the state and an action dispatcher.
1775
1780
  */
1776
1781
 
1782
+
1777
1783
  function useEnhancedReducer(reducer, initialState, props) {
1778
1784
  var prevStateRef = react.useRef();
1779
1785
  var actionRef = react.useRef();
@@ -1817,6 +1823,7 @@ function useEnhancedReducer(reducer, initialState, props) {
1817
1823
  * @returns {Array} An array with the state and an action dispatcher.
1818
1824
  */
1819
1825
 
1826
+
1820
1827
  function useControlledReducer(reducer, initialState, props) {
1821
1828
  var _useEnhancedReducer = useEnhancedReducer(reducer, initialState, props),
1822
1829
  state = _useEnhancedReducer[0],
@@ -1824,6 +1831,7 @@ function useControlledReducer(reducer, initialState, props) {
1824
1831
 
1825
1832
  return [getState(state, props), dispatch];
1826
1833
  }
1834
+
1827
1835
  var defaultProps = {
1828
1836
  itemToString: itemToString,
1829
1837
  stateReducer: stateReducer,
@@ -1834,6 +1842,7 @@ var defaultProps = {
1834
1842
  /* istanbul ignore next (ssr) */
1835
1843
  ? {} : window
1836
1844
  };
1845
+
1837
1846
  function getDefaultValue(props, propKey, defaultStateValues) {
1838
1847
  if (defaultStateValues === void 0) {
1839
1848
  defaultStateValues = dropdownDefaultStateValues;
@@ -1847,6 +1856,7 @@ function getDefaultValue(props, propKey, defaultStateValues) {
1847
1856
 
1848
1857
  return defaultStateValues[propKey];
1849
1858
  }
1859
+
1850
1860
  function getInitialValue(props, propKey, defaultStateValues) {
1851
1861
  if (defaultStateValues === void 0) {
1852
1862
  defaultStateValues = dropdownDefaultStateValues;
@@ -1864,6 +1874,7 @@ function getInitialValue(props, propKey, defaultStateValues) {
1864
1874
 
1865
1875
  return getDefaultValue(props, propKey, defaultStateValues);
1866
1876
  }
1877
+
1867
1878
  function getInitialState(props) {
1868
1879
  var selectedItem = getInitialValue(props, 'selectedItem');
1869
1880
  var isOpen = getInitialValue(props, 'isOpen');
@@ -1876,6 +1887,7 @@ function getInitialState(props) {
1876
1887
  inputValue: inputValue
1877
1888
  };
1878
1889
  }
1890
+
1879
1891
  function getHighlightedIndexOnOpen(props, state, offset, getItemNodeFromIndex) {
1880
1892
  var items = props.items,
1881
1893
  initialHighlightedIndex = props.initialHighlightedIndex,
@@ -1920,6 +1932,7 @@ function getHighlightedIndexOnOpen(props, state, offset, getItemNodeFromIndex) {
1920
1932
  * @returns {Object} Ref containing whether mouseDown or touchMove event is happening
1921
1933
  */
1922
1934
 
1935
+
1923
1936
  function useMouseAndTouchTracker(isOpen, downshiftElementRefs, environment, handleBlur) {
1924
1937
  var mouseAndTouchTrackersRef = react.useRef({
1925
1938
  isMouseDown: false,
@@ -1973,6 +1986,13 @@ function useMouseAndTouchTracker(isOpen, downshiftElementRefs, environment, hand
1973
1986
  }, [isOpen, environment]);
1974
1987
  return mouseAndTouchTrackersRef;
1975
1988
  }
1989
+ /* istanbul ignore next */
1990
+ // eslint-disable-next-line import/no-mutable-exports
1991
+
1992
+
1993
+ var useGetterPropsCalledChecker = function useGetterPropsCalledChecker() {
1994
+ return noop;
1995
+ };
1976
1996
  /**
1977
1997
  * Custom hook that checks if getter props are called correctly.
1978
1998
  *
@@ -1980,63 +2000,61 @@ function useMouseAndTouchTracker(isOpen, downshiftElementRefs, environment, hand
1980
2000
  * @returns {Function} Setter function called inside getter props to set call information.
1981
2001
  */
1982
2002
 
1983
- function useGetterPropsCalledChecker() {
1984
- var isNotProduction = process.env.NODE_ENV !== 'production';
1985
- var isInitialMountRef = react.useRef(true);
2003
+ /* istanbul ignore next */
1986
2004
 
1987
- for (var _len = arguments.length, propKeys = new Array(_len), _key = 0; _key < _len; _key++) {
1988
- propKeys[_key] = arguments[_key];
1989
- }
1990
2005
 
1991
- var getterPropsCalledRef = react.useRef(propKeys.reduce(function (acc, propKey) {
1992
- acc[propKey] = {};
1993
- return acc;
1994
- }, {}));
1995
- react.useEffect(function () {
1996
- if (!isNotProduction) {
1997
- return;
1998
- }
2006
+ if (process.env.NODE_ENV !== 'production') {
2007
+ useGetterPropsCalledChecker = function useGetterPropsCalledChecker() {
2008
+ var isInitialMountRef = react.useRef(true);
1999
2009
 
2000
- Object.keys(getterPropsCalledRef.current).forEach(function (propKey) {
2001
- var propCallInfo = getterPropsCalledRef.current[propKey];
2010
+ for (var _len = arguments.length, propKeys = new Array(_len), _key = 0; _key < _len; _key++) {
2011
+ propKeys[_key] = arguments[_key];
2012
+ }
2002
2013
 
2003
- if (isInitialMountRef.current) {
2004
- if (!Object.keys(propCallInfo).length) {
2005
- // eslint-disable-next-line no-console
2006
- console.error("downshift: You forgot to call the " + propKey + " getter function on your component / element.");
2007
- return;
2014
+ var getterPropsCalledRef = react.useRef(propKeys.reduce(function (acc, propKey) {
2015
+ acc[propKey] = {};
2016
+ return acc;
2017
+ }, {}));
2018
+ react.useEffect(function () {
2019
+ Object.keys(getterPropsCalledRef.current).forEach(function (propKey) {
2020
+ var propCallInfo = getterPropsCalledRef.current[propKey];
2021
+
2022
+ if (isInitialMountRef.current) {
2023
+ if (!Object.keys(propCallInfo).length) {
2024
+ // eslint-disable-next-line no-console
2025
+ console.error("downshift: You forgot to call the " + propKey + " getter function on your component / element.");
2026
+ return;
2027
+ }
2008
2028
  }
2009
- }
2010
2029
 
2011
- var suppressRefError = propCallInfo.suppressRefError,
2012
- refKey = propCallInfo.refKey,
2013
- elementRef = propCallInfo.elementRef;
2030
+ var suppressRefError = propCallInfo.suppressRefError,
2031
+ refKey = propCallInfo.refKey,
2032
+ elementRef = propCallInfo.elementRef;
2014
2033
 
2015
- if ((!elementRef || !elementRef.current) && !suppressRefError) {
2016
- // eslint-disable-next-line no-console
2017
- console.error("downshift: The ref prop \"" + refKey + "\" from " + propKey + " was not applied correctly on your element.");
2018
- }
2034
+ if ((!elementRef || !elementRef.current) && !suppressRefError) {
2035
+ // eslint-disable-next-line no-console
2036
+ console.error("downshift: The ref prop \"" + refKey + "\" from " + propKey + " was not applied correctly on your element.");
2037
+ }
2038
+ });
2039
+ isInitialMountRef.current = false;
2019
2040
  });
2020
- isInitialMountRef.current = false;
2021
- });
2022
- var setGetterPropCallInfo = react.useCallback(function (propKey, suppressRefError, refKey, elementRef) {
2023
- if (process.env.NODE_ENV !== 'production') {
2041
+ var setGetterPropCallInfo = react.useCallback(function (propKey, suppressRefError, refKey, elementRef) {
2024
2042
  getterPropsCalledRef.current[propKey] = {
2025
2043
  suppressRefError: suppressRefError,
2026
2044
  refKey: refKey,
2027
2045
  elementRef: elementRef
2028
2046
  };
2029
- }
2030
- }, []);
2031
- return setGetterPropCallInfo;
2047
+ }, []);
2048
+ return setGetterPropCallInfo;
2049
+ };
2032
2050
  }
2051
+
2033
2052
  function useA11yMessageSetter(getA11yMessage, dependencyArray, _ref2) {
2034
2053
  var isInitialMount = _ref2.isInitialMount,
2035
- previousResultCount = _ref2.previousResultCount,
2036
2054
  highlightedIndex = _ref2.highlightedIndex,
2037
2055
  items = _ref2.items,
2038
2056
  environment = _ref2.environment,
2039
- rest = _objectWithoutPropertiesLoose__default['default'](_ref2, ["isInitialMount", "previousResultCount", "highlightedIndex", "items", "environment"]);
2057
+ rest = _objectWithoutPropertiesLoose__default['default'](_ref2, ["isInitialMount", "highlightedIndex", "items", "environment"]);
2040
2058
 
2041
2059
  // Sets a11y status message on changes in state.
2042
2060
  react.useEffect(function () {
@@ -2048,12 +2066,12 @@ function useA11yMessageSetter(getA11yMessage, dependencyArray, _ref2) {
2048
2066
  return getA11yMessage(_extends__default['default']({
2049
2067
  highlightedIndex: highlightedIndex,
2050
2068
  highlightedItem: items[highlightedIndex],
2051
- resultCount: items.length,
2052
- previousResultCount: previousResultCount
2069
+ resultCount: items.length
2053
2070
  }, rest));
2054
2071
  }, environment.document); // eslint-disable-next-line react-hooks/exhaustive-deps
2055
2072
  }, dependencyArray);
2056
2073
  }
2074
+
2057
2075
  function useScrollIntoView(_ref3) {
2058
2076
  var highlightedIndex = _ref3.highlightedIndex,
2059
2077
  isOpen = _ref3.isOpen,
@@ -2077,47 +2095,112 @@ function useScrollIntoView(_ref3) {
2077
2095
 
2078
2096
  }, [highlightedIndex]);
2079
2097
  return shouldScrollRef;
2080
- }
2081
- function useControlPropsValidator(_ref4) {
2082
- var isInitialMount = _ref4.isInitialMount,
2083
- props = _ref4.props,
2084
- state = _ref4.state;
2085
- // used for checking when props are moving from controlled to uncontrolled.
2086
- var prevPropsRef = react.useRef(props);
2087
- react.useEffect(function () {
2088
- if (isInitialMount) {
2089
- return;
2090
- }
2098
+ } // eslint-disable-next-line import/no-mutable-exports
2091
2099
 
2092
- validateControlledUnchanged(state, prevPropsRef.current, props);
2093
- prevPropsRef.current = props;
2094
- }, [state, props, isInitialMount]);
2095
- }
2096
2100
 
2097
- function getItemIndexByCharacterKey(keysSoFar, highlightedIndex, items, itemToStringParam, getItemNodeFromIndex) {
2098
- var lowerCasedItemStrings = items.map(function (item) {
2099
- return itemToStringParam(item).toLowerCase();
2100
- });
2101
- var lowerCasedKeysSoFar = keysSoFar.toLowerCase();
2101
+ var useControlPropsValidator = noop;
2102
+ /* istanbul ignore next */
2102
2103
 
2103
- var isValid = function isValid(itemString, index) {
2104
- var element = getItemNodeFromIndex(index);
2105
- return itemString.startsWith(lowerCasedKeysSoFar) && !(element && element.hasAttribute('disabled'));
2104
+ if (process.env.NODE_ENV !== 'production') {
2105
+ useControlPropsValidator = function useControlPropsValidator(_ref4) {
2106
+ var isInitialMount = _ref4.isInitialMount,
2107
+ props = _ref4.props,
2108
+ state = _ref4.state;
2109
+ // used for checking when props are moving from controlled to uncontrolled.
2110
+ var prevPropsRef = react.useRef(props);
2111
+ react.useEffect(function () {
2112
+ if (isInitialMount) {
2113
+ return;
2114
+ }
2115
+
2116
+ validateControlledUnchanged(state, prevPropsRef.current, props);
2117
+ prevPropsRef.current = props;
2118
+ }, [state, props, isInitialMount]);
2106
2119
  };
2120
+ }
2107
2121
 
2108
- for (var index = highlightedIndex + 1; index < lowerCasedItemStrings.length; index++) {
2109
- var itemString = lowerCasedItemStrings[index];
2122
+ /* eslint-disable complexity */
2110
2123
 
2111
- if (isValid(itemString, index)) {
2112
- return index;
2113
- }
2124
+ function downshiftCommonReducer(state, action, stateChangeTypes) {
2125
+ var type = action.type,
2126
+ props = action.props;
2127
+ var changes;
2128
+
2129
+ switch (type) {
2130
+ case stateChangeTypes.ItemMouseMove:
2131
+ changes = {
2132
+ highlightedIndex: action.index
2133
+ };
2134
+ break;
2135
+
2136
+ case stateChangeTypes.MenuMouseLeave:
2137
+ changes = {
2138
+ highlightedIndex: -1
2139
+ };
2140
+ break;
2141
+
2142
+ case stateChangeTypes.ToggleButtonClick:
2143
+ case stateChangeTypes.FunctionToggleMenu:
2144
+ changes = {
2145
+ isOpen: !state.isOpen,
2146
+ highlightedIndex: state.isOpen ? -1 : getHighlightedIndexOnOpen(props, state, 0)
2147
+ };
2148
+ break;
2149
+
2150
+ case stateChangeTypes.FunctionOpenMenu:
2151
+ changes = {
2152
+ isOpen: true,
2153
+ highlightedIndex: getHighlightedIndexOnOpen(props, state, 0)
2154
+ };
2155
+ break;
2156
+
2157
+ case stateChangeTypes.FunctionCloseMenu:
2158
+ changes = {
2159
+ isOpen: false
2160
+ };
2161
+ break;
2162
+
2163
+ case stateChangeTypes.FunctionSetHighlightedIndex:
2164
+ changes = {
2165
+ highlightedIndex: action.highlightedIndex
2166
+ };
2167
+ break;
2168
+
2169
+ case stateChangeTypes.FunctionSetInputValue:
2170
+ changes = {
2171
+ inputValue: action.inputValue
2172
+ };
2173
+ break;
2174
+
2175
+ case stateChangeTypes.FunctionReset:
2176
+ changes = {
2177
+ highlightedIndex: getDefaultValue(props, 'highlightedIndex'),
2178
+ isOpen: getDefaultValue(props, 'isOpen'),
2179
+ selectedItem: getDefaultValue(props, 'selectedItem'),
2180
+ inputValue: getDefaultValue(props, 'inputValue')
2181
+ };
2182
+ break;
2183
+
2184
+ default:
2185
+ throw new Error('Reducer called without proper action type.');
2114
2186
  }
2115
2187
 
2116
- for (var _index = 0; _index < highlightedIndex; _index++) {
2117
- var _itemString = lowerCasedItemStrings[_index];
2188
+ return _extends__default['default']({}, state, changes);
2189
+ }
2190
+ /* eslint-enable complexity */
2191
+
2192
+ function getItemIndexByCharacterKey(keysSoFar, highlightedIndex, items, itemToString, getItemNodeFromIndex) {
2193
+ var lowerCasedKeysSoFar = keysSoFar.toLowerCase();
2194
+
2195
+ for (var index = 0; index < items.length; index++) {
2196
+ var offsetIndex = (index + highlightedIndex + 1) % items.length;
2197
+
2198
+ if (itemToString(items[offsetIndex]).toLowerCase().startsWith(lowerCasedKeysSoFar)) {
2199
+ var element = getItemNodeFromIndex(offsetIndex);
2118
2200
 
2119
- if (isValid(_itemString, _index)) {
2120
- return _index;
2201
+ if (!(element && element.hasAttribute('disabled'))) {
2202
+ return offsetIndex;
2203
+ }
2121
2204
  }
2122
2205
  }
2123
2206
 
@@ -2190,7 +2273,17 @@ function getA11yStatusMessage$1(_ref) {
2190
2273
 
2191
2274
  var defaultProps$1 = _extends__default['default']({}, defaultProps, {
2192
2275
  getA11yStatusMessage: getA11yStatusMessage$1
2193
- });
2276
+ }); // eslint-disable-next-line import/no-mutable-exports
2277
+
2278
+
2279
+ var validatePropTypes = noop;
2280
+ /* istanbul ignore next */
2281
+
2282
+ if (process.env.NODE_ENV !== 'production') {
2283
+ validatePropTypes = function validatePropTypes(options, caller) {
2284
+ PropTypes__default['default'].checkPropTypes(propTypes, options, 'prop', caller.name);
2285
+ };
2286
+ }
2194
2287
 
2195
2288
  var MenuKeyDownArrowDown = process.env.NODE_ENV !== "production" ? '__menu_keydown_arrow_down__' : 0;
2196
2289
  var MenuKeyDownArrowUp = process.env.NODE_ENV !== "production" ? '__menu_keydown_arrow_up__' : 1;
@@ -2252,12 +2345,6 @@ function downshiftSelectReducer(state, action) {
2252
2345
  var changes;
2253
2346
 
2254
2347
  switch (type) {
2255
- case ItemMouseMove:
2256
- changes = {
2257
- highlightedIndex: action.index
2258
- };
2259
- break;
2260
-
2261
2348
  case ItemClick:
2262
2349
  changes = {
2263
2350
  isOpen: getDefaultValue(props, 'isOpen'),
@@ -2356,71 +2443,20 @@ function downshiftSelectReducer(state, action) {
2356
2443
  };
2357
2444
  break;
2358
2445
 
2359
- case MenuMouseLeave:
2360
- changes = {
2361
- highlightedIndex: -1
2362
- };
2363
- break;
2364
-
2365
- case ToggleButtonClick:
2366
- case FunctionToggleMenu:
2367
- changes = {
2368
- isOpen: !state.isOpen,
2369
- highlightedIndex: state.isOpen ? -1 : getHighlightedIndexOnOpen(props, state, 0)
2370
- };
2371
- break;
2372
-
2373
- case FunctionOpenMenu:
2374
- changes = {
2375
- isOpen: true,
2376
- highlightedIndex: getHighlightedIndexOnOpen(props, state, 0)
2377
- };
2378
- break;
2379
-
2380
- case FunctionCloseMenu:
2381
- changes = {
2382
- isOpen: false
2383
- };
2384
- break;
2385
-
2386
- case FunctionSetHighlightedIndex:
2387
- changes = {
2388
- highlightedIndex: action.highlightedIndex
2389
- };
2390
- break;
2391
-
2392
2446
  case FunctionSelectItem:
2393
2447
  changes = {
2394
2448
  selectedItem: action.selectedItem
2395
2449
  };
2396
2450
  break;
2397
2451
 
2398
- case FunctionSetInputValue:
2399
- changes = {
2400
- inputValue: action.inputValue
2401
- };
2402
- break;
2403
-
2404
- case FunctionReset:
2405
- changes = {
2406
- highlightedIndex: getDefaultValue(props, 'highlightedIndex'),
2407
- isOpen: getDefaultValue(props, 'isOpen'),
2408
- selectedItem: getDefaultValue(props, 'selectedItem'),
2409
- inputValue: getDefaultValue(props, 'inputValue')
2410
- };
2411
- break;
2412
-
2413
2452
  default:
2414
- throw new Error('Reducer called without proper action type.');
2453
+ return downshiftCommonReducer(state, action, stateChangeTypes$1);
2415
2454
  }
2416
2455
 
2417
2456
  return _extends__default['default']({}, state, changes);
2418
2457
  }
2419
2458
  /* eslint-enable complexity */
2420
2459
 
2421
- var validatePropTypes = process.env.NODE_ENV === 'production' ?
2422
- /* istanbul ignore next */
2423
- null : getPropTypesValidator(useSelect, propTypes);
2424
2460
  useSelect.stateChangeTypes = stateChangeTypes$1;
2425
2461
 
2426
2462
  function useSelect(userProps) {
@@ -2428,11 +2464,7 @@ function useSelect(userProps) {
2428
2464
  userProps = {};
2429
2465
  }
2430
2466
 
2431
- /* istanbul ignore else */
2432
- if (process.env.NODE_ENV !== 'production') {
2433
- validatePropTypes(userProps);
2434
- } // Props defaults and destructuring.
2435
-
2467
+ validatePropTypes(userProps, useSelect); // Props defaults and destructuring.
2436
2468
 
2437
2469
  var props = _extends__default['default']({}, defaultProps$1, userProps);
2438
2470
 
@@ -2458,14 +2490,13 @@ function useSelect(userProps) {
2458
2490
 
2459
2491
  var toggleButtonRef = react.useRef(null);
2460
2492
  var menuRef = react.useRef(null);
2461
- var itemRefs = react.useRef();
2462
- itemRefs.current = {}; // used not to trigger menu blur action in some scenarios.
2493
+ var itemRefs = react.useRef({}); // used not to trigger menu blur action in some scenarios.
2463
2494
 
2464
2495
  var shouldBlurRef = react.useRef(true); // used to keep the inputValue clearTimeout object between renders.
2465
2496
 
2466
2497
  var clearTimeoutRef = react.useRef(null); // prevent id re-generation between renders.
2467
2498
 
2468
- var elementIdsRef = react.useRef(getElementIds(props)); // used to keep track of how many items we had on previous cycle.
2499
+ var elementIds = useElementIds(props); // used to keep track of how many items we had on previous cycle.
2469
2500
 
2470
2501
  var previousResultCountRef = react.useRef();
2471
2502
  var isInitialMountRef = react.useRef(true); // utility callback to get item element.
@@ -2475,12 +2506,11 @@ function useSelect(userProps) {
2475
2506
  props: props
2476
2507
  }); // Some utils.
2477
2508
 
2478
- var getItemNodeFromIndex = function getItemNodeFromIndex(index) {
2479
- return itemRefs.current[elementIdsRef.current.getItemId(index)];
2480
- }; // Effects.
2509
+ var getItemNodeFromIndex = react.useCallback(function (index) {
2510
+ return itemRefs.current[elementIds.getItemId(index)];
2511
+ }, [elementIds]); // Effects.
2481
2512
  // Sets a11y status message on changes in state.
2482
2513
 
2483
-
2484
2514
  useA11yMessageSetter(getA11yStatusMessage, [isOpen, highlightedIndex, inputValue, items], _extends__default['default']({
2485
2515
  isInitialMount: isInitialMountRef.current,
2486
2516
  previousResultCount: previousResultCountRef.current,
@@ -2578,7 +2608,13 @@ function useSelect(userProps) {
2578
2608
 
2579
2609
  react.useEffect(function () {
2580
2610
  isInitialMountRef.current = false;
2581
- }, []); // Event handler functions.
2611
+ }, []); // Reset itemRefs on close.
2612
+
2613
+ react.useEffect(function () {
2614
+ if (!isOpen) {
2615
+ itemRefs.current = {};
2616
+ }
2617
+ }, [isOpen]); // Event handler functions.
2582
2618
 
2583
2619
  var toggleButtonKeyDownHandlers = react.useMemo(function () {
2584
2620
  return {
@@ -2599,7 +2635,7 @@ function useSelect(userProps) {
2599
2635
  });
2600
2636
  }
2601
2637
  };
2602
- }, [dispatch]);
2638
+ }, [dispatch, getItemNodeFromIndex]);
2603
2639
  var menuKeyDownHandlers = react.useMemo(function () {
2604
2640
  return {
2605
2641
  ArrowDown: function ArrowDown(event) {
@@ -2650,7 +2686,7 @@ function useSelect(userProps) {
2650
2686
  });
2651
2687
  }
2652
2688
  };
2653
- }, [dispatch]); // Action functions.
2689
+ }, [dispatch, getItemNodeFromIndex]); // Action functions.
2654
2690
 
2655
2691
  var toggleMenu = react.useCallback(function () {
2656
2692
  dispatch({
@@ -2693,10 +2729,10 @@ function useSelect(userProps) {
2693
2729
 
2694
2730
  var getLabelProps = react.useCallback(function (labelProps) {
2695
2731
  return _extends__default['default']({
2696
- id: elementIdsRef.current.labelId,
2697
- htmlFor: elementIdsRef.current.toggleButtonId
2732
+ id: elementIds.labelId,
2733
+ htmlFor: elementIds.toggleButtonId
2698
2734
  }, labelProps);
2699
- }, []);
2735
+ }, [elementIds]);
2700
2736
  var getMenuProps = react.useCallback(function (_temp, _temp2) {
2701
2737
  var _extends2;
2702
2738
 
@@ -2755,14 +2791,14 @@ function useSelect(userProps) {
2755
2791
  setGetterPropCallInfo('getMenuProps', suppressRefError, refKey, menuRef);
2756
2792
  return _extends__default['default']((_extends2 = {}, _extends2[refKey] = handleRefs(ref, function (menuNode) {
2757
2793
  menuRef.current = menuNode;
2758
- }), _extends2.id = elementIdsRef.current.menuId, _extends2.role = 'listbox', _extends2['aria-labelledby'] = elementIdsRef.current.labelId, _extends2.tabIndex = -1, _extends2), latestState.isOpen && latestState.highlightedIndex > -1 && {
2759
- 'aria-activedescendant': elementIdsRef.current.getItemId(latestState.highlightedIndex)
2794
+ }), _extends2.id = elementIds.menuId, _extends2.role = 'listbox', _extends2['aria-labelledby'] = elementIds.labelId, _extends2.tabIndex = -1, _extends2), latestState.isOpen && latestState.highlightedIndex > -1 && {
2795
+ 'aria-activedescendant': elementIds.getItemId(latestState.highlightedIndex)
2760
2796
  }, {
2761
2797
  onMouseLeave: callAllEventHandlers(onMouseLeave, menuHandleMouseLeave),
2762
2798
  onKeyDown: callAllEventHandlers(onKeyDown, menuHandleKeyDown),
2763
2799
  onBlur: callAllEventHandlers(onBlur, menuHandleBlur)
2764
2800
  }, rest);
2765
- }, [dispatch, latest, menuKeyDownHandlers, mouseAndTouchTrackersRef, setGetterPropCallInfo]);
2801
+ }, [dispatch, latest, menuKeyDownHandlers, mouseAndTouchTrackersRef, setGetterPropCallInfo, elementIds, getItemNodeFromIndex]);
2766
2802
  var getToggleButtonProps = react.useCallback(function (_temp3, _temp4) {
2767
2803
  var _extends3;
2768
2804
 
@@ -2800,7 +2836,7 @@ function useSelect(userProps) {
2800
2836
 
2801
2837
  var toggleProps = _extends__default['default']((_extends3 = {}, _extends3[refKey] = handleRefs(ref, function (toggleButtonNode) {
2802
2838
  toggleButtonRef.current = toggleButtonNode;
2803
- }), _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);
2839
+ }), _extends3.id = elementIds.toggleButtonId, _extends3['aria-haspopup'] = 'listbox', _extends3['aria-expanded'] = latest.current.state.isOpen, _extends3['aria-labelledby'] = elementIds.labelId + " " + elementIds.toggleButtonId, _extends3), rest);
2804
2840
 
2805
2841
  if (!rest.disabled) {
2806
2842
  toggleProps.onClick = callAllEventHandlers(onClick, toggleButtonHandleClick);
@@ -2809,7 +2845,7 @@ function useSelect(userProps) {
2809
2845
 
2810
2846
  setGetterPropCallInfo('getToggleButtonProps', suppressRefError, refKey, toggleButtonRef);
2811
2847
  return toggleProps;
2812
- }, [dispatch, latest, toggleButtonKeyDownHandlers, setGetterPropCallInfo]);
2848
+ }, [dispatch, latest, toggleButtonKeyDownHandlers, setGetterPropCallInfo, elementIds, getItemNodeFromIndex]);
2813
2849
  var getItemProps = react.useCallback(function (_temp5) {
2814
2850
  var _extends4;
2815
2851
 
@@ -2855,10 +2891,10 @@ function useSelect(userProps) {
2855
2891
  var itemProps = _extends__default['default']((_extends4 = {
2856
2892
  role: 'option',
2857
2893
  'aria-selected': "" + (itemIndex === latestState.highlightedIndex),
2858
- id: elementIdsRef.current.getItemId(itemIndex)
2894
+ id: elementIds.getItemId(itemIndex)
2859
2895
  }, _extends4[refKey] = handleRefs(ref, function (itemNode) {
2860
2896
  if (itemNode) {
2861
- itemRefs.current[elementIdsRef.current.getItemId(itemIndex)] = itemNode;
2897
+ itemRefs.current[elementIds.getItemId(itemIndex)] = itemNode;
2862
2898
  }
2863
2899
  }), _extends4), rest);
2864
2900
 
@@ -2868,7 +2904,7 @@ function useSelect(userProps) {
2868
2904
  }
2869
2905
 
2870
2906
  return itemProps;
2871
- }, [dispatch, latest, shouldScrollRef]);
2907
+ }, [dispatch, latest, shouldScrollRef, elementIds]);
2872
2908
  return {
2873
2909
  // prop getters.
2874
2910
  getToggleButtonProps: getToggleButtonProps,
@@ -2936,18 +2972,6 @@ var stateChangeTypes$2 = /*#__PURE__*/Object.freeze({
2936
2972
  ControlledPropUpdatedSelectedItem: ControlledPropUpdatedSelectedItem
2937
2973
  });
2938
2974
 
2939
- function getElementIds$1(_ref) {
2940
- var id = _ref.id,
2941
- inputId = _ref.inputId,
2942
- rest = _objectWithoutPropertiesLoose__default['default'](_ref, ["id", "inputId"]);
2943
-
2944
- var uniqueId = id === undefined ? "downshift-" + generateId() : id;
2945
- return _extends__default['default']({
2946
- inputId: inputId || uniqueId + "-input"
2947
- }, getElementIds(_extends__default['default']({
2948
- id: id
2949
- }, rest)));
2950
- }
2951
2975
  function getInitialState$1(props) {
2952
2976
  var initialState = getInitialState(props);
2953
2977
  var selectedItem = initialState.selectedItem;
@@ -2961,6 +2985,7 @@ function getInitialState$1(props) {
2961
2985
  inputValue: inputValue
2962
2986
  });
2963
2987
  }
2988
+
2964
2989
  var propTypes$1 = {
2965
2990
  items: PropTypes__default['default'].array.isRequired,
2966
2991
  itemToString: PropTypes__default['default'].func,
@@ -3035,7 +3060,18 @@ function useControlledReducer$1(reducer, initialState, props) {
3035
3060
  }
3036
3061
  });
3037
3062
  return [getState(state, props), dispatch];
3063
+ } // eslint-disable-next-line import/no-mutable-exports
3064
+
3065
+
3066
+ var validatePropTypes$1 = noop;
3067
+ /* istanbul ignore next */
3068
+
3069
+ if (process.env.NODE_ENV !== 'production') {
3070
+ validatePropTypes$1 = function validatePropTypes(options, caller) {
3071
+ PropTypes__default['default'].checkPropTypes(propTypes$1, options, 'prop', caller.name);
3072
+ };
3038
3073
  }
3074
+
3039
3075
  var defaultProps$2 = _extends__default['default']({}, defaultProps, {
3040
3076
  getA11yStatusMessage: getA11yStatusMessage,
3041
3077
  circularNavigation: true
@@ -3050,12 +3086,6 @@ function downshiftUseComboboxReducer(state, action) {
3050
3086
  var changes;
3051
3087
 
3052
3088
  switch (type) {
3053
- case ItemMouseMove$1:
3054
- changes = {
3055
- highlightedIndex: action.index
3056
- };
3057
- break;
3058
-
3059
3089
  case ItemClick$1:
3060
3090
  changes = {
3061
3091
  isOpen: getDefaultValue(props, 'isOpen'),
@@ -3073,7 +3103,7 @@ function downshiftUseComboboxReducer(state, action) {
3073
3103
  } else {
3074
3104
  changes = {
3075
3105
  highlightedIndex: getHighlightedIndexOnOpen(props, state, 1, action.getItemNodeFromIndex),
3076
- isOpen: true
3106
+ isOpen: props.items.length >= 0
3077
3107
  };
3078
3108
  }
3079
3109
 
@@ -3087,7 +3117,7 @@ function downshiftUseComboboxReducer(state, action) {
3087
3117
  } else {
3088
3118
  changes = {
3089
3119
  highlightedIndex: getHighlightedIndexOnOpen(props, state, -1, action.getItemNodeFromIndex),
3090
- isOpen: true
3120
+ isOpen: props.items.length >= 0
3091
3121
  };
3092
3122
  }
3093
3123
 
@@ -3113,28 +3143,25 @@ function downshiftUseComboboxReducer(state, action) {
3113
3143
  break;
3114
3144
 
3115
3145
  case InputKeyDownHome:
3116
- changes = _extends__default['default']({}, state.isOpen && {
3146
+ changes = {
3117
3147
  highlightedIndex: getNextNonDisabledIndex(1, 0, props.items.length, action.getItemNodeFromIndex, false)
3118
- });
3148
+ };
3119
3149
  break;
3120
3150
 
3121
3151
  case InputKeyDownEnd:
3122
- changes = _extends__default['default']({}, state.isOpen && {
3152
+ changes = {
3123
3153
  highlightedIndex: getNextNonDisabledIndex(-1, props.items.length - 1, props.items.length, action.getItemNodeFromIndex, false)
3124
- });
3154
+ };
3125
3155
  break;
3126
3156
 
3127
3157
  case InputBlur:
3128
- if (state.isOpen) {
3129
- changes = _extends__default['default']({
3130
- isOpen: false,
3131
- highlightedIndex: -1
3132
- }, state.highlightedIndex >= 0 && action.selectItem && {
3133
- selectedItem: props.items[state.highlightedIndex],
3134
- inputValue: props.itemToString(props.items[state.highlightedIndex])
3135
- });
3136
- }
3137
-
3158
+ changes = _extends__default['default']({
3159
+ isOpen: false,
3160
+ highlightedIndex: -1
3161
+ }, state.highlightedIndex >= 0 && action.selectItem && {
3162
+ selectedItem: props.items[state.highlightedIndex],
3163
+ inputValue: props.itemToString(props.items[state.highlightedIndex])
3164
+ });
3138
3165
  break;
3139
3166
 
3140
3167
  case InputChange:
@@ -3145,39 +3172,6 @@ function downshiftUseComboboxReducer(state, action) {
3145
3172
  };
3146
3173
  break;
3147
3174
 
3148
- case MenuMouseLeave$1:
3149
- changes = {
3150
- highlightedIndex: -1
3151
- };
3152
- break;
3153
-
3154
- case ToggleButtonClick$1:
3155
- case FunctionToggleMenu$1:
3156
- changes = {
3157
- isOpen: !state.isOpen,
3158
- highlightedIndex: state.isOpen ? -1 : getHighlightedIndexOnOpen(props, state, 0)
3159
- };
3160
- break;
3161
-
3162
- case FunctionOpenMenu$1:
3163
- changes = {
3164
- isOpen: true,
3165
- highlightedIndex: getHighlightedIndexOnOpen(props, state, 0)
3166
- };
3167
- break;
3168
-
3169
- case FunctionCloseMenu$1:
3170
- changes = {
3171
- isOpen: false
3172
- };
3173
- break;
3174
-
3175
- case FunctionSetHighlightedIndex$1:
3176
- changes = {
3177
- highlightedIndex: action.highlightedIndex
3178
- };
3179
- break;
3180
-
3181
3175
  case FunctionSelectItem$1:
3182
3176
  changes = {
3183
3177
  selectedItem: action.selectedItem,
@@ -3186,32 +3180,19 @@ function downshiftUseComboboxReducer(state, action) {
3186
3180
  break;
3187
3181
 
3188
3182
  case ControlledPropUpdatedSelectedItem:
3189
- case FunctionSetInputValue$1:
3190
3183
  changes = {
3191
3184
  inputValue: action.inputValue
3192
3185
  };
3193
3186
  break;
3194
3187
 
3195
- case FunctionReset$1:
3196
- changes = {
3197
- highlightedIndex: getDefaultValue(props, 'highlightedIndex'),
3198
- isOpen: getDefaultValue(props, 'isOpen'),
3199
- selectedItem: getDefaultValue(props, 'selectedItem'),
3200
- inputValue: getDefaultValue(props, 'inputValue')
3201
- };
3202
- break;
3203
-
3204
3188
  default:
3205
- throw new Error('Reducer called without proper action type.');
3189
+ return downshiftCommonReducer(state, action, stateChangeTypes$2);
3206
3190
  }
3207
3191
 
3208
3192
  return _extends__default['default']({}, state, changes);
3209
3193
  }
3210
3194
  /* eslint-enable complexity */
3211
3195
 
3212
- var validatePropTypes$1 = process.env.NODE_ENV === 'production' ?
3213
- /* istanbul ignore next */
3214
- null : getPropTypesValidator(useCombobox, propTypes$1);
3215
3196
  useCombobox.stateChangeTypes = stateChangeTypes$2;
3216
3197
 
3217
3198
  function useCombobox(userProps) {
@@ -3219,11 +3200,7 @@ function useCombobox(userProps) {
3219
3200
  userProps = {};
3220
3201
  }
3221
3202
 
3222
- /* istanbul ignore else */
3223
- if (process.env.NODE_ENV !== 'production') {
3224
- validatePropTypes$1(userProps);
3225
- } // Props defaults and destructuring.
3226
-
3203
+ validatePropTypes$1(userProps, useCombobox); // Props defaults and destructuring.
3227
3204
 
3228
3205
  var props = _extends__default['default']({}, defaultProps$2, userProps);
3229
3206
 
@@ -3248,14 +3225,13 @@ function useCombobox(userProps) {
3248
3225
  inputValue = state.inputValue; // Element refs.
3249
3226
 
3250
3227
  var menuRef = react.useRef(null);
3251
- var itemRefs = react.useRef();
3228
+ var itemRefs = react.useRef({});
3252
3229
  var inputRef = react.useRef(null);
3253
3230
  var toggleButtonRef = react.useRef(null);
3254
3231
  var comboboxRef = react.useRef(null);
3255
- itemRefs.current = {};
3256
3232
  var isInitialMountRef = react.useRef(true); // prevent id re-generation between renders.
3257
3233
 
3258
- var elementIdsRef = react.useRef(getElementIds$1(props)); // used to keep track of how many items we had on previous cycle.
3234
+ var elementIds = useElementIds(props); // used to keep track of how many items we had on previous cycle.
3259
3235
 
3260
3236
  var previousResultCountRef = react.useRef(); // utility callback to get item element.
3261
3237
 
@@ -3263,13 +3239,11 @@ function useCombobox(userProps) {
3263
3239
  state: state,
3264
3240
  props: props
3265
3241
  });
3266
-
3267
- var getItemNodeFromIndex = function getItemNodeFromIndex(index) {
3268
- return itemRefs.current[elementIdsRef.current.getItemId(index)];
3269
- }; // Effects.
3242
+ var getItemNodeFromIndex = react.useCallback(function (index) {
3243
+ return itemRefs.current[elementIds.getItemId(index)];
3244
+ }, [elementIds]); // Effects.
3270
3245
  // Sets a11y status message on changes in state.
3271
3246
 
3272
-
3273
3247
  useA11yMessageSetter(getA11yStatusMessage, [isOpen, highlightedIndex, inputValue, items], _extends__default['default']({
3274
3248
  isInitialMount: isInitialMountRef.current,
3275
3249
  previousResultCount: previousResultCountRef.current,
@@ -3298,20 +3272,16 @@ function useCombobox(userProps) {
3298
3272
  isInitialMount: isInitialMountRef.current,
3299
3273
  props: props,
3300
3274
  state: state
3301
- }); // Controls the focus on the input on open.
3275
+ }); // Focus the input on first render if required.
3302
3276
 
3303
3277
  react.useEffect(function () {
3304
- // Don't focus menu on first render.
3305
- if (isInitialMountRef.current) {
3306
- // Unless it was initialised as open.
3307
- if (initialIsOpen || defaultIsOpen || isOpen) {
3308
- if (inputRef.current) {
3309
- inputRef.current.focus();
3310
- }
3311
- }
3278
+ var focusOnOpen = initialIsOpen || defaultIsOpen || isOpen;
3279
+
3280
+ if (focusOnOpen && inputRef.current) {
3281
+ inputRef.current.focus();
3312
3282
  } // eslint-disable-next-line react-hooks/exhaustive-deps
3313
3283
 
3314
- }, [isOpen]);
3284
+ }, []);
3315
3285
  react.useEffect(function () {
3316
3286
  if (isInitialMountRef.current) {
3317
3287
  return;
@@ -3330,7 +3300,13 @@ function useCombobox(userProps) {
3330
3300
 
3331
3301
  react.useEffect(function () {
3332
3302
  isInitialMountRef.current = false;
3333
- }, []);
3303
+ }, []); // Reset itemRefs on close.
3304
+
3305
+ react.useEffect(function () {
3306
+ if (!isOpen) {
3307
+ itemRefs.current = {};
3308
+ }
3309
+ }, [isOpen]);
3334
3310
  /* Event handler functions */
3335
3311
 
3336
3312
  var inputKeyDownHandlers = react.useMemo(function () {
@@ -3352,6 +3328,10 @@ function useCombobox(userProps) {
3352
3328
  });
3353
3329
  },
3354
3330
  Home: function Home(event) {
3331
+ if (!latest.current.state.isOpen) {
3332
+ return;
3333
+ }
3334
+
3355
3335
  event.preventDefault();
3356
3336
  dispatch({
3357
3337
  type: InputKeyDownHome,
@@ -3359,6 +3339,10 @@ function useCombobox(userProps) {
3359
3339
  });
3360
3340
  },
3361
3341
  End: function End(event) {
3342
+ if (!latest.current.state.isOpen) {
3343
+ return;
3344
+ }
3345
+
3362
3346
  event.preventDefault();
3363
3347
  dispatch({
3364
3348
  type: InputKeyDownEnd,
@@ -3366,36 +3350,37 @@ function useCombobox(userProps) {
3366
3350
  });
3367
3351
  },
3368
3352
  Escape: function Escape() {
3369
- dispatch({
3370
- type: InputKeyDownEscape
3371
- });
3372
- },
3373
- Enter: function Enter(event) {
3374
- // if IME composing, wait for next Enter keydown event.
3375
- if (event.which === 229) {
3376
- return;
3377
- }
3378
-
3379
3353
  var latestState = latest.current.state;
3380
3354
 
3381
- if (latestState.isOpen) {
3382
- event.preventDefault();
3355
+ if (latestState.isOpen || latestState.inputValue || latestState.selectedItem || latestState.highlightedIndex > -1) {
3356
+ dispatch({
3357
+ type: InputKeyDownEscape
3358
+ });
3383
3359
  }
3360
+ },
3361
+ Enter: function Enter(event) {
3362
+ var latestState = latest.current.state; // if closed or no highlighted index, do nothing.
3384
3363
 
3364
+ if (!latestState.isOpen || latestState.highlightedIndex < 0 || event.which === 229 // if IME composing, wait for next Enter keydown event.
3365
+ ) {
3366
+ return;
3367
+ }
3368
+
3369
+ event.preventDefault();
3385
3370
  dispatch({
3386
3371
  type: InputKeyDownEnter,
3387
3372
  getItemNodeFromIndex: getItemNodeFromIndex
3388
3373
  });
3389
3374
  }
3390
3375
  };
3391
- }, [dispatch, latest]); // Getter props.
3376
+ }, [dispatch, latest, getItemNodeFromIndex]); // Getter props.
3392
3377
 
3393
3378
  var getLabelProps = react.useCallback(function (labelProps) {
3394
3379
  return _extends__default['default']({
3395
- id: elementIdsRef.current.labelId,
3396
- htmlFor: elementIdsRef.current.inputId
3380
+ id: elementIds.labelId,
3381
+ htmlFor: elementIds.inputId
3397
3382
  }, labelProps);
3398
- }, []);
3383
+ }, [elementIds]);
3399
3384
  var getMenuProps = react.useCallback(function (_temp, _temp2) {
3400
3385
  var _extends2;
3401
3386
 
@@ -3413,12 +3398,12 @@ function useCombobox(userProps) {
3413
3398
  setGetterPropCallInfo('getMenuProps', suppressRefError, refKey, menuRef);
3414
3399
  return _extends__default['default']((_extends2 = {}, _extends2[refKey] = handleRefs(ref, function (menuNode) {
3415
3400
  menuRef.current = menuNode;
3416
- }), _extends2.id = elementIdsRef.current.menuId, _extends2.role = 'listbox', _extends2['aria-labelledby'] = elementIdsRef.current.labelId, _extends2.onMouseLeave = callAllEventHandlers(onMouseLeave, function () {
3401
+ }), _extends2.id = elementIds.menuId, _extends2.role = 'listbox', _extends2['aria-labelledby'] = elementIds.labelId, _extends2.onMouseLeave = callAllEventHandlers(onMouseLeave, function () {
3417
3402
  dispatch({
3418
3403
  type: MenuMouseLeave$1
3419
3404
  });
3420
3405
  }), _extends2), rest);
3421
- }, [dispatch, setGetterPropCallInfo]);
3406
+ }, [dispatch, setGetterPropCallInfo, elementIds]);
3422
3407
  var getItemProps = react.useCallback(function (_temp3) {
3423
3408
  var _extends3, _ref4;
3424
3409
 
@@ -3474,12 +3459,12 @@ function useCombobox(userProps) {
3474
3459
 
3475
3460
  return _extends__default['default']((_extends3 = {}, _extends3[refKey] = handleRefs(ref, function (itemNode) {
3476
3461
  if (itemNode) {
3477
- itemRefs.current[elementIdsRef.current.getItemId(itemIndex)] = itemNode;
3462
+ itemRefs.current[elementIds.getItemId(itemIndex)] = itemNode;
3478
3463
  }
3479
- }), _extends3.role = 'option', _extends3['aria-selected'] = "" + (itemIndex === latestState.highlightedIndex), _extends3.id = elementIdsRef.current.getItemId(itemIndex), _extends3), !rest.disabled && (_ref4 = {
3464
+ }), _extends3.role = 'option', _extends3['aria-selected'] = "" + (itemIndex === latestState.highlightedIndex), _extends3.id = elementIds.getItemId(itemIndex), _extends3), !rest.disabled && (_ref4 = {
3480
3465
  onMouseMove: callAllEventHandlers(onMouseMove, itemHandleMouseMove)
3481
3466
  }, _ref4[onSelectKey] = callAllEventHandlers(customClickHandler, itemHandleClick), _ref4), rest);
3482
- }, [dispatch, latest, shouldScrollRef]);
3467
+ }, [dispatch, latest, shouldScrollRef, elementIds]);
3483
3468
  var getToggleButtonProps = react.useCallback(function (_temp4) {
3484
3469
  var _extends4;
3485
3470
 
@@ -3503,12 +3488,12 @@ function useCombobox(userProps) {
3503
3488
 
3504
3489
  return _extends__default['default']((_extends4 = {}, _extends4[refKey] = handleRefs(ref, function (toggleButtonNode) {
3505
3490
  toggleButtonRef.current = toggleButtonNode;
3506
- }), _extends4.id = elementIdsRef.current.toggleButtonId, _extends4.tabIndex = -1, _extends4), !rest.disabled && _extends__default['default']({},
3491
+ }), _extends4.id = elementIds.toggleButtonId, _extends4.tabIndex = -1, _extends4), !rest.disabled && _extends__default['default']({},
3507
3492
  /* istanbul ignore next (react-native) */
3508
3493
  {
3509
3494
  onPress: callAllEventHandlers(onPress, toggleButtonHandleClick)
3510
3495
  } ), rest);
3511
- }, [dispatch, latest]);
3496
+ }, [dispatch, latest, elementIds]);
3512
3497
  var getInputProps = react.useCallback(function (_temp5, _temp6) {
3513
3498
  var _extends5;
3514
3499
 
@@ -3549,7 +3534,7 @@ function useCombobox(userProps) {
3549
3534
 
3550
3535
  var inputHandleBlur = function inputHandleBlur() {
3551
3536
  /* istanbul ignore else */
3552
- if (!mouseAndTouchTrackersRef.current.isMouseDown) {
3537
+ if (latestState.isOpen && !mouseAndTouchTrackersRef.current.isMouseDown) {
3553
3538
  dispatch({
3554
3539
  type: InputBlur,
3555
3540
  selectItem: true
@@ -3583,16 +3568,16 @@ function useCombobox(userProps) {
3583
3568
 
3584
3569
  return _extends__default['default']((_extends5 = {}, _extends5[refKey] = handleRefs(ref, function (inputNode) {
3585
3570
  inputRef.current = inputNode;
3586
- }), _extends5.id = elementIdsRef.current.inputId, _extends5['aria-autocomplete'] = 'list', _extends5['aria-controls'] = elementIdsRef.current.menuId, _extends5), latestState.isOpen && latestState.highlightedIndex > -1 && {
3587
- 'aria-activedescendant': elementIdsRef.current.getItemId(latestState.highlightedIndex)
3571
+ }), _extends5.id = elementIds.inputId, _extends5['aria-autocomplete'] = 'list', _extends5['aria-controls'] = elementIds.menuId, _extends5), latestState.isOpen && latestState.highlightedIndex > -1 && {
3572
+ 'aria-activedescendant': elementIds.getItemId(latestState.highlightedIndex)
3588
3573
  }, {
3589
- 'aria-labelledby': elementIdsRef.current.labelId,
3574
+ 'aria-labelledby': elementIds.labelId,
3590
3575
  // https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion
3591
3576
  // revert back since autocomplete="nope" is ignored on latest Chrome and Opera
3592
3577
  autoComplete: 'off',
3593
3578
  value: latestState.inputValue
3594
3579
  }, eventHandlers, rest);
3595
- }, [dispatch, inputKeyDownHandlers, latest, mouseAndTouchTrackersRef, setGetterPropCallInfo]);
3580
+ }, [dispatch, inputKeyDownHandlers, latest, mouseAndTouchTrackersRef, setGetterPropCallInfo, elementIds]);
3596
3581
  var getComboboxProps = react.useCallback(function (_temp7, _temp8) {
3597
3582
  var _extends6;
3598
3583
 
@@ -3609,8 +3594,8 @@ function useCombobox(userProps) {
3609
3594
  setGetterPropCallInfo('getComboboxProps', suppressRefError, refKey, comboboxRef);
3610
3595
  return _extends__default['default']((_extends6 = {}, _extends6[refKey] = handleRefs(ref, function (comboboxNode) {
3611
3596
  comboboxRef.current = comboboxNode;
3612
- }), _extends6.role = 'combobox', _extends6['aria-haspopup'] = 'listbox', _extends6['aria-owns'] = elementIdsRef.current.menuId, _extends6['aria-expanded'] = latest.current.state.isOpen, _extends6), rest);
3613
- }, [latest, setGetterPropCallInfo]); // returns
3597
+ }), _extends6.role = 'combobox', _extends6['aria-haspopup'] = 'listbox', _extends6['aria-owns'] = elementIds.menuId, _extends6['aria-expanded'] = latest.current.state.isOpen, _extends6), rest);
3598
+ }, [latest, setGetterPropCallInfo, elementIds]); // returns
3614
3599
 
3615
3600
  var toggleMenu = react.useCallback(function () {
3616
3601
  dispatch({
@@ -3712,6 +3697,7 @@ function getDefaultValue$1(props, propKey) {
3712
3697
  * @returns {Object} The initial state.
3713
3698
  */
3714
3699
 
3700
+
3715
3701
  function getInitialState$2(props) {
3716
3702
  var activeIndex = getInitialValue$1(props, 'activeIndex');
3717
3703
  var selectedItems = getInitialValue$1(props, 'selectedItems');
@@ -3730,6 +3716,7 @@ function getInitialState$2(props) {
3730
3716
  * @returns {boolean} Whether the operation is allowed.
3731
3717
  */
3732
3718
 
3719
+
3733
3720
  function isKeyDownOperationPermitted(event) {
3734
3721
  if (event.shiftKey || event.metaKey || event.ctrlKey || event.altKey) {
3735
3722
  return false;
@@ -3753,6 +3740,7 @@ function isKeyDownOperationPermitted(event) {
3753
3740
  * @returns {string} The a11y message.
3754
3741
  */
3755
3742
 
3743
+
3756
3744
  function getA11yRemovalMessage(selectionParameters) {
3757
3745
  var removedSelectedItem = selectionParameters.removedSelectedItem,
3758
3746
  itemToStringLocal = selectionParameters.itemToString;
@@ -3790,7 +3778,16 @@ var defaultProps$3 = {
3790
3778
  getA11yRemovalMessage: getA11yRemovalMessage,
3791
3779
  keyNavigationNext: 'ArrowRight',
3792
3780
  keyNavigationPrevious: 'ArrowLeft'
3793
- };
3781
+ }; // eslint-disable-next-line import/no-mutable-exports
3782
+
3783
+ var validatePropTypes$2 = noop;
3784
+ /* istanbul ignore next */
3785
+
3786
+ if (process.env.NODE_ENV !== 'production') {
3787
+ validatePropTypes$2 = function validatePropTypes(options, caller) {
3788
+ PropTypes__default['default'].checkPropTypes(propTypes$2, options, 'prop', caller.name);
3789
+ };
3790
+ }
3794
3791
 
3795
3792
  var SelectedItemClick = process.env.NODE_ENV !== "production" ? '__selected_item_click__' : 0;
3796
3793
  var SelectedItemKeyDownDelete = process.env.NODE_ENV !== "production" ? '__selected_item_keydown_delete__' : 1;
@@ -3954,7 +3951,8 @@ function useMultipleSelection(userProps) {
3954
3951
  userProps = {};
3955
3952
  }
3956
3953
 
3957
- // Props defaults and destructuring.
3954
+ validatePropTypes$2(userProps, useMultipleSelection); // Props defaults and destructuring.
3955
+
3958
3956
  var props = _extends__default['default']({}, defaultProps$3, userProps);
3959
3957
 
3960
3958
  var getA11yRemovalMessage = props.getA11yRemovalMessage,