downshift 8.2.3 → 8.2.4-alpha.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.
@@ -58,9 +58,10 @@ export namespace defaultProps {
58
58
  * @param {Function} reducer Reducer function from downshift.
59
59
  * @param {Object} props The hook props, also passed to createInitialState.
60
60
  * @param {Function} createInitialState Function that returns the initial state.
61
+ * @param {Function} isStateEqual Function that checks if a previous state is equal to the next.
61
62
  * @returns {Array} An array with the state and an action dispatcher.
62
63
  */
63
- export function useControlledReducer(reducer: Function, props: Object, createInitialState: Function): any[];
64
+ export function useControlledReducer(reducer: Function, props: Object, createInitialState: Function, isStateEqual: Function): any[];
64
65
  /**
65
66
  * Computes the controlled state using a the previous state, props,
66
67
  * two reducers, one from downshift and an optional one from the user.
@@ -69,9 +70,10 @@ export function useControlledReducer(reducer: Function, props: Object, createIni
69
70
  * @param {Function} reducer Reducer function from downshift.
70
71
  * @param {Object} props The hook props, also passed to createInitialState.
71
72
  * @param {Function} createInitialState Function that returns the initial state.
73
+ * @param {Function} isStateEqual Function that checks if a previous state is equal to the next.
72
74
  * @returns {Array} An array with the state and an action dispatcher.
73
75
  */
74
- export function useEnhancedReducer(reducer: Function, props: Object, createInitialState: Function): any[];
76
+ export function useEnhancedReducer(reducer: Function, props: Object, createInitialState: Function, isStateEqual: Function): any[];
75
77
  export function useLatestRef(val: any): React.MutableRefObject<any>;
76
78
  export function capitalizeString(string: any): string;
77
79
  export function isAcceptedCharacterKey(key: any): boolean;
@@ -112,6 +114,15 @@ export const useElementIds: (({ id, labelId, menuId, getItemId, toggleButtonId,
112
114
  * @returns The changes for the state.
113
115
  */
114
116
  export function getChangesOnSelection(props: Object, highlightedIndex: number, inputValue?: boolean): any;
117
+ /**
118
+ * Check if a state is equal for dropdowns, by comparing isOpen, inputValue, highlightedIndex and selected item.
119
+ * Used by useSelect and useCombobox.
120
+ *
121
+ * @param {Object} prevState
122
+ * @param {Object} newState
123
+ * @returns {boolean} Wheather the states are deeply equal.
124
+ */
125
+ export function isDropdownsStateEqual(prevState: Object, newState: Object): boolean;
115
126
  export namespace commonDropdownPropTypes {
116
127
  export const getA11yStatusMessage: PropTypes.Requireable<(...args: any[]) => any>;
117
128
  export const highlightedIndex: PropTypes.Requireable<number>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "downshift",
3
- "version": "8.2.3",
3
+ "version": "8.2.4-alpha.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",
@@ -108,6 +108,7 @@
108
108
  "eslint-plugin-react": "7.33.2",
109
109
  "flow-bin": "^0.216.1",
110
110
  "flow-coverage-report": "^0.8.0",
111
+ "formik": "^2.4.5",
111
112
  "get-pkg-repo": "5.0.0",
112
113
  "kcd-scripts": "^14.0.0",
113
114
  "node-polyfill-webpack-plugin": "^2.0.1",
@@ -1658,9 +1658,10 @@ function useLatestRef(val) {
1658
1658
  * @param {Function} reducer Reducer function from downshift.
1659
1659
  * @param {Object} props The hook props, also passed to createInitialState.
1660
1660
  * @param {Function} createInitialState Function that returns the initial state.
1661
+ * @param {Function} isStateEqual Function that checks if a previous state is equal to the next.
1661
1662
  * @returns {Array} An array with the state and an action dispatcher.
1662
1663
  */
1663
- function useEnhancedReducer(reducer, props, createInitialState) {
1664
+ function useEnhancedReducer(reducer, props, createInitialState, isStateEqual) {
1664
1665
  var prevStateRef = React.useRef();
1665
1666
  var actionRef = React.useRef();
1666
1667
  var enhancedReducer = React.useCallback(function (state, action) {
@@ -1683,11 +1684,19 @@ function useEnhancedReducer(reducer, props, createInitialState) {
1683
1684
  }, [propsRef]);
1684
1685
  var action = actionRef.current;
1685
1686
  React.useEffect(function () {
1686
- if (action && prevStateRef.current && prevStateRef.current !== state) {
1687
+ console.log('effect');
1688
+ var shouldCallOnChangeProps = action && prevStateRef.current && !isStateEqual(prevStateRef.current, state);
1689
+ console.log('passed', prevStateRef.current, state);
1690
+ if (shouldCallOnChangeProps) {
1687
1691
  callOnChangeProps(action, getState(prevStateRef.current, action.props), state);
1688
1692
  }
1689
1693
  prevStateRef.current = state;
1690
- }, [state, props, action]);
1694
+ }, [state, action, isStateEqual]);
1695
+ React.useEffect(function () {
1696
+ if (props) {
1697
+ prevStateRef.current = getState(prevStateRef.current, props);
1698
+ }
1699
+ }, [props]);
1691
1700
  return [state, dispatchWithProps];
1692
1701
  }
1693
1702
 
@@ -1698,10 +1707,11 @@ function useEnhancedReducer(reducer, props, createInitialState) {
1698
1707
  * @param {Function} reducer Reducer function from downshift.
1699
1708
  * @param {Object} props The hook props, also passed to createInitialState.
1700
1709
  * @param {Function} createInitialState Function that returns the initial state.
1710
+ * @param {Function} isStateEqual Function that checks if a previous state is equal to the next.
1701
1711
  * @returns {Array} An array with the state and an action dispatcher.
1702
1712
  */
1703
- function useControlledReducer$1(reducer, props, createInitialState) {
1704
- var _useEnhancedReducer = useEnhancedReducer(reducer, props, createInitialState),
1713
+ function useControlledReducer$1(reducer, props, createInitialState, isStateEqual) {
1714
+ var _useEnhancedReducer = useEnhancedReducer(reducer, props, createInitialState, isStateEqual),
1705
1715
  state = _useEnhancedReducer[0],
1706
1716
  dispatch = _useEnhancedReducer[1];
1707
1717
  return [getState(state, props), dispatch];
@@ -1983,6 +1993,18 @@ function getChangesOnSelection(props, highlightedIndex, inputValue) {
1983
1993
  }));
1984
1994
  }
1985
1995
 
1996
+ /**
1997
+ * Check if a state is equal for dropdowns, by comparing isOpen, inputValue, highlightedIndex and selected item.
1998
+ * Used by useSelect and useCombobox.
1999
+ *
2000
+ * @param {Object} prevState
2001
+ * @param {Object} newState
2002
+ * @returns {boolean} Wheather the states are deeply equal.
2003
+ */
2004
+ function isDropdownsStateEqual(prevState, newState) {
2005
+ return prevState.isOpen === newState.isOpen && prevState.inputValue === newState.inputValue && prevState.highlightedIndex === newState.highlightedIndex && prevState.selectedItem === newState.selectedItem;
2006
+ }
2007
+
1986
2008
  // Shared between all exports.
1987
2009
  var commonPropTypes = {
1988
2010
  environment: PropTypes__default["default"].shape({
@@ -2305,14 +2327,13 @@ function useSelect(userProps) {
2305
2327
  getA11ySelectionMessage = props.getA11ySelectionMessage,
2306
2328
  getA11yStatusMessage = props.getA11yStatusMessage;
2307
2329
  // Initial state depending on controlled props.
2308
- var _useControlledReducer = useControlledReducer$1(downshiftSelectReducer, props, getInitialState$2),
2330
+ var _useControlledReducer = useControlledReducer$1(downshiftSelectReducer, props, getInitialState$2, isDropdownsStateEqual),
2309
2331
  state = _useControlledReducer[0],
2310
2332
  dispatch = _useControlledReducer[1];
2311
2333
  var isOpen = state.isOpen,
2312
2334
  highlightedIndex = state.highlightedIndex,
2313
2335
  selectedItem = state.selectedItem,
2314
2336
  inputValue = state.inputValue;
2315
-
2316
2337
  // Element efs.
2317
2338
  var toggleButtonRef = React.useRef(null);
2318
2339
  var menuRef = React.useRef(null);
@@ -2790,11 +2811,12 @@ var propTypes$1 = _extends__default["default"]({}, commonDropdownPropTypes, {
2790
2811
  * @param {Function} reducer Reducer function from downshift.
2791
2812
  * @param {Object} props The hook props, also passed to createInitialState.
2792
2813
  * @param {Function} createInitialState Function that returns the initial state.
2814
+ * @param {Function} isStateEqual Function that checks if a previous state is equal to the next.
2793
2815
  * @returns {Array} An array with the state and an action dispatcher.
2794
2816
  */
2795
- function useControlledReducer(reducer, props, createInitialState) {
2817
+ function useControlledReducer(reducer, props, createInitialState, isStateEqual) {
2796
2818
  var previousSelectedItemRef = React.useRef();
2797
- var _useEnhancedReducer = useEnhancedReducer(reducer, props, createInitialState),
2819
+ var _useEnhancedReducer = useEnhancedReducer(reducer, props, createInitialState, isStateEqual),
2798
2820
  state = _useEnhancedReducer[0],
2799
2821
  dispatch = _useEnhancedReducer[1];
2800
2822
 
@@ -2968,7 +2990,7 @@ function useCombobox(userProps) {
2968
2990
  getA11ySelectionMessage = props.getA11ySelectionMessage,
2969
2991
  itemToString = props.itemToString;
2970
2992
  // Initial state depending on controlled props.
2971
- var _useControlledReducer = useControlledReducer(downshiftUseComboboxReducer, props, getInitialState$1),
2993
+ var _useControlledReducer = useControlledReducer(downshiftUseComboboxReducer, props, getInitialState$1, isDropdownsStateEqual),
2972
2994
  state = _useControlledReducer[0],
2973
2995
  dispatch = _useControlledReducer[1];
2974
2996
  var isOpen = state.isOpen,
@@ -3453,6 +3475,18 @@ function getA11yRemovalMessage(selectionParameters) {
3453
3475
  itemToStringLocal = selectionParameters.itemToString;
3454
3476
  return itemToStringLocal(removedSelectedItem) + " has been removed.";
3455
3477
  }
3478
+
3479
+ /**
3480
+ * Check if a state is equal for taglist, by comparing active index and selected items.
3481
+ * Used by useSelect and useCombobox.
3482
+ *
3483
+ * @param {Object} prevState
3484
+ * @param {Object} newState
3485
+ * @returns {boolean} Wheather the states are deeply equal.
3486
+ */
3487
+ function isStateEqual(prevState, newState) {
3488
+ return prevState.selectedItems === newState.selectedItems && prevState.activeIndex === newState.activeIndex;
3489
+ }
3456
3490
  var propTypes = _extends__default["default"]({}, commonPropTypes, {
3457
3491
  selectedItems: PropTypes__default["default"].array,
3458
3492
  initialSelectedItems: PropTypes__default["default"].array,
@@ -3642,7 +3676,7 @@ function useMultipleSelection(userProps) {
3642
3676
  keyNavigationPrevious = props.keyNavigationPrevious;
3643
3677
 
3644
3678
  // Reducer init.
3645
- var _useControlledReducer = useControlledReducer$1(downshiftMultipleSelectionReducer, props, getInitialState),
3679
+ var _useControlledReducer = useControlledReducer$1(downshiftMultipleSelectionReducer, props, getInitialState, isStateEqual),
3646
3680
  state = _useControlledReducer[0],
3647
3681
  dispatch = _useControlledReducer[1];
3648
3682
  var activeIndex = state.activeIndex,
@@ -1645,9 +1645,10 @@ function useLatestRef(val) {
1645
1645
  * @param {Function} reducer Reducer function from downshift.
1646
1646
  * @param {Object} props The hook props, also passed to createInitialState.
1647
1647
  * @param {Function} createInitialState Function that returns the initial state.
1648
+ * @param {Function} isStateEqual Function that checks if a previous state is equal to the next.
1648
1649
  * @returns {Array} An array with the state and an action dispatcher.
1649
1650
  */
1650
- function useEnhancedReducer(reducer, props, createInitialState) {
1651
+ function useEnhancedReducer(reducer, props, createInitialState, isStateEqual) {
1651
1652
  var prevStateRef = useRef();
1652
1653
  var actionRef = useRef();
1653
1654
  var enhancedReducer = useCallback(function (state, action) {
@@ -1670,11 +1671,19 @@ function useEnhancedReducer(reducer, props, createInitialState) {
1670
1671
  }, [propsRef]);
1671
1672
  var action = actionRef.current;
1672
1673
  useEffect(function () {
1673
- if (action && prevStateRef.current && prevStateRef.current !== state) {
1674
+ console.log('effect');
1675
+ var shouldCallOnChangeProps = action && prevStateRef.current && !isStateEqual(prevStateRef.current, state);
1676
+ console.log('passed', prevStateRef.current, state);
1677
+ if (shouldCallOnChangeProps) {
1674
1678
  callOnChangeProps(action, getState(prevStateRef.current, action.props), state);
1675
1679
  }
1676
1680
  prevStateRef.current = state;
1677
- }, [state, props, action]);
1681
+ }, [state, action, isStateEqual]);
1682
+ useEffect(function () {
1683
+ if (props) {
1684
+ prevStateRef.current = getState(prevStateRef.current, props);
1685
+ }
1686
+ }, [props]);
1678
1687
  return [state, dispatchWithProps];
1679
1688
  }
1680
1689
 
@@ -1685,10 +1694,11 @@ function useEnhancedReducer(reducer, props, createInitialState) {
1685
1694
  * @param {Function} reducer Reducer function from downshift.
1686
1695
  * @param {Object} props The hook props, also passed to createInitialState.
1687
1696
  * @param {Function} createInitialState Function that returns the initial state.
1697
+ * @param {Function} isStateEqual Function that checks if a previous state is equal to the next.
1688
1698
  * @returns {Array} An array with the state and an action dispatcher.
1689
1699
  */
1690
- function useControlledReducer$1(reducer, props, createInitialState) {
1691
- var _useEnhancedReducer = useEnhancedReducer(reducer, props, createInitialState),
1700
+ function useControlledReducer$1(reducer, props, createInitialState, isStateEqual) {
1701
+ var _useEnhancedReducer = useEnhancedReducer(reducer, props, createInitialState, isStateEqual),
1692
1702
  state = _useEnhancedReducer[0],
1693
1703
  dispatch = _useEnhancedReducer[1];
1694
1704
  return [getState(state, props), dispatch];
@@ -1970,6 +1980,18 @@ function getChangesOnSelection(props, highlightedIndex, inputValue) {
1970
1980
  }));
1971
1981
  }
1972
1982
 
1983
+ /**
1984
+ * Check if a state is equal for dropdowns, by comparing isOpen, inputValue, highlightedIndex and selected item.
1985
+ * Used by useSelect and useCombobox.
1986
+ *
1987
+ * @param {Object} prevState
1988
+ * @param {Object} newState
1989
+ * @returns {boolean} Wheather the states are deeply equal.
1990
+ */
1991
+ function isDropdownsStateEqual(prevState, newState) {
1992
+ return prevState.isOpen === newState.isOpen && prevState.inputValue === newState.inputValue && prevState.highlightedIndex === newState.highlightedIndex && prevState.selectedItem === newState.selectedItem;
1993
+ }
1994
+
1973
1995
  // Shared between all exports.
1974
1996
  var commonPropTypes = {
1975
1997
  environment: PropTypes.shape({
@@ -2292,14 +2314,13 @@ function useSelect(userProps) {
2292
2314
  getA11ySelectionMessage = props.getA11ySelectionMessage,
2293
2315
  getA11yStatusMessage = props.getA11yStatusMessage;
2294
2316
  // Initial state depending on controlled props.
2295
- var _useControlledReducer = useControlledReducer$1(downshiftSelectReducer, props, getInitialState$2),
2317
+ var _useControlledReducer = useControlledReducer$1(downshiftSelectReducer, props, getInitialState$2, isDropdownsStateEqual),
2296
2318
  state = _useControlledReducer[0],
2297
2319
  dispatch = _useControlledReducer[1];
2298
2320
  var isOpen = state.isOpen,
2299
2321
  highlightedIndex = state.highlightedIndex,
2300
2322
  selectedItem = state.selectedItem,
2301
2323
  inputValue = state.inputValue;
2302
-
2303
2324
  // Element efs.
2304
2325
  var toggleButtonRef = useRef(null);
2305
2326
  var menuRef = useRef(null);
@@ -2777,11 +2798,12 @@ var propTypes$1 = _extends({}, commonDropdownPropTypes, {
2777
2798
  * @param {Function} reducer Reducer function from downshift.
2778
2799
  * @param {Object} props The hook props, also passed to createInitialState.
2779
2800
  * @param {Function} createInitialState Function that returns the initial state.
2801
+ * @param {Function} isStateEqual Function that checks if a previous state is equal to the next.
2780
2802
  * @returns {Array} An array with the state and an action dispatcher.
2781
2803
  */
2782
- function useControlledReducer(reducer, props, createInitialState) {
2804
+ function useControlledReducer(reducer, props, createInitialState, isStateEqual) {
2783
2805
  var previousSelectedItemRef = useRef();
2784
- var _useEnhancedReducer = useEnhancedReducer(reducer, props, createInitialState),
2806
+ var _useEnhancedReducer = useEnhancedReducer(reducer, props, createInitialState, isStateEqual),
2785
2807
  state = _useEnhancedReducer[0],
2786
2808
  dispatch = _useEnhancedReducer[1];
2787
2809
 
@@ -2955,7 +2977,7 @@ function useCombobox(userProps) {
2955
2977
  getA11ySelectionMessage = props.getA11ySelectionMessage,
2956
2978
  itemToString = props.itemToString;
2957
2979
  // Initial state depending on controlled props.
2958
- var _useControlledReducer = useControlledReducer(downshiftUseComboboxReducer, props, getInitialState$1),
2980
+ var _useControlledReducer = useControlledReducer(downshiftUseComboboxReducer, props, getInitialState$1, isDropdownsStateEqual),
2959
2981
  state = _useControlledReducer[0],
2960
2982
  dispatch = _useControlledReducer[1];
2961
2983
  var isOpen = state.isOpen,
@@ -3440,6 +3462,18 @@ function getA11yRemovalMessage(selectionParameters) {
3440
3462
  itemToStringLocal = selectionParameters.itemToString;
3441
3463
  return itemToStringLocal(removedSelectedItem) + " has been removed.";
3442
3464
  }
3465
+
3466
+ /**
3467
+ * Check if a state is equal for taglist, by comparing active index and selected items.
3468
+ * Used by useSelect and useCombobox.
3469
+ *
3470
+ * @param {Object} prevState
3471
+ * @param {Object} newState
3472
+ * @returns {boolean} Wheather the states are deeply equal.
3473
+ */
3474
+ function isStateEqual(prevState, newState) {
3475
+ return prevState.selectedItems === newState.selectedItems && prevState.activeIndex === newState.activeIndex;
3476
+ }
3443
3477
  var propTypes = _extends({}, commonPropTypes, {
3444
3478
  selectedItems: PropTypes.array,
3445
3479
  initialSelectedItems: PropTypes.array,
@@ -3629,7 +3663,7 @@ function useMultipleSelection(userProps) {
3629
3663
  keyNavigationPrevious = props.keyNavigationPrevious;
3630
3664
 
3631
3665
  // Reducer init.
3632
- var _useControlledReducer = useControlledReducer$1(downshiftMultipleSelectionReducer, props, getInitialState),
3666
+ var _useControlledReducer = useControlledReducer$1(downshiftMultipleSelectionReducer, props, getInitialState, isStateEqual),
3633
3667
  state = _useControlledReducer[0],
3634
3668
  dispatch = _useControlledReducer[1];
3635
3669
  var activeIndex = state.activeIndex,
@@ -295,7 +295,7 @@
295
295
 
296
296
  var reactIsExports = reactIs.exports;
297
297
 
298
- const t=t=>"object"==typeof t&&null!=t&&1===t.nodeType,e=(t,e)=>(!e||"hidden"!==t)&&("visible"!==t&&"clip"!==t),n=(t,n)=>{if(t.clientHeight<t.scrollHeight||t.clientWidth<t.scrollWidth){const o=getComputedStyle(t,null);return e(o.overflowY,n)||e(o.overflowX,n)||(t=>{const e=(t=>{if(!t.ownerDocument||!t.ownerDocument.defaultView)return null;try{return t.ownerDocument.defaultView.frameElement}catch(t){return null}})(t);return !!e&&(e.clientHeight<t.scrollHeight||e.clientWidth<t.scrollWidth)})(t)}return !1},o=(t,e,n,o,l,r,i,s)=>r<t&&i>e||r>t&&i<e?0:r<=t&&s<=n||i>=e&&s>=n?r-t-o:i>e&&s<n||r<t&&s>n?i-e+l:0,l=t=>{const e=t.parentElement;return null==e?t.getRootNode().host||null:e},r=(e,r)=>{var i,s,d,h;if("undefined"==typeof document)return [];const{scrollMode:c,block:f,inline:u,boundary:a,skipOverflowHiddenElements:g}=r,p="function"==typeof a?a:t=>t!==a;if(!t(e))throw new TypeError("Invalid target");const m=document.scrollingElement||document.documentElement,w=[];let W=e;for(;t(W)&&p(W);){if(W=l(W),W===m){w.push(W);break}null!=W&&W===document.body&&n(W)&&!n(document.documentElement)||null!=W&&n(W,g)&&w.push(W);}const b=null!=(s=null==(i=window.visualViewport)?void 0:i.width)?s:innerWidth,H=null!=(h=null==(d=window.visualViewport)?void 0:d.height)?h:innerHeight,{scrollX:y,scrollY:M}=window,{height:v,width:E,top:x,right:C,bottom:I,left:R}=e.getBoundingClientRect(),{top:T,right:B,bottom:F,left:V}=(t=>{const e=window.getComputedStyle(t);return {top:parseFloat(e.scrollMarginTop)||0,right:parseFloat(e.scrollMarginRight)||0,bottom:parseFloat(e.scrollMarginBottom)||0,left:parseFloat(e.scrollMarginLeft)||0}})(e);let k="start"===f||"nearest"===f?x-T:"end"===f?I+F:x+v/2-T+F,D="center"===u?R+E/2-V+B:"end"===u?C+B:R-V;const L=[];for(let t=0;t<w.length;t++){const e=w[t],{height:n,width:l,top:r,right:i,bottom:s,left:d}=e.getBoundingClientRect();if("if-needed"===c&&x>=0&&R>=0&&I<=H&&C<=b&&x>=r&&I<=s&&R>=d&&C<=i)return L;const h=getComputedStyle(e),a=parseInt(h.borderLeftWidth,10),g=parseInt(h.borderTopWidth,10),p=parseInt(h.borderRightWidth,10),W=parseInt(h.borderBottomWidth,10);let T=0,B=0;const F="offsetWidth"in e?e.offsetWidth-e.clientWidth-a-p:0,V="offsetHeight"in e?e.offsetHeight-e.clientHeight-g-W:0,S="offsetWidth"in e?0===e.offsetWidth?0:l/e.offsetWidth:0,X="offsetHeight"in e?0===e.offsetHeight?0:n/e.offsetHeight:0;if(m===e)T="start"===f?k:"end"===f?k-H:"nearest"===f?o(M,M+H,H,g,W,M+k,M+k+v,v):k-H/2,B="start"===u?D:"center"===u?D-b/2:"end"===u?D-b:o(y,y+b,b,a,p,y+D,y+D+E,E),T=Math.max(0,T+M),B=Math.max(0,B+y);else {T="start"===f?k-r-g:"end"===f?k-s+W+V:"nearest"===f?o(r,s,n,g,W+V,k,k+v,v):k-(r+n/2)+V/2,B="start"===u?D-d-a:"center"===u?D-(d+l/2)+F/2:"end"===u?D-i+p+F:o(d,i,l,a,p+F,D,D+E,E);const{scrollLeft:t,scrollTop:h}=e;T=0===X?0:Math.max(0,Math.min(h+T/X,e.scrollHeight-n/X+V)),B=0===S?0:Math.max(0,Math.min(t+B/S,e.scrollWidth-l/S+F)),k+=h-T,D+=t-B;}L.push({el:e,top:T,left:B});}return L};
298
+ const t=t=>"object"==typeof t&&null!=t&&1===t.nodeType,e=(t,e)=>(!e||"hidden"!==t)&&("visible"!==t&&"clip"!==t),n=(t,n)=>{if(t.clientHeight<t.scrollHeight||t.clientWidth<t.scrollWidth){const o=getComputedStyle(t,null);return e(o.overflowY,n)||e(o.overflowX,n)||(t=>{const e=(t=>{if(!t.ownerDocument||!t.ownerDocument.defaultView)return null;try{return t.ownerDocument.defaultView.frameElement}catch(t){return null}})(t);return !!e&&(e.clientHeight<t.scrollHeight||e.clientWidth<t.scrollWidth)})(t)}return !1},o=(t,e,n,o,i,l,r,d)=>l<t&&r>e||l>t&&r<e?0:l<=t&&d<=n||r>=e&&d>=n?l-t-o:r>e&&d<n||l<t&&d>n?r-e+i:0,i=t=>{const e=t.parentElement;return null==e?t.getRootNode().host||null:e},l=(e,l)=>{var r,d,s,h;if("undefined"==typeof document)return [];const{scrollMode:c,block:f,inline:u,boundary:a,skipOverflowHiddenElements:g}=l,m="function"==typeof a?a:t=>t!==a;if(!t(e))throw new TypeError("Invalid target");const p=document.scrollingElement||document.documentElement,w=[];let W=e;for(;t(W)&&m(W);){if(W=i(W),W===p){w.push(W);break}null!=W&&W===document.body&&n(W)&&!n(document.documentElement)||null!=W&&n(W,g)&&w.push(W);}const H=null!=(d=null==(r=window.visualViewport)?void 0:r.width)?d:innerWidth,b=null!=(h=null==(s=window.visualViewport)?void 0:s.height)?h:innerHeight,{scrollX:v,scrollY:y}=window,{height:E,width:M,top:x,right:I,bottom:C,left:R}=e.getBoundingClientRect();let T="start"===f||"nearest"===f?x:"end"===f?C:x+E/2,V="center"===u?R+M/2:"end"===u?I:R;const k=[];for(let t=0;t<w.length;t++){const e=w[t],{height:n,width:i,top:l,right:r,bottom:d,left:s}=e.getBoundingClientRect();if("if-needed"===c&&x>=0&&R>=0&&C<=b&&I<=H&&x>=l&&C<=d&&R>=s&&I<=r)return k;const h=getComputedStyle(e),a=parseInt(h.borderLeftWidth,10),g=parseInt(h.borderTopWidth,10),m=parseInt(h.borderRightWidth,10),W=parseInt(h.borderBottomWidth,10);let B=0,D=0;const L="offsetWidth"in e?e.offsetWidth-e.clientWidth-a-m:0,S="offsetHeight"in e?e.offsetHeight-e.clientHeight-g-W:0,X="offsetWidth"in e?0===e.offsetWidth?0:i/e.offsetWidth:0,Y="offsetHeight"in e?0===e.offsetHeight?0:n/e.offsetHeight:0;if(p===e)B="start"===f?T:"end"===f?T-b:"nearest"===f?o(y,y+b,b,g,W,y+T,y+T+E,E):T-b/2,D="start"===u?V:"center"===u?V-H/2:"end"===u?V-H:o(v,v+H,H,a,m,v+V,v+V+M,M),B=Math.max(0,B+y),D=Math.max(0,D+v);else {B="start"===f?T-l-g:"end"===f?T-d+W+S:"nearest"===f?o(l,d,n,g,W+S,T,T+E,E):T-(l+n/2)+S/2,D="start"===u?V-s-a:"center"===u?V-(s+i/2)+L/2:"end"===u?V-r+m+L:o(s,r,i,a,m+L,V,V+M,M);const{scrollLeft:t,scrollTop:h}=e;B=Math.max(0,Math.min(h+B/Y,e.scrollHeight-n/Y+S)),D=Math.max(0,Math.min(t+D/X,e.scrollWidth-i/X+L)),T+=h-B,V+=t-D;}k.push({el:e,top:B,left:D});}return k};
299
299
 
300
300
  var idCounter = 0;
301
301
 
@@ -321,7 +321,7 @@
321
321
  if (!node) {
322
322
  return;
323
323
  }
324
- var actions = r(node, {
324
+ var actions = l(node, {
325
325
  boundary: menuNode,
326
326
  block: 'nearest',
327
327
  scrollMode: 'if-needed'
@@ -1927,9 +1927,10 @@
1927
1927
  * @param {Function} reducer Reducer function from downshift.
1928
1928
  * @param {Object} props The hook props, also passed to createInitialState.
1929
1929
  * @param {Function} createInitialState Function that returns the initial state.
1930
+ * @param {Function} isStateEqual Function that checks if a previous state is equal to the next.
1930
1931
  * @returns {Array} An array with the state and an action dispatcher.
1931
1932
  */
1932
- function useEnhancedReducer(reducer, props, createInitialState) {
1933
+ function useEnhancedReducer(reducer, props, createInitialState, isStateEqual) {
1933
1934
  var prevStateRef = React.useRef();
1934
1935
  var actionRef = React.useRef();
1935
1936
  var enhancedReducer = React.useCallback(function (state, action) {
@@ -1952,11 +1953,19 @@
1952
1953
  }, [propsRef]);
1953
1954
  var action = actionRef.current;
1954
1955
  React.useEffect(function () {
1955
- if (action && prevStateRef.current && prevStateRef.current !== state) {
1956
+ console.log('effect');
1957
+ var shouldCallOnChangeProps = action && prevStateRef.current && !isStateEqual(prevStateRef.current, state);
1958
+ console.log('passed', prevStateRef.current, state);
1959
+ if (shouldCallOnChangeProps) {
1956
1960
  callOnChangeProps(action, getState(prevStateRef.current, action.props), state);
1957
1961
  }
1958
1962
  prevStateRef.current = state;
1959
- }, [state, props, action]);
1963
+ }, [state, action, isStateEqual]);
1964
+ React.useEffect(function () {
1965
+ if (props) {
1966
+ prevStateRef.current = getState(prevStateRef.current, props);
1967
+ }
1968
+ }, [props]);
1960
1969
  return [state, dispatchWithProps];
1961
1970
  }
1962
1971
 
@@ -1967,10 +1976,11 @@
1967
1976
  * @param {Function} reducer Reducer function from downshift.
1968
1977
  * @param {Object} props The hook props, also passed to createInitialState.
1969
1978
  * @param {Function} createInitialState Function that returns the initial state.
1979
+ * @param {Function} isStateEqual Function that checks if a previous state is equal to the next.
1970
1980
  * @returns {Array} An array with the state and an action dispatcher.
1971
1981
  */
1972
- function useControlledReducer$1(reducer, props, createInitialState) {
1973
- var _useEnhancedReducer = useEnhancedReducer(reducer, props, createInitialState),
1982
+ function useControlledReducer$1(reducer, props, createInitialState, isStateEqual) {
1983
+ var _useEnhancedReducer = useEnhancedReducer(reducer, props, createInitialState, isStateEqual),
1974
1984
  state = _useEnhancedReducer[0],
1975
1985
  dispatch = _useEnhancedReducer[1];
1976
1986
  return [getState(state, props), dispatch];
@@ -2252,6 +2262,18 @@
2252
2262
  }));
2253
2263
  }
2254
2264
 
2265
+ /**
2266
+ * Check if a state is equal for dropdowns, by comparing isOpen, inputValue, highlightedIndex and selected item.
2267
+ * Used by useSelect and useCombobox.
2268
+ *
2269
+ * @param {Object} prevState
2270
+ * @param {Object} newState
2271
+ * @returns {boolean} Wheather the states are deeply equal.
2272
+ */
2273
+ function isDropdownsStateEqual(prevState, newState) {
2274
+ return prevState.isOpen === newState.isOpen && prevState.inputValue === newState.inputValue && prevState.highlightedIndex === newState.highlightedIndex && prevState.selectedItem === newState.selectedItem;
2275
+ }
2276
+
2255
2277
  // Shared between all exports.
2256
2278
  var commonPropTypes = {
2257
2279
  environment: PropTypes__default["default"].shape({
@@ -2605,14 +2627,13 @@
2605
2627
  getA11ySelectionMessage = props.getA11ySelectionMessage,
2606
2628
  getA11yStatusMessage = props.getA11yStatusMessage;
2607
2629
  // Initial state depending on controlled props.
2608
- var _useControlledReducer = useControlledReducer$1(downshiftSelectReducer, props, getInitialState$2),
2630
+ var _useControlledReducer = useControlledReducer$1(downshiftSelectReducer, props, getInitialState$2, isDropdownsStateEqual),
2609
2631
  state = _useControlledReducer[0],
2610
2632
  dispatch = _useControlledReducer[1];
2611
2633
  var isOpen = state.isOpen,
2612
2634
  highlightedIndex = state.highlightedIndex,
2613
2635
  selectedItem = state.selectedItem,
2614
2636
  inputValue = state.inputValue;
2615
-
2616
2637
  // Element efs.
2617
2638
  var toggleButtonRef = React.useRef(null);
2618
2639
  var menuRef = React.useRef(null);
@@ -3090,11 +3111,12 @@
3090
3111
  * @param {Function} reducer Reducer function from downshift.
3091
3112
  * @param {Object} props The hook props, also passed to createInitialState.
3092
3113
  * @param {Function} createInitialState Function that returns the initial state.
3114
+ * @param {Function} isStateEqual Function that checks if a previous state is equal to the next.
3093
3115
  * @returns {Array} An array with the state and an action dispatcher.
3094
3116
  */
3095
- function useControlledReducer(reducer, props, createInitialState) {
3117
+ function useControlledReducer(reducer, props, createInitialState, isStateEqual) {
3096
3118
  var previousSelectedItemRef = React.useRef();
3097
- var _useEnhancedReducer = useEnhancedReducer(reducer, props, createInitialState),
3119
+ var _useEnhancedReducer = useEnhancedReducer(reducer, props, createInitialState, isStateEqual),
3098
3120
  state = _useEnhancedReducer[0],
3099
3121
  dispatch = _useEnhancedReducer[1];
3100
3122
 
@@ -3268,7 +3290,7 @@
3268
3290
  getA11ySelectionMessage = props.getA11ySelectionMessage,
3269
3291
  itemToString = props.itemToString;
3270
3292
  // Initial state depending on controlled props.
3271
- var _useControlledReducer = useControlledReducer(downshiftUseComboboxReducer, props, getInitialState$1),
3293
+ var _useControlledReducer = useControlledReducer(downshiftUseComboboxReducer, props, getInitialState$1, isDropdownsStateEqual),
3272
3294
  state = _useControlledReducer[0],
3273
3295
  dispatch = _useControlledReducer[1];
3274
3296
  var isOpen = state.isOpen,
@@ -3753,6 +3775,18 @@
3753
3775
  itemToStringLocal = selectionParameters.itemToString;
3754
3776
  return itemToStringLocal(removedSelectedItem) + " has been removed.";
3755
3777
  }
3778
+
3779
+ /**
3780
+ * Check if a state is equal for taglist, by comparing active index and selected items.
3781
+ * Used by useSelect and useCombobox.
3782
+ *
3783
+ * @param {Object} prevState
3784
+ * @param {Object} newState
3785
+ * @returns {boolean} Wheather the states are deeply equal.
3786
+ */
3787
+ function isStateEqual(prevState, newState) {
3788
+ return prevState.selectedItems === newState.selectedItems && prevState.activeIndex === newState.activeIndex;
3789
+ }
3756
3790
  var propTypes = _extends({}, commonPropTypes, {
3757
3791
  selectedItems: PropTypes__default["default"].array,
3758
3792
  initialSelectedItems: PropTypes__default["default"].array,
@@ -3942,7 +3976,7 @@
3942
3976
  keyNavigationPrevious = props.keyNavigationPrevious;
3943
3977
 
3944
3978
  // Reducer init.
3945
- var _useControlledReducer = useControlledReducer$1(downshiftMultipleSelectionReducer, props, getInitialState),
3979
+ var _useControlledReducer = useControlledReducer$1(downshiftMultipleSelectionReducer, props, getInitialState, isStateEqual),
3946
3980
  state = _useControlledReducer[0],
3947
3981
  dispatch = _useControlledReducer[1];
3948
3982
  var activeIndex = state.activeIndex,