downshift 8.3.1 → 8.3.2

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.
@@ -7,9 +7,8 @@ export function useScrollIntoView({ highlightedIndex, isOpen, itemRefs, getItemN
7
7
  menuElement: any;
8
8
  scrollIntoView: any;
9
9
  }): React.MutableRefObject<boolean>;
10
- export function useA11yMessageSetter(getA11yMessage: any, dependencyArray: any, { isInitialMount, highlightedIndex, items, environment, ...rest }: {
10
+ export function useA11yMessageSetter(getA11yMessage: any, dependencyArray: any, { highlightedIndex, items, environment, ...rest }: {
11
11
  [x: string]: any;
12
- isInitialMount: any;
13
12
  highlightedIndex: any;
14
13
  items: any;
15
14
  environment: any;
@@ -163,6 +162,10 @@ export namespace commonDropdownPropTypes {
163
162
  export { stateReducer_1 as stateReducer };
164
163
  }
165
164
  export namespace commonPropTypes { }
165
+ /**
166
+ * Tracks if it's the first render.
167
+ */
168
+ export function useIsInitialMount(): boolean;
166
169
  import { noop } from "../utils";
167
170
  import React from "react";
168
171
  declare function itemToString(item: any): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "downshift",
3
- "version": "8.3.1",
3
+ "version": "8.3.2",
4
4
  "description": "🏎 A set of primitives to build simple, flexible, WAI-ARIA compliant React autocomplete, combobox or select dropdown components.",
5
5
  "main": "dist/downshift.cjs.js",
6
6
  "react-native": "dist/downshift.native.cjs.js",
@@ -262,6 +262,9 @@ function pickState(state) {
262
262
  * @returns {Object} The merged controlled state.
263
263
  */
264
264
  function getState(state, props) {
265
+ if (!state || !props) {
266
+ return state;
267
+ }
265
268
  return Object.keys(state).reduce(function (prevState, key) {
266
269
  prevState[key] = isControlledProp(props, key) ? props[key] : state[key];
267
270
  return prevState;
@@ -1506,7 +1509,7 @@ function validateGetRootPropsCalledCorrectly(element, _ref13) {
1506
1509
  }
1507
1510
  }
1508
1511
 
1509
- var _excluded$3 = ["isInitialMount", "highlightedIndex", "items", "environment"];
1512
+ var _excluded$3 = ["highlightedIndex", "items", "environment"];
1510
1513
  var dropdownDefaultStateValues = {
1511
1514
  highlightedIndex: -1,
1512
1515
  isOpen: false,
@@ -1684,9 +1687,10 @@ function useEnhancedReducer(reducer, props, createInitialState, isStateEqual) {
1684
1687
  }, [propsRef]);
1685
1688
  var action = actionRef.current;
1686
1689
  React.useEffect(function () {
1687
- var shouldCallOnChangeProps = action && prevStateRef.current && !isStateEqual(prevStateRef.current, state);
1690
+ var prevState = getState(prevStateRef.current, action == null ? void 0 : action.props);
1691
+ var shouldCallOnChangeProps = action && prevStateRef.current && !isStateEqual(prevState, state);
1688
1692
  if (shouldCallOnChangeProps) {
1689
- callOnChangeProps(action, getState(prevStateRef.current, action.props), state);
1693
+ callOnChangeProps(action, prevState, state);
1690
1694
  }
1691
1695
  prevStateRef.current = state;
1692
1696
  }, [state, action, isStateEqual]);
@@ -1791,7 +1795,8 @@ function getHighlightedIndexOnOpen(props, state, offset) {
1791
1795
  function useMouseAndTouchTracker(isOpen, downshiftElementRefs, environment, handleBlur) {
1792
1796
  var mouseAndTouchTrackersRef = React.useRef({
1793
1797
  isMouseDown: false,
1794
- isTouchMove: false
1798
+ isTouchMove: false,
1799
+ isTouchEnd: false
1795
1800
  });
1796
1801
  React.useEffect(function () {
1797
1802
  if (!environment) {
@@ -1801,6 +1806,7 @@ function useMouseAndTouchTracker(isOpen, downshiftElementRefs, environment, hand
1801
1806
  // The same strategy for checking if a click occurred inside or outside downshift
1802
1807
  // as in downshift.js.
1803
1808
  var onMouseDown = function onMouseDown() {
1809
+ mouseAndTouchTrackersRef.current.isTouchEnd = false; // reset this one.
1804
1810
  mouseAndTouchTrackersRef.current.isMouseDown = true;
1805
1811
  };
1806
1812
  var onMouseUp = function onMouseUp(event) {
@@ -1812,12 +1818,14 @@ function useMouseAndTouchTracker(isOpen, downshiftElementRefs, environment, hand
1812
1818
  }
1813
1819
  };
1814
1820
  var onTouchStart = function onTouchStart() {
1821
+ mouseAndTouchTrackersRef.current.isTouchEnd = false;
1815
1822
  mouseAndTouchTrackersRef.current.isTouchMove = false;
1816
1823
  };
1817
1824
  var onTouchMove = function onTouchMove() {
1818
1825
  mouseAndTouchTrackersRef.current.isTouchMove = true;
1819
1826
  };
1820
1827
  var onTouchEnd = function onTouchEnd(event) {
1828
+ mouseAndTouchTrackersRef.current.isTouchEnd = true;
1821
1829
  if (isOpen && !mouseAndTouchTrackersRef.current.isTouchMove && !targetWithinDownshift(event.target, downshiftElementRefs.map(function (ref) {
1822
1830
  return ref.current;
1823
1831
  }), environment, false)) {
@@ -1896,11 +1904,11 @@ if (process.env.NODE_ENV !== 'production') {
1896
1904
  };
1897
1905
  }
1898
1906
  function useA11yMessageSetter(getA11yMessage, dependencyArray, _ref3) {
1899
- var isInitialMount = _ref3.isInitialMount,
1900
- highlightedIndex = _ref3.highlightedIndex,
1907
+ var highlightedIndex = _ref3.highlightedIndex,
1901
1908
  items = _ref3.items,
1902
1909
  environment = _ref3.environment,
1903
1910
  rest = _objectWithoutPropertiesLoose__default["default"](_ref3, _excluded$3);
1911
+ var isInitialMount = useIsInitialMount();
1904
1912
  // Sets a11y status message on changes in state.
1905
1913
  React.useEffect(function () {
1906
1914
  if (isInitialMount || false || !(environment != null && environment.document)) {
@@ -1945,11 +1953,11 @@ var useControlPropsValidator = noop;
1945
1953
  /* istanbul ignore next */
1946
1954
  if (process.env.NODE_ENV !== 'production') {
1947
1955
  useControlPropsValidator = function useControlPropsValidator(_ref5) {
1948
- var isInitialMount = _ref5.isInitialMount,
1949
- props = _ref5.props,
1956
+ var props = _ref5.props,
1950
1957
  state = _ref5.state;
1951
1958
  // used for checking when props are moving from controlled to uncontrolled.
1952
1959
  var prevPropsRef = React.useRef(props);
1960
+ var isInitialMount = useIsInitialMount();
1953
1961
  React.useEffect(function () {
1954
1962
  if (isInitialMount) {
1955
1963
  return;
@@ -1998,6 +2006,20 @@ function isDropdownsStateEqual(prevState, newState) {
1998
2006
  return prevState.isOpen === newState.isOpen && prevState.inputValue === newState.inputValue && prevState.highlightedIndex === newState.highlightedIndex && prevState.selectedItem === newState.selectedItem;
1999
2007
  }
2000
2008
 
2009
+ /**
2010
+ * Tracks if it's the first render.
2011
+ */
2012
+ function useIsInitialMount() {
2013
+ var isInitialMountRef = React__default["default"].useRef(true);
2014
+ React__default["default"].useEffect(function () {
2015
+ isInitialMountRef.current = false;
2016
+ return function () {
2017
+ isInitialMountRef.current = true;
2018
+ };
2019
+ }, []);
2020
+ return isInitialMountRef.current;
2021
+ }
2022
+
2001
2023
  // Shared between all exports.
2002
2024
  var commonPropTypes = {
2003
2025
  environment: PropTypes__default["default"].shape({
@@ -2338,7 +2360,7 @@ function useSelect(userProps) {
2338
2360
  var elementIds = useElementIds(props);
2339
2361
  // used to keep track of how many items we had on previous cycle.
2340
2362
  var previousResultCountRef = React.useRef();
2341
- var isInitialMountRef = React.useRef(true);
2363
+ var isInitialMount = useIsInitialMount();
2342
2364
  // utility callback to get item element.
2343
2365
  var latest = useLatestRef({
2344
2366
  state: state,
@@ -2353,7 +2375,6 @@ function useSelect(userProps) {
2353
2375
  // Effects.
2354
2376
  // Sets a11y status message on changes in state.
2355
2377
  useA11yMessageSetter(getA11yStatusMessage, [isOpen, highlightedIndex, inputValue, items], _extends__default["default"]({
2356
- isInitialMount: isInitialMountRef.current,
2357
2378
  previousResultCount: previousResultCountRef.current,
2358
2379
  items: items,
2359
2380
  environment: environment,
@@ -2361,7 +2382,6 @@ function useSelect(userProps) {
2361
2382
  }, state));
2362
2383
  // Sets a11y status message on changes in selectedItem.
2363
2384
  useA11yMessageSetter(getA11ySelectionMessage, [selectedItem], _extends__default["default"]({
2364
- isInitialMount: isInitialMountRef.current,
2365
2385
  previousResultCount: previousResultCountRef.current,
2366
2386
  items: items,
2367
2387
  environment: environment,
@@ -2401,12 +2421,11 @@ function useSelect(userProps) {
2401
2421
  clearTimeoutRef.current(dispatch);
2402
2422
  }, [dispatch, inputValue]);
2403
2423
  useControlPropsValidator({
2404
- isInitialMount: isInitialMountRef.current,
2405
2424
  props: props,
2406
2425
  state: state
2407
2426
  });
2408
2427
  React.useEffect(function () {
2409
- if (isInitialMountRef.current) {
2428
+ if (isInitialMount) {
2410
2429
  return;
2411
2430
  }
2412
2431
  previousResultCountRef.current = items.length;
@@ -2426,13 +2445,6 @@ function useSelect(userProps) {
2426
2445
  });
2427
2446
  });
2428
2447
  var setGetterPropCallInfo = useGetterPropsCalledChecker('getMenuProps', 'getToggleButtonProps');
2429
- // Make initial ref false.
2430
- React.useEffect(function () {
2431
- isInitialMountRef.current = false;
2432
- return function () {
2433
- isInitialMountRef.current = true;
2434
- };
2435
- }, []);
2436
2448
  // Reset itemRefs on close.
2437
2449
  React.useEffect(function () {
2438
2450
  if (!isOpen) {
@@ -2672,7 +2684,7 @@ function useSelect(userProps) {
2672
2684
  index = _getItemAndIndex[1];
2673
2685
  var disabled = latestProps.isItemDisabled(item, index);
2674
2686
  var itemHandleMouseMove = function itemHandleMouseMove() {
2675
- if (index === latestState.highlightedIndex) {
2687
+ if (mouseAndTouchTrackersRef.current.isTouchEnd || index === latestState.highlightedIndex) {
2676
2688
  return;
2677
2689
  }
2678
2690
  shouldScrollRef.current = false;
@@ -2706,7 +2718,7 @@ function useSelect(userProps) {
2706
2718
  itemProps.onMouseMove = callAllEventHandlers(onMouseMove, itemHandleMouseMove);
2707
2719
  itemProps.onMouseDown = callAllEventHandlers(onMouseDown, itemHandleMouseDown);
2708
2720
  return itemProps;
2709
- }, [latest, elementIds, shouldScrollRef, dispatch]);
2721
+ }, [latest, elementIds, mouseAndTouchTrackersRef, shouldScrollRef, dispatch]);
2710
2722
  return {
2711
2723
  // prop getters.
2712
2724
  getToggleButtonProps: getToggleButtonProps,
@@ -2821,13 +2833,14 @@ function useControlledReducer(reducer, props, createInitialState, isStateEqual)
2821
2833
  var _useEnhancedReducer = useEnhancedReducer(reducer, props, createInitialState, isStateEqual),
2822
2834
  state = _useEnhancedReducer[0],
2823
2835
  dispatch = _useEnhancedReducer[1];
2824
-
2825
- // ToDo: if needed, make same approach as selectedItemChanged from Downshift.
2836
+ var isInitialMount = useIsInitialMount();
2826
2837
  React.useEffect(function () {
2827
2838
  if (!isControlledProp(props, 'selectedItem')) {
2828
2839
  return;
2829
2840
  }
2830
- if (props.selectedItemChanged(previousSelectedItemRef.current, props.selectedItem)) {
2841
+ if (!isInitialMount &&
2842
+ // on first mount we already have the proper inputValue for a initial selected item.
2843
+ props.selectedItemChanged(previousSelectedItemRef.current, props.selectedItem)) {
2831
2844
  dispatch({
2832
2845
  type: ControlledPropUpdatedSelectedItem,
2833
2846
  inputValue: props.itemToString(props.selectedItem)
@@ -3005,7 +3018,8 @@ function useCombobox(userProps) {
3005
3018
  var itemRefs = React.useRef({});
3006
3019
  var inputRef = React.useRef(null);
3007
3020
  var toggleButtonRef = React.useRef(null);
3008
- var isInitialMountRef = React.useRef(true);
3021
+ var isInitialMount = useIsInitialMount();
3022
+
3009
3023
  // prevent id re-generation between renders.
3010
3024
  var elementIds = useElementIds(props);
3011
3025
  // used to keep track of how many items we had on previous cycle.
@@ -3022,7 +3036,6 @@ function useCombobox(userProps) {
3022
3036
  // Effects.
3023
3037
  // Sets a11y status message on changes in state.
3024
3038
  useA11yMessageSetter(getA11yStatusMessage, [isOpen, highlightedIndex, inputValue, items], _extends__default["default"]({
3025
- isInitialMount: isInitialMountRef.current,
3026
3039
  previousResultCount: previousResultCountRef.current,
3027
3040
  items: items,
3028
3041
  environment: environment,
@@ -3030,7 +3043,6 @@ function useCombobox(userProps) {
3030
3043
  }, state));
3031
3044
  // Sets a11y status message on changes in selectedItem.
3032
3045
  useA11yMessageSetter(getA11ySelectionMessage, [selectedItem], _extends__default["default"]({
3033
- isInitialMount: isInitialMountRef.current,
3034
3046
  previousResultCount: previousResultCountRef.current,
3035
3047
  items: items,
3036
3048
  environment: environment,
@@ -3046,7 +3058,6 @@ function useCombobox(userProps) {
3046
3058
  getItemNodeFromIndex: getItemNodeFromIndex
3047
3059
  });
3048
3060
  useControlPropsValidator({
3049
- isInitialMount: isInitialMountRef.current,
3050
3061
  props: props,
3051
3062
  state: state
3052
3063
  });
@@ -3059,10 +3070,9 @@ function useCombobox(userProps) {
3059
3070
  // eslint-disable-next-line react-hooks/exhaustive-deps
3060
3071
  }, []);
3061
3072
  React.useEffect(function () {
3062
- if (isInitialMountRef.current) {
3063
- return;
3073
+ if (!isInitialMount) {
3074
+ previousResultCountRef.current = items.length;
3064
3075
  }
3065
- previousResultCountRef.current = items.length;
3066
3076
  });
3067
3077
  // Add mouse/touch events to document.
3068
3078
  var mouseAndTouchTrackersRef = useMouseAndTouchTracker(isOpen, [inputRef, menuRef, toggleButtonRef], environment, function () {
@@ -3072,13 +3082,6 @@ function useCombobox(userProps) {
3072
3082
  });
3073
3083
  });
3074
3084
  var setGetterPropCallInfo = useGetterPropsCalledChecker('getInputProps', 'getMenuProps');
3075
- // Make initial ref false.
3076
- React.useEffect(function () {
3077
- isInitialMountRef.current = false;
3078
- return function () {
3079
- isInitialMountRef.current = true;
3080
- };
3081
- }, []);
3082
3085
  // Reset itemRefs on close.
3083
3086
  React.useEffect(function () {
3084
3087
  if (!isOpen) {
@@ -3225,7 +3228,7 @@ function useCombobox(userProps) {
3225
3228
  var onSelectKey = 'onClick';
3226
3229
  var customClickHandler = onClick;
3227
3230
  var itemHandleMouseMove = function itemHandleMouseMove() {
3228
- if (index === latestState.highlightedIndex) {
3231
+ if (mouseAndTouchTrackersRef.current.isTouchEnd || index === latestState.highlightedIndex) {
3229
3232
  return;
3230
3233
  }
3231
3234
  shouldScrollRef.current = false;
@@ -3253,7 +3256,7 @@ function useCombobox(userProps) {
3253
3256
  onMouseMove: callAllEventHandlers(onMouseMove, itemHandleMouseMove),
3254
3257
  onMouseDown: callAllEventHandlers(onMouseDown, itemHandleMouseDown)
3255
3258
  }, rest);
3256
- }, [dispatch, latest, shouldScrollRef, elementIds]);
3259
+ }, [dispatch, elementIds, latest, mouseAndTouchTrackersRef, shouldScrollRef]);
3257
3260
  var getToggleButtonProps = React.useCallback(function (_temp4) {
3258
3261
  var _extends4;
3259
3262
  var _ref5 = _temp4 === void 0 ? {} : _temp4,
@@ -3685,7 +3688,7 @@ function useMultipleSelection(userProps) {
3685
3688
  selectedItems = state.selectedItems;
3686
3689
 
3687
3690
  // Refs.
3688
- var isInitialMountRef = React.useRef(true);
3691
+ var isInitialMount = useIsInitialMount();
3689
3692
  var dropdownRef = React.useRef(null);
3690
3693
  var previousSelectedItemsRef = React.useRef(selectedItems);
3691
3694
  var selectedItemRefs = React.useRef();
@@ -3698,7 +3701,7 @@ function useMultipleSelection(userProps) {
3698
3701
  // Effects.
3699
3702
  /* Sets a11y status message on changes in selectedItem. */
3700
3703
  React.useEffect(function () {
3701
- if (isInitialMountRef.current || false || !(environment != null && environment.document)) {
3704
+ if (isInitialMount || false || !(environment != null && environment.document)) {
3702
3705
  return;
3703
3706
  }
3704
3707
  if (selectedItems.length < previousSelectedItemsRef.current.length) {
@@ -3719,7 +3722,7 @@ function useMultipleSelection(userProps) {
3719
3722
  }, [selectedItems.length]);
3720
3723
  // Sets focus on active item.
3721
3724
  React.useEffect(function () {
3722
- if (isInitialMountRef.current) {
3725
+ if (isInitialMount) {
3723
3726
  return;
3724
3727
  }
3725
3728
  if (activeIndex === -1 && dropdownRef.current) {
@@ -3727,20 +3730,12 @@ function useMultipleSelection(userProps) {
3727
3730
  } else if (selectedItemRefs.current[activeIndex]) {
3728
3731
  selectedItemRefs.current[activeIndex].focus();
3729
3732
  }
3730
- }, [activeIndex]);
3733
+ }, [activeIndex, isInitialMount]);
3731
3734
  useControlPropsValidator({
3732
- isInitialMount: isInitialMountRef.current,
3733
3735
  props: props,
3734
3736
  state: state
3735
3737
  });
3736
3738
  var setGetterPropCallInfo = useGetterPropsCalledChecker('getDropdownProps');
3737
- // Make initial ref false.
3738
- React.useEffect(function () {
3739
- isInitialMountRef.current = false;
3740
- return function () {
3741
- isInitialMountRef.current = true;
3742
- };
3743
- }, []);
3744
3739
 
3745
3740
  // Event handler functions.
3746
3741
  var selectedItemKeyDownHandlers = React.useMemo(function () {
@@ -249,6 +249,9 @@ function pickState(state) {
249
249
  * @returns {Object} The merged controlled state.
250
250
  */
251
251
  function getState(state, props) {
252
+ if (!state || !props) {
253
+ return state;
254
+ }
252
255
  return Object.keys(state).reduce(function (prevState, key) {
253
256
  prevState[key] = isControlledProp(props, key) ? props[key] : state[key];
254
257
  return prevState;
@@ -1493,7 +1496,7 @@ function validateGetRootPropsCalledCorrectly(element, _ref13) {
1493
1496
  }
1494
1497
  }
1495
1498
 
1496
- var _excluded$3 = ["isInitialMount", "highlightedIndex", "items", "environment"];
1499
+ var _excluded$3 = ["highlightedIndex", "items", "environment"];
1497
1500
  var dropdownDefaultStateValues = {
1498
1501
  highlightedIndex: -1,
1499
1502
  isOpen: false,
@@ -1671,9 +1674,10 @@ function useEnhancedReducer(reducer, props, createInitialState, isStateEqual) {
1671
1674
  }, [propsRef]);
1672
1675
  var action = actionRef.current;
1673
1676
  useEffect(function () {
1674
- var shouldCallOnChangeProps = action && prevStateRef.current && !isStateEqual(prevStateRef.current, state);
1677
+ var prevState = getState(prevStateRef.current, action == null ? void 0 : action.props);
1678
+ var shouldCallOnChangeProps = action && prevStateRef.current && !isStateEqual(prevState, state);
1675
1679
  if (shouldCallOnChangeProps) {
1676
- callOnChangeProps(action, getState(prevStateRef.current, action.props), state);
1680
+ callOnChangeProps(action, prevState, state);
1677
1681
  }
1678
1682
  prevStateRef.current = state;
1679
1683
  }, [state, action, isStateEqual]);
@@ -1778,7 +1782,8 @@ function getHighlightedIndexOnOpen(props, state, offset) {
1778
1782
  function useMouseAndTouchTracker(isOpen, downshiftElementRefs, environment, handleBlur) {
1779
1783
  var mouseAndTouchTrackersRef = useRef({
1780
1784
  isMouseDown: false,
1781
- isTouchMove: false
1785
+ isTouchMove: false,
1786
+ isTouchEnd: false
1782
1787
  });
1783
1788
  useEffect(function () {
1784
1789
  if (!environment) {
@@ -1788,6 +1793,7 @@ function useMouseAndTouchTracker(isOpen, downshiftElementRefs, environment, hand
1788
1793
  // The same strategy for checking if a click occurred inside or outside downshift
1789
1794
  // as in downshift.js.
1790
1795
  var onMouseDown = function onMouseDown() {
1796
+ mouseAndTouchTrackersRef.current.isTouchEnd = false; // reset this one.
1791
1797
  mouseAndTouchTrackersRef.current.isMouseDown = true;
1792
1798
  };
1793
1799
  var onMouseUp = function onMouseUp(event) {
@@ -1799,12 +1805,14 @@ function useMouseAndTouchTracker(isOpen, downshiftElementRefs, environment, hand
1799
1805
  }
1800
1806
  };
1801
1807
  var onTouchStart = function onTouchStart() {
1808
+ mouseAndTouchTrackersRef.current.isTouchEnd = false;
1802
1809
  mouseAndTouchTrackersRef.current.isTouchMove = false;
1803
1810
  };
1804
1811
  var onTouchMove = function onTouchMove() {
1805
1812
  mouseAndTouchTrackersRef.current.isTouchMove = true;
1806
1813
  };
1807
1814
  var onTouchEnd = function onTouchEnd(event) {
1815
+ mouseAndTouchTrackersRef.current.isTouchEnd = true;
1808
1816
  if (isOpen && !mouseAndTouchTrackersRef.current.isTouchMove && !targetWithinDownshift(event.target, downshiftElementRefs.map(function (ref) {
1809
1817
  return ref.current;
1810
1818
  }), environment, false)) {
@@ -1883,11 +1891,11 @@ if (process.env.NODE_ENV !== 'production') {
1883
1891
  };
1884
1892
  }
1885
1893
  function useA11yMessageSetter(getA11yMessage, dependencyArray, _ref3) {
1886
- var isInitialMount = _ref3.isInitialMount,
1887
- highlightedIndex = _ref3.highlightedIndex,
1894
+ var highlightedIndex = _ref3.highlightedIndex,
1888
1895
  items = _ref3.items,
1889
1896
  environment = _ref3.environment,
1890
1897
  rest = _objectWithoutPropertiesLoose(_ref3, _excluded$3);
1898
+ var isInitialMount = useIsInitialMount();
1891
1899
  // Sets a11y status message on changes in state.
1892
1900
  useEffect(function () {
1893
1901
  if (isInitialMount || false || !(environment != null && environment.document)) {
@@ -1932,11 +1940,11 @@ var useControlPropsValidator = noop;
1932
1940
  /* istanbul ignore next */
1933
1941
  if (process.env.NODE_ENV !== 'production') {
1934
1942
  useControlPropsValidator = function useControlPropsValidator(_ref5) {
1935
- var isInitialMount = _ref5.isInitialMount,
1936
- props = _ref5.props,
1943
+ var props = _ref5.props,
1937
1944
  state = _ref5.state;
1938
1945
  // used for checking when props are moving from controlled to uncontrolled.
1939
1946
  var prevPropsRef = useRef(props);
1947
+ var isInitialMount = useIsInitialMount();
1940
1948
  useEffect(function () {
1941
1949
  if (isInitialMount) {
1942
1950
  return;
@@ -1985,6 +1993,20 @@ function isDropdownsStateEqual(prevState, newState) {
1985
1993
  return prevState.isOpen === newState.isOpen && prevState.inputValue === newState.inputValue && prevState.highlightedIndex === newState.highlightedIndex && prevState.selectedItem === newState.selectedItem;
1986
1994
  }
1987
1995
 
1996
+ /**
1997
+ * Tracks if it's the first render.
1998
+ */
1999
+ function useIsInitialMount() {
2000
+ var isInitialMountRef = React.useRef(true);
2001
+ React.useEffect(function () {
2002
+ isInitialMountRef.current = false;
2003
+ return function () {
2004
+ isInitialMountRef.current = true;
2005
+ };
2006
+ }, []);
2007
+ return isInitialMountRef.current;
2008
+ }
2009
+
1988
2010
  // Shared between all exports.
1989
2011
  var commonPropTypes = {
1990
2012
  environment: PropTypes.shape({
@@ -2325,7 +2347,7 @@ function useSelect(userProps) {
2325
2347
  var elementIds = useElementIds(props);
2326
2348
  // used to keep track of how many items we had on previous cycle.
2327
2349
  var previousResultCountRef = useRef();
2328
- var isInitialMountRef = useRef(true);
2350
+ var isInitialMount = useIsInitialMount();
2329
2351
  // utility callback to get item element.
2330
2352
  var latest = useLatestRef({
2331
2353
  state: state,
@@ -2340,7 +2362,6 @@ function useSelect(userProps) {
2340
2362
  // Effects.
2341
2363
  // Sets a11y status message on changes in state.
2342
2364
  useA11yMessageSetter(getA11yStatusMessage, [isOpen, highlightedIndex, inputValue, items], _extends({
2343
- isInitialMount: isInitialMountRef.current,
2344
2365
  previousResultCount: previousResultCountRef.current,
2345
2366
  items: items,
2346
2367
  environment: environment,
@@ -2348,7 +2369,6 @@ function useSelect(userProps) {
2348
2369
  }, state));
2349
2370
  // Sets a11y status message on changes in selectedItem.
2350
2371
  useA11yMessageSetter(getA11ySelectionMessage, [selectedItem], _extends({
2351
- isInitialMount: isInitialMountRef.current,
2352
2372
  previousResultCount: previousResultCountRef.current,
2353
2373
  items: items,
2354
2374
  environment: environment,
@@ -2388,12 +2408,11 @@ function useSelect(userProps) {
2388
2408
  clearTimeoutRef.current(dispatch);
2389
2409
  }, [dispatch, inputValue]);
2390
2410
  useControlPropsValidator({
2391
- isInitialMount: isInitialMountRef.current,
2392
2411
  props: props,
2393
2412
  state: state
2394
2413
  });
2395
2414
  useEffect(function () {
2396
- if (isInitialMountRef.current) {
2415
+ if (isInitialMount) {
2397
2416
  return;
2398
2417
  }
2399
2418
  previousResultCountRef.current = items.length;
@@ -2413,13 +2432,6 @@ function useSelect(userProps) {
2413
2432
  });
2414
2433
  });
2415
2434
  var setGetterPropCallInfo = useGetterPropsCalledChecker('getMenuProps', 'getToggleButtonProps');
2416
- // Make initial ref false.
2417
- useEffect(function () {
2418
- isInitialMountRef.current = false;
2419
- return function () {
2420
- isInitialMountRef.current = true;
2421
- };
2422
- }, []);
2423
2435
  // Reset itemRefs on close.
2424
2436
  useEffect(function () {
2425
2437
  if (!isOpen) {
@@ -2659,7 +2671,7 @@ function useSelect(userProps) {
2659
2671
  index = _getItemAndIndex[1];
2660
2672
  var disabled = latestProps.isItemDisabled(item, index);
2661
2673
  var itemHandleMouseMove = function itemHandleMouseMove() {
2662
- if (index === latestState.highlightedIndex) {
2674
+ if (mouseAndTouchTrackersRef.current.isTouchEnd || index === latestState.highlightedIndex) {
2663
2675
  return;
2664
2676
  }
2665
2677
  shouldScrollRef.current = false;
@@ -2693,7 +2705,7 @@ function useSelect(userProps) {
2693
2705
  itemProps.onMouseMove = callAllEventHandlers(onMouseMove, itemHandleMouseMove);
2694
2706
  itemProps.onMouseDown = callAllEventHandlers(onMouseDown, itemHandleMouseDown);
2695
2707
  return itemProps;
2696
- }, [latest, elementIds, shouldScrollRef, dispatch]);
2708
+ }, [latest, elementIds, mouseAndTouchTrackersRef, shouldScrollRef, dispatch]);
2697
2709
  return {
2698
2710
  // prop getters.
2699
2711
  getToggleButtonProps: getToggleButtonProps,
@@ -2808,13 +2820,14 @@ function useControlledReducer(reducer, props, createInitialState, isStateEqual)
2808
2820
  var _useEnhancedReducer = useEnhancedReducer(reducer, props, createInitialState, isStateEqual),
2809
2821
  state = _useEnhancedReducer[0],
2810
2822
  dispatch = _useEnhancedReducer[1];
2811
-
2812
- // ToDo: if needed, make same approach as selectedItemChanged from Downshift.
2823
+ var isInitialMount = useIsInitialMount();
2813
2824
  useEffect(function () {
2814
2825
  if (!isControlledProp(props, 'selectedItem')) {
2815
2826
  return;
2816
2827
  }
2817
- if (props.selectedItemChanged(previousSelectedItemRef.current, props.selectedItem)) {
2828
+ if (!isInitialMount &&
2829
+ // on first mount we already have the proper inputValue for a initial selected item.
2830
+ props.selectedItemChanged(previousSelectedItemRef.current, props.selectedItem)) {
2818
2831
  dispatch({
2819
2832
  type: ControlledPropUpdatedSelectedItem,
2820
2833
  inputValue: props.itemToString(props.selectedItem)
@@ -2992,7 +3005,8 @@ function useCombobox(userProps) {
2992
3005
  var itemRefs = useRef({});
2993
3006
  var inputRef = useRef(null);
2994
3007
  var toggleButtonRef = useRef(null);
2995
- var isInitialMountRef = useRef(true);
3008
+ var isInitialMount = useIsInitialMount();
3009
+
2996
3010
  // prevent id re-generation between renders.
2997
3011
  var elementIds = useElementIds(props);
2998
3012
  // used to keep track of how many items we had on previous cycle.
@@ -3009,7 +3023,6 @@ function useCombobox(userProps) {
3009
3023
  // Effects.
3010
3024
  // Sets a11y status message on changes in state.
3011
3025
  useA11yMessageSetter(getA11yStatusMessage, [isOpen, highlightedIndex, inputValue, items], _extends({
3012
- isInitialMount: isInitialMountRef.current,
3013
3026
  previousResultCount: previousResultCountRef.current,
3014
3027
  items: items,
3015
3028
  environment: environment,
@@ -3017,7 +3030,6 @@ function useCombobox(userProps) {
3017
3030
  }, state));
3018
3031
  // Sets a11y status message on changes in selectedItem.
3019
3032
  useA11yMessageSetter(getA11ySelectionMessage, [selectedItem], _extends({
3020
- isInitialMount: isInitialMountRef.current,
3021
3033
  previousResultCount: previousResultCountRef.current,
3022
3034
  items: items,
3023
3035
  environment: environment,
@@ -3033,7 +3045,6 @@ function useCombobox(userProps) {
3033
3045
  getItemNodeFromIndex: getItemNodeFromIndex
3034
3046
  });
3035
3047
  useControlPropsValidator({
3036
- isInitialMount: isInitialMountRef.current,
3037
3048
  props: props,
3038
3049
  state: state
3039
3050
  });
@@ -3046,10 +3057,9 @@ function useCombobox(userProps) {
3046
3057
  // eslint-disable-next-line react-hooks/exhaustive-deps
3047
3058
  }, []);
3048
3059
  useEffect(function () {
3049
- if (isInitialMountRef.current) {
3050
- return;
3060
+ if (!isInitialMount) {
3061
+ previousResultCountRef.current = items.length;
3051
3062
  }
3052
- previousResultCountRef.current = items.length;
3053
3063
  });
3054
3064
  // Add mouse/touch events to document.
3055
3065
  var mouseAndTouchTrackersRef = useMouseAndTouchTracker(isOpen, [inputRef, menuRef, toggleButtonRef], environment, function () {
@@ -3059,13 +3069,6 @@ function useCombobox(userProps) {
3059
3069
  });
3060
3070
  });
3061
3071
  var setGetterPropCallInfo = useGetterPropsCalledChecker('getInputProps', 'getMenuProps');
3062
- // Make initial ref false.
3063
- useEffect(function () {
3064
- isInitialMountRef.current = false;
3065
- return function () {
3066
- isInitialMountRef.current = true;
3067
- };
3068
- }, []);
3069
3072
  // Reset itemRefs on close.
3070
3073
  useEffect(function () {
3071
3074
  if (!isOpen) {
@@ -3212,7 +3215,7 @@ function useCombobox(userProps) {
3212
3215
  var onSelectKey = 'onClick';
3213
3216
  var customClickHandler = onClick;
3214
3217
  var itemHandleMouseMove = function itemHandleMouseMove() {
3215
- if (index === latestState.highlightedIndex) {
3218
+ if (mouseAndTouchTrackersRef.current.isTouchEnd || index === latestState.highlightedIndex) {
3216
3219
  return;
3217
3220
  }
3218
3221
  shouldScrollRef.current = false;
@@ -3240,7 +3243,7 @@ function useCombobox(userProps) {
3240
3243
  onMouseMove: callAllEventHandlers(onMouseMove, itemHandleMouseMove),
3241
3244
  onMouseDown: callAllEventHandlers(onMouseDown, itemHandleMouseDown)
3242
3245
  }, rest);
3243
- }, [dispatch, latest, shouldScrollRef, elementIds]);
3246
+ }, [dispatch, elementIds, latest, mouseAndTouchTrackersRef, shouldScrollRef]);
3244
3247
  var getToggleButtonProps = useCallback(function (_temp4) {
3245
3248
  var _extends4;
3246
3249
  var _ref5 = _temp4 === void 0 ? {} : _temp4,
@@ -3672,7 +3675,7 @@ function useMultipleSelection(userProps) {
3672
3675
  selectedItems = state.selectedItems;
3673
3676
 
3674
3677
  // Refs.
3675
- var isInitialMountRef = useRef(true);
3678
+ var isInitialMount = useIsInitialMount();
3676
3679
  var dropdownRef = useRef(null);
3677
3680
  var previousSelectedItemsRef = useRef(selectedItems);
3678
3681
  var selectedItemRefs = useRef();
@@ -3685,7 +3688,7 @@ function useMultipleSelection(userProps) {
3685
3688
  // Effects.
3686
3689
  /* Sets a11y status message on changes in selectedItem. */
3687
3690
  useEffect(function () {
3688
- if (isInitialMountRef.current || false || !(environment != null && environment.document)) {
3691
+ if (isInitialMount || false || !(environment != null && environment.document)) {
3689
3692
  return;
3690
3693
  }
3691
3694
  if (selectedItems.length < previousSelectedItemsRef.current.length) {
@@ -3706,7 +3709,7 @@ function useMultipleSelection(userProps) {
3706
3709
  }, [selectedItems.length]);
3707
3710
  // Sets focus on active item.
3708
3711
  useEffect(function () {
3709
- if (isInitialMountRef.current) {
3712
+ if (isInitialMount) {
3710
3713
  return;
3711
3714
  }
3712
3715
  if (activeIndex === -1 && dropdownRef.current) {
@@ -3714,20 +3717,12 @@ function useMultipleSelection(userProps) {
3714
3717
  } else if (selectedItemRefs.current[activeIndex]) {
3715
3718
  selectedItemRefs.current[activeIndex].focus();
3716
3719
  }
3717
- }, [activeIndex]);
3720
+ }, [activeIndex, isInitialMount]);
3718
3721
  useControlPropsValidator({
3719
- isInitialMount: isInitialMountRef.current,
3720
3722
  props: props,
3721
3723
  state: state
3722
3724
  });
3723
3725
  var setGetterPropCallInfo = useGetterPropsCalledChecker('getDropdownProps');
3724
- // Make initial ref false.
3725
- useEffect(function () {
3726
- isInitialMountRef.current = false;
3727
- return function () {
3728
- isInitialMountRef.current = true;
3729
- };
3730
- }, []);
3731
3726
 
3732
3727
  // Event handler functions.
3733
3728
  var selectedItemKeyDownHandlers = useMemo(function () {