downshift 7.2.1 → 7.2.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.
package/README.md CHANGED
@@ -57,7 +57,7 @@ has been around for a while. It established a successful pattern for making
57
57
  components accessible and functional while giving developers complete freedom
58
58
  when building the UI.
59
59
 
60
- Both _useSelect_ and _useCombobox_ support he latest ARIA combobox patterns for
60
+ Both _useSelect_ and _useCombobox_ support the latest ARIA combobox patterns for
61
61
  W3C, which _Downshift_ does not. Consequently, we strongly recommend the you use
62
62
  the hooks. The hooks have been migrated to the ARIA 1.2 combobox pattern in the
63
63
  version 7 of _downshift_. There is a [Migration Guide][migration-guide-v7] that
@@ -1773,8 +1773,11 @@ function useMouseAndTouchTracker(isOpen, downshiftElementRefs, environment, hand
1773
1773
  isTouchMove: false
1774
1774
  });
1775
1775
  react.useEffect(function () {
1776
+ if ((environment == null ? void 0 : environment.addEventListener) == null) {
1777
+ return;
1778
+ }
1776
1779
 
1777
- // The same strategy for checking if a click occurred inside or outside downsift
1780
+ // The same strategy for checking if a click occurred inside or outside downshift
1778
1781
  // as in downshift.js.
1779
1782
  var onMouseDown = function onMouseDown() {
1780
1783
  mouseAndTouchTrackersRef.current.isMouseDown = true;
@@ -3038,13 +3041,14 @@ function useCombobox(userProps) {
3038
3041
  }, []);
3039
3042
  // Reset itemRefs on close.
3040
3043
  react.useEffect(function () {
3044
+ var _environment$document;
3041
3045
  if (!isOpen) {
3042
3046
  itemRefs.current = {};
3043
- } else if (document.activeElement !== inputRef.current) {
3047
+ } else if (((_environment$document = environment.document) == null ? void 0 : _environment$document.activeElement) !== inputRef.current) {
3044
3048
  var _inputRef$current;
3045
3049
  inputRef == null ? void 0 : (_inputRef$current = inputRef.current) == null ? void 0 : _inputRef$current.focus();
3046
3050
  }
3047
- }, [isOpen]);
3051
+ }, [isOpen, environment]);
3048
3052
 
3049
3053
  /* Event handler functions */
3050
3054
  var inputKeyDownHandlers = react.useMemo(function () {
@@ -1760,8 +1760,11 @@ function useMouseAndTouchTracker(isOpen, downshiftElementRefs, environment, hand
1760
1760
  isTouchMove: false
1761
1761
  });
1762
1762
  useEffect(function () {
1763
+ if ((environment == null ? void 0 : environment.addEventListener) == null) {
1764
+ return;
1765
+ }
1763
1766
 
1764
- // The same strategy for checking if a click occurred inside or outside downsift
1767
+ // The same strategy for checking if a click occurred inside or outside downshift
1765
1768
  // as in downshift.js.
1766
1769
  var onMouseDown = function onMouseDown() {
1767
1770
  mouseAndTouchTrackersRef.current.isMouseDown = true;
@@ -3025,13 +3028,14 @@ function useCombobox(userProps) {
3025
3028
  }, []);
3026
3029
  // Reset itemRefs on close.
3027
3030
  useEffect(function () {
3031
+ var _environment$document;
3028
3032
  if (!isOpen) {
3029
3033
  itemRefs.current = {};
3030
- } else if (document.activeElement !== inputRef.current) {
3034
+ } else if (((_environment$document = environment.document) == null ? void 0 : _environment$document.activeElement) !== inputRef.current) {
3031
3035
  var _inputRef$current;
3032
3036
  inputRef == null ? void 0 : (_inputRef$current = inputRef.current) == null ? void 0 : _inputRef$current.focus();
3033
3037
  }
3034
- }, [isOpen]);
3038
+ }, [isOpen, environment]);
3035
3039
 
3036
3040
  /* Event handler functions */
3037
3041
  var inputKeyDownHandlers = useMemo(function () {
@@ -59,6 +59,17 @@ function scrollIntoView(node, menuNode) {
59
59
  });
60
60
  }
61
61
 
62
+ /**
63
+ * @param {HTMLElement} parent the parent node
64
+ * @param {HTMLElement} child the child node
65
+ * @param {Window} environment The window context where downshift renders.
66
+ * @return {Boolean} whether the parent is the child or the child is in the parent
67
+ */
68
+ function isOrContainsNode(parent, child, environment) {
69
+ var result = parent === child || child instanceof environment.Node && parent.contains && parent.contains(child);
70
+ return result;
71
+ }
72
+
62
73
  /**
63
74
  * Simple debounce implementation. Will call the given
64
75
  * function once after the time given has passed since
@@ -351,6 +362,25 @@ function getNextNonDisabledIndex(moveAmount, baseIndex, itemCount, getItemNodeFr
351
362
  return -1;
352
363
  }
353
364
 
365
+ /**
366
+ * Checks if event target is within the downshift elements.
367
+ *
368
+ * @param {EventTarget} target Target to check.
369
+ * @param {HTMLElement[]} downshiftElements The elements that form downshift (list, toggle button etc).
370
+ * @param {Window} environment The window context where downshift renders.
371
+ * @param {boolean} checkActiveElement Whether to also check activeElement.
372
+ *
373
+ * @returns {boolean} Whether or not the target is within downshift elements.
374
+ */
375
+ function targetWithinDownshift(target, downshiftElements, environment, checkActiveElement) {
376
+ if (checkActiveElement === void 0) {
377
+ checkActiveElement = true;
378
+ }
379
+ return downshiftElements.some(function (contextNode) {
380
+ return contextNode && (isOrContainsNode(contextNode, target, environment) || checkActiveElement && isOrContainsNode(contextNode, environment.document.activeElement, environment));
381
+ });
382
+ }
383
+
354
384
  // eslint-disable-next-line import/no-mutable-exports
355
385
  var validateControlledUnchanged = noop;
356
386
  /* istanbul ignore next */
@@ -1681,10 +1711,50 @@ function useMouseAndTouchTracker(isOpen, downshiftElementRefs, environment, hand
1681
1711
  isTouchMove: false
1682
1712
  });
