downshift 8.3.3 → 8.5.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.
@@ -13,7 +13,8 @@ declare function getA11yStatusMessage<Item>({ isOpen, resultCount, previousResul
13
13
  export declare const defaultProps: {
14
14
  getA11yStatusMessage: typeof getA11yStatusMessage;
15
15
  isItemDisabled(): boolean;
16
- itemToString: (item: any) => string;
16
+ itemToString(item: any): string;
17
+ itemToKey(item: any): any;
17
18
  stateReducer: (s: Object, a: Object) => Object;
18
19
  getA11ySelectionMessage: (selectionParameters: Object) => string;
19
20
  scrollIntoView: typeof import("../../utils").scrollIntoView;
@@ -15,15 +15,14 @@ export function useA11yMessageSetter(getA11yMessage: any, dependencyArray: any,
15
15
  }): void;
16
16
  export function useGetterPropsCalledChecker(): typeof noop;
17
17
  /**
18
- * Reuse the movement tracking of mouse and touch events.
18
+ * Tracks mouse and touch events, such as mouseDown, touchMove and touchEnd.
19
19
  *
20
- * @param {boolean} isOpen Whether the dropdown is open or not.
21
- * @param {Array<Object>} downshiftElementRefs Downshift element refs to track movement (toggleButton, menu etc.)
22
- * @param {Object} environment Environment where component/hook exists.
23
- * @param {Function} handleBlur Handler on blur from mouse or touch.
24
- * @returns {Object} Ref containing whether mouseDown or touchMove event is happening
20
+ * @param {Object} environment The environment to add the event listeners to, for instance window.
21
+ * @param {Array<HTMLElement>} downshiftElementRefs The refs for the element that should not trigger a blur action from mouseDown or touchEnd.
22
+ * @param {Function} handleBlur The function that is called if mouseDown or touchEnd occured outside the downshiftElements.
23
+ * @returns {Object} The mouse and touch events information, if any of are happening.
25
24
  */
26
- export function useMouseAndTouchTracker(isOpen: boolean, downshiftElementRefs: Array<Object>, environment: Object, handleBlur: Function): Object;
25
+ export function useMouseAndTouchTracker(environment: Object, downshiftElementRefs: Array<HTMLElement>, handleBlur: Function): Object;
27
26
  export function getHighlightedIndexOnOpen(props: any, state: any, offset: any): any;
28
27
  export function getInitialState(props: any): {
29
28
  highlightedIndex: any;
@@ -44,7 +43,8 @@ export function getDefaultValue(props: any, propKey: any, defaultStateValues?: {
44
43
  inputValue: string;
45
44
  }): any;
46
45
  export namespace defaultProps {
47
- export { itemToString };
46
+ export function itemToString(item: any): string;
47
+ export function itemToKey(item: any): any;
48
48
  export { stateReducer };
49
49
  export { getA11ySelectionMessage };
50
50
  export { scrollIntoView };
@@ -156,8 +156,8 @@ export namespace commonDropdownPropTypes {
156
156
  Node: PropTypes.Validator<(...args: any[]) => any>;
157
157
  }>>;
158
158
  export { environment_1 as environment };
159
- const itemToString_1: PropTypes.Requireable<(...args: any[]) => any>;
160
- export { itemToString_1 as itemToString };
159
+ export const itemToString: PropTypes.Requireable<(...args: any[]) => any>;
160
+ export const itemToKey: PropTypes.Requireable<(...args: any[]) => any>;
161
161
  const stateReducer_1: PropTypes.Requireable<(...args: any[]) => any>;
162
162
  export { stateReducer_1 as stateReducer };
163
163
  }
@@ -168,7 +168,6 @@ export namespace commonPropTypes { }
168
168
  export function useIsInitialMount(): boolean;
169
169
  import { noop } from "../utils";
170
170
  import React from "react";
171
- declare function itemToString(item: any): string;
172
171
  /**
173
172
  * Default state reducer that returns the changes.
174
173
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "downshift",
3
- "version": "8.3.3",
3
+ "version": "8.5.0",
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",
@@ -1562,8 +1562,8 @@ function stateReducer(s, a) {
1562
1562
  */
1563
1563
  function getA11ySelectionMessage(selectionParameters) {
1564
1564
  var selectedItem = selectionParameters.selectedItem,
1565
- itemToStringLocal = selectionParameters.itemToString;
1566
- return selectedItem ? itemToStringLocal(selectedItem) + " has been selected." : '';
1565
+ itemToString = selectionParameters.itemToString;
1566
+ return selectedItem ? itemToString(selectedItem) + " has been selected." : '';
1567
1567
  }
1568
1568
 
1569
1569
  /**
@@ -1633,9 +1633,6 @@ function getItemAndIndex(itemProp, indexProp, items, errorMessage) {
1633
1633
  }
1634
1634
  return [item, index];
1635
1635
  }
1636
- function itemToString(item) {
1637
- return item ? String(item) : '';
1638
- }
1639
1636
  function isAcceptedCharacterKey(key) {
1640
1637
  return /^\S{1}$/.test(key);
1641
1638
  }
@@ -1714,7 +1711,12 @@ function useControlledReducer$1(reducer, props, createInitialState, isStateEqual
1714
1711
  return [getState(state, props), dispatch];
1715
1712
  }
1716
1713
  var defaultProps$3 = {
1717
- itemToString: itemToString,
1714
+ itemToString: function itemToString(item) {
1715
+ return item ? String(item) : '';
1716
+ },
1717
+ itemToKey: function itemToKey(item) {
1718
+ return item;
1719
+ },
1718
1720
  stateReducer: stateReducer,
1719
1721
  getA11ySelectionMessage: getA11ySelectionMessage,
1720
1722
  scrollIntoView: scrollIntoView,
@@ -1751,7 +1753,9 @@ function getInitialState$2(props) {
1751
1753
  var highlightedIndex = getInitialValue$1(props, 'highlightedIndex');
1752
1754
  var inputValue = getInitialValue$1(props, 'inputValue');
1753
1755
  return {
1754
- highlightedIndex: highlightedIndex < 0 && selectedItem && isOpen ? props.items.indexOf(selectedItem) : highlightedIndex,
1756
+ highlightedIndex: highlightedIndex < 0 && selectedItem && isOpen ? props.items.findIndex(function (item) {
1757
+ return props.itemToKey(item) === props.itemToKey(selectedItem);
1758
+ }) : highlightedIndex,
1755
1759
  isOpen: isOpen,
1756
1760
  selectedItem: selectedItem,
1757
1761
  inputValue: inputValue
@@ -1760,7 +1764,8 @@ function getInitialState$2(props) {
1760
1764
  function getHighlightedIndexOnOpen(props, state, offset) {
1761
1765
  var items = props.items,
1762
1766
  initialHighlightedIndex = props.initialHighlightedIndex,
1763
- defaultHighlightedIndex = props.defaultHighlightedIndex;
1767
+ defaultHighlightedIndex = props.defaultHighlightedIndex,
1768
+ itemToKey = props.itemToKey;
1764
1769
  var selectedItem = state.selectedItem,
1765
1770
  highlightedIndex = state.highlightedIndex;
1766
1771
  if (items.length === 0) {
@@ -1775,24 +1780,24 @@ function getHighlightedIndexOnOpen(props, state, offset) {
1775
1780
  return defaultHighlightedIndex;
1776
1781
  }
1777
1782
  if (selectedItem) {
1778
- return items.indexOf(selectedItem);
1783
+ return items.findIndex(function (item) {
1784
+ return itemToKey(selectedItem) === itemToKey(item);
1785
+ });
1779
1786
  }
1780
1787
  if (offset === 0) {
1781
1788
  return -1;
1782
1789
  }
1783
1790
  return offset < 0 ? items.length - 1 : 0;
1784
1791
  }
1785
-
1786
1792
  /**
1787
- * Reuse the movement tracking of mouse and touch events.
1793
+ * Tracks mouse and touch events, such as mouseDown, touchMove and touchEnd.
1788
1794
  *
1789
- * @param {boolean} isOpen Whether the dropdown is open or not.
1790
- * @param {Array<Object>} downshiftElementRefs Downshift element refs to track movement (toggleButton, menu etc.)
1791
- * @param {Object} environment Environment where component/hook exists.
1792
- * @param {Function} handleBlur Handler on blur from mouse or touch.
1793
- * @returns {Object} Ref containing whether mouseDown or touchMove event is happening
1795
+ * @param {Object} environment The environment to add the event listeners to, for instance window.
1796
+ * @param {Array<HTMLElement>} downshiftElementRefs The refs for the element that should not trigger a blur action from mouseDown or touchEnd.
1797
+ * @param {Function} handleBlur The function that is called if mouseDown or touchEnd occured outside the downshiftElements.
1798
+ * @returns {Object} The mouse and touch events information, if any of are happening.
1794
1799
  */
1795
- function useMouseAndTouchTracker(isOpen, downshiftElementRefs, environment, handleBlur) {
1800
+ function useMouseAndTouchTracker(environment, downshiftElementRefs, handleBlur) {
1796
1801
  var mouseAndTouchTrackersRef = React.useRef({
1797
1802
  isMouseDown: false,
1798
1803
  isTouchMove: false,
@@ -1800,45 +1805,39 @@ function useMouseAndTouchTracker(isOpen, downshiftElementRefs, environment, hand
1800
1805
  });
1801
1806
  React.useEffect(function () {
1802
1807
  if (!environment) {
1803
- return;
1808
+ return noop;
1804
1809
  }
1805
-
1806
- // The same strategy for checking if a click occurred inside or outside downshift
1807
- // as in downshift.js.
1808
- var onMouseDown = function onMouseDown() {
1810
+ var downshiftElements = downshiftElementRefs.map(function (ref) {
1811
+ return ref.current;
1812
+ });
1813
+ function onMouseDown() {
1809
1814
  mouseAndTouchTrackersRef.current.isTouchEnd = false; // reset this one.
1810
1815
  mouseAndTouchTrackersRef.current.isMouseDown = true;
1811
- };
1812
- var onMouseUp = function onMouseUp(event) {
1816
+ }
1817
+ function onMouseUp(event) {
1813
1818
  mouseAndTouchTrackersRef.current.isMouseDown = false;
1814
- if (isOpen && !targetWithinDownshift(event.target, downshiftElementRefs.map(function (ref) {
1815
- return ref.current;
1816
- }), environment)) {
1819
+ if (!targetWithinDownshift(event.target, downshiftElements, environment)) {
1817
1820
  handleBlur();
1818
1821
  }
1819
- };
1820
- var onTouchStart = function onTouchStart() {
1822
+ }
1823
+ function onTouchStart() {
1821
1824
  mouseAndTouchTrackersRef.current.isTouchEnd = false;
1822
1825
  mouseAndTouchTrackersRef.current.isTouchMove = false;
1823
- };
1824
- var onTouchMove = function onTouchMove() {
1826
+ }
1827
+ function onTouchMove() {
1825
1828
  mouseAndTouchTrackersRef.current.isTouchMove = true;
1826
- };
1827
- var onTouchEnd = function onTouchEnd(event) {
1829
+ }
1830
+ function onTouchEnd(event) {
1828
1831
  mouseAndTouchTrackersRef.current.isTouchEnd = true;
1829
- if (isOpen && !mouseAndTouchTrackersRef.current.isTouchMove && !targetWithinDownshift(event.target, downshiftElementRefs.map(function (ref) {
1830
- return ref.current;
1831
- }), environment, false)) {
1832
+ if (!mouseAndTouchTrackersRef.current.isTouchMove && !targetWithinDownshift(event.target, downshiftElements, environment, false)) {
1832
1833
  handleBlur();
1833
1834
  }
1834
- };
1835
+ }
1835
1836
  environment.addEventListener('mousedown', onMouseDown);
1836
1837
  environment.addEventListener('mouseup', onMouseUp);
1837
1838
  environment.addEventListener('touchstart', onTouchStart);
1838
1839
  environment.addEventListener('touchmove', onTouchMove);
1839
1840
  environment.addEventListener('touchend', onTouchEnd);
1840
-
1841
- // eslint-disable-next-line consistent-return
1842
1841
  return function cleanup() {
1843
1842
  environment.removeEventListener('mousedown', onMouseDown);
1844
1843
  environment.removeEventListener('mouseup', onMouseUp);
@@ -1846,9 +1845,9 @@ function useMouseAndTouchTracker(isOpen, downshiftElementRefs, environment, hand
1846
1845
  environment.removeEventListener('touchmove', onTouchMove);
1847
1846
  environment.removeEventListener('touchend', onTouchEnd);
1848
1847
  };
1849
- // eslint-disable-next-line react-hooks/exhaustive-deps
1850
- }, [isOpen, environment]);
1851
- return mouseAndTouchTrackersRef;
1848
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- refs don't change
1849
+ }, [environment, handleBlur]);
1850
+ return mouseAndTouchTrackersRef.current;
1852
1851
  }
1853
1852
 
1854
1853
  /* istanbul ignore next */
@@ -2034,6 +2033,7 @@ var commonPropTypes = {
2034
2033
  Node: PropTypes__default["default"].func.isRequired
2035
2034
  }),
2036
2035
  itemToString: PropTypes__default["default"].func,
2036
+ itemToKey: PropTypes__default["default"].func,
2037
2037
  stateReducer: PropTypes__default["default"].func
2038
2038
  };
2039
2039
 
@@ -2236,7 +2236,9 @@ function downshiftSelectReducer(state, action) {
2236
2236
  {
2237
2237
  var lowercasedKey = action.key;
2238
2238
  var inputValue = "" + state.inputValue + lowercasedKey;
2239
- var prevHighlightedIndex = !state.isOpen && state.selectedItem ? props.items.indexOf(state.selectedItem) : state.highlightedIndex;
2239
+ var prevHighlightedIndex = !state.isOpen && state.selectedItem ? props.items.findIndex(function (item) {
2240
+ return props.itemToKey(item) === props.itemToKey(state.selectedItem);
2241
+ }) : state.highlightedIndex;
2240
2242
  var highlightedIndex = getItemIndexByCharacterKey({
2241
2243
  keysSoFar: inputValue,
2242
2244
  highlightedIndex: prevHighlightedIndex,
@@ -2438,12 +2440,13 @@ function useSelect(userProps) {
2438
2440
  }
2439
2441
  // eslint-disable-next-line react-hooks/exhaustive-deps
2440
2442
  }, []);
2441
- // Add mouse/touch events to document.
2442
- var mouseAndTouchTrackersRef = useMouseAndTouchTracker(isOpen, [menuRef, toggleButtonRef], environment, function () {
2443
- dispatch({
2444
- type: ToggleButtonBlur
2445
- });
2446
- });
2443
+ var mouseAndTouchTrackers = useMouseAndTouchTracker(environment, [toggleButtonRef, menuRef], React.useCallback(function handleBlur() {
2444
+ if (latest.current.state.isOpen) {
2445
+ dispatch({
2446
+ type: ToggleButtonBlur
2447
+ });
2448
+ }
2449
+ }, [dispatch, latest]));
2447
2450
  var setGetterPropCallInfo = useGetterPropsCalledChecker('getMenuProps', 'getToggleButtonProps');
2448
2451
  // Reset itemRefs on close.
2449
2452
  React.useEffect(function () {
@@ -2629,7 +2632,7 @@ function useSelect(userProps) {
2629
2632
  });
2630
2633
  };
2631
2634
  var toggleButtonHandleBlur = function toggleButtonHandleBlur() {
2632
- if (latestState.isOpen && !mouseAndTouchTrackersRef.current.isMouseDown) {
2635
+ if (latestState.isOpen && !mouseAndTouchTrackers.isMouseDown) {
2633
2636
  dispatch({
2634
2637
  type: ToggleButtonBlur
2635
2638
  });
@@ -2658,7 +2661,7 @@ function useSelect(userProps) {
2658
2661
  }
2659
2662
  setGetterPropCallInfo('getToggleButtonProps', suppressRefError, refKey, toggleButtonRef);
2660
2663
  return toggleProps;
2661
- }, [latest, elementIds, setGetterPropCallInfo, dispatch, mouseAndTouchTrackersRef, toggleButtonKeyDownHandlers]);
2664
+ }, [dispatch, elementIds, latest, mouseAndTouchTrackers, setGetterPropCallInfo, toggleButtonKeyDownHandlers]);
2662
2665
  var getItemProps = React.useCallback(function (_temp6) {
2663
2666
  var _extends4;
2664
2667
  var _ref6 = _temp6 === void 0 ? {} : _temp6,
@@ -2684,7 +2687,7 @@ function useSelect(userProps) {
2684
2687
  index = _getItemAndIndex[1];
2685
2688
  var disabled = latestProps.isItemDisabled(item, index);
2686
2689
  var itemHandleMouseMove = function itemHandleMouseMove() {
2687
- if (mouseAndTouchTrackersRef.current.isTouchEnd || index === latestState.highlightedIndex) {
2690
+ if (mouseAndTouchTrackers.isTouchEnd || index === latestState.highlightedIndex) {
2688
2691
  return;
2689
2692
  }
2690
2693
  shouldScrollRef.current = false;
@@ -2718,7 +2721,7 @@ function useSelect(userProps) {
2718
2721
  itemProps.onMouseMove = callAllEventHandlers(onMouseMove, itemHandleMouseMove);
2719
2722
  itemProps.onMouseDown = callAllEventHandlers(onMouseDown, itemHandleMouseDown);
2720
2723
  return itemProps;
2721
- }, [latest, elementIds, mouseAndTouchTrackersRef, shouldScrollRef, dispatch]);
2724
+ }, [latest, elementIds, mouseAndTouchTrackers, shouldScrollRef, dispatch]);
2722
2725
  return {
2723
2726
  // prop getters.
2724
2727
  getToggleButtonProps: getToggleButtonProps,
@@ -2838,13 +2841,21 @@ function useControlledReducer(reducer, props, createInitialState, isStateEqual)
2838
2841
  if (!isControlledProp(props, 'selectedItem')) {
2839
2842
  return;
2840
2843
  }
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)) {
2844
- dispatch({
2845
- type: ControlledPropUpdatedSelectedItem,
2846
- inputValue: props.itemToString(props.selectedItem)
2847
- });
2844
+ if (!isInitialMount // on first mount we already have the proper inputValue for a initial selected item.
2845
+ ) {
2846
+ var shouldCallDispatch;
2847
+ if (props.selectedItemChanged === undefined) {
2848
+ shouldCallDispatch = props.itemToKey(props.selectedItem) !== props.itemToKey(previousSelectedItemRef.current);
2849
+ } else {
2850
+ console.warn("The \"selectedItemChanged\" is deprecated. Please use \"itemToKey instead\". https://github.com/downshift-js/downshift/blob/master/src/hooks/useCombobox/README.md#selecteditemchanged");
2851
+ shouldCallDispatch = props.selectedItemChanged(previousSelectedItemRef.current, props.selectedItem);
2852
+ }
2853
+ if (shouldCallDispatch) {
2854
+ dispatch({
2855
+ type: ControlledPropUpdatedSelectedItem,
2856
+ inputValue: props.itemToString(props.selectedItem)
2857
+ });
2858
+ }
2848
2859
  }
2849
2860
  previousSelectedItemRef.current = state.selectedItem === previousSelectedItemRef.current ? props.selectedItem : state.selectedItem;
2850
2861
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -2861,9 +2872,6 @@ if (process.env.NODE_ENV !== 'production') {
2861
2872
  };
2862
2873
  }
2863
2874
  var defaultProps$1 = _extends__default["default"]({}, defaultProps$3, {
2864
- selectedItemChanged: function selectedItemChanged(prevItem, item) {
2865
- return prevItem !== item;
2866
- },
2867
2875
  getA11yStatusMessage: getA11yStatusMessage$1,
2868
2876
  isItemDisabled: function isItemDisabled() {
2869
2877
  return false;
@@ -3074,13 +3082,14 @@ function useCombobox(userProps) {
3074
3082
  previousResultCountRef.current = items.length;
3075
3083
  }
3076
3084
  });
3077
- // Add mouse/touch events to document.
3078
- var mouseAndTouchTrackersRef = useMouseAndTouchTracker(isOpen, [inputRef, menuRef, toggleButtonRef], environment, function () {
3079
- dispatch({
3080
- type: InputBlur,
3081
- selectItem: false
3082
- });
3083
- });
3085
+ var mouseAndTouchTrackers = useMouseAndTouchTracker(environment, [toggleButtonRef, menuRef, inputRef], React.useCallback(function handleBlur() {
3086
+ if (latest.current.state.isOpen) {
3087
+ dispatch({
3088
+ type: InputBlur,
3089
+ selectItem: false
3090
+ });
3091
+ }
3092
+ }, [dispatch, latest]));
3084
3093
  var setGetterPropCallInfo = useGetterPropsCalledChecker('getInputProps', 'getMenuProps');
3085
3094
  // Reset itemRefs on close.
3086
3095
  React.useEffect(function () {
@@ -3228,7 +3237,7 @@ function useCombobox(userProps) {
3228
3237
  var onSelectKey = 'onClick';
3229
3238
  var customClickHandler = onClick;
3230
3239
  var itemHandleMouseMove = function itemHandleMouseMove() {
3231
- if (mouseAndTouchTrackersRef.current.isTouchEnd || index === latestState.highlightedIndex) {
3240
+ if (mouseAndTouchTrackers.isTouchEnd || index === latestState.highlightedIndex) {
3232
3241
  return;
3233
3242
  }
3234
3243
  shouldScrollRef.current = false;
@@ -3256,7 +3265,7 @@ function useCombobox(userProps) {
3256
3265
  onMouseMove: callAllEventHandlers(onMouseMove, itemHandleMouseMove),
3257
3266
  onMouseDown: callAllEventHandlers(onMouseDown, itemHandleMouseDown)
3258
3267
  }, rest);
3259
- }, [dispatch, elementIds, latest, mouseAndTouchTrackersRef, shouldScrollRef]);
3268
+ }, [dispatch, elementIds, latest, mouseAndTouchTrackers, shouldScrollRef]);
3260
3269
  var getToggleButtonProps = React.useCallback(function (_temp4) {
3261
3270
  var _extends4;
3262
3271
  var _ref5 = _temp4 === void 0 ? {} : _temp4,
@@ -3310,7 +3319,7 @@ function useCombobox(userProps) {
3310
3319
  };
3311
3320
  var inputHandleBlur = function inputHandleBlur(event) {
3312
3321
  /* istanbul ignore else */
3313
- if (environment != null && environment.document && latestState.isOpen && !mouseAndTouchTrackersRef.current.isMouseDown) {
3322
+ if (environment != null && environment.document && latestState.isOpen && !mouseAndTouchTrackers.isMouseDown) {
3314
3323
  var isBlurByTabChange = event.relatedTarget === null && environment.document.activeElement !== environment.document.body;
3315
3324
  dispatch({
3316
3325
  type: InputBlur,
@@ -3334,7 +3343,7 @@ function useCombobox(userProps) {
3334
3343
  return _extends__default["default"]((_extends5 = {}, _extends5[refKey] = handleRefs(ref, function (inputNode) {
3335
3344
  inputRef.current = inputNode;
3336
3345
  }), _extends5['aria-activedescendant'] = latestState.isOpen && latestState.highlightedIndex > -1 ? elementIds.getItemId(latestState.highlightedIndex) : '', _extends5['aria-autocomplete'] = 'list', _extends5['aria-controls'] = elementIds.menuId, _extends5['aria-expanded'] = latestState.isOpen, _extends5['aria-labelledby'] = rest && rest['aria-label'] ? undefined : elementIds.labelId, _extends5.autoComplete = 'off', _extends5.id = elementIds.inputId, _extends5.role = 'combobox', _extends5.value = latestState.inputValue, _extends5), eventHandlers, rest);
3337
- }, [setGetterPropCallInfo, latest, elementIds, inputKeyDownHandlers, dispatch, mouseAndTouchTrackersRef, environment]);
3346
+ }, [dispatch, elementIds, environment, inputKeyDownHandlers, latest, mouseAndTouchTrackers, setGetterPropCallInfo]);
3338
3347
 
3339
3348
  // returns
3340
3349
  var toggleMenu = React.useCallback(function () {
@@ -3507,6 +3516,7 @@ var propTypes = _extends__default["default"]({}, commonPropTypes, {
3507
3516
  });
3508
3517
  var defaultProps = {
3509
3518
  itemToString: defaultProps$3.itemToString,
3519
+ itemToKey: defaultProps$3.itemToKey,
3510
3520
  stateReducer: defaultProps$3.stateReducer,
3511
3521
  environment: defaultProps$3.environment,
3512
3522
  getA11yRemovalMessage: getA11yRemovalMessage,
@@ -3621,7 +3631,9 @@ function downshiftMultipleSelectionReducer(state, action) {
3621
3631
  case FunctionRemoveSelectedItem:
3622
3632
  {
3623
3633
  var _newActiveIndex = activeIndex;
3624
- var selectedItemIndex = selectedItems.indexOf(selectedItem);
3634
+ var selectedItemIndex = selectedItems.findIndex(function (item) {
3635
+ return props.itemToKey(item) === props.itemToKey(selectedItem);
3636
+ });
3625
3637
  if (selectedItemIndex < 0) {
3626
3638
  break;
3627
3639
  }
@@ -3705,8 +3717,10 @@ function useMultipleSelection(userProps) {
3705
3717
  return;
3706
3718
  }
3707
3719
  if (selectedItems.length < previousSelectedItemsRef.current.length) {
3708
- var removedSelectedItem = previousSelectedItemsRef.current.find(function (item) {
3709
- return selectedItems.indexOf(item) < 0;
3720
+ var removedSelectedItem = previousSelectedItemsRef.current.find(function (selectedItem) {
3721
+ return selectedItems.findIndex(function (item) {
3722
+ return props.itemToKey(item) === props.itemToKey(selectedItem);
3723
+ }) < 0;
3710
3724
  });
3711
3725
  setStatus(getA11yRemovalMessage({
3712
3726
  itemToString: itemToString,