UNPKG

ivt

Version:

Ivt Components Library

251 lines (247 loc) 10.1 kB
import * as React from 'react'; import { P as Primitive, c as composeEventHandlers, d as dispatchDiscreteCustomEvent } from './index-Dsw02Eup.mjs'; import { u as useComposedRefs } from './index-D4jPaBZ2.mjs'; import { u as useCallbackRef } from './index-DC-gAYjS.mjs'; import { jsx } from 'react/jsx-runtime'; // packages/react/use-escape-keydown/src/use-escape-keydown.tsx function useEscapeKeydown(onEscapeKeyDownProp, ownerDocument = globalThis?.document) { const onEscapeKeyDown = useCallbackRef(onEscapeKeyDownProp); React.useEffect(()=>{ const handleKeyDown = (event)=>{ if (event.key === "Escape") { onEscapeKeyDown(event); } }; ownerDocument.addEventListener("keydown", handleKeyDown, { capture: true }); return ()=>ownerDocument.removeEventListener("keydown", handleKeyDown, { capture: true }); }, [ onEscapeKeyDown, ownerDocument ]); } var DISMISSABLE_LAYER_NAME = "DismissableLayer"; var CONTEXT_UPDATE = "dismissableLayer.update"; var POINTER_DOWN_OUTSIDE = "dismissableLayer.pointerDownOutside"; var FOCUS_OUTSIDE = "dismissableLayer.focusOutside"; var originalBodyPointerEvents; var DismissableLayerContext = React.createContext({ layers: /* @__PURE__ */ new Set(), layersWithOutsidePointerEventsDisabled: /* @__PURE__ */ new Set(), branches: /* @__PURE__ */ new Set() }); var DismissableLayer = React.forwardRef((props, forwardedRef)=>{ const { disableOutsidePointerEvents = false, onEscapeKeyDown, onPointerDownOutside, onFocusOutside, onInteractOutside, onDismiss, ...layerProps } = props; const context = React.useContext(DismissableLayerContext); const [node, setNode] = React.useState(null); const ownerDocument = node?.ownerDocument ?? globalThis?.document; const [, force] = React.useState({}); const composedRefs = useComposedRefs(forwardedRef, (node2)=>setNode(node2)); const layers = Array.from(context.layers); const [highestLayerWithOutsidePointerEventsDisabled] = [ ...context.layersWithOutsidePointerEventsDisabled ].slice(-1); const highestLayerWithOutsidePointerEventsDisabledIndex = layers.indexOf(highestLayerWithOutsidePointerEventsDisabled); const index = node ? layers.indexOf(node) : -1; const isBodyPointerEventsDisabled = context.layersWithOutsidePointerEventsDisabled.size > 0; const isPointerEventsEnabled = index >= highestLayerWithOutsidePointerEventsDisabledIndex; const pointerDownOutside = usePointerDownOutside((event)=>{ const target = event.target; const isPointerDownOnBranch = [ ...context.branches ].some((branch)=>branch.contains(target)); if (!isPointerEventsEnabled || isPointerDownOnBranch) return; onPointerDownOutside?.(event); onInteractOutside?.(event); if (!event.defaultPrevented) onDismiss?.(); }, ownerDocument); const focusOutside = useFocusOutside((event)=>{ const target = event.target; const isFocusInBranch = [ ...context.branches ].some((branch)=>branch.contains(target)); if (isFocusInBranch) return; onFocusOutside?.(event); onInteractOutside?.(event); if (!event.defaultPrevented) onDismiss?.(); }, ownerDocument); useEscapeKeydown((event)=>{ const isHighestLayer = index === context.layers.size - 1; if (!isHighestLayer) return; onEscapeKeyDown?.(event); if (!event.defaultPrevented && onDismiss) { event.preventDefault(); onDismiss(); } }, ownerDocument); React.useEffect(()=>{ if (!node) return; if (disableOutsidePointerEvents) { if (context.layersWithOutsidePointerEventsDisabled.size === 0) { originalBodyPointerEvents = ownerDocument.body.style.pointerEvents; ownerDocument.body.style.pointerEvents = "none"; } context.layersWithOutsidePointerEventsDisabled.add(node); } context.layers.add(node); dispatchUpdate(); return ()=>{ if (disableOutsidePointerEvents && context.layersWithOutsidePointerEventsDisabled.size === 1) { ownerDocument.body.style.pointerEvents = originalBodyPointerEvents; } }; }, [ node, ownerDocument, disableOutsidePointerEvents, context ]); React.useEffect(()=>{ return ()=>{ if (!node) return; context.layers.delete(node); context.layersWithOutsidePointerEventsDisabled.delete(node); dispatchUpdate(); }; }, [ node, context ]); React.useEffect(()=>{ const handleUpdate = ()=>force({}); document.addEventListener(CONTEXT_UPDATE, handleUpdate); return ()=>document.removeEventListener(CONTEXT_UPDATE, handleUpdate); }, []); return /* @__PURE__ */ jsx(Primitive.div, { ...layerProps, ref: composedRefs, style: { pointerEvents: isBodyPointerEventsDisabled ? isPointerEventsEnabled ? "auto" : "none" : void 0, ...props.style }, onFocusCapture: composeEventHandlers(props.onFocusCapture, focusOutside.onFocusCapture), onBlurCapture: composeEventHandlers(props.onBlurCapture, focusOutside.onBlurCapture), onPointerDownCapture: composeEventHandlers(props.onPointerDownCapture, pointerDownOutside.onPointerDownCapture) }); }); DismissableLayer.displayName = DISMISSABLE_LAYER_NAME; var BRANCH_NAME = "DismissableLayerBranch"; var DismissableLayerBranch = React.forwardRef((props, forwardedRef)=>{ const context = React.useContext(DismissableLayerContext); const ref = React.useRef(null); const composedRefs = useComposedRefs(forwardedRef, ref); React.useEffect(()=>{ const node = ref.current; if (node) { context.branches.add(node); return ()=>{ context.branches.delete(node); }; } }, [ context.branches ]); return /* @__PURE__ */ jsx(Primitive.div, { ...props, ref: composedRefs }); }); DismissableLayerBranch.displayName = BRANCH_NAME; function usePointerDownOutside(onPointerDownOutside, ownerDocument = globalThis?.document) { const handlePointerDownOutside = useCallbackRef(onPointerDownOutside); const isPointerInsideReactTreeRef = React.useRef(false); const handleClickRef = React.useRef(()=>{}); React.useEffect(()=>{ const handlePointerDown = (event)=>{ if (event.target && !isPointerInsideReactTreeRef.current) { let handleAndDispatchPointerDownOutsideEvent2 = function() { handleAndDispatchCustomEvent(POINTER_DOWN_OUTSIDE, handlePointerDownOutside, eventDetail, { discrete: true }); }; const eventDetail = { originalEvent: event }; if (event.pointerType === "touch") { ownerDocument.removeEventListener("click", handleClickRef.current); handleClickRef.current = handleAndDispatchPointerDownOutsideEvent2; ownerDocument.addEventListener("click", handleClickRef.current, { once: true }); } else { handleAndDispatchPointerDownOutsideEvent2(); } } else { ownerDocument.removeEventListener("click", handleClickRef.current); } isPointerInsideReactTreeRef.current = false; }; const timerId = window.setTimeout(()=>{ ownerDocument.addEventListener("pointerdown", handlePointerDown); }, 0); return ()=>{ window.clearTimeout(timerId); ownerDocument.removeEventListener("pointerdown", handlePointerDown); ownerDocument.removeEventListener("click", handleClickRef.current); }; }, [ ownerDocument, handlePointerDownOutside ]); return { // ensures we check React component tree (not just DOM tree) onPointerDownCapture: ()=>isPointerInsideReactTreeRef.current = true }; } function useFocusOutside(onFocusOutside, ownerDocument = globalThis?.document) { const handleFocusOutside = useCallbackRef(onFocusOutside); const isFocusInsideReactTreeRef = React.useRef(false); React.useEffect(()=>{ const handleFocus = (event)=>{ if (event.target && !isFocusInsideReactTreeRef.current) { const eventDetail = { originalEvent: event }; handleAndDispatchCustomEvent(FOCUS_OUTSIDE, handleFocusOutside, eventDetail, { discrete: false }); } }; ownerDocument.addEventListener("focusin", handleFocus); return ()=>ownerDocument.removeEventListener("focusin", handleFocus); }, [ ownerDocument, handleFocusOutside ]); return { onFocusCapture: ()=>isFocusInsideReactTreeRef.current = true, onBlurCapture: ()=>isFocusInsideReactTreeRef.current = false }; } function dispatchUpdate() { const event = new CustomEvent(CONTEXT_UPDATE); document.dispatchEvent(event); } function handleAndDispatchCustomEvent(name, handler, detail, { discrete }) { const target = detail.originalEvent.target; const event = new CustomEvent(name, { bubbles: false, cancelable: true, detail }); if (handler) target.addEventListener(name, handler, { once: true }); if (discrete) { dispatchDiscreteCustomEvent(target, event); } else { target.dispatchEvent(event); } } var Root = DismissableLayer; var Branch = DismissableLayerBranch; export { Branch as B, DismissableLayer as D, Root as R }; //# sourceMappingURL=index-4NpeUekv.mjs.map