downshift 5.1.0-beta.0 → 5.2.1

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, useCallback, useReducer, useRef, useEffect } from 'preact';
5
+ import { cloneElement, Component, useState, useRef, useEffect } 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';
@@ -164,7 +164,8 @@ function resetIdCounter() {
164
164
 
165
165
  function getA11yStatusMessage(_ref2) {
166
166
  var isOpen = _ref2.isOpen,
167
- resultCount = _ref2.resultCount;
167
+ resultCount = _ref2.resultCount,
168
+ previousResultCount = _ref2.previousResultCount;
168
169
 
169
170
  if (!isOpen) {
170
171
  return '';
@@ -174,7 +175,11 @@ function getA11yStatusMessage(_ref2) {
174
175
  return 'No results are available.';
175
176
  }
176
177
 
177
- return resultCount + " result" + (resultCount === 1 ? ' is' : 's are') + " available, use up and down arrow keys to navigate. Press Enter key to select.";
178
+ if (resultCount !== previousResultCount) {
179
+ return resultCount + " result" + (resultCount === 1 ? ' is' : 's are') + " available, use up and down arrow keys to navigate. Press Enter key to select.";
180
+ }
181
+
182
+ return '';
178
183
  }
179
184
  /**
180
185
  * Takes an argument and if it's an array, returns the first item in the array
@@ -503,8 +508,12 @@ var stateChangeTypes = /*#__PURE__*/Object.freeze({
503
508
  touchEnd: touchEnd
504
509
  });
505
510
 
506
- var Downshift = /*#__PURE__*/function () {
507
- var Downshift = /*#__PURE__*/function (_Component) {
511
+ var Downshift =
512
+ /*#__PURE__*/
513
+ function () {
514
+ var Downshift =
515
+ /*#__PURE__*/
516
+ function (_Component) {
508
517
  _inheritsLoose(Downshift, _Component);
509
518
 
510
519
  function Downshift(_props) {
@@ -778,6 +787,10 @@ var Downshift = /*#__PURE__*/function () {
778
787
  }
779
788
  },
780
789
  Enter: function Enter(event) {
790
+ if (event.which === 229) {
791
+ return;
792
+ }
793
+
781
794
  var _this$getState2 = this.getState(),
782
795
  isOpen = _this$getState2.isOpen,
783
796
  highlightedIndex = _this$getState2.highlightedIndex;
@@ -1623,6 +1636,65 @@ var dropdownDefaultStateValues = {
1623
1636
  inputValue: ''
1624
1637
  };
1625
1638
 
1639
+ function callOnChangeProps(action, state, newState) {
1640
+ var props = action.props,
1641
+ type = action.type;
1642
+ var changes = {};
1643
+ Object.keys(state).forEach(function (key) {
1644
+ invokeOnChangeHandler(key, props, state, newState);
1645
+
1646
+ if (newState[key] !== state[key]) {
1647
+ changes[key] = newState[key];
1648
+ }
1649
+ });
1650
+
1651
+ if (props.onStateChange && Object.keys(changes).length) {
1652
+ props.onStateChange(_extends({
1653
+ type: type
1654
+ }, changes));
1655
+ }
1656
+ }
1657
+
1658
+ function invokeOnChangeHandler(key, props, state, newState) {
1659
+ var handler = "on" + capitalizeString(key) + "Change";
1660
+
1661
+ if (props[handler] && newState[key] !== undefined && newState[key] !== state[key]) {
1662
+ props[handler](newState);
1663
+ }
1664
+ }
1665
+ /**
1666
+ * Default state reducer that returns the changes.
1667
+ *
1668
+ * @param {Object} s state.
1669
+ * @param {Object} a action with changes.
1670
+ * @returns {Object} changes.
1671
+ */
1672
+
1673
+
1674
+ function stateReducer(s, a) {
1675
+ return a.changes;
1676
+ }
1677
+ /**
1678
+ * Returns a message to be added to aria-live region when item is selected.
1679
+ *
1680
+ * @param {Object} selectionParameters Parameters required to build the message.
1681
+ * @returns {string} The a11y message.
1682
+ */
1683
+
1684
+
1685
+ function getA11ySelectionMessage(selectionParameters) {
1686
+ var selectedItem = selectionParameters.selectedItem,
1687
+ itemToStringLocal = selectionParameters.itemToString;
1688
+ return selectedItem ? itemToStringLocal(selectedItem) + " has been selected." : '';
1689
+ }
1690
+ /**
1691
+ * Debounced call for updating the a11y message.
1692
+ */
1693
+
1694
+
1695
+ var updateA11yStatus = debounce(function (getA11yMessage, document) {
1696
+ setStatus(getA11yMessage(), document);
1697
+ }, 200);
1626
1698
  function getElementIds(_ref) {
1627
1699
  var id = _ref.id,
1628
1700
  labelId = _ref.labelId,
@@ -1639,7 +1711,6 @@ function getElementIds(_ref) {
1639
1711
  toggleButtonId: toggleButtonId || uniqueId + "-toggle-button"
1640
1712
  };
1641
1713
  }
1642
-
1643
1714
  function getItemIndex(index, item, items) {
1644
1715
  if (index !== undefined) {
1645
1716
  return index;
@@ -1668,57 +1739,39 @@ function getPropTypesValidator(caller, propTypes) {
1668
1739
  });
1669
1740
  };
1670
1741
  }
1671
-
1672
1742
  function isAcceptedCharacterKey(key) {
1673
1743
  return /^\S{1}$/.test(key);
1674
1744
  }
1675
-
1676
1745
  function capitalizeString(string) {
1677
1746
  return "" + string.slice(0, 1).toUpperCase() + string.slice(1);
1678
1747
  }
1748
+ /**
1749
+ * Computes the controlled state using a the previous state, props,
1750
+ * two reducers, one from downshift and an optional one from the user.
1751
+ * Also calls the onChange handlers for state values that have changed.
1752
+ *
1753
+ * @param {Function} reducer Reducer function from downshift.
1754
+ * @param {Object} initialState Initial state of the hook.
1755
+ * @param {Object} props The hook props.
1756
+ * @returns {Array} An array with the state and an action dispatcher.
1757
+ */
1679
1758
 
1680
- function invokeOnChangeHandler(key, props, state, newState) {
1681
- var handler = "on" + capitalizeString(key) + "Change";
1682
-
1683
- if (props[handler] && newState[key] !== undefined && newState[key] !== state[key]) {
1684
- props[handler](newState);
1685
- }
1686
- }
1687
-
1688
- function callOnChangeProps(action, state, newState) {
1689
- var props = action.props,
1690
- type = action.type;
1691
- var changes = {};
1692
- Object.keys(state).forEach(function (key) {
1693
- invokeOnChangeHandler(key, props, state, newState);
1759
+ function useControlledState(reducer, initialState, props) {
1760
+ var _useState = useState(initialState),
1761
+ uncontrolledState = _useState[0],
1762
+ setState = _useState[1];
1694
1763
 
1695
- if (newState[key] !== state[key]) {
1696
- changes[key] = newState[key];
1697
- }
1698
- });
1764
+ var state = getState(uncontrolledState, props);
1699
1765
 
1700
- if (props.onStateChange && Object.keys(changes).length) {
1701
- props.onStateChange(_extends({
1702
- type: type
1703
- }, changes));
1704
- }
1705
- }
1706
-
1707
- function useEnhancedReducer(reducer, initialState, props) {
1708
- var enhancedReducer = useCallback(function (state, action) {
1709
- state = getState(state, action.props);
1710
- var stateReduceLocal = action.props.stateReducer;
1766
+ var dispatch = function (action) {
1767
+ var stateReducerFromProps = action.props.stateReducer;
1711
1768
  var changes = reducer(state, action);
1712
- var newState = stateReduceLocal(state, _extends({}, action, {
1769
+ var newState = stateReducerFromProps(state, _extends({}, action, {
1713
1770
  changes: changes
1714
1771
  }));
1715
1772
  callOnChangeProps(action, state, newState);
1716
- return newState;
1717
- }, [reducer]);
1718
-
1719
- var _useReducer = useReducer(enhancedReducer, initialState),
1720
- state = _useReducer[0],
1721
- dispatch = _useReducer[1];
1773
+ setState(newState);
1774
+ };
1722
1775
 
1723
1776
  return [getState(state, props), function dispatchWithProps(action) {
1724
1777
  return dispatch(_extends({
@@ -1726,32 +1779,6 @@ function useEnhancedReducer(reducer, initialState, props) {
1726
1779
  }, action));
1727
1780
  }];
1728
1781
  }
1729
- /**
1730
- * Default state reducer that returns the changes.
1731
- *
1732
- * @param {Object} s state.
1733
- * @param {Object} a action with changes.
1734
- * @returns {Object} changes.
1735
- */
1736
-
1737
-
1738
- function stateReducer(s, a) {
1739
- return a.changes;
1740
- }
1741
- /**
1742
- * Returns a message to be added to aria-live region when item is selected.
1743
- *
1744
- * @param {Object} selectionParameters Parameters required to build the message.
1745
- * @returns {string} The a11y message.
1746
- */
1747
-
1748
-
1749
- function getA11ySelectionMessage(selectionParameters) {
1750
- var selectedItem = selectionParameters.selectedItem,
1751
- itemToStringLocal = selectionParameters.itemToString;
1752
- return itemToStringLocal(selectedItem) + " has been selected.";
1753
- }
1754
-
1755
1782
  var defaultProps = {
1756
1783
  itemToString: itemToString,
1757
1784
  stateReducer: stateReducer,
@@ -1762,7 +1789,6 @@ var defaultProps = {
1762
1789
  /* istanbul ignore next (ssr) */
1763
1790
  ? {} : window
1764
1791
  };
1765
-
1766
1792
  function getDefaultValue(props, propKey, defaultStateValues) {
1767
1793
  if (defaultStateValues === void 0) {
1768
1794
  defaultStateValues = dropdownDefaultStateValues;
@@ -1776,7 +1802,6 @@ function getDefaultValue(props, propKey, defaultStateValues) {
1776
1802
 
1777
1803
  return defaultStateValues[propKey];
1778
1804
  }
1779
-
1780
1805
  function getInitialValue(props, propKey, defaultStateValues) {
1781
1806
  if (defaultStateValues === void 0) {
1782
1807
  defaultStateValues = dropdownDefaultStateValues;
@@ -1794,7 +1819,6 @@ function getInitialValue(props, propKey, defaultStateValues) {
1794
1819
 
1795
1820
  return getDefaultValue(props, propKey, defaultStateValues);
1796
1821
  }
1797
-
1798
1822
  function getInitialState(props) {
1799
1823
  var selectedItem = getInitialValue(props, 'selectedItem');
1800
1824
  var isOpen = getInitialValue(props, 'isOpen');
@@ -1807,7 +1831,6 @@ function getInitialState(props) {
1807
1831
  inputValue: inputValue
1808
1832
  };
1809
1833
  }
1810
-
1811
1834
  function getHighlightedIndexOnOpen(props, state, offset, getItemNodeFromIndex) {
1812
1835
  var items = props.items,
1813
1836
  initialHighlightedIndex = props.initialHighlightedIndex,
@@ -1914,7 +1937,8 @@ var propTypes = {
1914
1937
 
1915
1938
  function getA11yStatusMessage$1(_ref) {
1916
1939
  var isOpen = _ref.isOpen,
1917
- resultCount = _ref.resultCount;
1940
+ resultCount = _ref.resultCount,
1941
+ previousResultCount = _ref.previousResultCount;
1918
1942
 
1919
1943
  if (!isOpen) {
1920
1944
  return '';
@@ -1924,7 +1948,11 @@ function getA11yStatusMessage$1(_ref) {
1924
1948
  return 'No results are available.';
1925
1949
  }
1926
1950
 
1927
- return resultCount + " result" + (resultCount === 1 ? ' is' : 's are') + " available, use up and down arrow keys to navigate. Press Enter or Space Bar keys to select.";
1951
+ if (resultCount !== previousResultCount) {
1952
+ return resultCount + " result" + (resultCount === 1 ? ' is' : 's are') + " available, use up and down arrow keys to navigate. Press Enter or Space Bar keys to select.";
1953
+ }
1954
+
1955
+ return '';
1928
1956
  }
1929
1957
 
1930
1958
  var defaultProps$1 = _extends({}, defaultProps, {
@@ -2176,24 +2204,23 @@ function useSelect(userProps) {
2176
2204
  var props = _extends({}, defaultProps$1, {}, userProps);
2177
2205
 
2178
2206
  var items = props.items,
2179
- itemToString = props.itemToString,
2180
- getA11yStatusMessage = props.getA11yStatusMessage,
2181
- getA11ySelectionMessage = props.getA11ySelectionMessage,
2182
2207
  scrollIntoView = props.scrollIntoView,
2183
2208
  environment = props.environment,
2184
2209
  initialIsOpen = props.initialIsOpen,
2185
- defaultIsOpen = props.defaultIsOpen; // Initial state depending on controlled props.
2210
+ defaultIsOpen = props.defaultIsOpen,
2211
+ itemToString = props.itemToString,
2212
+ getA11ySelectionMessage = props.getA11ySelectionMessage,
2213
+ getA11yStatusMessage = props.getA11yStatusMessage; // Initial state depending on controlled props.
2186
2214
 
2187
2215
  var initialState = getInitialState(props); // Reducer init.
2188
2216
 
2189
- var _useEnhancedReducer = useEnhancedReducer(downshiftSelectReducer, initialState, props),
2190
- _useEnhancedReducer$ = _useEnhancedReducer[0],
2191
- isOpen = _useEnhancedReducer$.isOpen,
2192
- highlightedIndex = _useEnhancedReducer$.highlightedIndex,
2193
- selectedItem = _useEnhancedReducer$.selectedItem,
2194
- inputValue = _useEnhancedReducer$.inputValue,
2195
- dispatch = _useEnhancedReducer[1];
2196
- /* Refs */
2217
+ var _useControlledState = useControlledState(downshiftSelectReducer, initialState, props),
2218
+ _useControlledState$ = _useControlledState[0],
2219
+ isOpen = _useControlledState$.isOpen,
2220
+ highlightedIndex = _useControlledState$.highlightedIndex,
2221
+ selectedItem = _useControlledState$.selectedItem,
2222
+ inputValue = _useControlledState$.inputValue,
2223
+ dispatch = _useControlledState[1]; // Refs
2197
2224
 
2198
2225
 
2199
2226
  var toggleButtonRef = useRef(null);
@@ -2205,13 +2232,14 @@ function useSelect(userProps) {
2205
2232
  isMouseDown: false,
2206
2233
  isTouchMove: false
2207
2234
  });
2208
- var elementIds = useRef(getElementIds(props)); // Some utils.
2235
+ var elementIds = useRef(getElementIds(props));
2236
+ var previousResultCountRef = useRef(); // Some utils.
2209
2237
 
2210
2238
  var getItemNodeFromIndex = function (index) {
2211
2239
  return environment.document.getElementById(elementIds.current.getItemId(index));
2212
2240
  }; // Effects.
2213
2241
 
2214
- /* Sets a11y status message on changes in isOpen. */
2242
+ /* Sets a11y status message on changes in state. */
2215
2243
 
2216
2244
 
2217
2245
  useEffect(function () {
@@ -2219,16 +2247,20 @@ function useSelect(userProps) {
2219
2247
  return;
2220
2248
  }
2221
2249
 
2222
- setStatus(getA11yStatusMessage({
2223
- highlightedIndex: highlightedIndex,
2224
- inputValue: inputValue,
2225
- isOpen: isOpen,
2226
- itemToString: itemToString,
2227
- resultCount: items.length,
2228
- highlightedItem: items[highlightedIndex],
2229
- selectedItem: selectedItem
2230
- }), environment.document); // eslint-disable-next-line react-hooks/exhaustive-deps
2231
- }, [isOpen]);
2250
+ var previousResultCount = previousResultCountRef.current;
2251
+ updateA11yStatus(function () {
2252
+ return getA11yStatusMessage({
2253
+ isOpen: isOpen,
2254
+ highlightedIndex: highlightedIndex,
2255
+ selectedItem: selectedItem,
2256
+ inputValue: inputValue,
2257
+ highlightedItem: items[highlightedIndex],
2258
+ resultCount: items.length,
2259
+ itemToString: itemToString,
2260
+ previousResultCount: previousResultCount
2261
+ });
2262
+ }, environment.document); // eslint-disable-next-line react-hooks/exhaustive-deps
2263
+ }, [isOpen, highlightedIndex, selectedItem, inputValue]);
2232
2264
  /* Sets a11y status message on changes in selectedItem. */
2233
2265
 
2234
2266
  useEffect(function () {
@@ -2236,15 +2268,19 @@ function useSelect(userProps) {
2236
2268
  return;
2237
2269
  }
2238
2270
 
2239
- setStatus(getA11ySelectionMessage({
2240
- highlightedIndex: highlightedIndex,
2241
- inputValue: inputValue,
2242
- isOpen: isOpen,
2243
- itemToString: itemToString,
2244
- resultCount: items.length,
2245
- highlightedItem: items[highlightedIndex],
2246
- selectedItem: selectedItem
2247
- }), environment.document); // eslint-disable-next-line react-hooks/exhaustive-deps
2271
+ var previousResultCount = previousResultCountRef.current;
2272
+ updateA11yStatus(function () {
2273
+ return getA11ySelectionMessage({
2274
+ isOpen: isOpen,
2275
+ highlightedIndex: highlightedIndex,
2276
+ selectedItem: selectedItem,
2277
+ inputValue: inputValue,
2278
+ highlightedItem: items[highlightedIndex],
2279
+ resultCount: items.length,
2280
+ itemToString: itemToString,
2281
+ previousResultCount: previousResultCount
2282
+ });
2283
+ }, environment.document); // eslint-disable-next-line react-hooks/exhaustive-deps
2248
2284
  }, [selectedItem]);
2249
2285
  /* Sets cleanup for the keysSoFar after 500ms. */
2250
2286
 
@@ -2301,6 +2337,13 @@ function useSelect(userProps) {
2301
2337
  } // eslint-disable-next-line react-hooks/exhaustive-deps
2302
2338
 
2303
2339
  }, [highlightedIndex]);
2340
+ useEffect(function () {
2341
+ if (isInitialMount.current) {
2342
+ return;
2343
+ }
2344
+
2345
+ previousResultCountRef.current = items.length;
2346
+ });
2304
2347
  /* Make initial ref false. */
2305
2348
 
2306
2349
  useEffect(function () {
@@ -2624,6 +2667,51 @@ function useSelect(userProps) {
2624
2667
  };
2625
2668
  }
2626
2669
 
2670
+ var InputKeyDownArrowDown = process.env.NODE_ENV !== "production" ? '__input_keydown_arrow_down__' : 0;
2671
+ var InputKeyDownArrowUp = process.env.NODE_ENV !== "production" ? '__input_keydown_arrow_up__' : 1;
2672
+ var InputKeyDownEscape = process.env.NODE_ENV !== "production" ? '__input_keydown_escape__' : 2;
2673
+ var InputKeyDownHome = process.env.NODE_ENV !== "production" ? '__input_keydown_home__' : 3;
2674
+ var InputKeyDownEnd = process.env.NODE_ENV !== "production" ? '__input_keydown_end__' : 4;
2675
+ var InputKeyDownEnter = process.env.NODE_ENV !== "production" ? '__input_keydown_enter__' : 5;
2676
+ var InputChange = process.env.NODE_ENV !== "production" ? '__input_change__' : 6;
2677
+ var InputBlur = process.env.NODE_ENV !== "production" ? '__input_blur__' : 7;
2678
+ var MenuMouseLeave$1 = process.env.NODE_ENV !== "production" ? '__menu_mouse_leave__' : 8;
2679
+ var ItemMouseMove$1 = process.env.NODE_ENV !== "production" ? '__item_mouse_move__' : 9;
2680
+ var ItemClick$1 = process.env.NODE_ENV !== "production" ? '__item_click__' : 10;
2681
+ var ToggleButtonClick$1 = process.env.NODE_ENV !== "production" ? '__togglebutton_click__' : 11;
2682
+ var FunctionToggleMenu$1 = process.env.NODE_ENV !== "production" ? '__function_toggle_menu__' : 12;
2683
+ var FunctionOpenMenu$1 = process.env.NODE_ENV !== "production" ? '__function_open_menu__' : 13;
2684
+ var FunctionCloseMenu$1 = process.env.NODE_ENV !== "production" ? '__function_close_menu__' : 14;
2685
+ var FunctionSetHighlightedIndex$1 = process.env.NODE_ENV !== "production" ? '__function_set_highlighted_index__' : 15;
2686
+ var FunctionSelectItem$1 = process.env.NODE_ENV !== "production" ? '__function_select_item__' : 16;
2687
+ var FunctionSetInputValue$1 = process.env.NODE_ENV !== "production" ? '__function_set_input_value__' : 17;
2688
+ var FunctionReset$1 = process.env.NODE_ENV !== "production" ? '__function_reset__' : 18;
2689
+ var ControlledPropUpdatedSelectedItem = process.env.NODE_ENV !== "production" ? '__controlled_prop_updated_selected_item__' : 19;
2690
+
2691
+ var stateChangeTypes$2 = /*#__PURE__*/Object.freeze({
2692
+ __proto__: null,
2693
+ InputKeyDownArrowDown: InputKeyDownArrowDown,
2694
+ InputKeyDownArrowUp: InputKeyDownArrowUp,
2695
+ InputKeyDownEscape: InputKeyDownEscape,
2696
+ InputKeyDownHome: InputKeyDownHome,
2697
+ InputKeyDownEnd: InputKeyDownEnd,
2698
+ InputKeyDownEnter: InputKeyDownEnter,
2699
+ InputChange: InputChange,
2700
+ InputBlur: InputBlur,
2701
+ MenuMouseLeave: MenuMouseLeave$1,
2702
+ ItemMouseMove: ItemMouseMove$1,
2703
+ ItemClick: ItemClick$1,
2704
+ ToggleButtonClick: ToggleButtonClick$1,
2705
+ FunctionToggleMenu: FunctionToggleMenu$1,
2706
+ FunctionOpenMenu: FunctionOpenMenu$1,
2707
+ FunctionCloseMenu: FunctionCloseMenu$1,
2708
+ FunctionSetHighlightedIndex: FunctionSetHighlightedIndex$1,
2709
+ FunctionSelectItem: FunctionSelectItem$1,
2710
+ FunctionSetInputValue: FunctionSetInputValue$1,
2711
+ FunctionReset: FunctionReset$1,
2712
+ ControlledPropUpdatedSelectedItem: ControlledPropUpdatedSelectedItem
2713
+ });
2714
+
2627
2715
  function getElementIds$1(_ref) {
2628
2716
  var id = _ref.id,
2629
2717
  inputId = _ref.inputId,
@@ -2636,7 +2724,6 @@ function getElementIds$1(_ref) {
2636
2724
  id: id
2637
2725
  }, rest)));
2638
2726
  }
2639
-
2640
2727
  function getInitialState$1(props) {
2641
2728
  var initialState = getInitialState(props);
2642
2729
  var selectedItem = initialState.selectedItem;
@@ -2650,7 +2737,6 @@ function getInitialState$1(props) {
2650
2737
  inputValue: inputValue
2651
2738
  });
2652
2739
  }
2653
-
2654
2740
  var propTypes$1 = {
2655
2741
  items: PropTypes.array.isRequired,
2656
2742
  itemToString: PropTypes.func,
@@ -2691,55 +2777,43 @@ var propTypes$1 = {
2691
2777
  })
2692
2778
  })
2693
2779
  };
2780
+ /**
2781
+ * The useCombobox version of useControlledState, which also
2782
+ * checks if the controlled prop selectedItem changed between
2783
+ * renders. If so, it will also update inputValue with its
2784
+ * string equivalent. It uses the common useControlledState to
2785
+ * compute the rest of the state.
2786
+ *
2787
+ * @param {Function} reducer Reducer function from downshift.
2788
+ * @param {Object} initialState Initial state of the hook.
2789
+ * @param {Object} props The hook props.
2790
+ * @returns {Array} An array with the state and an action dispatcher.
2791
+ */
2792
+
2793
+ function useControlledState$1(reducer, initialState, props) {
2794
+ var _useControlledStateCo = useControlledState(reducer, initialState, props),
2795
+ newState = _useControlledStateCo[0],
2796
+ dispatch = _useControlledStateCo[1];
2797
+
2798
+ var previousSelectedItemRef = useRef(null);
2799
+ var selectedItem = props.selectedItem,
2800
+ itemToString = props.itemToString; // ToDo: if needed, make same approach as selectedItemChanged from Downshift.
2801
+
2802
+ if (isControlledProp(props, 'selectedItem') && previousSelectedItemRef.current !== selectedItem) {
2803
+ dispatch({
2804
+ type: ControlledPropUpdatedSelectedItem,
2805
+ inputValue: itemToString(selectedItem)
2806
+ });
2807
+ }
2694
2808
 
2809
+ previousSelectedItemRef.current = selectedItem;
2810
+ return [newState, dispatch];
2811
+ }
2695
2812
  var defaultProps$2 = _extends({}, defaultProps, {
2696
2813
  getA11yStatusMessage: getA11yStatusMessage,
2697
2814
  circularNavigation: true
2698
2815
  });
2699
2816
 
2700
- var InputKeyDownArrowDown = process.env.NODE_ENV !== "production" ? '__input_keydown_arrow_down__' : 0;
2701
- var InputKeyDownArrowUp = process.env.NODE_ENV !== "production" ? '__input_keydown_arrow_up__' : 1;
2702
- var InputKeyDownEscape = process.env.NODE_ENV !== "production" ? '__input_keydown_escape__' : 2;
2703
- var InputKeyDownHome = process.env.NODE_ENV !== "production" ? '__input_keydown_home__' : 3;
2704
- var InputKeyDownEnd = process.env.NODE_ENV !== "production" ? '__input_keydown_end__' : 4;
2705
- var InputKeyDownEnter = process.env.NODE_ENV !== "production" ? '__input_keydown_enter__' : 5;
2706
- var InputChange = process.env.NODE_ENV !== "production" ? '__input_change__' : 6;
2707
- var InputBlur = process.env.NODE_ENV !== "production" ? '__input_blur__' : 7;
2708
- var MenuMouseLeave$1 = process.env.NODE_ENV !== "production" ? '__menu_mouse_leave__' : 8;
2709
- var ItemMouseMove$1 = process.env.NODE_ENV !== "production" ? '__item_mouse_move__' : 9;
2710
- var ItemClick$1 = process.env.NODE_ENV !== "production" ? '__item_click__' : 10;
2711
- var ToggleButtonClick$1 = process.env.NODE_ENV !== "production" ? '__togglebutton_click__' : 11;
2712
- var FunctionToggleMenu$1 = process.env.NODE_ENV !== "production" ? '__function_toggle_menu__' : 12;
2713
- var FunctionOpenMenu$1 = process.env.NODE_ENV !== "production" ? '__function_open_menu__' : 13;
2714
- var FunctionCloseMenu$1 = process.env.NODE_ENV !== "production" ? '__function_close_menu__' : 14;
2715
- var FunctionSetHighlightedIndex$1 = process.env.NODE_ENV !== "production" ? '__function_set_highlighted_index__' : 15;
2716
- var FunctionSelectItem$1 = process.env.NODE_ENV !== "production" ? '__function_select_item__' : 16;
2717
- var FunctionSetInputValue$1 = process.env.NODE_ENV !== "production" ? '__function_set_input_value__' : 17;
2718
- var FunctionReset$1 = process.env.NODE_ENV !== "production" ? '__function_reset__' : 18;
2719
-
2720
- var stateChangeTypes$2 = /*#__PURE__*/Object.freeze({
2721
- __proto__: null,
2722
- InputKeyDownArrowDown: InputKeyDownArrowDown,
2723
- InputKeyDownArrowUp: InputKeyDownArrowUp,
2724
- InputKeyDownEscape: InputKeyDownEscape,
2725
- InputKeyDownHome: InputKeyDownHome,
2726
- InputKeyDownEnd: InputKeyDownEnd,
2727
- InputKeyDownEnter: InputKeyDownEnter,
2728
- InputChange: InputChange,
2729
- InputBlur: InputBlur,
2730
- MenuMouseLeave: MenuMouseLeave$1,
2731
- ItemMouseMove: ItemMouseMove$1,
2732
- ItemClick: ItemClick$1,
2733
- ToggleButtonClick: ToggleButtonClick$1,
2734
- FunctionToggleMenu: FunctionToggleMenu$1,
2735
- FunctionOpenMenu: FunctionOpenMenu$1,
2736
- FunctionCloseMenu: FunctionCloseMenu$1,
2737
- FunctionSetHighlightedIndex: FunctionSetHighlightedIndex$1,
2738
- FunctionSelectItem: FunctionSelectItem$1,
2739
- FunctionSetInputValue: FunctionSetInputValue$1,
2740
- FunctionReset: FunctionReset$1
2741
- });
2742
-
2743
2817
  /* eslint-disable complexity */
2744
2818
 
2745
2819
  function downshiftUseComboboxReducer(state, action) {
@@ -2879,6 +2953,7 @@ function downshiftUseComboboxReducer(state, action) {
2879
2953
  };
2880
2954
  break;
2881
2955
 
2956
+ case ControlledPropUpdatedSelectedItem:
2882
2957
  case FunctionSetInputValue$1:
2883
2958
  changes = {
2884
2959
  inputValue: action.inputValue
@@ -2924,20 +2999,20 @@ function useCombobox(userProps) {
2924
2999
  defaultIsOpen = props.defaultIsOpen,
2925
3000
  items = props.items,
2926
3001
  scrollIntoView = props.scrollIntoView,
2927
- getA11ySelectionMessage = props.getA11ySelectionMessage,
3002
+ environment = props.environment,
2928
3003
  getA11yStatusMessage = props.getA11yStatusMessage,
2929
- itemToString = props.itemToString,
2930
- environment = props.environment; // Initial state depending on controlled props.
3004
+ getA11ySelectionMessage = props.getA11ySelectionMessage,
3005
+ itemToString = props.itemToString; // Initial state depending on controlled props.
2931
3006
 
2932
3007
  var initialState = getInitialState$1(props); // Reducer init.
2933
3008
 
2934
- var _useEnhancedReducer = useEnhancedReducer(downshiftUseComboboxReducer, initialState, props),
2935
- _useEnhancedReducer$ = _useEnhancedReducer[0],
2936
- isOpen = _useEnhancedReducer$.isOpen,
2937
- highlightedIndex = _useEnhancedReducer$.highlightedIndex,
2938
- selectedItem = _useEnhancedReducer$.selectedItem,
2939
- inputValue = _useEnhancedReducer$.inputValue,
2940
- dispatch = _useEnhancedReducer[1];
3009
+ var _useControlledState = useControlledState$1(downshiftUseComboboxReducer, initialState, props),
3010
+ _useControlledState$ = _useControlledState[0],
3011
+ isOpen = _useControlledState$.isOpen,
3012
+ highlightedIndex = _useControlledState$.highlightedIndex,
3013
+ selectedItem = _useControlledState$.selectedItem,
3014
+ inputValue = _useControlledState$.inputValue,
3015
+ dispatch = _useControlledState[1];
2941
3016
  /* Refs */
2942
3017
 
2943
3018
 
@@ -2954,25 +3029,30 @@ function useCombobox(userProps) {
2954
3029
  isTouchMove: false
2955
3030
  });
2956
3031
  var elementIds = useRef(getElementIds$1(props));
3032
+ var previousResultCountRef = useRef();
2957
3033
  /* Effects */
2958
3034
 
2959
- /* Sets a11y status message on changes in isOpen. */
3035
+ /* Sets a11y status message on changes in state. */
2960
3036
 
2961
3037
  useEffect(function () {
2962
3038
  if (isInitialMount.current) {
2963
3039
  return;
2964
3040
  }
2965
3041
 
2966
- setStatus(getA11yStatusMessage({
2967
- highlightedIndex: highlightedIndex,
2968
- inputValue: inputValue,
2969
- isOpen: isOpen,
2970
- itemToString: itemToString,
2971
- resultCount: items.length,
2972
- highlightedItem: items[highlightedIndex],
2973
- selectedItem: selectedItem
2974
- }), environment.document); // eslint-disable-next-line react-hooks/exhaustive-deps
2975
- }, [isOpen]);
3042
+ var previousResultCount = previousResultCountRef.current;
3043
+ updateA11yStatus(function () {
3044
+ return getA11yStatusMessage({
3045
+ isOpen: isOpen,
3046
+ highlightedIndex: highlightedIndex,
3047
+ selectedItem: selectedItem,
3048
+ inputValue: inputValue,
3049
+ highlightedItem: items[highlightedIndex],
3050
+ resultCount: items.length,
3051
+ itemToString: itemToString,
3052
+ previousResultCount: previousResultCount
3053
+ });
3054
+ }, environment.document); // eslint-disable-next-line react-hooks/exhaustive-deps
3055
+ }, [isOpen, highlightedIndex, selectedItem, inputValue]);
2976
3056
  /* Sets a11y status message on changes in selectedItem. */
2977
3057
 
2978
3058
  useEffect(function () {
@@ -2980,15 +3060,19 @@ function useCombobox(userProps) {
2980
3060
  return;
2981
3061
  }
2982
3062
 
2983
- setStatus(getA11ySelectionMessage({
2984
- highlightedIndex: highlightedIndex,
2985
- inputValue: inputValue,
2986
- isOpen: isOpen,
2987
- itemToString: itemToString,
2988
- resultCount: items.length,
2989
- highlightedItem: items[highlightedIndex],
2990
- selectedItem: selectedItem
2991
- }), environment.document); // eslint-disable-next-line react-hooks/exhaustive-deps
3063
+ var previousResultCount = previousResultCountRef.current;
3064
+ updateA11yStatus(function () {
3065
+ return getA11ySelectionMessage({
3066
+ isOpen: isOpen,
3067
+ highlightedIndex: highlightedIndex,
3068
+ selectedItem: selectedItem,
3069
+ inputValue: inputValue,
3070
+ highlightedItem: items[highlightedIndex],
3071
+ resultCount: items.length,
3072
+ itemToString: itemToString,
3073
+ previousResultCount: previousResultCount
3074
+ });
3075
+ }, environment.document); // eslint-disable-next-line react-hooks/exhaustive-deps
2992
3076
  }, [selectedItem]);
2993
3077
  /* Scroll on highlighted item if change comes from keyboard. */
2994
3078
 
@@ -3018,8 +3102,13 @@ function useCombobox(userProps) {
3018
3102
  } // eslint-disable-next-line react-hooks/exhaustive-deps
3019
3103
 
3020
3104
  }, [isOpen]);
3021
- /* Make initial ref false. */
3105
+ useEffect(function () {
3106
+ if (isInitialMount.current) {
3107
+ return;
3108
+ }
3022
3109
 
3110
+ previousResultCountRef.current = items.length;
3111
+ });
3023
3112
  useEffect(function () {
3024
3113
  isInitialMount.current = false;
3025
3114
  }, []);
@@ -3115,6 +3204,11 @@ function useCombobox(userProps) {
3115
3204
  });
3116
3205
  },
3117
3206
  Enter: function Enter(event) {
3207
+ // if IME composing, wait for next Enter keydown event.
3208
+ if (event.which === 229) {
3209
+ return;
3210
+ }
3211
+
3118
3212
  event.preventDefault();
3119
3213
  dispatch({
3120
3214
  type: InputKeyDownEnter,
@@ -3645,11 +3739,11 @@ function useMultipleSelection(userProps) {
3645
3739
  keyNavigationNext = props.keyNavigationNext,
3646
3740
  keyNavigationPrevious = props.keyNavigationPrevious; // Reducer init.
3647
3741
 
3648
- var _useEnhancedReducer = useEnhancedReducer(downshiftMultipleSelectionReducer, getInitialState$2(props), props),
3649
- _useEnhancedReducer$ = _useEnhancedReducer[0],
3650
- activeIndex = _useEnhancedReducer$.activeIndex,
3651
- selectedItems = _useEnhancedReducer$.selectedItems,
3652
- dispatch = _useEnhancedReducer[1]; // Refs.
3742
+ var _useControlledState = useControlledState(downshiftMultipleSelectionReducer, getInitialState$2(props), props),
3743
+ _useControlledState$ = _useControlledState[0],
3744
+ activeIndex = _useControlledState$.activeIndex,
3745
+ selectedItems = _useControlledState$.selectedItems,
3746
+ dispatch = _useControlledState[1]; // Refs.
3653
3747
 
3654
3748
 
3655
3749
  var isInitialMount = useRef(true);