@react-aria/interactions 3.23.0 → 3.24.1

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.
Files changed (84) hide show
  1. package/dist/Pressable.main.js +28 -4
  2. package/dist/Pressable.main.js.map +1 -1
  3. package/dist/Pressable.mjs +30 -6
  4. package/dist/Pressable.module.js +30 -6
  5. package/dist/Pressable.module.js.map +1 -1
  6. package/dist/focusSafely.main.js +40 -0
  7. package/dist/focusSafely.main.js.map +1 -0
  8. package/dist/focusSafely.mjs +35 -0
  9. package/dist/focusSafely.module.js +35 -0
  10. package/dist/focusSafely.module.js.map +1 -0
  11. package/dist/import.mjs +5 -1
  12. package/dist/main.js +9 -0
  13. package/dist/main.js.map +1 -1
  14. package/dist/module.js +5 -1
  15. package/dist/module.js.map +1 -1
  16. package/dist/textSelection.main.js +5 -3
  17. package/dist/textSelection.main.js.map +1 -1
  18. package/dist/textSelection.mjs +5 -3
  19. package/dist/textSelection.module.js +5 -3
  20. package/dist/textSelection.module.js.map +1 -1
  21. package/dist/types.d.ts +59 -25
  22. package/dist/types.d.ts.map +1 -1
  23. package/dist/useFocus.main.js +2 -1
  24. package/dist/useFocus.main.js.map +1 -1
  25. package/dist/useFocus.mjs +3 -2
  26. package/dist/useFocus.module.js +3 -2
  27. package/dist/useFocus.module.js.map +1 -1
  28. package/dist/useFocusVisible.main.js +9 -3
  29. package/dist/useFocusVisible.main.js.map +1 -1
  30. package/dist/useFocusVisible.mjs +9 -3
  31. package/dist/useFocusVisible.module.js +9 -3
  32. package/dist/useFocusVisible.module.js.map +1 -1
  33. package/dist/useFocusWithin.main.js +33 -4
  34. package/dist/useFocusWithin.main.js.map +1 -1
  35. package/dist/useFocusWithin.mjs +34 -5
  36. package/dist/useFocusWithin.module.js +34 -5
  37. package/dist/useFocusWithin.module.js.map +1 -1
  38. package/dist/useFocusable.main.js +112 -0
  39. package/dist/useFocusable.main.js.map +1 -0
  40. package/dist/useFocusable.mjs +100 -0
  41. package/dist/useFocusable.module.js +100 -0
  42. package/dist/useFocusable.module.js.map +1 -0
  43. package/dist/useHover.main.js +18 -3
  44. package/dist/useHover.main.js.map +1 -1
  45. package/dist/useHover.mjs +18 -3
  46. package/dist/useHover.module.js +18 -3
  47. package/dist/useHover.module.js.map +1 -1
  48. package/dist/useInteractOutside.main.js +6 -1
  49. package/dist/useInteractOutside.main.js.map +1 -1
  50. package/dist/useInteractOutside.mjs +6 -1
  51. package/dist/useInteractOutside.module.js +6 -1
  52. package/dist/useInteractOutside.module.js.map +1 -1
  53. package/dist/useLongPress.main.js +2 -0
  54. package/dist/useLongPress.main.js.map +1 -1
  55. package/dist/useLongPress.mjs +3 -1
  56. package/dist/useLongPress.module.js +3 -1
  57. package/dist/useLongPress.module.js.map +1 -1
  58. package/dist/usePress.main.js +85 -80
  59. package/dist/usePress.main.js.map +1 -1
  60. package/dist/usePress.mjs +86 -81
  61. package/dist/usePress.module.js +86 -81
  62. package/dist/usePress.module.js.map +1 -1
  63. package/dist/utils.main.js +57 -1
  64. package/dist/utils.main.js.map +1 -1
  65. package/dist/utils.mjs +55 -2
  66. package/dist/utils.module.js +55 -2
  67. package/dist/utils.module.js.map +1 -1
  68. package/package.json +5 -4
  69. package/src/Pressable.tsx +66 -6
  70. package/src/focusSafely.ts +45 -0
  71. package/src/index.ts +3 -0
  72. package/src/textSelection.ts +6 -4
  73. package/src/useFocus.ts +3 -3
  74. package/src/useFocusVisible.ts +14 -4
  75. package/src/useFocusWithin.ts +34 -5
  76. package/src/useFocusable.tsx +183 -0
  77. package/src/useHover.ts +17 -3
  78. package/src/useInteractOutside.ts +9 -3
  79. package/src/useLongPress.ts +8 -2
  80. package/src/usePress.ts +117 -115
  81. package/src/utils.ts +80 -1
  82. package/src/DOMPropsContext.ts +0 -39
  83. package/src/DOMPropsResponder.tsx +0 -47
  84. package/src/useDOMPropsResponder.ts +0 -27