1683
1713
  react.useEffect(function () {
1684
- /* istanbul ignore if (react-native) */
1685
- {
1714
+ if ((environment == null ? void 0 : environment.addEventListener) == null) {
1686
1715
  return;
1687
1716
  }
1717
+
1718
+ // The same strategy for checking if a click occurred inside or outside downshift
1719
+ // as in downshift.js.
1720
+ var onMouseDown = function onMouseDown() {
1721
+ mouseAndTouchTrackersRef.current.isMouseDown = true;
1722
+ };
1723
+ var onMouseUp = function onMouseUp(event) {
1724
+ mouseAndTouchTrackersRef.current.isMouseDown = false;
1725
+ if (isOpen && !targetWithinDownshift(event.target, downshiftElementRefs.map(function (ref) {
1726
+ return ref.current;
1727
+ }), environment)) {
1728
+ handleBlur();
1729
+ }
1730
+ };
1731
+ var onTouchStart = function onTouchStart() {
1732
+ mouseAndTouchTrackersRef.current.isTouchMove = false;
1733
+ };
1734
+ var onTouchMove = function onTouchMove() {
1735
+ mouseAndTouchTrackersRef.current.isTouchMove = true;
1736
+ };
1737
+ var onTouchEnd = function onTouchEnd(event) {
1738
+ if (isOpen && !mouseAndTouchTrackersRef.current.isTouchMove && !targetWithinDownshift(event.target, downshiftElementRefs.map(function (ref) {
1739
+ return ref.current;
1740
+ }), environment, false)) {
1741
+ handleBlur();
1742
+ }
1743
+ };
1744
+ environment.addEventListener('mousedown', onMouseDown);
1745
+ environment.addEventListener('mouseup', onMouseUp);
1746
+ environment.addEventListener('touchstart', onTouchStart);
1747
+ environment.addEventListener('touchmove', onTouchMove);
1748
+ environment.addEventListener('touchend', onTouchEnd);
1749
+
1750
+ // eslint-disable-next-line consistent-return
1751
+ return function cleanup() {
1752
+ environment.removeEventListener('mousedown', onMouseDown);
1753
+ environment.removeEventListener('mouseup', onMouseUp);
1754
+ environment.removeEventListener('touchstart', onTouchStart);
1755
+ environment.removeEventListener('touchmove', onTouchMove);
1756
+ environment.removeEventListener('touchend', onTouchEnd);
1757
+ };
1688
1758
  // eslint-disable-next-line react-hooks/exhaustive-deps
1689
1759
  }, [isOpen, environment]);
1690
1760
  return mouseAndTouchTrackersRef;
@@ -2223,7 +2293,11 @@ function useSelect(userProps) {
2223
2293
  previousResultCountRef.current = items.length;
2224
2294
  });
