downshift 7.3.3 → 7.4.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.
@@ -1944,6 +1944,32 @@ if (process.env.NODE_ENV !== 'production') {
1944
1944
  };
1945
1945
  }
1946
1946
 
1947
+ /**
1948
+ * Handles selection on Enter / Alt + ArrowUp. Closes the menu and resets the highlighted index, unless there is a highlighted.
1949
+ * In that case, selects the item and resets to defaults for open state and highlighted idex.
1950
+ * @param {Object} props The useCombobox props.
1951
+ * @param {number} highlightedIndex The index from the state.
1952
+ * @param {boolean} inputValue Also return the input value for state.
1953
+ * @returns The changes for the state.
1954
+ */
1955
+ function getChangesOnSelection(props, highlightedIndex, inputValue) {
1956
+ var _props$items;
1957
+ if (inputValue === void 0) {
1958
+ inputValue = true;
1959
+ }
1960
+ var shouldSelect = ((_props$items = props.items) == null ? void 0 : _props$items.length) && highlightedIndex >= 0;
1961
+ return _extends__default["default"]({
1962
+ isOpen: false,
1963
+ highlightedIndex: -1
1964
+ }, shouldSelect && _extends__default["default"]({
1965
+ selectedItem: props.items[highlightedIndex],
1966
+ isOpen: getDefaultValue$1(props, 'isOpen'),
1967
+ highlightedIndex: getDefaultValue$1(props, 'highlightedIndex')
1968
+ }, inputValue && {
1969
+ inputValue: props.itemToString(props.items[highlightedIndex])
1970
+ }));
1971
+ }
1972
+
1947
1973
  function downshiftCommonReducer(state, action, stateChangeTypes) {
1948
1974
  var type = action.type,
1949
1975
  props = action.props;
@@ -2135,6 +2161,7 @@ var stateChangeTypes$2 = /*#__PURE__*/Object.freeze({
2135
2161
 
2136
2162
  /* eslint-disable complexity */
2137
2163
  function downshiftSelectReducer(state, action) {
2164
+ var _props$items;
2138
2165
  var type = action.type,
2139
2166
  props = action.props,
2140
2167
  altKey = action.altKey;
@@ -2177,12 +2204,7 @@ function downshiftSelectReducer(state, action) {
2177
2204
  break;
2178
2205
  case ToggleButtonKeyDownArrowUp:
2179
2206
  if (state.isOpen && altKey) {
2180
- changes = _extends__default["default"]({
2181
- isOpen: getDefaultValue$1(props, 'isOpen'),
2182
- highlightedIndex: getDefaultValue$1(props, 'highlightedIndex')
2183
- }, state.highlightedIndex >= 0 && {
2184
- selectedItem: props.items[state.highlightedIndex]
2185
- });
2207
+ changes = getChangesOnSelection(props, state.highlightedIndex, false);
2186
2208
  } else {
2187
2209
  var _highlightedIndex2 = state.isOpen ? getNextWrappingIndex(-1, state.highlightedIndex, props.items.length, action.getItemNodeFromIndex, false) : getHighlightedIndexOnOpen(props, state, -1);
2188
2210
  changes = {
@@ -2194,12 +2216,7 @@ function downshiftSelectReducer(state, action) {
2194
2216
  // only triggered when menu is open.
2195
2217
  case ToggleButtonKeyDownEnter:
2196
2218
  case ToggleButtonKeyDownSpaceButton:
2197
- changes = _extends__default["default"]({
2198
- isOpen: getDefaultValue$1(props, 'isOpen'),
2199
- highlightedIndex: getDefaultValue$1(props, 'highlightedIndex')
2200
- }, state.highlightedIndex >= 0 && {
2201
- selectedItem: props.items[state.highlightedIndex]
2202
- });
2219
+ changes = getChangesOnSelection(props, state.highlightedIndex, false);
2203
2220
  break;
2204
2221
  case ToggleButtonKeyDownHome:
2205
2222
  changes = {
@@ -2233,7 +2250,7 @@ function downshiftSelectReducer(state, action) {
2233
2250
  changes = _extends__default["default"]({
2234
2251
  isOpen: false,
2235
2252
  highlightedIndex: -1
2236
- }, state.highlightedIndex >= 0 && {
2253
+ }, state.highlightedIndex >= 0 && ((_props$items = props.items) == null ? void 0 : _props$items.length) && {
2237
2254
  selectedItem: props.items[state.highlightedIndex]
2238
2255
  });
2239
2256
  break;
@@ -2731,6 +2748,7 @@ function getInitialState$1(props) {
2731
2748
  var propTypes$1 = {
2732
2749
  items: PropTypes__default["default"].array.isRequired,
2733
2750
  itemToString: PropTypes__default["default"].func,
2751
+ selectedItemChanged: PropTypes__default["default"].func,
2734
2752
  getA11yStatusMessage: PropTypes__default["default"].func,
2735
2753
  getA11ySelectionMessage: PropTypes__default["default"].func,
2736
2754
  highlightedIndex: PropTypes__default["default"].number,
@@ -2788,16 +2806,18 @@ function useControlledReducer(reducer, initialState, props) {
2788
2806
 
2789
2807
  // ToDo: if needed, make same approach as selectedItemChanged from Downshift.
2790
2808
  react.useEffect(function () {
2791
- if (isControlledProp(props, 'selectedItem')) {
2792
- if (previousSelectedItemRef.current !== props.selectedItem) {
2793
- dispatch({
2794
- type: ControlledPropUpdatedSelectedItem,
2795
- inputValue: props.itemToString(props.selectedItem)
2796
- });
2797
- }
2798
- previousSelectedItemRef.current = state.selectedItem === previousSelectedItemRef.current ? props.selectedItem : state.selectedItem;
2809
+ if (!isControlledProp(props, 'selectedItem')) {
2810
+ return;
2799
2811
  }
2800
- }, [props.selectedItem, state.selectedItem]);
2812
+ if (props.selectedItemChanged(previousSelectedItemRef.current, props.selectedItem)) {
2813
+ dispatch({
2814
+ type: ControlledPropUpdatedSelectedItem,
2815
+ inputValue: props.itemToString(props.selectedItem)
2816
+ });
2817
+ }
2818
+ previousSelectedItemRef.current = state.selectedItem === previousSelectedItemRef.current ? props.selectedItem : state.selectedItem;
2819
+ // eslint-disable-next-line react-hooks/exhaustive-deps
2820
+ }, [state.selectedItem, props.selectedItem]);
2801
2821
  return [getState(state, props), dispatch];
2802
2822
  }
2803
2823
 
@@ -2810,11 +2830,15 @@ if (process.env.NODE_ENV !== 'production') {
2810
2830
  };
2811
2831
  }
2812
2832
  var defaultProps$1 = _extends__default["default"]({}, defaultProps$3, {
2833
+ selectedItemChanged: function selectedItemChanged(prevItem, item) {
2834
+ return prevItem !== item;
2835
+ },
2813
2836
  getA11yStatusMessage: getA11yStatusMessage$1
2814
2837
  });
2815
2838
 
2816
2839
  /* eslint-disable complexity */
2817
2840
  function downshiftUseComboboxReducer(state, action) {
2841
+ var _props$items;
2818
2842
  var type = action.type,
2819
2843
  props = action.props,
2820
2844
  altKey = action.altKey;
@@ -2843,13 +2867,7 @@ function downshiftUseComboboxReducer(state, action) {
2843
2867
  case InputKeyDownArrowUp:
2844
2868
  if (state.isOpen) {
2845
2869
  if (altKey) {
2846
- changes = _extends__default["default"]({
2847
- isOpen: getDefaultValue$1(props, 'isOpen'),
2848
- highlightedIndex: getDefaultValue$1(props, 'highlightedIndex')
2849
- }, state.highlightedIndex >= 0 && {
2850
- selectedItem: props.items[state.highlightedIndex],
2851
- inputValue: props.itemToString(props.items[state.highlightedIndex])
2852
- });
2870
+ changes = getChangesOnSelection(props, state.highlightedIndex);
2853
2871
  } else {
2854
2872
  changes = {
2855
2873
  highlightedIndex: getNextWrappingIndex(-1, state.highlightedIndex, props.items.length, action.getItemNodeFromIndex, true)
@@ -2863,13 +2881,7 @@ function downshiftUseComboboxReducer(state, action) {
2863
2881
  }
2864
2882
  break;
2865
2883
  case InputKeyDownEnter:
2866
- changes = _extends__default["default"]({
2867
- isOpen: getDefaultValue$1(props, 'isOpen'),
2868
- highlightedIndex: getDefaultValue$1(props, 'highlightedIndex')
2869
- }, state.highlightedIndex >= 0 && {
2870
- selectedItem: props.items[state.highlightedIndex],
2871
- inputValue: props.itemToString(props.items[state.highlightedIndex])
2872
- });
2884
+ changes = getChangesOnSelection(props, state.highlightedIndex);
2873
2885
  break;
2874
2886
  case InputKeyDownEscape:
2875
2887
  changes = _extends__default["default"]({
@@ -2904,7 +2916,7 @@ function downshiftUseComboboxReducer(state, action) {
2904
2916
  changes = _extends__default["default"]({
2905
2917
  isOpen: false,
2906
2918
  highlightedIndex: -1
2907
- }, state.highlightedIndex >= 0 && action.selectItem && {
2919
+ }, state.highlightedIndex >= 0 && ((_props$items = props.items) == null ? void 0 : _props$items.length) && action.selectItem && {
2908
2920
  selectedItem: props.items[state.highlightedIndex],
2909
2921
  inputValue: props.itemToString(props.items[state.highlightedIndex])
2910
2922
  });
@@ -1931,6 +1931,32 @@ if (process.env.NODE_ENV !== 'production') {
1931
1931
  };
1932
1932
  }
1933
1933
 
1934
+ /**
1935
+ * Handles selection on Enter / Alt + ArrowUp. Closes the menu and resets the highlighted index, unless there is a highlighted.
1936
+ * In that case, selects the item and resets to defaults for open state and highlighted idex.
1937
+ * @param {Object} props The useCombobox props.
1938
+ * @param {number} highlightedIndex The index from the state.
1939
+ * @param {boolean} inputValue Also return the input value for state.
1940
+ * @returns The changes for the state.
1941
+ */
1942
+ function getChangesOnSelection(props, highlightedIndex, inputValue) {
1943
+ var _props$items;
1944
+ if (inputValue === void 0) {
1945
+ inputValue = true;
1946
+ }
1947
+ var shouldSelect = ((_props$items = props.items) == null ? void 0 : _props$items.length) && highlightedIndex >= 0;
1948
+ return _extends({
1949
+ isOpen: false,
1950
+ highlightedIndex: -1
1951
+ }, shouldSelect && _extends({
1952
+ selectedItem: props.items[highlightedIndex],
1953
+ isOpen: getDefaultValue$1(props, 'isOpen'),
1954
+ highlightedIndex: getDefaultValue$1(props, 'highlightedIndex')
1955
+ }, inputValue && {
1956
+ inputValue: props.itemToString(props.items[highlightedIndex])
1957
+ }));
1958
+ }
1959
+
1934
1960
  function downshiftCommonReducer(state, action, stateChangeTypes) {
1935
1961
  var type = action.type,
1936
1962
  props = action.props;
@@ -2122,6 +2148,7 @@ var stateChangeTypes$2 = /*#__PURE__*/Object.freeze({
2122
2148
 
2123
2149
  /* eslint-disable complexity */
2124
2150
  function downshiftSelectReducer(state, action) {
2151
+ var _props$items;
2125
2152
  var type = action.type,
2126
2153
  props = action.props,
2127
2154
  altKey = action.altKey;
@@ -2164,12 +2191,7 @@ function downshiftSelectReducer(state, action) {
2164
2191
  break;
2165
2192
  case ToggleButtonKeyDownArrowUp:
2166
2193
  if (state.isOpen && altKey) {
2167
- changes = _extends({
2168
- isOpen: getDefaultValue$1(props, 'isOpen'),
2169
- highlightedIndex: getDefaultValue$1(props, 'highlightedIndex')
2170
- }, state.highlightedIndex >= 0 && {
2171
- selectedItem: props.items[state.highlightedIndex]
2172
- });
2194
+ changes = getChangesOnSelection(props, state.highlightedIndex, false);
2173
2195
  } else {
2174
2196
  var _highlightedIndex2 = state.isOpen ? getNextWrappingIndex(-1, state.highlightedIndex, props.items.length, action.getItemNodeFromIndex, false) : getHighlightedIndexOnOpen(props, state, -1);
2175
2197
  changes = {
@@ -2181,12 +2203,7 @@ function downshiftSelectReducer(state, action) {
2181
2203
  // only triggered when menu is open.
2182
2204
  case ToggleButtonKeyDownEnter:
2183
2205
  case ToggleButtonKeyDownSpaceButton:
2184
- changes = _extends({
2185
- isOpen: getDefaultValue$1(props, 'isOpen'),
2186
- highlightedIndex: getDefaultValue$1(props, 'highlightedIndex')
2187
- }, state.highlightedIndex >= 0 && {
2188
- selectedItem: props.items[state.highlightedIndex]
2189
- });
2206
+ changes = getChangesOnSelection(props, state.highlightedIndex, false);
2190
2207
  break;
2191
2208
  case ToggleButtonKeyDownHome:
2192
2209
  changes = {
@@ -2220,7 +2237,7 @@ function downshiftSelectReducer(state, action) {
2220
2237
  changes = _extends({
2221
2238
  isOpen: false,
2222
2239
  highlightedIndex: -1
2223
- }, state.highlightedIndex >= 0 && {
2240
+ }, state.highlightedIndex >= 0 && ((_props$items = props.items) == null ? void 0 : _props$items.length) && {
2224
2241
  selectedItem: props.items[state.highlightedIndex]
2225
2242
  });
2226
2243
  break;
@@ -2718,6 +2735,7 @@ function getInitialState$1(props) {
2718
2735
  var propTypes$1 = {
2719
2736
  items: PropTypes.array.isRequired,
2720
2737
  itemToString: PropTypes.func,
2738
+ selectedItemChanged: PropTypes.func,
2721
2739
  getA11yStatusMessage: PropTypes.func,
2722
2740
  getA11ySelectionMessage: PropTypes.func,
2723
2741
  highlightedIndex: PropTypes.number,
@@ -2775,16 +2793,18 @@ function useControlledReducer(reducer, initialState, props) {
2775
2793
 
2776
2794
  // ToDo: if needed, make same approach as selectedItemChanged from Downshift.
2777
2795
  useEffect(function () {
2778
- if (isControlledProp(props, 'selectedItem')) {
2779
- if (previousSelectedItemRef.current !== props.selectedItem) {
2780
- dispatch({
2781
- type: ControlledPropUpdatedSelectedItem,
2782
- inputValue: props.itemToString(props.selectedItem)
2783
- });
2784
- }
2785
- previousSelectedItemRef.current = state.selectedItem === previousSelectedItemRef.current ? props.selectedItem : state.selectedItem;
2796
+ if (!isControlledProp(props, 'selectedItem')) {
2797
+ return;
2786
2798
  }
2787
- }, [props.selectedItem, state.selectedItem]);
2799
+ if (props.selectedItemChanged(previousSelectedItemRef.current, props.selectedItem)) {
2800
+ dispatch({
2801
+ type: ControlledPropUpdatedSelectedItem,
2802
+ inputValue: props.itemToString(props.selectedItem)
2803
+ });
2804
+ }
2805
+ previousSelectedItemRef.current = state.selectedItem === previousSelectedItemRef.current ? props.selectedItem : state.selectedItem;
2806
+ // eslint-disable-next-line react-hooks/exhaustive-deps
2807
+ }, [state.selectedItem, props.selectedItem]);
2788
2808
  return [getState(state, props), dispatch];
2789
2809
  }
2790
2810
 
@@ -2797,11 +2817,15 @@ if (process.env.NODE_ENV !== 'production') {
2797
2817
  };
2798
2818
  }
2799
2819
  var defaultProps$1 = _extends({}, defaultProps$3, {
2820
+ selectedItemChanged: function selectedItemChanged(prevItem, item) {
2821
+ return prevItem !== item;
2822
+ },
2800
2823
  getA11yStatusMessage: getA11yStatusMessage$1
2801
2824
  });
2802
2825
 
2803
2826
  /* eslint-disable complexity */
2804
2827
  function downshiftUseComboboxReducer(state, action) {
2828
+ var _props$items;
2805
2829
  var type = action.type,
2806
2830
  props = action.props,
2807
2831
  altKey = action.altKey;
@@ -2830,13 +2854,7 @@ function downshiftUseComboboxReducer(state, action) {
2830
2854
  case InputKeyDownArrowUp:
2831
2855
  if (state.isOpen) {
2832
2856
  if (altKey) {
2833
- changes = _extends({
2834
- isOpen: getDefaultValue$1(props, 'isOpen'),
2835
- highlightedIndex: getDefaultValue$1(props, 'highlightedIndex')
2836
- }, state.highlightedIndex >= 0 && {
2837
- selectedItem: props.items[state.highlightedIndex],
2838
- inputValue: props.itemToString(props.items[state.highlightedIndex])
2839
- });
2857
+ changes = getChangesOnSelection(props, state.highlightedIndex);
2840
2858
  } else {
2841
2859
  changes = {
2842
2860
  highlightedIndex: getNextWrappingIndex(-1, state.highlightedIndex, props.items.length, action.getItemNodeFromIndex, true)
@@ -2850,13 +2868,7 @@ function downshiftUseComboboxReducer(state, action) {
2850
2868
  }
2851
2869
  break;
2852
2870
  case InputKeyDownEnter:
2853
- changes = _extends({
2854
- isOpen: getDefaultValue$1(props, 'isOpen'),
2855
- highlightedIndex: getDefaultValue$1(props, 'highlightedIndex')
2856
- }, state.highlightedIndex >= 0 && {
2857
- selectedItem: props.items[state.highlightedIndex],
2858
- inputValue: props.itemToString(props.items[state.highlightedIndex])
2859
- });
2871
+ changes = getChangesOnSelection(props, state.highlightedIndex);
2860
2872
  break;
2861
2873
  case InputKeyDownEscape:
2862
2874
  changes = _extends({
@@ -2891,7 +2903,7 @@ function downshiftUseComboboxReducer(state, action) {
2891
2903
  changes = _extends({
2892
2904
  isOpen: false,
2893
2905
  highlightedIndex: -1
2894
- }, state.highlightedIndex >= 0 && action.selectItem && {
2906
+ }, state.highlightedIndex >= 0 && ((_props$items = props.items) == null ? void 0 : _props$items.length) && action.selectItem && {
2895
2907
  selectedItem: props.items[state.highlightedIndex],
2896
2908
  inputValue: props.itemToString(props.items[state.highlightedIndex])
2897
2909
  });
@@ -1879,6 +1879,32 @@ if (process.env.NODE_ENV !== 'production') {
1879
1879
  };
1880
1880
  }
1881
1881
 
1882
+ /**
1883
+ * Handles selection on Enter / Alt + ArrowUp. Closes the menu and resets the highlighted index, unless there is a highlighted.
1884
+ * In that case, selects the item and resets to defaults for open state and highlighted idex.
1885
+ * @param {Object} props The useCombobox props.
1886
+ * @param {number} highlightedIndex The index from the state.
1887
+ * @param {boolean} inputValue Also return the input value for state.
1888
+ * @returns The changes for the state.
1889
+ */
1890
+ function getChangesOnSelection(props, highlightedIndex, inputValue) {
1891
+ var _props$items;
1892
+ if (inputValue === void 0) {
1893
+ inputValue = true;
1894
+ }
1895
+ var shouldSelect = ((_props$items = props.items) == null ? void 0 : _props$items.length) && highlightedIndex >= 0;
1896
+ return _extends__default["default"]({
1897
+ isOpen: false,
1898
+ highlightedIndex: -1
1899
+ }, shouldSelect && _extends__default["default"]({
1900
+ selectedItem: props.items[highlightedIndex],
1901
+ isOpen: getDefaultValue$1(props, 'isOpen'),
1902
+ highlightedIndex: getDefaultValue$1(props, 'highlightedIndex')
1903
+ }, inputValue && {
1904
+ inputValue: props.itemToString(props.items[highlightedIndex])
1905
+ }));
1906
+ }
1907
+
1882
1908
  function downshiftCommonReducer(state, action, stateChangeTypes) {
1883
1909
  var type = action.type,
1884
1910
  props = action.props;
@@ -2070,6 +2096,7 @@ var stateChangeTypes$2 = /*#__PURE__*/Object.freeze({
2070
2096
 
2071
2097
  /* eslint-disable complexity */
2072
2098
  function downshiftSelectReducer(state, action) {
2099
+ var _props$items;
2073
2100
  var type = action.type,
2074
2101
  props = action.props,
2075
2102
  altKey = action.altKey;
@@ -2112,12 +2139,7 @@ function downshiftSelectReducer(state, action) {
2112
2139
  break;
2113
2140
  case ToggleButtonKeyDownArrowUp:
2114
2141
  if (state.isOpen && altKey) {
2115
- changes = _extends__default["default"]({
2116
- isOpen: getDefaultValue$1(props, 'isOpen'),
2117
- highlightedIndex: getDefaultValue$1(props, 'highlightedIndex')
2118
- }, state.highlightedIndex >= 0 && {
2119
- selectedItem: props.items[state.highlightedIndex]
2120
- });
2142
+ changes = getChangesOnSelection(props, state.highlightedIndex, false);
2121
2143
  } else {
2122
2144
  var _highlightedIndex2 = state.isOpen ? getNextWrappingIndex(-1, state.highlightedIndex, props.items.length, action.getItemNodeFromIndex, false) : getHighlightedIndexOnOpen(props, state, -1);
2123
2145
  changes = {
@@ -2129,12 +2151,7 @@ function downshiftSelectReducer(state, action) {
2129
2151
  // only triggered when menu is open.
2130
2152
  case ToggleButtonKeyDownEnter:
2131
2153
  case ToggleButtonKeyDownSpaceButton:
2132
- changes = _extends__default["default"]({
2133
- isOpen: getDefaultValue$1(props, 'isOpen'),
2134
- highlightedIndex: getDefaultValue$1(props, 'highlightedIndex')
2135
- }, state.highlightedIndex >= 0 && {
2136
- selectedItem: props.items[state.highlightedIndex]
2137
- });
2154
+ changes = getChangesOnSelection(props, state.highlightedIndex, false);
2138
2155
  break;
2139
2156
  case ToggleButtonKeyDownHome:
2140
2157
  changes = {
@@ -2168,7 +2185,7 @@ function downshiftSelectReducer(state, action) {
2168
2185
  changes = _extends__default["default"]({
2169
2186
  isOpen: false,
2170
2187
  highlightedIndex: -1
2171
- }, state.highlightedIndex >= 0 && {
2188
+ }, state.highlightedIndex >= 0 && ((_props$items = props.items) == null ? void 0 : _props$items.length) && {
2172
2189
  selectedItem: props.items[state.highlightedIndex]
2173
2190
  });
2174
2191
  break;
@@ -2653,6 +2670,7 @@ function getInitialState$1(props) {
2653
2670
  var propTypes$1 = {
2654
2671
  items: PropTypes__default["default"].array.isRequired,
2655
2672
  itemToString: PropTypes__default["default"].func,
2673
+ selectedItemChanged: PropTypes__default["default"].func,
2656
2674
  getA11yStatusMessage: PropTypes__default["default"].func,
2657
2675
  getA11ySelectionMessage: PropTypes__default["default"].func,
2658
2676
  highlightedIndex: PropTypes__default["default"].number,
@@ -2710,16 +2728,18 @@ function useControlledReducer(reducer, initialState, props) {
2710
2728
 
2711
2729
  // ToDo: if needed, make same approach as selectedItemChanged from Downshift.
2712
2730
  react.useEffect(function () {
2713
- if (isControlledProp(props, 'selectedItem')) {
2714
- if (previousSelectedItemRef.current !== props.selectedItem) {
2715
- dispatch({
2716
- type: ControlledPropUpdatedSelectedItem,
2717
- inputValue: props.itemToString(props.selectedItem)
2718
- });
2719
- }
2720
- previousSelectedItemRef.current = state.selectedItem === previousSelectedItemRef.current ? props.selectedItem : state.selectedItem;
2731
+ if (!isControlledProp(props, 'selectedItem')) {
2732
+ return;
2721
2733
  }
2722
- }, [props.selectedItem, state.selectedItem]);
2734
+ if (props.selectedItemChanged(previousSelectedItemRef.current, props.selectedItem)) {
2735
+ dispatch({
2736
+ type: ControlledPropUpdatedSelectedItem,
2737
+ inputValue: props.itemToString(props.selectedItem)
2738
+ });
2739
+ }
2740
+ previousSelectedItemRef.current = state.selectedItem === previousSelectedItemRef.current ? props.selectedItem : state.selectedItem;
2741
+ // eslint-disable-next-line react-hooks/exhaustive-deps
2742
+ }, [state.selectedItem, props.selectedItem]);
2723
2743
  return [getState(state, props), dispatch];
2724
2744
  }
2725
2745
 
@@ -2732,11 +2752,15 @@ if (process.env.NODE_ENV !== 'production') {
2732
2752
  };
2733
2753
  }
2734
2754
  var defaultProps$1 = _extends__default["default"]({}, defaultProps$3, {
2755
+ selectedItemChanged: function selectedItemChanged(prevItem, item) {
2756
+ return prevItem !== item;
2757
+ },
2735
2758
  getA11yStatusMessage: getA11yStatusMessage$1
2736
2759
  });
2737
2760
 
2738
2761
  /* eslint-disable complexity */
2739
2762
  function downshiftUseComboboxReducer(state, action) {
2763
+ var _props$items;
2740
2764
  var type = action.type,
2741
2765
  props = action.props,
2742
2766
  altKey = action.altKey;
@@ -2765,13 +2789,7 @@ function downshiftUseComboboxReducer(state, action) {
2765
2789
  case InputKeyDownArrowUp:
2766
2790
  if (state.isOpen) {
2767
2791
  if (altKey) {
2768
- changes = _extends__default["default"]({
2769
- isOpen: getDefaultValue$1(props, 'isOpen'),
2770
- highlightedIndex: getDefaultValue$1(props, 'highlightedIndex')
2771
- }, state.highlightedIndex >= 0 && {
2772
- selectedItem: props.items[state.highlightedIndex],
2773
- inputValue: props.itemToString(props.items[state.highlightedIndex])
2774
- });
2792
+ changes = getChangesOnSelection(props, state.highlightedIndex);
2775
2793
  } else {
2776
2794
  changes = {
2777
2795
  highlightedIndex: getNextWrappingIndex(-1, state.highlightedIndex, props.items.length, action.getItemNodeFromIndex, true)
@@ -2785,13 +2803,7 @@ function downshiftUseComboboxReducer(state, action) {
2785
2803
  }
2786
2804
  break;
2787
2805
  case InputKeyDownEnter:
2788
- changes = _extends__default["default"]({
2789
- isOpen: getDefaultValue$1(props, 'isOpen'),
2790
- highlightedIndex: getDefaultValue$1(props, 'highlightedIndex')
2791
- }, state.highlightedIndex >= 0 && {
2792
- selectedItem: props.items[state.highlightedIndex],
2793
- inputValue: props.itemToString(props.items[state.highlightedIndex])
2794
- });
2806
+ changes = getChangesOnSelection(props, state.highlightedIndex);
2795
2807
  break;
2796
2808
  case InputKeyDownEscape:
2797
2809
  changes = _extends__default["default"]({
@@ -2826,7 +2838,7 @@ function downshiftUseComboboxReducer(state, action) {
2826
2838
  changes = _extends__default["default"]({
2827
2839
  isOpen: false,
2828
2840
  highlightedIndex: -1
2829
- }, state.highlightedIndex >= 0 && action.selectItem && {
2841
+ }, state.highlightedIndex >= 0 && ((_props$items = props.items) == null ? void 0 : _props$items.length) && action.selectItem && {
2830
2842
  selectedItem: props.items[state.highlightedIndex],
2831
2843
  inputValue: props.itemToString(props.items[state.highlightedIndex])
2832
2844
  });
@@ -3230,6 +3230,32 @@
3230
3230
  };
3231
3231
  }
3232
3232
 
3233
+ /**
3234
+ * Handles selection on Enter / Alt + ArrowUp. Closes the menu and resets the highlighted index, unless there is a highlighted.
3235
+ * In that case, selects the item and resets to defaults for open state and highlighted idex.
3236
+ * @param {Object} props The useCombobox props.
3237
+ * @param {number} highlightedIndex The index from the state.
3238
+ * @param {boolean} inputValue Also return the input value for state.
3239
+ * @returns The changes for the state.
3240
+ */
3241
+ function getChangesOnSelection(props, highlightedIndex, inputValue) {
3242
+ var _props$items;
3243
+ if (inputValue === void 0) {
3244
+ inputValue = true;
3245
+ }
3246
+ var shouldSelect = ((_props$items = props.items) == null ? void 0 : _props$items.length) && highlightedIndex >= 0;
3247
+ return _extends({
3248
+ isOpen: false,
3249
+ highlightedIndex: -1
3250
+ }, shouldSelect && _extends({
3251
+ selectedItem: props.items[highlightedIndex],
3252
+ isOpen: getDefaultValue$1(props, 'isOpen'),
3253
+ highlightedIndex: getDefaultValue$1(props, 'highlightedIndex')
3254
+ }, inputValue && {
3255
+ inputValue: props.itemToString(props.items[highlightedIndex])
3256
+ }));
3257
+ }
3258
+
3233
3259
  function downshiftCommonReducer(state, action, stateChangeTypes) {
3234
3260
  var type = action.type,
3235
3261
  props = action.props;
@@ -3447,6 +3473,7 @@
3447
3473
 
3448
3474
  /* eslint-disable complexity */
3449
3475
  function downshiftSelectReducer(state, action) {
3476
+ var _props$items;
3450
3477
  var type = action.type,
3451
3478
  props = action.props,
3452
3479
  altKey = action.altKey;
@@ -3489,12 +3516,7 @@
3489
3516
  break;
3490
3517
  case ToggleButtonKeyDownArrowUp:
3491
3518
  if (state.isOpen && altKey) {
3492
- changes = _extends({
3493
- isOpen: getDefaultValue$1(props, 'isOpen'),
3494
- highlightedIndex: getDefaultValue$1(props, 'highlightedIndex')
3495
- }, state.highlightedIndex >= 0 && {
3496
- selectedItem: props.items[state.highlightedIndex]
3497
- });
3519
+ changes = getChangesOnSelection(props, state.highlightedIndex, false);
3498
3520
  } else {
3499
3521
  var _highlightedIndex2 = state.isOpen ? getNextWrappingIndex(-1, state.highlightedIndex, props.items.length, action.getItemNodeFromIndex, false) : getHighlightedIndexOnOpen(props, state, -1);
3500
3522
  changes = {
@@ -3506,12 +3528,7 @@
3506
3528
  // only triggered when menu is open.
3507
3529
  case ToggleButtonKeyDownEnter:
3508
3530
  case ToggleButtonKeyDownSpaceButton:
3509
- changes = _extends({
3510
- isOpen: getDefaultValue$1(props, 'isOpen'),
3511
- highlightedIndex: getDefaultValue$1(props, 'highlightedIndex')
3512
- }, state.highlightedIndex >= 0 && {
3513
- selectedItem: props.items[state.highlightedIndex]
3514
- });
3531
+ changes = getChangesOnSelection(props, state.highlightedIndex, false);
3515
3532
  break;
3516
3533
  case ToggleButtonKeyDownHome:
3517
3534
  changes = {
@@ -3545,7 +3562,7 @@
3545
3562
  changes = _extends({
3546
3563
  isOpen: false,
3547
3564
  highlightedIndex: -1
3548
- }, state.highlightedIndex >= 0 && {
3565
+ }, state.highlightedIndex >= 0 && ((_props$items = props.items) == null ? void 0 : _props$items.length) && {
3549
3566
  selectedItem: props.items[state.highlightedIndex]
3550
3567
  });
3551
3568
  break;
@@ -4043,6 +4060,7 @@
4043
4060
  var propTypes$1 = {
4044
4061
  items: PropTypes.array.isRequired,
4045
4062
  itemToString: PropTypes.func,
4063
+ selectedItemChanged: PropTypes.func,
4046
4064
  getA11yStatusMessage: PropTypes.func,
4047
4065
  getA11ySelectionMessage: PropTypes.func,
4048
4066
  highlightedIndex: PropTypes.number,
@@ -4100,16 +4118,18 @@
4100
4118
 
4101
4119
  // ToDo: if needed, make same approach as selectedItemChanged from Downshift.
4102
4120
  react.useEffect(function () {
4103
- if (isControlledProp(props, 'selectedItem')) {
4104
- if (previousSelectedItemRef.current !== props.selectedItem) {
4105
- dispatch({
4106
- type: ControlledPropUpdatedSelectedItem,
4107
- inputValue: props.itemToString(props.selectedItem)
4108
- });
4109
- }
4110
- previousSelectedItemRef.current = state.selectedItem === previousSelectedItemRef.current ? props.selectedItem : state.selectedItem;
4121
+ if (!isControlledProp(props, 'selectedItem')) {
4122
+ return;
4111
4123
  }
4112
- }, [props.selectedItem, state.selectedItem]);
4124
+ if (props.selectedItemChanged(previousSelectedItemRef.current, props.selectedItem)) {
4125
+ dispatch({
4126
+ type: ControlledPropUpdatedSelectedItem,
4127
+ inputValue: props.itemToString(props.selectedItem)
4128
+ });
4129
+ }
4130
+ previousSelectedItemRef.current = state.selectedItem === previousSelectedItemRef.current ? props.selectedItem : state.selectedItem;
4131
+ // eslint-disable-next-line react-hooks/exhaustive-deps
4132
+ }, [state.selectedItem, props.selectedItem]);
4113
4133
  return [getState(state, props), dispatch];
4114
4134
  }
4115
4135
 
@@ -4122,11 +4142,15 @@
4122
4142
  };
4123
4143
  }
4124
4144
  var defaultProps$1 = _extends({}, defaultProps$3, {
4145
+ selectedItemChanged: function selectedItemChanged(prevItem, item) {
4146
+ return prevItem !== item;
4147
+ },
4125
4148
  getA11yStatusMessage: getA11yStatusMessage$1
4126
4149
  });
4127
4150
 
4128
4151
  /* eslint-disable complexity */
4129
4152
  function downshiftUseComboboxReducer(state, action) {
4153
+ var _props$items;
4130
4154
  var type = action.type,
4131
4155
  props = action.props,
4132
4156
  altKey = action.altKey;
@@ -4155,13 +4179,7 @@
4155
4179
  case InputKeyDownArrowUp:
4156
4180
  if (state.isOpen) {
4157
4181
  if (altKey) {
4158
- changes = _extends({
4159
- isOpen: getDefaultValue$1(props, 'isOpen'),
4160
- highlightedIndex: getDefaultValue$1(props, 'highlightedIndex')
4161
- }, state.highlightedIndex >= 0 && {
4162
- selectedItem: props.items[state.highlightedIndex],
4163
- inputValue: props.itemToString(props.items[state.highlightedIndex])
4164
- });
4182
+ changes = getChangesOnSelection(props, state.highlightedIndex);
4165
4183
  } else {
4166
4184
  changes = {
4167
4185
  highlightedIndex: getNextWrappingIndex(-1, state.highlightedIndex, props.items.length, action.getItemNodeFromIndex, true)
@@ -4175,13 +4193,7 @@
4175
4193
  }
4176
4194
  break;
4177
4195
  case InputKeyDownEnter:
4178
- changes = _extends({
4179
- isOpen: getDefaultValue$1(props, 'isOpen'),
4180
- highlightedIndex: getDefaultValue$1(props, 'highlightedIndex')
4181
- }, state.highlightedIndex >= 0 && {
4182
- selectedItem: props.items[state.highlightedIndex],
4183
- inputValue: props.itemToString(props.items[state.highlightedIndex])
4184
- });
4196
+ changes = getChangesOnSelection(props, state.highlightedIndex);
4185
4197
  break;
4186
4198
  case InputKeyDownEscape:
4187
4199
  changes = _extends({
@@ -4216,7 +4228,7 @@
4216
4228
  changes = _extends({
4217
4229
  isOpen: false,
4218
4230
  highlightedIndex: -1
4219
- }, state.highlightedIndex >= 0 && action.selectItem && {
4231
+ }, state.highlightedIndex >= 0 && ((_props$items = props.items) == null ? void 0 : _props$items.length) && action.selectItem && {
4220
4232
  selectedItem: props.items[state.highlightedIndex],
4221
4233
  inputValue: props.itemToString(props.items[state.highlightedIndex])
4222
4234
  });