@@ -1 +1 @@
1
- {"mappings":";;;AAAA;;;;;;;;;;CAUC,GAED,kEAAkE;AAClE,2DAA2D;AAC3D,yDAAyD;AACzD,kHAAkH;;;AAkB3G,SAAS,0CAAmB,KAA2B;IAC5D,IAAI,OAAC,GAAG,qBAAE,iBAAiB,cAAE,UAAU,0BAAE,sBAAsB,EAAC,GAAG;IACnE,IAAI,WAAW,CAAA,GAAA,aAAK,EAAE;QACpB,eAAe;QACf,2BAA2B;IAC7B;IAEA,IAAI,gBAAgB,CAAA,GAAA,qBAAa,EAAE,CAAC;QAClC,IAAI,qBAAqB,mCAAa,GAAG,MAAM;YAC7C,IAAI,wBACF,uBAAuB;YAEzB,SAAS,OAAO,CAAC,aAAa,GAAG;QACnC;IACF;IAEA,IAAI,yBAAyB,CAAA,GAAA,qBAAa,EAAE,CAAC;QAC3C,IAAI,mBACF,kBAAkB;IAEtB;IAEA,CAAA,GAAA,gBAAQ,EAAE;QACR,IAAI,QAAQ,SAAS,OAAO;QAC5B,IAAI,YACF;QAGF,MAAM,UAAU,IAAI,OAAO;QAC3B,MAAM,iBAAiB,CAAA,GAAA,uBAAe,EAAE;QAExC,mFAAmF;QACnF,IAAI,OAAO,iBAAiB,aAAa;YACvC,IAAI,cAAc,CAAC;gBACjB,IAAI,MAAM,aAAa,IAAI,mCAAa,GAAG,MACzC,uBAAuB;gBAEzB,MAAM,aAAa,GAAG;YACxB;YAEA,iDAAiD;YACjD,eAAe,gBAAgB,CAAC,eAAe,eAAe;YAC9D,eAAe,gBAAgB,CAAC,aAAa,aAAa;YAE1D,OAAO;gBACL,eAAe,mBAAmB,CAAC,eAAe,eAAe;gBACjE,eAAe,mBAAmB,CAAC,aAAa,aAAa;YAC/D;QACF,OAAO;YACL,IAAI,YAAY,CAAC;gBACf,IAAI,MAAM,yBAAyB,EACjC,MAAM,yBAAyB,GAAG;qBAC7B,IAAI,MAAM,aAAa,IAAI,mCAAa,GAAG,MAChD,uBAAuB;gBAEzB,MAAM,aAAa,GAAG;YACxB;YAEA,IAAI,aAAa,CAAC;gBAChB,MAAM,yBAAyB,GAAG;gBAClC,IAAI,MAAM,aAAa,IAAI,mCAAa,GAAG,MACzC,uBAAuB;gBAEzB,MAAM,aAAa,GAAG;YACxB;YAEA,eAAe,gBAAgB,CAAC,aAAa,eAAe;YAC5D,eAAe,gBAAgB,CAAC,WAAW,WAAW;YACtD,eAAe,gBAAgB,CAAC,cAAc,eAAe;YAC7D,eAAe,gBAAgB,CAAC,YAAY,YAAY;YAExD,OAAO;gBACL,eAAe,mBAAmB,CAAC,aAAa,eAAe;gBAC/D,eAAe,mBAAmB,CAAC,WAAW,WAAW;gBACzD,eAAe,mBAAmB,CAAC,cAAc,eAAe;gBAChE,eAAe,mBAAmB,CAAC,YAAY,YAAY;YAC7D;QACF;IACF,GAAG;QAAC;QAAK;QAAY;QAAe;KAAuB;AAC7D;AAEA,SAAS,mCAAa,KAAK,EAAE,GAAG;IAC9B,IAAI,MAAM,MAAM,GAAG,GACjB,OAAO;IAGT,IAAI,MAAM,MAAM,EAAE;QAChB,2DAA2D;QAC3D,MAAM,gBAAgB,MAAM,MAAM,CAAC,aAAa;QAChD,IAAI,CAAC,iBAAiB,CAAC,cAAc,eAAe,CAAC,QAAQ,CAAC,MAAM,MAAM,GACxE,OAAO;QAGT,qEAAqE;QACrE,IAAI,MAAM,MAAM,CAAC,OAAO,CAAC,gCACvB,OAAO;IAEX;IAEA,OAAO,IAAI,OAAO,IAAI,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,MAAM;AAC1D","sources":["packages/@react-aria/interactions/src/useInteractOutside.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\n// Portions of the code in this file are based on code from react.\n// Original licensing for the following can be found in the\n// NOTICE file in the root directory of this source tree.\n// See https://github.com/facebook/react/tree/cc7c1aece46a6b69b41958d731e0fd27c94bfc6c/packages/react-interactions\n\nimport {getOwnerDocument, useEffectEvent} from '@react-aria/utils';\nimport {RefObject} from '@react-types/shared';\nimport {useEffect, useRef} from 'react';\n\nexport interface InteractOutsideProps {\n ref: RefObject<Element | null>,\n onInteractOutside?: (e: PointerEvent) => void,\n onInteractOutsideStart?: (e: PointerEvent) => void,\n /** Whether the interact outside events should be disabled. */\n isDisabled?: boolean\n}\n\n/**\n * Example, used in components like Dialogs and Popovers so they can close\n * when a user clicks outside them.\n */\nexport function useInteractOutside(props: InteractOutsideProps) {\n let {ref, onInteractOutside, isDisabled, onInteractOutsideStart} = props;\n let stateRef = useRef({\n isPointerDown: false,\n ignoreEmulatedMouseEvents: false\n });\n\n let onPointerDown = useEffectEvent((e) => {\n if (onInteractOutside && isValidEvent(e, ref)) {\n if (onInteractOutsideStart) {\n onInteractOutsideStart(e);\n }\n stateRef.current.isPointerDown = true;\n }\n });\n\n let triggerInteractOutside = useEffectEvent((e: PointerEvent) => {\n if (onInteractOutside) {\n onInteractOutside(e);\n }\n });\n\n useEffect(() => {\n let state = stateRef.current;\n if (isDisabled) {\n return;\n }\n\n const element = ref.current;\n const documentObject = getOwnerDocument(element);\n\n // Use pointer events if available. Otherwise, fall back to mouse and touch events.\n if (typeof PointerEvent !== 'undefined') {\n let onPointerUp = (e) => {\n if (state.isPointerDown && isValidEvent(e, ref)) {\n triggerInteractOutside(e);\n }\n state.isPointerDown = false;\n };\n\n // changing these to capture phase fixed combobox\n documentObject.addEventListener('pointerdown', onPointerDown, true);\n documentObject.addEventListener('pointerup', onPointerUp, true);\n\n return () => {\n documentObject.removeEventListener('pointerdown', onPointerDown, true);\n documentObject.removeEventListener('pointerup', onPointerUp, true);\n };\n } else {\n let onMouseUp = (e) => {\n if (state.ignoreEmulatedMouseEvents) {\n state.ignoreEmulatedMouseEvents = false;\n } else if (state.isPointerDown && isValidEvent(e, ref)) {\n triggerInteractOutside(e);\n }\n state.isPointerDown = false;\n };\n\n let onTouchEnd = (e) => {\n state.ignoreEmulatedMouseEvents = true;\n if (state.isPointerDown && isValidEvent(e, ref)) {\n triggerInteractOutside(e);\n }\n state.isPointerDown = false;\n };\n\n documentObject.addEventListener('mousedown', onPointerDown, true);\n documentObject.addEventListener('mouseup', onMouseUp, true);\n documentObject.addEventListener('touchstart', onPointerDown, true);\n documentObject.addEventListener('touchend', onTouchEnd, true);\n\n return () => {\n documentObject.removeEventListener('mousedown', onPointerDown, true);\n documentObject.removeEventListener('mouseup', onMouseUp, true);\n documentObject.removeEventListener('touchstart', onPointerDown, true);\n documentObject.removeEventListener('touchend', onTouchEnd, true);\n };\n }\n }, [ref, isDisabled, onPointerDown, triggerInteractOutside]);\n}\n\nfunction isValidEvent(event, ref) {\n if (event.button > 0) {\n return false;\n }\n\n if (event.target) {\n // if the event target is no longer in the document, ignore\n const ownerDocument = event.target.ownerDocument;\n if (!ownerDocument || !ownerDocument.documentElement.contains(event.target)) {\n return false;\n }\n\n // If the target is within a top layer element (e.g. toasts), ignore.\n if (event.target.closest('[data-react-aria-top-layer]')) {\n return false;\n }\n }\n\n return ref.current && !ref.current.contains(event.target);\n}\n"],"names":[],"version":3,"file":"useInteractOutside.module.js.map"}
1
+ {"mappings":";;;AAAA;;;;;;;;;;CAUC,GAED,kEAAkE;AAClE,2DAA2D;AAC3D,yDAAyD;AACzD,kHAAkH;;;AAkB3G,SAAS,0CAAmB,KAA2B;IAC5D,IAAI,OAAC,GAAG,qBAAE,iBAAiB,cAAE,UAAU,0BAAE,sBAAsB,EAAC,GAAG;IACnE,IAAI,WAAW,CAAA,GAAA,aAAK,EAAE;QACpB,eAAe;QACf,2BAA2B;IAC7B;IAEA,IAAI,gBAAgB,CAAA,GAAA,qBAAa,EAAE,CAAC;QAClC,IAAI,qBAAqB,mCAAa,GAAG,MAAM;YAC7C,IAAI,wBACF,uBAAuB;YAEzB,SAAS,OAAO,CAAC,aAAa,GAAG;QACnC;IACF;IAEA,IAAI,yBAAyB,CAAA,GAAA,qBAAa,EAAE,CAAC;QAC3C,IAAI,mBACF,kBAAkB;IAEtB;IAEA,CAAA,GAAA,gBAAQ,EAAE;QACR,IAAI,QAAQ,SAAS,OAAO;QAC5B,IAAI,YACF;QAGF,MAAM,UAAU,IAAI,OAAO;QAC3B,MAAM,iBAAiB,CAAA,GAAA,uBAAe,EAAE;QAExC,mFAAmF;QACnF,IAAI,OAAO,iBAAiB,aAAa;YACvC,IAAI,cAAc,CAAC;gBACjB,IAAI,MAAM,aAAa,IAAI,mCAAa,GAAG,MACzC,uBAAuB;gBAEzB,MAAM,aAAa,GAAG;YACxB;YAEA,iDAAiD;YACjD,eAAe,gBAAgB,CAAC,eAAe,eAAe;YAC9D,eAAe,gBAAgB,CAAC,aAAa,aAAa;YAE1D,OAAO;gBACL,eAAe,mBAAmB,CAAC,eAAe,eAAe;gBACjE,eAAe,mBAAmB,CAAC,aAAa,aAAa;YAC/D;QACF,OAAO;YACL,IAAI,YAAY,CAAC;gBACf,IAAI,MAAM,yBAAyB,EACjC,MAAM,yBAAyB,GAAG;qBAC7B,IAAI,MAAM,aAAa,IAAI,mCAAa,GAAG,MAChD,uBAAuB;gBAEzB,MAAM,aAAa,GAAG;YACxB;YAEA,IAAI,aAAa,CAAC;gBAChB,MAAM,yBAAyB,GAAG;gBAClC,IAAI,MAAM,aAAa,IAAI,mCAAa,GAAG,MACzC,uBAAuB;gBAEzB,MAAM,aAAa,GAAG;YACxB;YAEA,eAAe,gBAAgB,CAAC,aAAa,eAAe;YAC5D,eAAe,gBAAgB,CAAC,WAAW,WAAW;YACtD,eAAe,gBAAgB,CAAC,cAAc,eAAe;YAC7D,eAAe,gBAAgB,CAAC,YAAY,YAAY;YAExD,OAAO;gBACL,eAAe,mBAAmB,CAAC,aAAa,eAAe;gBAC/D,eAAe,mBAAmB,CAAC,WAAW,WAAW;gBACzD,eAAe,mBAAmB,CAAC,cAAc,eAAe;gBAChE,eAAe,mBAAmB,CAAC,YAAY,YAAY;YAC7D;QACF;IACF,GAAG;QAAC;QAAK;QAAY;QAAe;KAAuB;AAC7D;AAEA,SAAS,mCAAa,KAAK,EAAE,GAAG;IAC9B,IAAI,MAAM,MAAM,GAAG,GACjB,OAAO;IAET,IAAI,MAAM,MAAM,EAAE;QAChB,2DAA2D;QAC3D,MAAM,gBAAgB,MAAM,MAAM,CAAC,aAAa;QAChD,IAAI,CAAC,iBAAiB,CAAC,cAAc,eAAe,CAAC,QAAQ,CAAC,MAAM,MAAM,GACxE,OAAO;QAET,qEAAqE;QACrE,IAAI,MAAM,MAAM,CAAC,OAAO,CAAC,gCACvB,OAAO;IAEX;IAEA,IAAI,CAAC,IAAI,OAAO,EACd,OAAO;IAGT,sFAAsF;IACtF,+FAA+F;IAC/F,yFAAyF;IACzF,sEAAsE;IACtE,OAAO,CAAC,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,OAAO;AACnD","sources":["packages/@react-aria/interactions/src/useInteractOutside.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\n// Portions of the code in this file are based on code from react.\n// Original licensing for the following can be found in the\n// NOTICE file in the root directory of this source tree.\n// See https://github.com/facebook/react/tree/cc7c1aece46a6b69b41958d731e0fd27c94bfc6c/packages/react-interactions\n\nimport {getOwnerDocument, useEffectEvent} from '@react-aria/utils';\nimport {RefObject} from '@react-types/shared';\nimport {useEffect, useRef} from 'react';\n\nexport interface InteractOutsideProps {\n ref: RefObject<Element | null>,\n onInteractOutside?: (e: PointerEvent) => void,\n onInteractOutsideStart?: (e: PointerEvent) => void,\n /** Whether the interact outside events should be disabled. */\n isDisabled?: boolean\n}\n\n/**\n * Example, used in components like Dialogs and Popovers so they can close\n * when a user clicks outside them.\n */\nexport function useInteractOutside(props: InteractOutsideProps) {\n let {ref, onInteractOutside, isDisabled, onInteractOutsideStart} = props;\n let stateRef = useRef({\n isPointerDown: false,\n ignoreEmulatedMouseEvents: false\n });\n\n let onPointerDown = useEffectEvent((e) => {\n if (onInteractOutside && isValidEvent(e, ref)) {\n if (onInteractOutsideStart) {\n onInteractOutsideStart(e);\n }\n stateRef.current.isPointerDown = true;\n }\n });\n\n let triggerInteractOutside = useEffectEvent((e: PointerEvent) => {\n if (onInteractOutside) {\n onInteractOutside(e);\n }\n });\n\n useEffect(() => {\n let state = stateRef.current;\n if (isDisabled) {\n return;\n }\n\n const element = ref.current;\n const documentObject = getOwnerDocument(element);\n\n // Use pointer events if available. Otherwise, fall back to mouse and touch events.\n if (typeof PointerEvent !== 'undefined') {\n let onPointerUp = (e) => {\n if (state.isPointerDown && isValidEvent(e, ref)) {\n triggerInteractOutside(e);\n }\n state.isPointerDown = false;\n };\n\n // changing these to capture phase fixed combobox\n documentObject.addEventListener('pointerdown', onPointerDown, true);\n documentObject.addEventListener('pointerup', onPointerUp, true);\n\n return () => {\n documentObject.removeEventListener('pointerdown', onPointerDown, true);\n documentObject.removeEventListener('pointerup', onPointerUp, true);\n };\n } else {\n let onMouseUp = (e) => {\n if (state.ignoreEmulatedMouseEvents) {\n state.ignoreEmulatedMouseEvents = false;\n } else if (state.isPointerDown && isValidEvent(e, ref)) {\n triggerInteractOutside(e);\n }\n state.isPointerDown = false;\n };\n\n let onTouchEnd = (e) => {\n state.ignoreEmulatedMouseEvents = true;\n if (state.isPointerDown && isValidEvent(e, ref)) {\n triggerInteractOutside(e);\n }\n state.isPointerDown = false;\n };\n\n documentObject.addEventListener('mousedown', onPointerDown, true);\n documentObject.addEventListener('mouseup', onMouseUp, true);\n documentObject.addEventListener('touchstart', onPointerDown, true);\n documentObject.addEventListener('touchend', onTouchEnd, true);\n\n return () => {\n documentObject.removeEventListener('mousedown', onPointerDown, true);\n documentObject.removeEventListener('mouseup', onMouseUp, true);\n documentObject.removeEventListener('touchstart', onPointerDown, true);\n documentObject.removeEventListener('touchend', onTouchEnd, true);\n };\n }\n }, [ref, isDisabled, onPointerDown, triggerInteractOutside]);\n}\n\nfunction isValidEvent(event, ref) {\n if (event.button > 0) {\n return false;\n }\n if (event.target) {\n // if the event target is no longer in the document, ignore\n const ownerDocument = event.target.ownerDocument;\n if (!ownerDocument || !ownerDocument.documentElement.contains(event.target)) {\n return false;\n }\n // If the target is within a top layer element (e.g. toasts), ignore.\n if (event.target.closest('[data-react-aria-top-layer]')) {\n return false;\n }\n }\n\n if (!ref.current) {\n return false;\n }\n\n // When the event source is inside a Shadow DOM, event.target is just the shadow root.\n // Using event.composedPath instead means we can get the actual element inside the shadow root.\n // This only works if the shadow root is open, there is no way to detect if it is closed.\n // If the event composed path contains the ref, interaction is inside.\n return !event.composedPath().includes(ref.current);\n}\n"],"names":[],"version":3,"file":"useInteractOutside.module.js.map"}
@@ -40,6 +40,8 @@ function $3cd7b5d0eebf0ca9$export$c24ed0104d07eab9(props) {
40
40
  e.target.dispatchEvent(new PointerEvent('pointercancel', {
41
41
  bubbles: true
42
42
  }));
43
+ // Ensure target is focused. On touch devices, browsers typically focus on pointer up.
44
+ if ((0, $5sxTM$reactariautils.getOwnerDocument)(e.target).activeElement !== e.target) (0, $5sxTM$reactariautils.focusWithoutScrolling)(e.target);
43
45
  if (onLongPress) onLongPress({
44
46
  ...e,
45
47
  type: 'longpress'
@@ -1 +1 @@
1
- {"mappings":";;;;;;;;;;AAAA;;;;;;;;;;CAUC;;;AAuCD,MAAM,0CAAoB;AAMnB,SAAS,0CAAa,KAAqB;IAChD,IAAI,cACF,UAAU,oBACV,gBAAgB,kBAChB,cAAc,eACd,WAAW,aACX,YAAY,mEACZ,wBAAwB,EACzB,GAAG;IAEJ,MAAM,UAAU,CAAA,GAAA,mBAAK,EAA6C;IAClE,IAAI,qBAAC,iBAAiB,wBAAE,oBAAoB,EAAC,GAAG,CAAA,GAAA,wCAAiB;IAEjE,IAAI,cAAC,UAAU,EAAC,GAAG,CAAA,GAAA,kCAAO,EAAE;oBAC1B;QACA,cAAa,CAAC;YACZ,EAAE,mBAAmB;YACrB,IAAI,EAAE,WAAW,KAAK,WAAW,EAAE,WAAW,KAAK,SAAS;gBAC1D,IAAI,kBACF,iBAAiB;oBACf,GAAG,CAAC;oBACJ,MAAM;gBACR;gBAGF,QAAQ,OAAO,GAAG,WAAW;oBAC3B,iEAAiE;oBACjE,EAAE,MAAM,CAAC,aAAa,CAAC,IAAI,aAAa,iBAAiB;wBAAC,SAAS;oBAAI;oBACvE,IAAI,aACF,YAAY;wBACV,GAAG,CAAC;wBACJ,MAAM;oBACR;oBAEF,QAAQ,OAAO,GAAG;gBACpB,GAAG;gBAEH,2EAA2E;gBAC3E,IAAI,EAAE,WAAW,KAAK,SAAS;oBAC7B,IAAI,gBAAgB,CAAA;wBAClB,EAAE,cAAc;oBAClB;oBAEA,kBAAkB,EAAE,MAAM,EAAE,eAAe,eAAe;wBAAC,MAAM;oBAAI;oBACrE,kBAAkB,QAAQ,aAAa;wBACrC,+EAA+E;wBAC/E,wEAAwE;wBACxE,WAAW;4BACT,qBAAqB,EAAE,MAAM,EAAE,eAAe;wBAChD,GAAG;oBACL,GAAG;wBAAC,MAAM;oBAAI;gBAChB;YACF;QACF;QACA,YAAW,CAAC;YACV,IAAI,QAAQ,OAAO,EACjB,aAAa,QAAQ,OAAO;YAG9B,IAAI,kBAAmB,CAAA,EAAE,WAAW,KAAK,WAAW,EAAE,WAAW,KAAK,OAAM,GAC1E,eAAe;gBACb,GAAG,CAAC;gBACJ,MAAM;YACR;QAEJ;IACF;IAEA,IAAI,mBAAmB,CAAA,GAAA,oCAAa,EAAE,eAAe,CAAC,aAAa,2BAA2B;IAE9F,OAAO;QACL,gBAAgB,CAAA,GAAA,gCAAS,EAAE,YAAY;IACzC;AACF","sources":["packages/@react-aria/interactions/src/useLongPress.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {DOMAttributes, LongPressEvent} from '@react-types/shared';\nimport {mergeProps, useDescription, useGlobalListeners} from '@react-aria/utils';\nimport {usePress} from './usePress';\nimport {useRef} from 'react';\n\nexport interface LongPressProps {\n /** Whether long press events should be disabled. */\n isDisabled?: boolean,\n /** Handler that is called when a long press interaction starts. */\n onLongPressStart?: (e: LongPressEvent) => void,\n /**\n * Handler that is called when a long press interaction ends, either\n * over the target or when the pointer leaves the target.\n */\n onLongPressEnd?: (e: LongPressEvent) => void,\n /**\n * Handler that is called when the threshold time is met while\n * the press is over the target.\n */\n onLongPress?: (e: LongPressEvent) => void,\n /**\n * The amount of time in milliseconds to wait before triggering a long press.\n * @default 500ms\n */\n threshold?: number,\n /**\n * A description for assistive techology users indicating that a long press\n * action is available, e.g. \"Long press to open menu\".\n */\n accessibilityDescription?: string\n}\n\nexport interface LongPressResult {\n /** Props to spread on the target element. */\n longPressProps: DOMAttributes\n}\n\nconst DEFAULT_THRESHOLD = 500;\n\n/**\n * Handles long press interactions across mouse and touch devices. Supports a customizable time threshold,\n * accessibility description, and normalizes behavior across browsers and devices.\n */\nexport function useLongPress(props: LongPressProps): LongPressResult {\n let {\n isDisabled,\n onLongPressStart,\n onLongPressEnd,\n onLongPress,\n threshold = DEFAULT_THRESHOLD,\n accessibilityDescription\n } = props;\n\n const timeRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n let {addGlobalListener, removeGlobalListener} = useGlobalListeners();\n\n let {pressProps} = usePress({\n isDisabled,\n onPressStart(e) {\n e.continuePropagation();\n if (e.pointerType === 'mouse' || e.pointerType === 'touch') {\n if (onLongPressStart) {\n onLongPressStart({\n ...e,\n type: 'longpressstart'\n });\n }\n\n timeRef.current = setTimeout(() => {\n // Prevent other usePress handlers from also handling this event.\n e.target.dispatchEvent(new PointerEvent('pointercancel', {bubbles: true}));\n if (onLongPress) {\n onLongPress({\n ...e,\n type: 'longpress'\n });\n }\n timeRef.current = undefined;\n }, threshold);\n\n // Prevent context menu, which may be opened on long press on touch devices\n if (e.pointerType === 'touch') {\n let onContextMenu = e => {\n e.preventDefault();\n };\n\n addGlobalListener(e.target, 'contextmenu', onContextMenu, {once: true});\n addGlobalListener(window, 'pointerup', () => {\n // If no contextmenu event is fired quickly after pointerup, remove the handler\n // so future context menu events outside a long press are not prevented.\n setTimeout(() => {\n removeGlobalListener(e.target, 'contextmenu', onContextMenu);\n }, 30);\n }, {once: true});\n }\n }\n },\n onPressEnd(e) {\n if (timeRef.current) {\n clearTimeout(timeRef.current);\n }\n\n if (onLongPressEnd && (e.pointerType === 'mouse' || e.pointerType === 'touch')) {\n onLongPressEnd({\n ...e,\n type: 'longpressend'\n });\n }\n }\n });\n\n let descriptionProps = useDescription(onLongPress && !isDisabled ? accessibilityDescription : undefined);\n\n return {\n longPressProps: mergeProps(pressProps, descriptionProps)\n };\n}\n"],"names":[],"version":3,"file":"useLongPress.main.js.map"}
1
+ {"mappings":";;;;;;;;;;AAAA;;;;;;;;;;CAUC;;;AAuCD,MAAM,0CAAoB;AAMnB,SAAS,0CAAa,KAAqB;IAChD,IAAI,cACF,UAAU,oBACV,gBAAgB,kBAChB,cAAc,eACd,WAAW,aACX,YAAY,mEACZ,wBAAwB,EACzB,GAAG;IAEJ,MAAM,UAAU,CAAA,GAAA,mBAAK,EAA6C;IAClE,IAAI,qBAAC,iBAAiB,wBAAE,oBAAoB,EAAC,GAAG,CAAA,GAAA,wCAAiB;IAEjE,IAAI,cAAC,UAAU,EAAC,GAAG,CAAA,GAAA,kCAAO,EAAE;oBAC1B;QACA,cAAa,CAAC;YACZ,EAAE,mBAAmB;YACrB,IAAI,EAAE,WAAW,KAAK,WAAW,EAAE,WAAW,KAAK,SAAS;gBAC1D,IAAI,kBACF,iBAAiB;oBACf,GAAG,CAAC;oBACJ,MAAM;gBACR;gBAGF,QAAQ,OAAO,GAAG,WAAW;oBAC3B,iEAAiE;oBACjE,EAAE,MAAM,CAAC,aAAa,CAAC,IAAI,aAAa,iBAAiB;wBAAC,SAAS;oBAAI;oBAEvE,sFAAsF;oBACtF,IAAI,CAAA,GAAA,sCAAe,EAAE,EAAE,MAAM,EAAE,aAAa,KAAK,EAAE,MAAM,EACvD,CAAA,GAAA,2CAAoB,EAAE,EAAE,MAAM;oBAGhC,IAAI,aACF,YAAY;wBACV,GAAG,CAAC;wBACJ,MAAM;oBACR;oBAEF,QAAQ,OAAO,GAAG;gBACpB,GAAG;gBAEH,2EAA2E;gBAC3E,IAAI,EAAE,WAAW,KAAK,SAAS;oBAC7B,IAAI,gBAAgB,CAAA;wBAClB,EAAE,cAAc;oBAClB;oBAEA,kBAAkB,EAAE,MAAM,EAAE,eAAe,eAAe;wBAAC,MAAM;oBAAI;oBACrE,kBAAkB,QAAQ,aAAa;wBACrC,+EAA+E;wBAC/E,wEAAwE;wBACxE,WAAW;4BACT,qBAAqB,EAAE,MAAM,EAAE,eAAe;wBAChD,GAAG;oBACL,GAAG;wBAAC,MAAM;oBAAI;gBAChB;YACF;QACF;QACA,YAAW,CAAC;YACV,IAAI,QAAQ,OAAO,EACjB,aAAa,QAAQ,OAAO;YAG9B,IAAI,kBAAmB,CAAA,EAAE,WAAW,KAAK,WAAW,EAAE,WAAW,KAAK,OAAM,GAC1E,eAAe;gBACb,GAAG,CAAC;gBACJ,MAAM;YACR;QAEJ;IACF;IAEA,IAAI,mBAAmB,CAAA,GAAA,oCAAa,EAAE,eAAe,CAAC,aAAa,2BAA2B;IAE9F,OAAO;QACL,gBAAgB,CAAA,GAAA,gCAAS,EAAE,YAAY;IACzC;AACF","sources":["packages/@react-aria/interactions/src/useLongPress.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {DOMAttributes, FocusableElement, LongPressEvent} from '@react-types/shared';\nimport {focusWithoutScrolling, getOwnerDocument, mergeProps, useDescription, useGlobalListeners} from '@react-aria/utils';\nimport {usePress} from './usePress';\nimport {useRef} from 'react';\n\nexport interface LongPressProps {\n /** Whether long press events should be disabled. */\n isDisabled?: boolean,\n /** Handler that is called when a long press interaction starts. */\n onLongPressStart?: (e: LongPressEvent) => void,\n /**\n * Handler that is called when a long press interaction ends, either\n * over the target or when the pointer leaves the target.\n */\n onLongPressEnd?: (e: LongPressEvent) => void,\n /**\n * Handler that is called when the threshold time is met while\n * the press is over the target.\n */\n onLongPress?: (e: LongPressEvent) => void,\n /**\n * The amount of time in milliseconds to wait before triggering a long press.\n * @default 500ms\n */\n threshold?: number,\n /**\n * A description for assistive techology users indicating that a long press\n * action is available, e.g. \"Long press to open menu\".\n */\n accessibilityDescription?: string\n}\n\nexport interface LongPressResult {\n /** Props to spread on the target element. */\n longPressProps: DOMAttributes\n}\n\nconst DEFAULT_THRESHOLD = 500;\n\n/**\n * Handles long press interactions across mouse and touch devices. Supports a customizable time threshold,\n * accessibility description, and normalizes behavior across browsers and devices.\n */\nexport function useLongPress(props: LongPressProps): LongPressResult {\n let {\n isDisabled,\n onLongPressStart,\n onLongPressEnd,\n onLongPress,\n threshold = DEFAULT_THRESHOLD,\n accessibilityDescription\n } = props;\n\n const timeRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n let {addGlobalListener, removeGlobalListener} = useGlobalListeners();\n\n let {pressProps} = usePress({\n isDisabled,\n onPressStart(e) {\n e.continuePropagation();\n if (e.pointerType === 'mouse' || e.pointerType === 'touch') {\n if (onLongPressStart) {\n onLongPressStart({\n ...e,\n type: 'longpressstart'\n });\n }\n\n timeRef.current = setTimeout(() => {\n // Prevent other usePress handlers from also handling this event.\n e.target.dispatchEvent(new PointerEvent('pointercancel', {bubbles: true}));\n\n // Ensure target is focused. On touch devices, browsers typically focus on pointer up.\n if (getOwnerDocument(e.target).activeElement !== e.target) {\n focusWithoutScrolling(e.target as FocusableElement);\n }\n\n if (onLongPress) {\n onLongPress({\n ...e,\n type: 'longpress'\n });\n }\n timeRef.current = undefined;\n }, threshold);\n\n // Prevent context menu, which may be opened on long press on touch devices\n if (e.pointerType === 'touch') {\n let onContextMenu = e => {\n e.preventDefault();\n };\n\n addGlobalListener(e.target, 'contextmenu', onContextMenu, {once: true});\n addGlobalListener(window, 'pointerup', () => {\n // If no contextmenu event is fired quickly after pointerup, remove the handler\n // so future context menu events outside a long press are not prevented.\n setTimeout(() => {\n removeGlobalListener(e.target, 'contextmenu', onContextMenu);\n }, 30);\n }, {once: true});\n }\n }\n },\n onPressEnd(e) {\n if (timeRef.current) {\n clearTimeout(timeRef.current);\n }\n\n if (onLongPressEnd && (e.pointerType === 'mouse' || e.pointerType === 'touch')) {\n onLongPressEnd({\n ...e,\n type: 'longpressend'\n });\n }\n }\n });\n\n let descriptionProps = useDescription(onLongPress && !isDisabled ? accessibilityDescription : undefined);\n\n return {\n longPressProps: mergeProps(pressProps, descriptionProps)\n };\n}\n"],"names":[],"version":3,"file":"useLongPress.main.js.map"}
@@ -1,5 +1,5 @@
1
1
  import {usePress as $f6c31cce2adf654f$export$45712eceda6fad21} from "./usePress.mjs";
2
- import {useGlobalListeners as $4k2kv$useGlobalListeners, useDescription as $4k2kv$useDescription, mergeProps as $4k2kv$mergeProps} from "@react-aria/utils";
2
+ import {useGlobalListeners as $4k2kv$useGlobalListeners, getOwnerDocument as $4k2kv$getOwnerDocument, focusWithoutScrolling as $4k2kv$focusWithoutScrolling, useDescription as $4k2kv$useDescription, mergeProps as $4k2kv$mergeProps} from "@react-aria/utils";
3
3
  import {useRef as $4k2kv$useRef} from "react";
4
4
 
5
5
  /*
@@ -34,6 +34,8 @@ function $8a26561d2877236e$export$c24ed0104d07eab9(props) {
34
34
  e.target.dispatchEvent(new PointerEvent('pointercancel', {
35
35
  bubbles: true
36
36
  }));
37
+ // Ensure target is focused. On touch devices, browsers typically focus on pointer up.
38
+ if ((0, $4k2kv$getOwnerDocument)(e.target).activeElement !== e.target) (0, $4k2kv$focusWithoutScrolling)(e.target);
37
39
  if (onLongPress) onLongPress({
38
40
  ...e,
39
41
  type: 'longpress'
@@ -1,5 +1,5 @@
1
1
  import {usePress as $f6c31cce2adf654f$export$45712eceda6fad21} from "./usePress.module.js";
2
- import {useGlobalListeners as $4k2kv$useGlobalListeners, useDescription as $4k2kv$useDescription, mergeProps as $4k2kv$mergeProps} from "@react-aria/utils";
2
+ import {useGlobalListeners as $4k2kv$useGlobalListeners, getOwnerDocument as $4k2kv$getOwnerDocument, focusWithoutScrolling as $4k2kv$focusWithoutScrolling, useDescription as $4k2kv$useDescription, mergeProps as $4k2kv$mergeProps} from "@react-aria/utils";
3
3
  import {useRef as $4k2kv$useRef} from "react";
4
4
 
5
5
  /*
@@ -34,6 +34,8 @@ function $8a26561d2877236e$export$c24ed0104d07eab9(props) {
34
34
  e.target.dispatchEvent(new PointerEvent('pointercancel', {
35
35
  bubbles: true
36
36
  }));
37
+ // Ensure target is focused. On touch devices, browsers typically focus on pointer up.
38
+ if ((0, $4k2kv$getOwnerDocument)(e.target).activeElement !== e.target) (0, $4k2kv$focusWithoutScrolling)(e.target);
37
39
  if (onLongPress) onLongPress({
38
40
  ...e,
39
41
  type: 'longpress'
@@ -1 +1 @@
1
- {"mappings":";;;;AAAA;;;;;;;;;;CAUC;;;AAuCD,MAAM,0CAAoB;AAMnB,SAAS,0CAAa,KAAqB;IAChD,IAAI,cACF,UAAU,oBACV,gBAAgB,kBAChB,cAAc,eACd,WAAW,aACX,YAAY,mEACZ,wBAAwB,EACzB,GAAG;IAEJ,MAAM,UAAU,CAAA,GAAA,aAAK,EAA6C;IAClE,IAAI,qBAAC,iBAAiB,wBAAE,oBAAoB,EAAC,GAAG,CAAA,GAAA,yBAAiB;IAEjE,IAAI,cAAC,UAAU,EAAC,GAAG,CAAA,GAAA,yCAAO,EAAE;oBAC1B;QACA,cAAa,CAAC;YACZ,EAAE,mBAAmB;YACrB,IAAI,EAAE,WAAW,KAAK,WAAW,EAAE,WAAW,KAAK,SAAS;gBAC1D,IAAI,kBACF,iBAAiB;oBACf,GAAG,CAAC;oBACJ,MAAM;gBACR;gBAGF,QAAQ,OAAO,GAAG,WAAW;oBAC3B,iEAAiE;oBACjE,EAAE,MAAM,CAAC,aAAa,CAAC,IAAI,aAAa,iBAAiB;wBAAC,SAAS;oBAAI;oBACvE,IAAI,aACF,YAAY;wBACV,GAAG,CAAC;wBACJ,MAAM;oBACR;oBAEF,QAAQ,OAAO,GAAG;gBACpB,GAAG;gBAEH,2EAA2E;gBAC3E,IAAI,EAAE,WAAW,KAAK,SAAS;oBAC7B,IAAI,gBAAgB,CAAA;wBAClB,EAAE,cAAc;oBAClB;oBAEA,kBAAkB,EAAE,MAAM,EAAE,eAAe,eAAe;wBAAC,MAAM;oBAAI;oBACrE,kBAAkB,QAAQ,aAAa;wBACrC,+EAA+E;wBAC/E,wEAAwE;wBACxE,WAAW;4BACT,qBAAqB,EAAE,MAAM,EAAE,eAAe;wBAChD,GAAG;oBACL,GAAG;wBAAC,MAAM;oBAAI;gBAChB;YACF;QACF;QACA,YAAW,CAAC;YACV,IAAI,QAAQ,OAAO,EACjB,aAAa,QAAQ,OAAO;YAG9B,IAAI,kBAAmB,CAAA,EAAE,WAAW,KAAK,WAAW,EAAE,WAAW,KAAK,OAAM,GAC1E,eAAe;gBACb,GAAG,CAAC;gBACJ,MAAM;YACR;QAEJ;IACF;IAEA,IAAI,mBAAmB,CAAA,GAAA,qBAAa,EAAE,eAAe,CAAC,aAAa,2BAA2B;IAE9F,OAAO;QACL,gBAAgB,CAAA,GAAA,iBAAS,EAAE,YAAY;IACzC;AACF","sources":["packages/@react-aria/interactions/src/useLongPress.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {DOMAttributes, LongPressEvent} from '@react-types/shared';\nimport {mergeProps, useDescription, useGlobalListeners} from '@react-aria/utils';\nimport {usePress} from './usePress';\nimport {useRef} from 'react';\n\nexport interface LongPressProps {\n /** Whether long press events should be disabled. */\n isDisabled?: boolean,\n /** Handler that is called when a long press interaction starts. */\n onLongPressStart?: (e: LongPressEvent) => void,\n /**\n * Handler that is called when a long press interaction ends, either\n * over the target or when the pointer leaves the target.\n */\n onLongPressEnd?: (e: LongPressEvent) => void,\n /**\n * Handler that is called when the threshold time is met while\n * the press is over the target.\n */\n onLongPress?: (e: LongPressEvent) => void,\n /**\n * The amount of time in milliseconds to wait before triggering a long press.\n * @default 500ms\n */\n threshold?: number,\n /**\n * A description for assistive techology users indicating that a long press\n * action is available, e.g. \"Long press to open menu\".\n */\n accessibilityDescription?: string\n}\n\nexport interface LongPressResult {\n /** Props to spread on the target element. */\n longPressProps: DOMAttributes\n}\n\nconst DEFAULT_THRESHOLD = 500;\n\n/**\n * Handles long press interactions across mouse and touch devices. Supports a customizable time threshold,\n * accessibility description, and normalizes behavior across browsers and devices.\n */\nexport function useLongPress(props: LongPressProps): LongPressResult {\n let {\n isDisabled,\n onLongPressStart,\n onLongPressEnd,\n onLongPress,\n threshold = DEFAULT_THRESHOLD,\n accessibilityDescription\n } = props;\n\n const timeRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n let {addGlobalListener, removeGlobalListener} = useGlobalListeners();\n\n let {pressProps} = usePress({\n isDisabled,\n onPressStart(e) {\n e.continuePropagation();\n if (e.pointerType === 'mouse' || e.pointerType === 'touch') {\n if (onLongPressStart) {\n onLongPressStart({\n ...e,\n type: 'longpressstart'\n });\n }\n\n timeRef.current = setTimeout(() => {\n // Prevent other usePress handlers from also handling this event.\n e.target.dispatchEvent(new PointerEvent('pointercancel', {bubbles: true}));\n if (onLongPress) {\n onLongPress({\n ...e,\n type: 'longpress'\n });\n }\n timeRef.current = undefined;\n }, threshold);\n\n // Prevent context menu, which may be opened on long press on touch devices\n if (e.pointerType === 'touch') {\n let onContextMenu = e => {\n e.preventDefault();\n };\n\n addGlobalListener(e.target, 'contextmenu', onContextMenu, {once: true});\n addGlobalListener(window, 'pointerup', () => {\n // If no contextmenu event is fired quickly after pointerup, remove the handler\n // so future context menu events outside a long press are not prevented.\n setTimeout(() => {\n removeGlobalListener(e.target, 'contextmenu', onContextMenu);\n }, 30);\n }, {once: true});\n }\n }\n },\n onPressEnd(e) {\n if (timeRef.current) {\n clearTimeout(timeRef.current);\n }\n\n if (onLongPressEnd && (e.pointerType === 'mouse' || e.pointerType === 'touch')) {\n onLongPressEnd({\n ...e,\n type: 'longpressend'\n });\n }\n }\n });\n\n let descriptionProps = useDescription(onLongPress && !isDisabled ? accessibilityDescription : undefined);\n\n return {\n longPressProps: mergeProps(pressProps, descriptionProps)\n };\n}\n"],"names":[],"version":3,"file":"useLongPress.module.js.map"}
1
+ {"mappings":";;;;AAAA;;;;;;;;;;CAUC;;;AAuCD,MAAM,0CAAoB;AAMnB,SAAS,0CAAa,KAAqB;IAChD,IAAI,cACF,UAAU,oBACV,gBAAgB,kBAChB,cAAc,eACd,WAAW,aACX,YAAY,mEACZ,wBAAwB,EACzB,GAAG;IAEJ,MAAM,UAAU,CAAA,GAAA,aAAK,EAA6C;IAClE,IAAI,qBAAC,iBAAiB,wBAAE,oBAAoB,EAAC,GAAG,CAAA,GAAA,yBAAiB;IAEjE,IAAI,cAAC,UAAU,EAAC,GAAG,CAAA,GAAA,yCAAO,EAAE;oBAC1B;QACA,cAAa,CAAC;YACZ,EAAE,mBAAmB;YACrB,IAAI,EAAE,WAAW,KAAK,WAAW,EAAE,WAAW,KAAK,SAAS;gBAC1D,IAAI,kBACF,iBAAiB;oBACf,GAAG,CAAC;oBACJ,MAAM;gBACR;gBAGF,QAAQ,OAAO,GAAG,WAAW;oBAC3B,iEAAiE;oBACjE,EAAE,MAAM,CAAC,aAAa,CAAC,IAAI,aAAa,iBAAiB;wBAAC,SAAS;oBAAI;oBAEvE,sFAAsF;oBACtF,IAAI,CAAA,GAAA,uBAAe,EAAE,EAAE,MAAM,EAAE,aAAa,KAAK,EAAE,MAAM,EACvD,CAAA,GAAA,4BAAoB,EAAE,EAAE,MAAM;oBAGhC,IAAI,aACF,YAAY;wBACV,GAAG,CAAC;wBACJ,MAAM;oBACR;oBAEF,QAAQ,OAAO,GAAG;gBACpB,GAAG;gBAEH,2EAA2E;gBAC3E,IAAI,EAAE,WAAW,KAAK,SAAS;oBAC7B,IAAI,gBAAgB,CAAA;wBAClB,EAAE,cAAc;oBAClB;oBAEA,kBAAkB,EAAE,MAAM,EAAE,eAAe,eAAe;wBAAC,MAAM;oBAAI;oBACrE,kBAAkB,QAAQ,aAAa;wBACrC,+EAA+E;wBAC/E,wEAAwE;wBACxE,WAAW;4BACT,qBAAqB,EAAE,MAAM,EAAE,eAAe;wBAChD,GAAG;oBACL,GAAG;wBAAC,MAAM;oBAAI;gBAChB;YACF;QACF;QACA,YAAW,CAAC;YACV,IAAI,QAAQ,OAAO,EACjB,aAAa,QAAQ,OAAO;YAG9B,IAAI,kBAAmB,CAAA,EAAE,WAAW,KAAK,WAAW,EAAE,WAAW,KAAK,OAAM,GAC1E,eAAe;gBACb,GAAG,CAAC;gBACJ,MAAM;YACR;QAEJ;IACF;IAEA,IAAI,mBAAmB,CAAA,GAAA,qBAAa,EAAE,eAAe,CAAC,aAAa,2BAA2B;IAE9F,OAAO;QACL,gBAAgB,CAAA,GAAA,iBAAS,EAAE,YAAY;IACzC;AACF","sources":["packages/@react-aria/interactions/src/useLongPress.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {DOMAttributes, FocusableElement, LongPressEvent} from '@react-types/shared';\nimport {focusWithoutScrolling, getOwnerDocument, mergeProps, useDescription, useGlobalListeners} from '@react-aria/utils';\nimport {usePress} from './usePress';\nimport {useRef} from 'react';\n\nexport interface LongPressProps {\n /** Whether long press events should be disabled. */\n isDisabled?: boolean,\n /** Handler that is called when a long press interaction starts. */\n onLongPressStart?: (e: LongPressEvent) => void,\n /**\n * Handler that is called when a long press interaction ends, either\n * over the target or when the pointer leaves the target.\n */\n onLongPressEnd?: (e: LongPressEvent) => void,\n /**\n * Handler that is called when the threshold time is met while\n * the press is over the target.\n */\n onLongPress?: (e: LongPressEvent) => void,\n /**\n * The amount of time in milliseconds to wait before triggering a long press.\n * @default 500ms\n */\n threshold?: number,\n /**\n * A description for assistive techology users indicating that a long press\n * action is available, e.g. \"Long press to open menu\".\n */\n accessibilityDescription?: string\n}\n\nexport interface LongPressResult {\n /** Props to spread on the target element. */\n longPressProps: DOMAttributes\n}\n\nconst DEFAULT_THRESHOLD = 500;\n\n/**\n * Handles long press interactions across mouse and touch devices. Supports a customizable time threshold,\n * accessibility description, and normalizes behavior across browsers and devices.\n */\nexport function useLongPress(props: LongPressProps): LongPressResult {\n let {\n isDisabled,\n onLongPressStart,\n onLongPressEnd,\n onLongPress,\n threshold = DEFAULT_THRESHOLD,\n accessibilityDescription\n } = props;\n\n const timeRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n let {addGlobalListener, removeGlobalListener} = useGlobalListeners();\n\n let {pressProps} = usePress({\n isDisabled,\n onPressStart(e) {\n e.continuePropagation();\n if (e.pointerType === 'mouse' || e.pointerType === 'touch') {\n if (onLongPressStart) {\n onLongPressStart({\n ...e,\n type: 'longpressstart'\n });\n }\n\n timeRef.current = setTimeout(() => {\n // Prevent other usePress handlers from also handling this event.\n e.target.dispatchEvent(new PointerEvent('pointercancel', {bubbles: true}));\n\n // Ensure target is focused. On touch devices, browsers typically focus on pointer up.\n if (getOwnerDocument(e.target).activeElement !== e.target) {\n focusWithoutScrolling(e.target as FocusableElement);\n }\n\n if (onLongPress) {\n onLongPress({\n ...e,\n type: 'longpress'\n });\n }\n timeRef.current = undefined;\n }, threshold);\n\n // Prevent context menu, which may be opened on long press on touch devices\n if (e.pointerType === 'touch') {\n let onContextMenu = e => {\n e.preventDefault();\n };\n\n addGlobalListener(e.target, 'contextmenu', onContextMenu, {once: true});\n addGlobalListener(window, 'pointerup', () => {\n // If no contextmenu event is fired quickly after pointerup, remove the handler\n // so future context menu events outside a long press are not prevented.\n setTimeout(() => {\n removeGlobalListener(e.target, 'contextmenu', onContextMenu);\n }, 30);\n }, {once: true});\n }\n }\n },\n onPressEnd(e) {\n if (timeRef.current) {\n clearTimeout(timeRef.current);\n }\n\n if (onLongPressEnd && (e.pointerType === 'mouse' || e.pointerType === 'touch')) {\n onLongPressEnd({\n ...e,\n type: 'longpressend'\n });\n }\n }\n });\n\n let descriptionProps = useDescription(onLongPress && !isDisabled ? accessibilityDescription : undefined);\n\n return {\n longPressProps: mergeProps(pressProps, descriptionProps)\n };\n}\n"],"names":[],"version":3,"file":"useLongPress.module.js.map"}
@@ -1,9 +1,11 @@
1
1
  var $f7e14e656343df57$exports = require("./textSelection.main.js");
2
2
  var $01d3f539e91688c8$exports = require("./context.main.js");
3
+ var $625cf83917e112ad$exports = require("./utils.main.js");
3
4
  var $bBqCQ$swchelperscjs_class_private_field_getcjs = require("@swc/helpers/cjs/_class_private_field_get.cjs");
4
5
  var $bBqCQ$swchelperscjs_class_private_field_initcjs = require("@swc/helpers/cjs/_class_private_field_init.cjs");
5
6
  var $bBqCQ$swchelperscjs_class_private_field_setcjs = require("@swc/helpers/cjs/_class_private_field_set.cjs");
6
7
  var $bBqCQ$reactariautils = require("@react-aria/utils");
8
+ var $bBqCQ$reactdom = require("react-dom");
7
9
  var $bBqCQ$react = require("react");
8
10
 
9
11
 
@@ -33,6 +35,8 @@ $parcel$export(module.exports, "usePress", () => $0294ea432cd92340$export$45712e
33
35
 
34
36
 
35
37
 
38
+
39
+
36
40
  function $0294ea432cd92340$var$usePressResponderContext(props) {
37
41
  // Consume context from <PressResponder> and merge with props.
38
42
  let context = (0, $bBqCQ$react.useContext)((0, $01d3f539e91688c8$exports.PressResponderContext));
@@ -95,13 +99,13 @@ function $0294ea432cd92340$export$45712eceda6fad21(props) {
95
99
  let ref = (0, $bBqCQ$react.useRef)({
96
100
  isPressed: false,
97
101
  ignoreEmulatedMouseEvents: false,
98
- ignoreClickAfterPress: false,
99
102
  didFirePressStart: false,
100
103
  isTriggeringEvent: false,
101
104
  activePointerId: null,
102
105
  target: null,
103
106
  isOverTarget: false,
104
- pointerType: null
107
+ pointerType: null,
108
+ disposables: []
105
109
  });
106
110
  let { addGlobalListener: addGlobalListener, removeAllGlobalListeners: removeAllGlobalListeners } = (0, $bBqCQ$reactariautils.useGlobalListeners)();
107
111
  let triggerPressStart = (0, $bBqCQ$reactariautils.useEffectEvent)((originalEvent, pointerType)=>{
@@ -123,7 +127,6 @@ function $0294ea432cd92340$export$45712eceda6fad21(props) {
123
127
  let triggerPressEnd = (0, $bBqCQ$reactariautils.useEffectEvent)((originalEvent, pointerType, wasPressed = true)=>{
124
128
  let state = ref.current;
125
129
  if (!state.didFirePressStart) return false;
126
- state.ignoreClickAfterPress = true;
127
130
  state.didFirePressStart = false;
128
131
  state.isTriggeringEvent = true;
129
132
  let shouldStopPropagation = true;
@@ -157,13 +160,15 @@ function $0294ea432cd92340$export$45712eceda6fad21(props) {
157
160
  let cancel = (0, $bBqCQ$reactariautils.useEffectEvent)((e)=>{
158
161
  let state = ref.current;
159
162
  if (state.isPressed && state.target) {
160
- if (state.isOverTarget && state.pointerType != null) triggerPressEnd($0294ea432cd92340$var$createEvent(state.target, e), state.pointerType, false);
163
+ if (state.didFirePressStart && state.pointerType != null) triggerPressEnd($0294ea432cd92340$var$createEvent(state.target, e), state.pointerType, false);
161
164
  state.isPressed = false;
162
165
  state.isOverTarget = false;
163
166
  state.activePointerId = null;
164
167
  state.pointerType = null;
165
168
  removeAllGlobalListeners();
166
169
  if (!allowTextSelectionOnPress) (0, $f7e14e656343df57$exports.restoreTextSelection)(state.target);
170
+ for (let dispose of state.disposables)dispose();
171
+ state.disposables = [];
167
172
  }
168
173
  });
169
174
  let cancelOnPointerExit = (0, $bBqCQ$reactariautils.useEffectEvent)((e)=>{
@@ -173,9 +178,9 @@ function $0294ea432cd92340$export$45712eceda6fad21(props) {
173
178
  let state = ref.current;
174
179
  let pressProps = {
175
180
  onKeyDown (e) {
176
- if ($0294ea432cd92340$var$isValidKeyboardEvent(e.nativeEvent, e.currentTarget) && e.currentTarget.contains(e.target)) {
181
+ if ($0294ea432cd92340$var$isValidKeyboardEvent(e.nativeEvent, e.currentTarget) && (0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent))) {
177
182
  var _state_metaKeyEvents;
178
- if ($0294ea432cd92340$var$shouldPreventDefaultKeyboard(e.target, e.key)) e.preventDefault();
183
+ if ($0294ea432cd92340$var$shouldPreventDefaultKeyboard((0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent), e.key)) e.preventDefault();
179
184
  // If the event is repeating, it may have started on a different element
180
185
  // after which focus moved to the current element. Ignore these events and
181
186
  // only handle the first key down event.
@@ -183,13 +188,14 @@ function $0294ea432cd92340$export$45712eceda6fad21(props) {
183
188
  if (!state.isPressed && !e.repeat) {
184
189
  state.target = e.currentTarget;
185
190
  state.isPressed = true;
191
+ state.pointerType = 'keyboard';
186
192
  shouldStopPropagation = triggerPressStart(e, 'keyboard');
187
193
  // Focus may move before the key up event, so register the event on the document
188
194
  // instead of the same element where the key down event occurred. Make it capturing so that it will trigger
189
195
  // before stopPropagation from useKeyboard on a child element may happen and thus we can still call triggerPress for the parent element.
190
196
  let originalTarget = e.currentTarget;
191
197
  let pressUp = (e)=>{
192
- if ($0294ea432cd92340$var$isValidKeyboardEvent(e, originalTarget) && !e.repeat && originalTarget.contains(e.target) && state.target) triggerPressUp($0294ea432cd92340$var$createEvent(state.target, e), 'keyboard');
198
+ if ($0294ea432cd92340$var$isValidKeyboardEvent(e, originalTarget) && !e.repeat && (0, $bBqCQ$reactariautils.nodeContains)(originalTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e)) && state.target) triggerPressUp($0294ea432cd92340$var$createEvent(state.target, e), 'keyboard');
193
199
  };
194
200
  addGlobalListener((0, $bBqCQ$reactariautils.getOwnerDocument)(e.currentTarget), 'keyup', (0, $bBqCQ$reactariautils.chain)(pressUp, onKeyUp), true);
195
201
  }
@@ -205,22 +211,24 @@ function $0294ea432cd92340$export$45712eceda6fad21(props) {
205
211
  } else if (e.key === 'Meta') state.metaKeyEvents = new Map();
206
212
  },
207
213
  onClick (e) {
208
- if (e && !e.currentTarget.contains(e.target)) return;
214
+ if (e && !(0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent))) return;
209
215
  if (e && e.button === 0 && !state.isTriggeringEvent && !(0, $bBqCQ$reactariautils.openLink).isOpening) {
210
216
  let shouldStopPropagation = true;
211
217
  if (isDisabled) e.preventDefault();
212
218
  // If triggered from a screen reader or by using element.click(),
213
219
  // trigger as if it were a keyboard click.
214
- if (!state.ignoreClickAfterPress && !state.ignoreEmulatedMouseEvents && !state.isPressed && (state.pointerType === 'virtual' || (0, $bBqCQ$reactariautils.isVirtualClick)(e.nativeEvent))) {
215
- // Ensure the element receives focus (VoiceOver on iOS does not do this)
216
- if (!isDisabled && !preventFocusOnPress) (0, $bBqCQ$reactariautils.focusWithoutScrolling)(e.currentTarget);
220
+ if (!state.ignoreEmulatedMouseEvents && !state.isPressed && (state.pointerType === 'virtual' || (0, $bBqCQ$reactariautils.isVirtualClick)(e.nativeEvent))) {
217
221
  let stopPressStart = triggerPressStart(e, 'virtual');
218
222
  let stopPressUp = triggerPressUp(e, 'virtual');
219
223
  let stopPressEnd = triggerPressEnd(e, 'virtual');
220
224
  shouldStopPropagation = stopPressStart && stopPressUp && stopPressEnd;
225
+ } else if (state.isPressed && state.pointerType !== 'keyboard') {
226
+ let pointerType = state.pointerType || e.nativeEvent.pointerType || 'virtual';
227
+ shouldStopPropagation = triggerPressEnd($0294ea432cd92340$var$createEvent(e.currentTarget, e), pointerType, true);
228
+ state.isOverTarget = false;
229
+ cancel(e);
221
230
  }
222
231
  state.ignoreEmulatedMouseEvents = false;
223
- state.ignoreClickAfterPress = false;
224
232
  if (shouldStopPropagation) e.stopPropagation();
225
233
  }
226
234
  }
@@ -229,14 +237,14 @@ function $0294ea432cd92340$export$45712eceda6fad21(props) {
229
237
  var _state_metaKeyEvents;
230
238
  if (state.isPressed && state.target && $0294ea432cd92340$var$isValidKeyboardEvent(e, state.target)) {
231
239
  var _state_metaKeyEvents1;
232
- if ($0294ea432cd92340$var$shouldPreventDefaultKeyboard(e.target, e.key)) e.preventDefault();
233
- let target = e.target;
234
- triggerPressEnd($0294ea432cd92340$var$createEvent(state.target, e), 'keyboard', state.target.contains(target));
240
+ if ($0294ea432cd92340$var$shouldPreventDefaultKeyboard((0, $bBqCQ$reactariautils.getEventTarget)(e), e.key)) e.preventDefault();
241
+ let target = (0, $bBqCQ$reactariautils.getEventTarget)(e);
242
+ triggerPressEnd($0294ea432cd92340$var$createEvent(state.target, e), 'keyboard', (0, $bBqCQ$reactariautils.nodeContains)(state.target, (0, $bBqCQ$reactariautils.getEventTarget)(e)));
235
243
  removeAllGlobalListeners();
236
244
  // If a link was triggered with a key other than Enter, open the URL ourselves.
237
245
  // This means the link has a role override, and the default browser behavior
238
246
  // only applies when using the Enter key.
239
- if (e.key !== 'Enter' && $0294ea432cd92340$var$isHTMLAnchorLink(state.target) && state.target.contains(target) && !e[$0294ea432cd92340$var$LINK_CLICKED]) {
247
+ if (e.key !== 'Enter' && $0294ea432cd92340$var$isHTMLAnchorLink(state.target) && (0, $bBqCQ$reactariautils.nodeContains)(state.target, target) && !e[$0294ea432cd92340$var$LINK_CLICKED]) {
240
248
  // Store a hidden property on the event so we only trigger link click once,
241
249
  // even if there are multiple usePress instances attached to the element.
242
250
  e[$0294ea432cd92340$var$LINK_CLICKED] = true;
@@ -257,7 +265,7 @@ function $0294ea432cd92340$export$45712eceda6fad21(props) {
257
265
  if (typeof PointerEvent !== 'undefined') {
258
266
  pressProps.onPointerDown = (e)=>{
259
267
  // Only handle left clicks, and ignore events that bubbled through portals.
260
- if (e.button !== 0 || !e.currentTarget.contains(e.target)) return;
268
+ if (e.button !== 0 || !(0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent))) return;
261
269
  // iOS safari fires pointer events from VoiceOver with incorrect coordinates/target.
262
270
  // Ignore and let the onClick handler take care of it instead.
263
271
  // https://bugs.webkit.org/show_bug.cgi?id=222627
@@ -266,9 +274,6 @@ function $0294ea432cd92340$export$45712eceda6fad21(props) {
266
274
  state.pointerType = 'virtual';
267
275
  return;
268
276
  }
269
- // Due to browser inconsistencies, especially on mobile browsers, we prevent
270
- // default on pointer down and handle focusing the pressable element ourselves.
271
- if ($0294ea432cd92340$var$shouldPreventDefaultDown(e.currentTarget)) e.preventDefault();
272
277
  state.pointerType = e.pointerType;
273
278
  let shouldStopPropagation = true;
274
279
  if (!state.isPressed) {
@@ -276,12 +281,11 @@ function $0294ea432cd92340$export$45712eceda6fad21(props) {
276
281
  state.isOverTarget = true;
277
282
  state.activePointerId = e.pointerId;
278
283
  state.target = e.currentTarget;
279
- if (!isDisabled && !preventFocusOnPress) (0, $bBqCQ$reactariautils.focusWithoutScrolling)(e.currentTarget);
280
284
  if (!allowTextSelectionOnPress) (0, $f7e14e656343df57$exports.disableTextSelection)(state.target);
281
285
  shouldStopPropagation = triggerPressStart(e, state.pointerType);
282
286
  // Release pointer capture so that touch interactions can leave the original target.
283
287
  // This enables onPointerLeave and onPointerEnter to fire.
284
- let target = e.target;
288
+ let target = (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent);
285
289
  if ('releasePointerCapture' in target) target.releasePointerCapture(e.pointerId);
286
290
  addGlobalListener((0, $bBqCQ$reactariautils.getOwnerDocument)(e.currentTarget), 'pointerup', onPointerUp, false);
287
291
  addGlobalListener((0, $bBqCQ$reactariautils.getOwnerDocument)(e.currentTarget), 'pointercancel', onPointerCancel, false);
@@ -289,18 +293,18 @@ function $0294ea432cd92340$export$45712eceda6fad21(props) {
289
293
  if (shouldStopPropagation) e.stopPropagation();
290
294
  };
291
295
  pressProps.onMouseDown = (e)=>{
292
- if (!e.currentTarget.contains(e.target)) return;
296
+ if (!(0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent))) return;
293
297
  if (e.button === 0) {
294
- // Chrome and Firefox on touch Windows devices require mouse down events
295
- // to be canceled in addition to pointer events, or an extra asynchronous
296
- // focus event will be fired.
297
- if ($0294ea432cd92340$var$shouldPreventDefaultDown(e.currentTarget)) e.preventDefault();
298
+ if (preventFocusOnPress) {
299
+ let dispose = (0, $625cf83917e112ad$exports.preventFocus)(e.target);
300
+ if (dispose) state.disposables.push(dispose);
301
+ }
298
302
  e.stopPropagation();
299
303
  }
300
304
  };
301
305
  pressProps.onPointerUp = (e)=>{
302
306
  // iOS fires pointerup with zero width and height, so check the pointerType recorded during pointerdown.
303
- if (!e.currentTarget.contains(e.target) || state.pointerType === 'virtual') return;
307
+ if (!(0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent)) || state.pointerType === 'virtual') return;
304
308
  // Only handle left clicks
305
309
  if (e.button === 0) triggerPressUp(e, state.pointerType || e.pointerType);
306
310
  };
@@ -319,46 +323,50 @@ function $0294ea432cd92340$export$45712eceda6fad21(props) {
319
323
  };
320
324
  let onPointerUp = (e)=>{
321
325
  if (e.pointerId === state.activePointerId && state.isPressed && e.button === 0 && state.target) {
322
- if (state.target.contains(e.target) && state.pointerType != null) triggerPressEnd($0294ea432cd92340$var$createEvent(state.target, e), state.pointerType);
323
- else if (state.isOverTarget && state.pointerType != null) triggerPressEnd($0294ea432cd92340$var$createEvent(state.target, e), state.pointerType, false);
324
- state.isPressed = false;
326
+ if ((0, $bBqCQ$reactariautils.nodeContains)(state.target, (0, $bBqCQ$reactariautils.getEventTarget)(e)) && state.pointerType != null) {
327
+ // Wait for onClick to fire onPress. This avoids browser issues when the DOM
328
+ // is mutated between onPointerUp and onClick, and is more compatible with third party libraries.
329
+ // https://github.com/adobe/react-spectrum/issues/1513
330
+ // https://issues.chromium.org/issues/40732224
331
+ // However, iOS and Android do not focus or fire onClick after a long press.
332
+ // We work around this by triggering a click ourselves after a timeout.
333
+ // This timeout is canceled during the click event in case the real one fires first.
334
+ // The timeout must be at least 32ms, because Safari on iOS delays the click event on
335
+ // non-form elements without certain ARIA roles (for hover emulation).
336
+ // https://github.com/WebKit/WebKit/blob/dccfae42bb29bd4bdef052e469f604a9387241c0/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm#L875-L892
337
+ let clicked = false;
338
+ let timeout = setTimeout(()=>{
339
+ if (state.isPressed && state.target instanceof HTMLElement) {
340
+ if (clicked) cancel(e);
341
+ else {
342
+ (0, $bBqCQ$reactariautils.focusWithoutScrolling)(state.target);
343
+ state.target.click();
344
+ }
345
+ }
346
+ }, 80);
347
+ // Use a capturing listener to track if a click occurred.
348
+ // If stopPropagation is called it may never reach our handler.
349
+ addGlobalListener(e.currentTarget, 'click', ()=>clicked = true, true);
350
+ state.disposables.push(()=>clearTimeout(timeout));
351
+ } else cancel(e);
352
+ // Ignore subsequent onPointerLeave event before onClick on touch devices.
325
353
  state.isOverTarget = false;
326
- state.activePointerId = null;
327
- state.pointerType = null;
328
- removeAllGlobalListeners();
329
- if (!allowTextSelectionOnPress) (0, $f7e14e656343df57$exports.restoreTextSelection)(state.target);
330
- // Prevent subsequent touchend event from triggering onClick on unrelated elements on Android. See below.
331
- // Both 'touch' and 'pen' pointerTypes trigger onTouchEnd, but 'mouse' does not.
332
- if ('ontouchend' in state.target && e.pointerType !== 'mouse') addGlobalListener(state.target, 'touchend', onTouchEnd, {
333
- once: true
334
- });
335
354
  }
336
355
  };
337
- // This is a workaround for an Android Chrome/Firefox issue where click events are fired on an incorrect element
338
- // if the original target is removed during onPointerUp (before onClick).
339
- // https://github.com/adobe/react-spectrum/issues/1513
340
- // https://issues.chromium.org/issues/40732224
341
- // Note: this event must be registered directly on the element, not via React props in order to work.
342
- // https://github.com/facebook/react/issues/9809
343
- let onTouchEnd = (e)=>{
344
- // Don't preventDefault if we actually want the default (e.g. submit/link click).
345
- if ($0294ea432cd92340$var$shouldPreventDefaultUp(e.currentTarget)) e.preventDefault();
346
- };
347
356
  let onPointerCancel = (e)=>{
348
357
  cancel(e);
349
358
  };
350
359
  pressProps.onDragStart = (e)=>{
351
- if (!e.currentTarget.contains(e.target)) return;
360
+ if (!(0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent))) return;
352
361
  // Safari does not call onPointerCancel when a drag starts, whereas Chrome and Firefox do.
353
362
  cancel(e);
354
363
  };
355
364
  } else {
365
+ // NOTE: this fallback branch is almost entirely used by unit tests.
366
+ // All browsers now support pointer events, but JSDOM still does not.
356
367
  pressProps.onMouseDown = (e)=>{
357
368
  // Only handle left clicks
358
- if (e.button !== 0 || !e.currentTarget.contains(e.target)) return;
359
- // Due to browser inconsistencies, especially on mobile browsers, we prevent
360
- // default on mouse down and handle focusing the pressable element ourselves.
361
- if ($0294ea432cd92340$var$shouldPreventDefaultDown(e.currentTarget)) e.preventDefault();
369
+ if (e.button !== 0 || !(0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent))) return;
362
370
  if (state.ignoreEmulatedMouseEvents) {
363
371
  e.stopPropagation();
364
372
  return;
@@ -367,13 +375,17 @@ function $0294ea432cd92340$export$45712eceda6fad21(props) {
367
375
  state.isOverTarget = true;
368
376
  state.target = e.currentTarget;
369
377
  state.pointerType = (0, $bBqCQ$reactariautils.isVirtualClick)(e.nativeEvent) ? 'virtual' : 'mouse';
370
- if (!isDisabled && !preventFocusOnPress) (0, $bBqCQ$reactariautils.focusWithoutScrolling)(e.currentTarget);
371
- let shouldStopPropagation = triggerPressStart(e, state.pointerType);
378
+ // Flush sync so that focus moved during react re-renders occurs before we yield back to the browser.
379
+ let shouldStopPropagation = (0, $bBqCQ$reactdom.flushSync)(()=>triggerPressStart(e, state.pointerType));
372
380
  if (shouldStopPropagation) e.stopPropagation();
381
+ if (preventFocusOnPress) {
382
+ let dispose = (0, $625cf83917e112ad$exports.preventFocus)(e.target);
383
+ if (dispose) state.disposables.push(dispose);
384
+ }
373
385
  addGlobalListener((0, $bBqCQ$reactariautils.getOwnerDocument)(e.currentTarget), 'mouseup', onMouseUp, false);
374
386
  };
375
387
  pressProps.onMouseEnter = (e)=>{
376
- if (!e.currentTarget.contains(e.target)) return;
388
+ if (!(0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent))) return;
377
389
  let shouldStopPropagation = true;
378
390
  if (state.isPressed && !state.ignoreEmulatedMouseEvents && state.pointerType != null) {
379
391
  state.isOverTarget = true;
@@ -382,7 +394,7 @@ function $0294ea432cd92340$export$45712eceda6fad21(props) {
382
394
  if (shouldStopPropagation) e.stopPropagation();
383
395
  };
384
396
  pressProps.onMouseLeave = (e)=>{
385
- if (!e.currentTarget.contains(e.target)) return;
397
+ if (!(0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent))) return;
386
398
  let shouldStopPropagation = true;
387
399
  if (state.isPressed && !state.ignoreEmulatedMouseEvents && state.pointerType != null) {
388
400
  state.isOverTarget = false;
@@ -392,24 +404,22 @@ function $0294ea432cd92340$export$45712eceda6fad21(props) {
392
404
  if (shouldStopPropagation) e.stopPropagation();
393
405
  };
394
406
  pressProps.onMouseUp = (e)=>{
395
- if (!e.currentTarget.contains(e.target)) return;
407
+ if (!(0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent))) return;
396
408
  if (!state.ignoreEmulatedMouseEvents && e.button === 0) triggerPressUp(e, state.pointerType || 'mouse');
397
409
  };
398
410
  let onMouseUp = (e)=>{
399
411
  // Only handle left clicks
400
412
  if (e.button !== 0) return;
401
- state.isPressed = false;
402
- removeAllGlobalListeners();
403
413
  if (state.ignoreEmulatedMouseEvents) {
404
414
  state.ignoreEmulatedMouseEvents = false;
405
415
  return;
406
416
  }
407
- if (state.target && $0294ea432cd92340$var$isOverTarget(e, state.target) && state.pointerType != null) triggerPressEnd($0294ea432cd92340$var$createEvent(state.target, e), state.pointerType);
408
- else if (state.target && state.isOverTarget && state.pointerType != null) triggerPressEnd($0294ea432cd92340$var$createEvent(state.target, e), state.pointerType, false);
417
+ if (state.target && state.target.contains(e.target) && state.pointerType != null) ;
418
+ else cancel(e);
409
419
  state.isOverTarget = false;
410
420
  };
411
421
  pressProps.onTouchStart = (e)=>{
412
- if (!e.currentTarget.contains(e.target)) return;
422
+ if (!(0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent))) return;
413
423
  let touch = $0294ea432cd92340$var$getTouchFromEvent(e.nativeEvent);
414
424
  if (!touch) return;
415
425
  state.activePointerId = touch.identifier;
@@ -418,16 +428,13 @@ function $0294ea432cd92340$export$45712eceda6fad21(props) {
418
428
  state.isPressed = true;
419
429
  state.target = e.currentTarget;
420
430
  state.pointerType = 'touch';
421
- // Due to browser inconsistencies, especially on mobile browsers, we prevent default
422
- // on the emulated mouse event and handle focusing the pressable element ourselves.
423
- if (!isDisabled && !preventFocusOnPress) (0, $bBqCQ$reactariautils.focusWithoutScrolling)(e.currentTarget);
424
431
  if (!allowTextSelectionOnPress) (0, $f7e14e656343df57$exports.disableTextSelection)(state.target);
425
432
  let shouldStopPropagation = triggerPressStart($0294ea432cd92340$var$createTouchEvent(state.target, e), state.pointerType);
426
433
  if (shouldStopPropagation) e.stopPropagation();
427
434
  addGlobalListener((0, $bBqCQ$reactariautils.getOwnerWindow)(e.currentTarget), 'scroll', onScroll, true);
428
435
  };
429
436
  pressProps.onTouchMove = (e)=>{
430
- if (!e.currentTarget.contains(e.target)) return;
437
+ if (!(0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent))) return;
431
438
  if (!state.isPressed) {
432
439
  e.stopPropagation();
433
440
  return;
@@ -447,7 +454,7 @@ function $0294ea432cd92340$export$45712eceda6fad21(props) {
447
454
  if (shouldStopPropagation) e.stopPropagation();
448
455
  };
449
456
  pressProps.onTouchEnd = (e)=>{
450
- if (!e.currentTarget.contains(e.target)) return;
457
+ if (!(0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent))) return;
451
458
  if (!state.isPressed) {
452
459
  e.stopPropagation();
453
460
  return;
@@ -467,12 +474,12 @@ function $0294ea432cd92340$export$45712eceda6fad21(props) {
467
474
  removeAllGlobalListeners();
468
475
  };
469
476
  pressProps.onTouchCancel = (e)=>{
470
- if (!e.currentTarget.contains(e.target)) return;
477
+ if (!(0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent))) return;
471
478
  e.stopPropagation();
472
479
  if (state.isPressed) cancel($0294ea432cd92340$var$createTouchEvent(state.target, e));
473
480
  };
474
481
  let onScroll = (e)=>{
475
- if (state.isPressed && e.target.contains(state.target)) cancel({
482
+ if (state.isPressed && (0, $bBqCQ$reactariautils.nodeContains)((0, $bBqCQ$reactariautils.getEventTarget)(e), state.target)) cancel({
476
483
  currentTarget: state.target,
477
484
  shiftKey: false,
478
485
  ctrlKey: false,
@@ -481,7 +488,7 @@ function $0294ea432cd92340$export$45712eceda6fad21(props) {
481
488
  });
482
489
  };
483
490
  pressProps.onDragStart = (e)=>{
484
- if (!e.currentTarget.contains(e.target)) return;
491
+ if (!(0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent))) return;
485
492
  cancel(e);
486
493
  };
487
494
  }
@@ -500,10 +507,12 @@ function $0294ea432cd92340$export$45712eceda6fad21(props) {
500
507
  ]);
501
508
  // Remove user-select: none in case component unmounts immediately after pressStart
502
509
  (0, $bBqCQ$react.useEffect)(()=>{
510
+ let state = ref.current;
503
511
  return ()=>{
504
- var _ref_current_target;
505
- if (!allowTextSelectionOnPress) // eslint-disable-next-line react-hooks/exhaustive-deps
506
- (0, $f7e14e656343df57$exports.restoreTextSelection)((_ref_current_target = ref.current.target) !== null && _ref_current_target !== void 0 ? _ref_current_target : undefined);
512
+ var _state_target;
513
+ if (!allowTextSelectionOnPress) (0, $f7e14e656343df57$exports.restoreTextSelection)((_state_target = state.target) !== null && _state_target !== void 0 ? _state_target : undefined);
514
+ for (let dispose of state.disposables)dispose();
515
+ state.disposables = [];
507
516
  };
508
517
  }, [
509
518
  allowTextSelectionOnPress
@@ -594,10 +603,6 @@ function $0294ea432cd92340$var$isOverTarget(point, target) {
594
603
  let pointRect = $0294ea432cd92340$var$getPointClientRect(point);
595
604
  return $0294ea432cd92340$var$areRectanglesOverlapping(rect, pointRect);
596
605
  }
597
- function $0294ea432cd92340$var$shouldPreventDefaultDown(target) {
598
- // We cannot prevent default if the target is a draggable element.
599
- return !(target instanceof HTMLElement) || !target.hasAttribute('draggable');
600
- }
601
606
  function $0294ea432cd92340$var$shouldPreventDefaultUp(target) {
602
607
  if (target instanceof HTMLInputElement) return false;
603
608
  if (target instanceof HTMLButtonElement) return target.type !== 'submit' && target.type !== 'reset';