2225
2295
  // Add mouse/touch events to document.
2226
- var mouseAndTouchTrackersRef = useMouseAndTouchTracker(isOpen, [menuRef, toggleButtonRef], environment);
2296
+ var mouseAndTouchTrackersRef = useMouseAndTouchTracker(isOpen, [menuRef, toggleButtonRef], environment, function () {
2297
+ dispatch({
2298
+ type: ToggleButtonBlur
2299
+ });
2300
+ });
2227
2301
  var setGetterPropCallInfo = useGetterPropsCalledChecker('getMenuProps', 'getToggleButtonProps');
2228
2302
  // Make initial ref false.
2229
2303
  react.useEffect(function () {
@@ -2889,7 +2963,12 @@ function useCombobox(userProps) {
2889
2963
  previousResultCountRef.current = items.length;
2890
2964
  });
2891
2965
  // Add mouse/touch events to document.
2892
- var mouseAndTouchTrackersRef = useMouseAndTouchTracker(isOpen, [inputRef, menuRef, toggleButtonRef], environment);
2966
+ var mouseAndTouchTrackersRef = useMouseAndTouchTracker(isOpen, [inputRef, menuRef, toggleButtonRef], environment, function () {
2967
+ dispatch({
2968
+ type: InputBlur,
2969
+ selectItem: false
2970
+ });
2971
+ });
2893
2972
  var setGetterPropCallInfo = useGetterPropsCalledChecker('getInputProps', 'getMenuProps');
2894
2973
  // Make initial ref false.
2895
2974
  react.useEffect(function () {
@@ -2900,13 +2979,14 @@ function useCombobox(userProps) {
2900
2979
  }, []);
2901
2980
  // Reset itemRefs on close.
2902
2981
  react.useEffect(function () {
2982
+ var _environment$document;
2903
2983
  if (!isOpen) {
2904
2984
  itemRefs.current = {};
2905
- } else if (document.activeElement !== inputRef.current) {
2985
+ } else if (((_environment$document = environment.document) == null ? void 0 : _environment$document.activeElement) !== inputRef.current) {
2906
2986
  var _inputRef$current;
2907
2987
  inputRef == null ? void 0 : (_inputRef$current = inputRef.current) == null ? void 0 : _inputRef$current.focus();
2908
2988
  }
2909
- }, [isOpen]);
2989
+ }, [isOpen, environment]);
2910
2990
 
2911
2991
  /* Event handler functions */
2912
2992
  var inputKeyDownHandlers = react.useMemo(function () {
@@ -3059,8 +3059,11 @@
3059
3059
  isTouchMove: false
3060
3060
  });
3061
3061
  react.useEffect(function () {
3062
+ if ((environment == null ? void 0 : environment.addEventListener) == null) {
3063
+ return;
3064
+ }
3062
3065
 
3063
- // The same strategy for checking if a click occurred inside or outside downsift
3066
+ // The same strategy for checking if a click occurred inside or outside downshift
3064
3067
  // as in downshift.js.
3065
3068
  var onMouseDown = function onMouseDown() {
3066
3069
  mouseAndTouchTrackersRef.current.isMouseDown = true;
@@ -4350,13 +4353,14 @@
4350
4353
  }, []);
4351
4354
  // Reset itemRefs on close.
4352
4355
  react.useEffect(function () {
4356
+ var _environment$document;
4353
4357
  if (!isOpen) {
4354
4358
  itemRefs.current = {};
4355
- } else if (document.activeElement !== inputRef.current) {
4359
+ } else if (((_environment$document = environment.document) == null ? void 0 : _environment$document.activeElement) !== inputRef.current) {
4356
4360
  var _inputRef$current;
4357
4361
  inputRef == null ? void 0 : (_inputRef$current = inputRef.current) == null ? void 0 : _inputRef$current.focus();
4358
4362
  }
4359
- }, [isOpen]);
4363
+ }, [isOpen, environment]);
4360
4364
 
4361
4365
  /* Event handler functions */
4362
4366
  var inputKeyDownHandlers = react.useMemo(function () {