downshift 8.3.3 → 8.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.
@@ -1601,8 +1601,8 @@ function stateReducer(s, a) {
1601
1601
  */
1602
1602
  function getA11ySelectionMessage(selectionParameters) {
1603
1603
  var selectedItem = selectionParameters.selectedItem,
1604
- itemToStringLocal = selectionParameters.itemToString;
1605
- return selectedItem ? itemToStringLocal(selectedItem) + " has been selected." : '';
1604
+ itemToString = selectionParameters.itemToString;
1605
+ return selectedItem ? itemToString(selectedItem) + " has been selected." : '';
1606
1606
  }
1607
1607
 
1608
1608
  /**
@@ -1672,9 +1672,6 @@ function getItemAndIndex(itemProp, indexProp, items, errorMessage) {
1672
1672
  }
1673
1673
  return [item, index];
1674
1674
  }
1675
- function itemToString(item) {
1676
- return item ? String(item) : '';
1677
- }
1678
1675
  function isAcceptedCharacterKey(key) {
1679
1676
  return /^\S{1}$/.test(key);
1680
1677
  }
@@ -1753,7 +1750,12 @@ function useControlledReducer$1(reducer, props, createInitialState, isStateEqual
1753
1750
  return [getState(state, props), dispatch];
1754
1751
  }
1755
1752
  var defaultProps$3 = {
1756
- itemToString: itemToString,
1753
+ itemToString: function itemToString(item) {
1754
+ return item ? String(item) : '';
1755
+ },
1756
+ itemToKey: function itemToKey(item) {
1757
+ return item;
1758
+ },
1757
1759
  stateReducer: stateReducer,
1758
1760
  getA11ySelectionMessage: getA11ySelectionMessage,
1759
1761
  scrollIntoView: scrollIntoView,
@@ -1790,7 +1792,9 @@ function getInitialState$2(props) {
1790
1792
  var highlightedIndex = getInitialValue$1(props, 'highlightedIndex');
1791
1793
  var inputValue = getInitialValue$1(props, 'inputValue');
1792
1794
  return {
1793
- highlightedIndex: highlightedIndex < 0 && selectedItem && isOpen ? props.items.indexOf(selectedItem) : highlightedIndex,
1795
+ highlightedIndex: highlightedIndex < 0 && selectedItem && isOpen ? props.items.findIndex(function (item) {
1796
+ return props.itemToKey(item) === props.itemToKey(selectedItem);
1797
+ }) : highlightedIndex,
1794
1798
  isOpen: isOpen,
1795
1799
  selectedItem: selectedItem,
1796
1800
  inputValue: inputValue
@@ -1799,7 +1803,8 @@ function getInitialState$2(props) {
1799
1803
  function getHighlightedIndexOnOpen(props, state, offset) {
1800
1804
  var items = props.items,
1801
1805
  initialHighlightedIndex = props.initialHighlightedIndex,
1802
- defaultHighlightedIndex = props.defaultHighlightedIndex;
1806
+ defaultHighlightedIndex = props.defaultHighlightedIndex,
1807
+ itemToKey = props.itemToKey;
1803
1808
  var selectedItem = state.selectedItem,
1804
1809
  highlightedIndex = state.highlightedIndex;
1805
1810
  if (items.length === 0) {
@@ -1814,7 +1819,9 @@ function getHighlightedIndexOnOpen(props, state, offset) {
1814
1819
  return defaultHighlightedIndex;
1815
1820
  }
1816
1821
  if (selectedItem) {
1817
- return items.indexOf(selectedItem);
1822
+ return items.findIndex(function (item) {
1823
+ return itemToKey(selectedItem) === itemToKey(item);
1824
+ });
1818
1825
  }
1819
1826
  if (offset === 0) {
1820
1827
  return -1;
@@ -2073,6 +2080,7 @@ var commonPropTypes = {
2073
2080
  Node: PropTypes__default["default"].func.isRequired
2074
2081
  }),
2075
2082
  itemToString: PropTypes__default["default"].func,
2083
+ itemToKey: PropTypes__default["default"].func,
2076
2084
  stateReducer: PropTypes__default["default"].func
2077
2085
  };
2078
2086
 
@@ -2275,7 +2283,9 @@ function downshiftSelectReducer(state, action) {
2275
2283
  {
2276
2284
  var lowercasedKey = action.key;
2277
2285
  var inputValue = "" + state.inputValue + lowercasedKey;
2278
- var prevHighlightedIndex = !state.isOpen && state.selectedItem ? props.items.indexOf(state.selectedItem) : state.highlightedIndex;
2286
+ var prevHighlightedIndex = !state.isOpen && state.selectedItem ? props.items.findIndex(function (item) {
2287
+ return props.itemToKey(item) === props.itemToKey(state.selectedItem);
2288
+ }) : state.highlightedIndex;
2279
2289
  var highlightedIndex = getItemIndexByCharacterKey({
2280
2290
  keysSoFar: inputValue,
2281
2291
  highlightedIndex: prevHighlightedIndex,
@@ -2877,13 +2887,21 @@ function useControlledReducer(reducer, props, createInitialState, isStateEqual)
2877
2887
  if (!isControlledProp(props, 'selectedItem')) {
2878
2888
  return;
2879
2889
  }
2880
- if (!isInitialMount &&
2881
- // on first mount we already have the proper inputValue for a initial selected item.
2882
- props.selectedItemChanged(previousSelectedItemRef.current, props.selectedItem)) {
2883
- dispatch({
2884
- type: ControlledPropUpdatedSelectedItem,
2885
- inputValue: props.itemToString(props.selectedItem)
2886
- });
2890
+ if (!isInitialMount // on first mount we already have the proper inputValue for a initial selected item.
2891
+ ) {
2892
+ var shouldCallDispatch;
2893
+ if (props.selectedItemChanged === undefined) {
2894
+ shouldCallDispatch = props.itemToKey(props.selectedItem) !== props.itemToKey(previousSelectedItemRef.current);
2895
+ } else {
2896
+ console.warn("The \"selectedItemChanged\" is deprecated. Please use \"itemToKey instead\". https://github.com/downshift-js/downshift/blob/master/src/hooks/useCombobox/README.md#selecteditemchanged");
2897
+ shouldCallDispatch = props.selectedItemChanged(previousSelectedItemRef.current, props.selectedItem);
2898
+ }
2899
+ if (shouldCallDispatch) {
2900
+ dispatch({
2901
+ type: ControlledPropUpdatedSelectedItem,
2902
+ inputValue: props.itemToString(props.selectedItem)
2903
+ });
2904
+ }
2887
2905
  }
2888
2906
  previousSelectedItemRef.current = state.selectedItem === previousSelectedItemRef.current ? props.selectedItem : state.selectedItem;
2889
2907
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -2900,9 +2918,6 @@ if (process.env.NODE_ENV !== 'production') {
2900
2918
  };
2901
2919
  }
2902
2920
  var defaultProps$1 = _extends__default["default"]({}, defaultProps$3, {
2903
- selectedItemChanged: function selectedItemChanged(prevItem, item) {
2904
- return prevItem !== item;
2905
- },
2906
2921
  getA11yStatusMessage: getA11yStatusMessage$1,
2907
2922
  isItemDisabled: function isItemDisabled() {
2908
2923
  return false;
@@ -3546,6 +3561,7 @@ var propTypes = _extends__default["default"]({}, commonPropTypes, {
3546
3561
  });
3547
3562
  var defaultProps = {
3548
3563
  itemToString: defaultProps$3.itemToString,
3564
+ itemToKey: defaultProps$3.itemToKey,
3549
3565
  stateReducer: defaultProps$3.stateReducer,
3550
3566
  environment: defaultProps$3.environment,
3551
3567
  getA11yRemovalMessage: getA11yRemovalMessage,
@@ -3660,7 +3676,9 @@ function downshiftMultipleSelectionReducer(state, action) {
3660
3676
  case FunctionRemoveSelectedItem:
3661
3677
  {
3662
3678
  var _newActiveIndex = activeIndex;
3663
- var selectedItemIndex = selectedItems.indexOf(selectedItem);
3679
+ var selectedItemIndex = selectedItems.findIndex(function (item) {
3680
+ return props.itemToKey(item) === props.itemToKey(selectedItem);
3681
+ });
3664
3682
  if (selectedItemIndex < 0) {
3665
3683
  break;
3666
3684
  }
@@ -3744,8 +3762,10 @@ function useMultipleSelection(userProps) {
3744
3762
  return;
3745
3763
  }
3746
3764
  if (selectedItems.length < previousSelectedItemsRef.current.length) {
3747
- var removedSelectedItem = previousSelectedItemsRef.current.find(function (item) {
3748
- return selectedItems.indexOf(item) < 0;
3765
+ var removedSelectedItem = previousSelectedItemsRef.current.find(function (selectedItem) {
3766
+ return selectedItems.findIndex(function (item) {
3767
+ return props.itemToKey(item) === props.itemToKey(selectedItem);
3768
+ }) < 0;
3749
3769
  });
3750
3770
  setStatus(getA11yRemovalMessage({
3751
3771
  itemToString: itemToString,
@@ -1588,8 +1588,8 @@ function stateReducer(s, a) {
1588
1588
  */
1589
1589
  function getA11ySelectionMessage(selectionParameters) {
1590
1590
  var selectedItem = selectionParameters.selectedItem,
1591
- itemToStringLocal = selectionParameters.itemToString;
1592
- return selectedItem ? itemToStringLocal(selectedItem) + " has been selected." : '';
1591
+ itemToString = selectionParameters.itemToString;
1592
+ return selectedItem ? itemToString(selectedItem) + " has been selected." : '';
1593
1593
  }
1594
1594
 
1595
1595
  /**
@@ -1659,9 +1659,6 @@ function getItemAndIndex(itemProp, indexProp, items, errorMessage) {
1659
1659
  }
1660
1660
  return [item, index];
1661
1661
  }
1662
- function itemToString(item) {
1663
- return item ? String(item) : '';
1664
- }
1665
1662
  function isAcceptedCharacterKey(key) {
1666
1663
  return /^\S{1}$/.test(key);
1667
1664
  }
@@ -1740,7 +1737,12 @@ function useControlledReducer$1(reducer, props, createInitialState, isStateEqual
1740
1737
  return [getState(state, props), dispatch];
1741
1738
  }
1742
1739
  var defaultProps$3 = {
1743
- itemToString: itemToString,
1740
+ itemToString: function itemToString(item) {
1741
+ return item ? String(item) : '';
1742
+ },
1743
+ itemToKey: function itemToKey(item) {
1744
+ return item;
1745
+ },
1744
1746
  stateReducer: stateReducer,
1745
1747
  getA11ySelectionMessage: getA11ySelectionMessage,
1746
1748
  scrollIntoView: scrollIntoView,
@@ -1777,7 +1779,9 @@ function getInitialState$2(props) {
1777
1779
  var highlightedIndex = getInitialValue$1(props, 'highlightedIndex');
1778
1780
  var inputValue = getInitialValue$1(props, 'inputValue');
1779
1781
  return {
1780
- highlightedIndex: highlightedIndex < 0 && selectedItem && isOpen ? props.items.indexOf(selectedItem) : highlightedIndex,
1782
+ highlightedIndex: highlightedIndex < 0 && selectedItem && isOpen ? props.items.findIndex(function (item) {
1783
+ return props.itemToKey(item) === props.itemToKey(selectedItem);
1784
+ }) : highlightedIndex,
1781
1785
  isOpen: isOpen,
1782
1786
  selectedItem: selectedItem,
1783
1787
  inputValue: inputValue
@@ -1786,7 +1790,8 @@ function getInitialState$2(props) {
1786
1790
  function getHighlightedIndexOnOpen(props, state, offset) {
1787
1791
  var items = props.items,
1788
1792
  initialHighlightedIndex = props.initialHighlightedIndex,
1789
- defaultHighlightedIndex = props.defaultHighlightedIndex;
1793
+ defaultHighlightedIndex = props.defaultHighlightedIndex,
1794
+ itemToKey = props.itemToKey;
1790
1795
  var selectedItem = state.selectedItem,
1791
1796
  highlightedIndex = state.highlightedIndex;
1792
1797
  if (items.length === 0) {
@@ -1801,7 +1806,9 @@ function getHighlightedIndexOnOpen(props, state, offset) {
1801
1806
  return defaultHighlightedIndex;
1802
1807
  }
1803
1808
  if (selectedItem) {
1804
- return items.indexOf(selectedItem);
1809
+ return items.findIndex(function (item) {
1810
+ return itemToKey(selectedItem) === itemToKey(item);
1811
+ });
1805
1812
  }
1806
1813
  if (offset === 0) {
1807
1814
  return -1;
@@ -2060,6 +2067,7 @@ var commonPropTypes = {
2060
2067
  Node: PropTypes.func.isRequired
2061
2068
  }),
2062
2069
  itemToString: PropTypes.func,
2070
+ itemToKey: PropTypes.func,
2063
2071
  stateReducer: PropTypes.func
2064
2072
  };
2065
2073
 
@@ -2262,7 +2270,9 @@ function downshiftSelectReducer(state, action) {
2262
2270
  {
2263
2271
  var lowercasedKey = action.key;
2264
2272
  var inputValue = "" + state.inputValue + lowercasedKey;
2265
- var prevHighlightedIndex = !state.isOpen && state.selectedItem ? props.items.indexOf(state.selectedItem) : state.highlightedIndex;
2273
+ var prevHighlightedIndex = !state.isOpen && state.selectedItem ? props.items.findIndex(function (item) {
2274
+ return props.itemToKey(item) === props.itemToKey(state.selectedItem);
2275
+ }) : state.highlightedIndex;
2266
2276
  var highlightedIndex = getItemIndexByCharacterKey({
2267
2277
  keysSoFar: inputValue,
2268
2278
  highlightedIndex: prevHighlightedIndex,
@@ -2864,13 +2874,21 @@ function useControlledReducer(reducer, props, createInitialState, isStateEqual)
2864
2874
  if (!isControlledProp(props, 'selectedItem')) {
2865
2875
  return;
2866
2876
  }
2867
- if (!isInitialMount &&
2868
- // on first mount we already have the proper inputValue for a initial selected item.
2869
- props.selectedItemChanged(previousSelectedItemRef.current, props.selectedItem)) {
2870
- dispatch({
2871
- type: ControlledPropUpdatedSelectedItem,
2872
- inputValue: props.itemToString(props.selectedItem)
2873
- });
2877
+ if (!isInitialMount // on first mount we already have the proper inputValue for a initial selected item.
2878
+ ) {
2879
+ var shouldCallDispatch;
2880
+ if (props.selectedItemChanged === undefined) {
2881
+ shouldCallDispatch = props.itemToKey(props.selectedItem) !== props.itemToKey(previousSelectedItemRef.current);
2882
+ } else {
2883
+ console.warn("The \"selectedItemChanged\" is deprecated. Please use \"itemToKey instead\". https://github.com/downshift-js/downshift/blob/master/src/hooks/useCombobox/README.md#selecteditemchanged");
2884
+ shouldCallDispatch = props.selectedItemChanged(previousSelectedItemRef.current, props.selectedItem);
2885
+ }
2886
+ if (shouldCallDispatch) {
2887
+ dispatch({
2888
+ type: ControlledPropUpdatedSelectedItem,
2889
+ inputValue: props.itemToString(props.selectedItem)
2890
+ });
2891
+ }
2874
2892
  }
2875
2893
  previousSelectedItemRef.current = state.selectedItem === previousSelectedItemRef.current ? props.selectedItem : state.selectedItem;
2876
2894
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -2887,9 +2905,6 @@ if (process.env.NODE_ENV !== 'production') {
2887
2905
  };
2888
2906
  }
2889
2907
  var defaultProps$1 = _extends({}, defaultProps$3, {
2890
- selectedItemChanged: function selectedItemChanged(prevItem, item) {
2891
- return prevItem !== item;
2892
- },
2893
2908
  getA11yStatusMessage: getA11yStatusMessage$1,
2894
2909
  isItemDisabled: function isItemDisabled() {
2895
2910
  return false;
@@ -3533,6 +3548,7 @@ var propTypes = _extends({}, commonPropTypes, {
3533
3548
  });
3534
3549
  var defaultProps = {
3535
3550
  itemToString: defaultProps$3.itemToString,
3551
+ itemToKey: defaultProps$3.itemToKey,
3536
3552
  stateReducer: defaultProps$3.stateReducer,
3537
3553
  environment: defaultProps$3.environment,
3538
3554
  getA11yRemovalMessage: getA11yRemovalMessage,
@@ -3647,7 +3663,9 @@ function downshiftMultipleSelectionReducer(state, action) {
3647
3663
  case FunctionRemoveSelectedItem:
3648
3664
  {
3649
3665
  var _newActiveIndex = activeIndex;
3650
- var selectedItemIndex = selectedItems.indexOf(selectedItem);
3666
+ var selectedItemIndex = selectedItems.findIndex(function (item) {
3667
+ return props.itemToKey(item) === props.itemToKey(selectedItem);
3668
+ });
3651
3669
  if (selectedItemIndex < 0) {
3652
3670
  break;
3653
3671
  }
@@ -3731,8 +3749,10 @@ function useMultipleSelection(userProps) {
3731
3749
  return;
3732
3750
  }
3733
3751
  if (selectedItems.length < previousSelectedItemsRef.current.length) {
3734
- var removedSelectedItem = previousSelectedItemsRef.current.find(function (item) {
3735
- return selectedItems.indexOf(item) < 0;
3752
+ var removedSelectedItem = previousSelectedItemsRef.current.find(function (selectedItem) {
3753
+ return selectedItems.findIndex(function (item) {
3754
+ return props.itemToKey(item) === props.itemToKey(selectedItem);
3755
+ }) < 0;
3736
3756
  });
3737
3757
  setStatus(getA11yRemovalMessage({
3738
3758
  itemToString: itemToString,
@@ -1500,8 +1500,8 @@ function stateReducer(s, a) {
1500
1500
  */
1501
1501
  function getA11ySelectionMessage(selectionParameters) {
1502
1502
  var selectedItem = selectionParameters.selectedItem,
1503
- itemToStringLocal = selectionParameters.itemToString;
1504
- return selectedItem ? itemToStringLocal(selectedItem) + " has been selected." : '';
1503
+ itemToString = selectionParameters.itemToString;
1504
+ return selectedItem ? itemToString(selectedItem) + " has been selected." : '';
1505
1505
  }
1506
1506
 
1507
1507
  /**
@@ -1571,9 +1571,6 @@ function getItemAndIndex(itemProp, indexProp, items, errorMessage) {
1571
1571
  }
1572
1572
  return [item, index];
1573
1573
  }
1574
- function itemToString(item) {
1575
- return item ? String(item) : '';
1576
- }
1577
1574
  function capitalizeString(string) {
1578
1575
  return "" + string.slice(0, 1).toUpperCase() + string.slice(1);
1579
1576
  }
@@ -1649,7 +1646,12 @@ function useControlledReducer$1(reducer, props, createInitialState, isStateEqual
1649
1646
  return [getState(state, props), dispatch];
1650
1647
  }
1651
1648
  var defaultProps$3 = {
1652
- itemToString: itemToString,
1649
+ itemToString: function itemToString(item) {
1650
+ return item ? String(item) : '';
1651
+ },
1652
+ itemToKey: function itemToKey(item) {
1653
+ return item;
1654
+ },
1653
1655
  stateReducer: stateReducer,
1654
1656
  getA11ySelectionMessage: getA11ySelectionMessage,
1655
1657
  scrollIntoView: scrollIntoView,
@@ -1686,7 +1688,9 @@ function getInitialState$2(props) {
1686
1688
  var highlightedIndex = getInitialValue$1(props, 'highlightedIndex');
1687
1689
  var inputValue = getInitialValue$1(props, 'inputValue');
1688
1690
  return {
1689
- highlightedIndex: highlightedIndex < 0 && selectedItem && isOpen ? props.items.indexOf(selectedItem) : highlightedIndex,
1691
+ highlightedIndex: highlightedIndex < 0 && selectedItem && isOpen ? props.items.findIndex(function (item) {
1692
+ return props.itemToKey(item) === props.itemToKey(selectedItem);
1693
+ }) : highlightedIndex,
1690
1694
  isOpen: isOpen,
1691
1695
  selectedItem: selectedItem,
1692
1696
  inputValue: inputValue
@@ -1695,7 +1699,8 @@ function getInitialState$2(props) {
1695
1699
  function getHighlightedIndexOnOpen(props, state, offset) {
1696
1700
  var items = props.items,
1697
1701
  initialHighlightedIndex = props.initialHighlightedIndex,
1698
- defaultHighlightedIndex = props.defaultHighlightedIndex;
1702
+ defaultHighlightedIndex = props.defaultHighlightedIndex,
1703
+ itemToKey = props.itemToKey;
1699
1704
  var selectedItem = state.selectedItem,
1700
1705
  highlightedIndex = state.highlightedIndex;
1701
1706
  if (items.length === 0) {
@@ -1710,7 +1715,9 @@ function getHighlightedIndexOnOpen(props, state, offset) {
1710
1715
  return defaultHighlightedIndex;
1711
1716
  }
1712
1717
  if (selectedItem) {
1713
- return items.indexOf(selectedItem);
1718
+ return items.findIndex(function (item) {
1719
+ return itemToKey(selectedItem) === itemToKey(item);
1720
+ });
1714
1721
  }
1715
1722
  if (offset === 0) {
1716
1723
  return -1;
@@ -1925,6 +1932,7 @@ var commonPropTypes = {
1925
1932
  Node: PropTypes__default["default"].func.isRequired
1926
1933
  }),
1927
1934
  itemToString: PropTypes__default["default"].func,
1935
+ itemToKey: PropTypes__default["default"].func,
1928
1936
  stateReducer: PropTypes__default["default"].func
1929
1937
  };
1930
1938
 
@@ -2127,7 +2135,9 @@ function downshiftSelectReducer(state, action) {
2127
2135
  {
2128
2136
  var lowercasedKey = action.key;
2129
2137
  var inputValue = "" + state.inputValue + lowercasedKey;
2130
- var prevHighlightedIndex = !state.isOpen && state.selectedItem ? props.items.indexOf(state.selectedItem) : state.highlightedIndex;
2138
+ var prevHighlightedIndex = !state.isOpen && state.selectedItem ? props.items.findIndex(function (item) {
2139
+ return props.itemToKey(item) === props.itemToKey(state.selectedItem);
2140
+ }) : state.highlightedIndex;
2131
2141
  var highlightedIndex = getItemIndexByCharacterKey({
2132
2142
  keysSoFar: inputValue,
2133
2143
  highlightedIndex: prevHighlightedIndex,
@@ -2713,13 +2723,21 @@ function useControlledReducer(reducer, props, createInitialState, isStateEqual)
2713
2723
  if (!isControlledProp(props, 'selectedItem')) {
2714
2724
  return;
2715
2725
  }
2716
- if (!isInitialMount &&
2717
- // on first mount we already have the proper inputValue for a initial selected item.
2718
- props.selectedItemChanged(previousSelectedItemRef.current, props.selectedItem)) {
2719
- dispatch({
2720
- type: ControlledPropUpdatedSelectedItem,
2721
- inputValue: props.itemToString(props.selectedItem)
2722
- });
2726
+ if (!isInitialMount // on first mount we already have the proper inputValue for a initial selected item.
2727
+ ) {
2728
+ var shouldCallDispatch;
2729
+ if (props.selectedItemChanged === undefined) {
2730
+ shouldCallDispatch = props.itemToKey(props.selectedItem) !== props.itemToKey(previousSelectedItemRef.current);
2731
+ } else {
2732
+ console.warn("The \"selectedItemChanged\" is deprecated. Please use \"itemToKey instead\". https://github.com/downshift-js/downshift/blob/master/src/hooks/useCombobox/README.md#selecteditemchanged");
2733
+ shouldCallDispatch = props.selectedItemChanged(previousSelectedItemRef.current, props.selectedItem);
2734
+ }
2735
+ if (shouldCallDispatch) {
2736
+ dispatch({
2737
+ type: ControlledPropUpdatedSelectedItem,
2738
+ inputValue: props.itemToString(props.selectedItem)
2739
+ });
2740
+ }
2723
2741
  }
2724
2742
  previousSelectedItemRef.current = state.selectedItem === previousSelectedItemRef.current ? props.selectedItem : state.selectedItem;
2725
2743
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -2736,9 +2754,6 @@ if (process.env.NODE_ENV !== 'production') {
2736
2754
  };
2737
2755
  }
2738
2756
  var defaultProps$1 = _extends__default["default"]({}, defaultProps$3, {
2739
- selectedItemChanged: function selectedItemChanged(prevItem, item) {
2740
- return prevItem !== item;
2741
- },
2742
2757
  getA11yStatusMessage: getA11yStatusMessage$1,
2743
2758
  isItemDisabled: function isItemDisabled() {
2744
2759
  return false;
@@ -3389,6 +3404,7 @@ var propTypes = _extends__default["default"]({}, commonPropTypes, {
3389
3404
  });
3390
3405
  var defaultProps = {
3391
3406
  itemToString: defaultProps$3.itemToString,
3407
+ itemToKey: defaultProps$3.itemToKey,
3392
3408
  stateReducer: defaultProps$3.stateReducer,
3393
3409
  environment: defaultProps$3.environment,
3394
3410
  getA11yRemovalMessage: getA11yRemovalMessage,
@@ -3503,7 +3519,9 @@ function downshiftMultipleSelectionReducer(state, action) {
3503
3519
  case FunctionRemoveSelectedItem:
3504
3520
  {
3505
3521
  var _newActiveIndex = activeIndex;
3506
- var selectedItemIndex = selectedItems.indexOf(selectedItem);
3522
+ var selectedItemIndex = selectedItems.findIndex(function (item) {
3523
+ return props.itemToKey(item) === props.itemToKey(selectedItem);
3524
+ });
3507
3525
  if (selectedItemIndex < 0) {
3508
3526
  break;
3509
3527
  }
@@ -3587,8 +3605,10 @@ function useMultipleSelection(userProps) {
3587
3605
  return;
3588
3606
  }
3589
3607
  if (selectedItems.length < previousSelectedItemsRef.current.length) {
3590
- var removedSelectedItem = previousSelectedItemsRef.current.find(function (item) {
3591
- return selectedItems.indexOf(item) < 0;
3608
+ var removedSelectedItem = previousSelectedItemsRef.current.find(function (selectedItem) {
3609
+ return selectedItems.findIndex(function (item) {
3610
+ return props.itemToKey(item) === props.itemToKey(selectedItem);
3611
+ }) < 0;
3592
3612
  });
3593
3613
  setStatus(getA11yRemovalMessage({
3594
3614
  itemToString: itemToString,
@@ -1599,8 +1599,8 @@ function stateReducer(s, a) {
1599
1599
  */
1600
1600
  function getA11ySelectionMessage(selectionParameters) {
1601
1601
  var selectedItem = selectionParameters.selectedItem,
1602
- itemToStringLocal = selectionParameters.itemToString;
1603
- return selectedItem ? itemToStringLocal(selectedItem) + " has been selected." : '';
1602
+ itemToString = selectionParameters.itemToString;
1603
+ return selectedItem ? itemToString(selectedItem) + " has been selected." : '';
1604
1604
  }
1605
1605
 
1606
1606
  /**
@@ -1670,9 +1670,6 @@ function getItemAndIndex(itemProp, indexProp, items, errorMessage) {
1670
1670
  }
1671
1671
  return [item, index];
1672
1672
  }
1673
- function itemToString(item) {
1674
- return item ? String(item) : '';
1675
- }
1676
1673
  function capitalizeString(string) {
1677
1674
  return "" + string.slice(0, 1).toUpperCase() + string.slice(1);
1678
1675
  }
@@ -1748,7 +1745,12 @@ function useControlledReducer$1(reducer, props, createInitialState, isStateEqual
1748
1745
  return [getState(state, props), dispatch];
1749
1746
  }
1750
1747
  var defaultProps$3 = {
1751
- itemToString: itemToString,
1748
+ itemToString: function itemToString(item) {
1749
+ return item ? String(item) : '';
1750
+ },
1751
+ itemToKey: function itemToKey(item) {
1752
+ return item;
1753
+ },
1752
1754
  stateReducer: stateReducer,
1753
1755
  getA11ySelectionMessage: getA11ySelectionMessage,
1754
1756
  scrollIntoView: scrollIntoView,
@@ -1785,7 +1787,9 @@ function getInitialState$2(props) {
1785
1787
  var highlightedIndex = getInitialValue$1(props, 'highlightedIndex');
1786
1788
  var inputValue = getInitialValue$1(props, 'inputValue');
1787
1789
  return {
1788
- highlightedIndex: highlightedIndex < 0 && selectedItem && isOpen ? props.items.indexOf(selectedItem) : highlightedIndex,
1790
+ highlightedIndex: highlightedIndex < 0 && selectedItem && isOpen ? props.items.findIndex(function (item) {
1791
+ return props.itemToKey(item) === props.itemToKey(selectedItem);
1792
+ }) : highlightedIndex,
1789
1793
  isOpen: isOpen,
1790
1794
  selectedItem: selectedItem,
1791
1795
  inputValue: inputValue
@@ -1794,7 +1798,8 @@ function getInitialState$2(props) {
1794
1798
  function getHighlightedIndexOnOpen(props, state, offset) {
1795
1799
  var items = props.items,
1796
1800
  initialHighlightedIndex = props.initialHighlightedIndex,
1797
- defaultHighlightedIndex = props.defaultHighlightedIndex;
1801
+ defaultHighlightedIndex = props.defaultHighlightedIndex,
1802
+ itemToKey = props.itemToKey;
1798
1803
  var selectedItem = state.selectedItem,
1799
1804
  highlightedIndex = state.highlightedIndex;
1800
1805
  if (items.length === 0) {
@@ -1809,7 +1814,9 @@ function getHighlightedIndexOnOpen(props, state, offset) {
1809
1814
  return defaultHighlightedIndex;
1810
1815
  }
1811
1816
  if (selectedItem) {
1812
- return items.indexOf(selectedItem);
1817
+ return items.findIndex(function (item) {
1818
+ return itemToKey(selectedItem) === itemToKey(item);
1819
+ });
1813
1820
  }
1814
1821
  if (offset === 0) {
1815
1822
  return -1;
@@ -2068,6 +2075,7 @@ var commonPropTypes = {
2068
2075
  Node: PropTypes__default["default"].func.isRequired
2069
2076
  }),
2070
2077
  itemToString: PropTypes__default["default"].func,
2078
+ itemToKey: PropTypes__default["default"].func,
2071
2079
  stateReducer: PropTypes__default["default"].func
2072
2080
  };
2073
2081
 
@@ -2270,7 +2278,9 @@ function downshiftSelectReducer(state, action) {
2270
2278
  {
2271
2279
  var lowercasedKey = action.key;
2272
2280
  var inputValue = "" + state.inputValue + lowercasedKey;
2273
- var prevHighlightedIndex = !state.isOpen && state.selectedItem ? props.items.indexOf(state.selectedItem) : state.highlightedIndex;
2281
+ var prevHighlightedIndex = !state.isOpen && state.selectedItem ? props.items.findIndex(function (item) {
2282
+ return props.itemToKey(item) === props.itemToKey(state.selectedItem);
2283
+ }) : state.highlightedIndex;
2274
2284
  var highlightedIndex = getItemIndexByCharacterKey({
2275
2285
  keysSoFar: inputValue,
2276
2286
  highlightedIndex: prevHighlightedIndex,
@@ -2860,13 +2870,21 @@ function useControlledReducer(reducer, props, createInitialState, isStateEqual)
2860
2870
  if (!isControlledProp(props, 'selectedItem')) {
2861
2871
  return;
2862
2872
  }
2863
- if (!isInitialMount &&
2864
- // on first mount we already have the proper inputValue for a initial selected item.
2865
- props.selectedItemChanged(previousSelectedItemRef.current, props.selectedItem)) {
2866
- dispatch({
2867
- type: ControlledPropUpdatedSelectedItem,
2868
- inputValue: props.itemToString(props.selectedItem)
2869
- });
2873
+ if (!isInitialMount // on first mount we already have the proper inputValue for a initial selected item.
2874
+ ) {
2875
+ var shouldCallDispatch;
2876
+ if (props.selectedItemChanged === undefined) {
2877
+ shouldCallDispatch = props.itemToKey(props.selectedItem) !== props.itemToKey(previousSelectedItemRef.current);
2878
+ } else {
2879
+ console.warn("The \"selectedItemChanged\" is deprecated. Please use \"itemToKey instead\". https://github.com/downshift-js/downshift/blob/master/src/hooks/useCombobox/README.md#selecteditemchanged");
2880
+ shouldCallDispatch = props.selectedItemChanged(previousSelectedItemRef.current, props.selectedItem);
2881
+ }
2882
+ if (shouldCallDispatch) {
2883
+ dispatch({
2884
+ type: ControlledPropUpdatedSelectedItem,
2885
+ inputValue: props.itemToString(props.selectedItem)
2886
+ });
2887
+ }
2870
2888
  }
2871
2889
  previousSelectedItemRef.current = state.selectedItem === previousSelectedItemRef.current ? props.selectedItem : state.selectedItem;
2872
2890
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -2883,9 +2901,6 @@ if (process.env.NODE_ENV !== 'production') {
2883
2901
  };
2884
2902
  }
2885
2903
  var defaultProps$1 = _extends__default["default"]({}, defaultProps$3, {
2886
- selectedItemChanged: function selectedItemChanged(prevItem, item) {
2887
- return prevItem !== item;
2888
- },
2889
2904
  getA11yStatusMessage: getA11yStatusMessage$1,
2890
2905
  isItemDisabled: function isItemDisabled() {
2891
2906
  return false;
@@ -3529,6 +3544,7 @@ var propTypes = _extends__default["default"]({}, commonPropTypes, {
3529
3544
  });
3530
3545
  var defaultProps = {
3531
3546
  itemToString: defaultProps$3.itemToString,
3547
+ itemToKey: defaultProps$3.itemToKey,
3532
3548
  stateReducer: defaultProps$3.stateReducer,
3533
3549
  environment: defaultProps$3.environment,
3534
3550
  getA11yRemovalMessage: getA11yRemovalMessage,
@@ -3643,7 +3659,9 @@ function downshiftMultipleSelectionReducer(state, action) {
3643
3659
  case FunctionRemoveSelectedItem:
3644
3660
  {
3645
3661
  var _newActiveIndex = activeIndex;
3646
- var selectedItemIndex = selectedItems.indexOf(selectedItem);
3662
+ var selectedItemIndex = selectedItems.findIndex(function (item) {
3663
+ return props.itemToKey(item) === props.itemToKey(selectedItem);
3664
+ });
3647
3665
  if (selectedItemIndex < 0) {
3648
3666
  break;
3649
3667
  }
@@ -3727,8 +3745,10 @@ function useMultipleSelection(userProps) {
3727
3745
  return;
3728
3746
  }
3729
3747
  if (selectedItems.length < previousSelectedItemsRef.current.length) {
3730
- var removedSelectedItem = previousSelectedItemsRef.current.find(function (item) {
3731
- return selectedItems.indexOf(item) < 0;
3748
+ var removedSelectedItem = previousSelectedItemsRef.current.find(function (selectedItem) {
3749
+ return selectedItems.findIndex(function (item) {
3750
+ return props.itemToKey(item) === props.itemToKey(selectedItem);
3751
+ }) < 0;
3732
3752
  });
3733
3753
  setStatus(getA11yRemovalMessage({
3734
3754
  itemToString: itemToString,