index.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. var $g2vWm$babelruntimehelpersextends = require("@babel/runtime/helpers/extends");
  2. var $g2vWm$react = require("react");
  3. var $g2vWm$radixuiprimitive = require("@radix-ui/primitive");
  4. var $g2vWm$radixuireactprimitive = require("@radix-ui/react-primitive");
  5. var $g2vWm$radixuireactcomposerefs = require("@radix-ui/react-compose-refs");
  6. var $g2vWm$radixuireactusecallbackref = require("@radix-ui/react-use-callback-ref");
  7. var $g2vWm$radixuireactuseescapekeydown = require("@radix-ui/react-use-escape-keydown");
  8. function $parcel$export(e, n, v, s) {
  9. Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
  10. }
  11. function $parcel$interopDefault(a) {
  12. return a && a.__esModule ? a.default : a;
  13. }
  14. $parcel$export(module.exports, "DismissableLayer", () => $d715e0554b679f1f$export$177fb62ff3ec1f22);
  15. $parcel$export(module.exports, "DismissableLayerBranch", () => $d715e0554b679f1f$export$4d5eb2109db14228);
  16. $parcel$export(module.exports, "Root", () => $d715e0554b679f1f$export$be92b6f5f03c0fe9);
  17. $parcel$export(module.exports, "Branch", () => $d715e0554b679f1f$export$aecb2ddcb55c95be);
  18. /* -------------------------------------------------------------------------------------------------
  19. * DismissableLayer
  20. * -----------------------------------------------------------------------------------------------*/ const $d715e0554b679f1f$var$DISMISSABLE_LAYER_NAME = 'DismissableLayer';
  21. const $d715e0554b679f1f$var$CONTEXT_UPDATE = 'dismissableLayer.update';
  22. const $d715e0554b679f1f$var$POINTER_DOWN_OUTSIDE = 'dismissableLayer.pointerDownOutside';
  23. const $d715e0554b679f1f$var$FOCUS_OUTSIDE = 'dismissableLayer.focusOutside';
  24. let $d715e0554b679f1f$var$originalBodyPointerEvents;
  25. const $d715e0554b679f1f$var$DismissableLayerContext = /*#__PURE__*/ $g2vWm$react.createContext({
  26. layers: new Set(),
  27. layersWithOutsidePointerEventsDisabled: new Set(),
  28. branches: new Set()
  29. });
  30. const $d715e0554b679f1f$export$177fb62ff3ec1f22 = /*#__PURE__*/ $g2vWm$react.forwardRef((props, forwardedRef)=>{
  31. var _node$ownerDocument;
  32. const { disableOutsidePointerEvents: disableOutsidePointerEvents = false , onEscapeKeyDown: onEscapeKeyDown , onPointerDownOutside: onPointerDownOutside , onFocusOutside: onFocusOutside , onInteractOutside: onInteractOutside , onDismiss: onDismiss , ...layerProps } = props;
  33. const context = $g2vWm$react.useContext($d715e0554b679f1f$var$DismissableLayerContext);
  34. const [node1, setNode] = $g2vWm$react.useState(null);
  35. const ownerDocument = (_node$ownerDocument = node1 === null || node1 === void 0 ? void 0 : node1.ownerDocument) !== null && _node$ownerDocument !== void 0 ? _node$ownerDocument : globalThis === null || globalThis === void 0 ? void 0 : globalThis.document;
  36. const [, force] = $g2vWm$react.useState({});
  37. const composedRefs = $g2vWm$radixuireactcomposerefs.useComposedRefs(forwardedRef, (node)=>setNode(node)
  38. );
  39. const layers = Array.from(context.layers);
  40. const [highestLayerWithOutsidePointerEventsDisabled] = [
  41. ...context.layersWithOutsidePointerEventsDisabled
  42. ].slice(-1); // prettier-ignore
  43. const highestLayerWithOutsidePointerEventsDisabledIndex = layers.indexOf(highestLayerWithOutsidePointerEventsDisabled); // prettier-ignore
  44. const index = node1 ? layers.indexOf(node1) : -1;
  45. const isBodyPointerEventsDisabled = context.layersWithOutsidePointerEventsDisabled.size > 0;
  46. const isPointerEventsEnabled = index >= highestLayerWithOutsidePointerEventsDisabledIndex;
  47. const pointerDownOutside = $d715e0554b679f1f$var$usePointerDownOutside((event)=>{
  48. const target = event.target;
  49. const isPointerDownOnBranch = [
  50. ...context.branches
  51. ].some((branch)=>branch.contains(target)
  52. );
  53. if (!isPointerEventsEnabled || isPointerDownOnBranch) return;
  54. onPointerDownOutside === null || onPointerDownOutside === void 0 || onPointerDownOutside(event);
  55. onInteractOutside === null || onInteractOutside === void 0 || onInteractOutside(event);
  56. if (!event.defaultPrevented) onDismiss === null || onDismiss === void 0 || onDismiss();
  57. }, ownerDocument);
  58. const focusOutside = $d715e0554b679f1f$var$useFocusOutside((event)=>{
  59. const target = event.target;
  60. const isFocusInBranch = [
  61. ...context.branches
  62. ].some((branch)=>branch.contains(target)
  63. );
  64. if (isFocusInBranch) return;
  65. onFocusOutside === null || onFocusOutside === void 0 || onFocusOutside(event);
  66. onInteractOutside === null || onInteractOutside === void 0 || onInteractOutside(event);
  67. if (!event.defaultPrevented) onDismiss === null || onDismiss === void 0 || onDismiss();
  68. }, ownerDocument);
  69. $g2vWm$radixuireactuseescapekeydown.useEscapeKeydown((event)=>{
  70. const isHighestLayer = index === context.layers.size - 1;
  71. if (!isHighestLayer) return;
  72. onEscapeKeyDown === null || onEscapeKeyDown === void 0 || onEscapeKeyDown(event);
  73. if (!event.defaultPrevented && onDismiss) {
  74. event.preventDefault();
  75. onDismiss();
  76. }
  77. }, ownerDocument);
  78. $g2vWm$react.useEffect(()=>{
  79. if (!node1) return;
  80. if (disableOutsidePointerEvents) {
  81. if (context.layersWithOutsidePointerEventsDisabled.size === 0) {
  82. $d715e0554b679f1f$var$originalBodyPointerEvents = ownerDocument.body.style.pointerEvents;
  83. ownerDocument.body.style.pointerEvents = 'none';
  84. }
  85. context.layersWithOutsidePointerEventsDisabled.add(node1);
  86. }
  87. context.layers.add(node1);
  88. $d715e0554b679f1f$var$dispatchUpdate();
  89. return ()=>{
  90. if (disableOutsidePointerEvents && context.layersWithOutsidePointerEventsDisabled.size === 1) ownerDocument.body.style.pointerEvents = $d715e0554b679f1f$var$originalBodyPointerEvents;
  91. };
  92. }, [
  93. node1,
  94. ownerDocument,
  95. disableOutsidePointerEvents,
  96. context
  97. ]);
  98. /**
  99. * We purposefully prevent combining this effect with the `disableOutsidePointerEvents` effect
  100. * because a change to `disableOutsidePointerEvents` would remove this layer from the stack
  101. * and add it to the end again so the layering order wouldn't be _creation order_.
  102. * We only want them to be removed from context stacks when unmounted.
  103. */ $g2vWm$react.useEffect(()=>{
  104. return ()=>{
  105. if (!node1) return;
  106. context.layers.delete(node1);
  107. context.layersWithOutsidePointerEventsDisabled.delete(node1);
  108. $d715e0554b679f1f$var$dispatchUpdate();
  109. };
  110. }, [
  111. node1,
  112. context
  113. ]);
  114. $g2vWm$react.useEffect(()=>{
  115. const handleUpdate = ()=>force({})
  116. ;
  117. document.addEventListener($d715e0554b679f1f$var$CONTEXT_UPDATE, handleUpdate);
  118. return ()=>document.removeEventListener($d715e0554b679f1f$var$CONTEXT_UPDATE, handleUpdate)
  119. ;
  120. }, []);
  121. return /*#__PURE__*/ $g2vWm$react.createElement($g2vWm$radixuireactprimitive.Primitive.div, ($parcel$interopDefault($g2vWm$babelruntimehelpersextends))({}, layerProps, {
  122. ref: composedRefs,
  123. style: {
  124. pointerEvents: isBodyPointerEventsDisabled ? isPointerEventsEnabled ? 'auto' : 'none' : undefined,
  125. ...props.style
  126. },
  127. onFocusCapture: $g2vWm$radixuiprimitive.composeEventHandlers(props.onFocusCapture, focusOutside.onFocusCapture),
  128. onBlurCapture: $g2vWm$radixuiprimitive.composeEventHandlers(props.onBlurCapture, focusOutside.onBlurCapture),
  129. onPointerDownCapture: $g2vWm$radixuiprimitive.composeEventHandlers(props.onPointerDownCapture, pointerDownOutside.onPointerDownCapture)
  130. }));
  131. });
  132. /*#__PURE__*/ Object.assign($d715e0554b679f1f$export$177fb62ff3ec1f22, {
  133. displayName: $d715e0554b679f1f$var$DISMISSABLE_LAYER_NAME
  134. });
  135. /* -------------------------------------------------------------------------------------------------
  136. * DismissableLayerBranch
  137. * -----------------------------------------------------------------------------------------------*/ const $d715e0554b679f1f$var$BRANCH_NAME = 'DismissableLayerBranch';
  138. const $d715e0554b679f1f$export$4d5eb2109db14228 = /*#__PURE__*/ $g2vWm$react.forwardRef((props, forwardedRef)=>{
  139. const context = $g2vWm$react.useContext($d715e0554b679f1f$var$DismissableLayerContext);
  140. const ref = $g2vWm$react.useRef(null);
  141. const composedRefs = $g2vWm$radixuireactcomposerefs.useComposedRefs(forwardedRef, ref);
  142. $g2vWm$react.useEffect(()=>{
  143. const node = ref.current;
  144. if (node) {
  145. context.branches.add(node);
  146. return ()=>{
  147. context.branches.delete(node);
  148. };
  149. }
  150. }, [
  151. context.branches
  152. ]);
  153. return /*#__PURE__*/ $g2vWm$react.createElement($g2vWm$radixuireactprimitive.Primitive.div, ($parcel$interopDefault($g2vWm$babelruntimehelpersextends))({}, props, {
  154. ref: composedRefs
  155. }));
  156. });
  157. /*#__PURE__*/ Object.assign($d715e0554b679f1f$export$4d5eb2109db14228, {
  158. displayName: $d715e0554b679f1f$var$BRANCH_NAME
  159. });
  160. /* -----------------------------------------------------------------------------------------------*/ /**
  161. * Listens for `pointerdown` outside a react subtree. We use `pointerdown` rather than `pointerup`
  162. * to mimic layer dismissing behaviour present in OS.
  163. * Returns props to pass to the node we want to check for outside events.
  164. */ function $d715e0554b679f1f$var$usePointerDownOutside(onPointerDownOutside, ownerDocument = globalThis === null || globalThis === void 0 ? void 0 : globalThis.document) {
  165. const handlePointerDownOutside = $g2vWm$radixuireactusecallbackref.useCallbackRef(onPointerDownOutside);
  166. const isPointerInsideReactTreeRef = $g2vWm$react.useRef(false);
  167. const handleClickRef = $g2vWm$react.useRef(()=>{});
  168. $g2vWm$react.useEffect(()=>{
  169. const handlePointerDown = (event)=>{
  170. if (event.target && !isPointerInsideReactTreeRef.current) {
  171. const eventDetail = {
  172. originalEvent: event
  173. };
  174. function handleAndDispatchPointerDownOutsideEvent() {
  175. $d715e0554b679f1f$var$handleAndDispatchCustomEvent($d715e0554b679f1f$var$POINTER_DOWN_OUTSIDE, handlePointerDownOutside, eventDetail, {
  176. discrete: true
  177. });
  178. }
  179. /**
  180. * On touch devices, we need to wait for a click event because browsers implement
  181. * a ~350ms delay between the time the user stops touching the display and when the
  182. * browser executres events. We need to ensure we don't reactivate pointer-events within
  183. * this timeframe otherwise the browser may execute events that should have been prevented.
  184. *
  185. * Additionally, this also lets us deal automatically with cancellations when a click event
  186. * isn't raised because the page was considered scrolled/drag-scrolled, long-pressed, etc.
  187. *
  188. * This is why we also continuously remove the previous listener, because we cannot be
  189. * certain that it was raised, and therefore cleaned-up.
  190. */ if (event.pointerType === 'touch') {
  191. ownerDocument.removeEventListener('click', handleClickRef.current);
  192. handleClickRef.current = handleAndDispatchPointerDownOutsideEvent;
  193. ownerDocument.addEventListener('click', handleClickRef.current, {
  194. once: true
  195. });
  196. } else handleAndDispatchPointerDownOutsideEvent();
  197. } else // We need to remove the event listener in case the outside click has been canceled.
  198. // See: https://github.com/radix-ui/primitives/issues/2171
  199. ownerDocument.removeEventListener('click', handleClickRef.current);
  200. isPointerInsideReactTreeRef.current = false;
  201. };
  202. /**
  203. * if this hook executes in a component that mounts via a `pointerdown` event, the event
  204. * would bubble up to the document and trigger a `pointerDownOutside` event. We avoid
  205. * this by delaying the event listener registration on the document.
  206. * This is not React specific, but rather how the DOM works, ie:
  207. * ```
  208. * button.addEventListener('pointerdown', () => {
  209. * console.log('I will log');
  210. * document.addEventListener('pointerdown', () => {
  211. * console.log('I will also log');
  212. * })
  213. * });
  214. */ const timerId = window.setTimeout(()=>{
  215. ownerDocument.addEventListener('pointerdown', handlePointerDown);
  216. }, 0);
  217. return ()=>{
  218. window.clearTimeout(timerId);
  219. ownerDocument.removeEventListener('pointerdown', handlePointerDown);
  220. ownerDocument.removeEventListener('click', handleClickRef.current);
  221. };
  222. }, [
  223. ownerDocument,
  224. handlePointerDownOutside
  225. ]);
  226. return {
  227. // ensures we check React component tree (not just DOM tree)
  228. onPointerDownCapture: ()=>isPointerInsideReactTreeRef.current = true
  229. };
  230. }
  231. /**
  232. * Listens for when focus happens outside a react subtree.
  233. * Returns props to pass to the root (node) of the subtree we want to check.
  234. */ function $d715e0554b679f1f$var$useFocusOutside(onFocusOutside, ownerDocument = globalThis === null || globalThis === void 0 ? void 0 : globalThis.document) {
  235. const handleFocusOutside = $g2vWm$radixuireactusecallbackref.useCallbackRef(onFocusOutside);
  236. const isFocusInsideReactTreeRef = $g2vWm$react.useRef(false);
  237. $g2vWm$react.useEffect(()=>{
  238. const handleFocus = (event)=>{
  239. if (event.target && !isFocusInsideReactTreeRef.current) {
  240. const eventDetail = {
  241. originalEvent: event
  242. };
  243. $d715e0554b679f1f$var$handleAndDispatchCustomEvent($d715e0554b679f1f$var$FOCUS_OUTSIDE, handleFocusOutside, eventDetail, {
  244. discrete: false
  245. });
  246. }
  247. };
  248. ownerDocument.addEventListener('focusin', handleFocus);
  249. return ()=>ownerDocument.removeEventListener('focusin', handleFocus)
  250. ;
  251. }, [
  252. ownerDocument,
  253. handleFocusOutside
  254. ]);
  255. return {
  256. onFocusCapture: ()=>isFocusInsideReactTreeRef.current = true
  257. ,
  258. onBlurCapture: ()=>isFocusInsideReactTreeRef.current = false
  259. };
  260. }
  261. function $d715e0554b679f1f$var$dispatchUpdate() {
  262. const event = new CustomEvent($d715e0554b679f1f$var$CONTEXT_UPDATE);
  263. document.dispatchEvent(event);
  264. }
  265. function $d715e0554b679f1f$var$handleAndDispatchCustomEvent(name, handler, detail, { discrete: discrete }) {
  266. const target = detail.originalEvent.target;
  267. const event = new CustomEvent(name, {
  268. bubbles: false,
  269. cancelable: true,
  270. detail: detail
  271. });
  272. if (handler) target.addEventListener(name, handler, {
  273. once: true
  274. });
  275. if (discrete) $g2vWm$radixuireactprimitive.dispatchDiscreteCustomEvent(target, event);
  276. else target.dispatchEvent(event);
  277. }
  278. const $d715e0554b679f1f$export$be92b6f5f03c0fe9 = $d715e0554b679f1f$export$177fb62ff3ec1f22;
  279. const $d715e0554b679f1f$export$aecb2ddcb55c95be = $d715e0554b679f1f$export$4d5eb2109db14228;
  280. //# sourceMappingURL=index.js.map