UNPKG

@ariakit/react-core

Version:

Ariakit React core

282 lines (242 loc) 9.88 kB
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); var _L6CLLK7Rcjs = require('./L6CLLK7R.cjs'); var _TPPZG3JZcjs = require('./TPPZG3JZ.cjs'); var _3OWJJMJRcjs = require('./3OWJJMJR.cjs'); var _7PVRUA4Ccjs = require('./7PVRUA4C.cjs'); var _WBFXWJUHcjs = require('./WBFXWJUH.cjs'); var _MZ2HG624cjs = require('./MZ2HG624.cjs'); // src/hovercard/hovercard.tsx var _dom = require('@ariakit/core/utils/dom'); var _events = require('@ariakit/core/utils/events'); var _focus = require('@ariakit/core/utils/focus'); var _misc = require('@ariakit/core/utils/misc'); var _store = require('@ariakit/core/utils/store'); var _react = require('react'); var _jsxruntime = require('react/jsx-runtime'); var TagName = "div"; function isMovingOnHovercard(target, card, anchor, nested) { if (_focus.hasFocusWithin.call(void 0, card)) return true; if (!target) return false; if (_dom.contains.call(void 0, card, target)) return true; if (anchor && _dom.contains.call(void 0, anchor, target)) return true; if (nested == null ? void 0 : nested.some((card2) => isMovingOnHovercard(target, card2, anchor))) { return true; } return false; } function useAutoFocusOnHide({ store, ...props }) { const [autoFocusOnHide, setAutoFocusOnHide] = _react.useState.call(void 0, false); const mounted = store.useState("mounted"); _react.useEffect.call(void 0, () => { if (!mounted) { setAutoFocusOnHide(false); } }, [mounted]); const onFocusProp = props.onFocus; const onFocus = _MZ2HG624cjs.useEvent.call(void 0, (event) => { onFocusProp == null ? void 0 : onFocusProp(event); if (event.defaultPrevented) return; setAutoFocusOnHide(true); }); const finalFocusRef = _react.useRef.call(void 0, null); _react.useEffect.call(void 0, () => { return _store.sync.call(void 0, store, ["anchorElement"], (state) => { finalFocusRef.current = state.anchorElement; }); }, []); props = { autoFocusOnHide, finalFocus: finalFocusRef, ...props, onFocus }; return props; } var NestedHovercardContext = _react.createContext.call(void 0, null); var useHovercard = _WBFXWJUHcjs.createHook.call(void 0, function useHovercard2({ store, modal = false, portal = !!modal, hideOnEscape = true, hideOnHoverOutside = true, disablePointerEventsOnApproach = !!hideOnHoverOutside, ...props }) { const context = _TPPZG3JZcjs.useHovercardProviderContext.call(void 0, ); store = store || context; _misc.invariant.call(void 0, store, process.env.NODE_ENV !== "production" && "Hovercard must receive a `store` prop or be wrapped in a HovercardProvider component." ); const ref = _react.useRef.call(void 0, null); const [nestedHovercards, setNestedHovercards] = _react.useState.call(void 0, []); const hideTimeoutRef = _react.useRef.call(void 0, 0); const enterPointRef = _react.useRef.call(void 0, null); const { portalRef, domReady } = _MZ2HG624cjs.usePortalRef.call(void 0, portal, props.portalRef); const isMouseMoving = _MZ2HG624cjs.useIsMouseMoving.call(void 0, ); const mayHideOnHoverOutside = !!hideOnHoverOutside; const hideOnHoverOutsideProp = _MZ2HG624cjs.useBooleanEvent.call(void 0, hideOnHoverOutside); const mayDisablePointerEvents = !!disablePointerEventsOnApproach; const disablePointerEventsProp = _MZ2HG624cjs.useBooleanEvent.call(void 0, disablePointerEventsOnApproach ); const open = store.useState("open"); const mounted = store.useState("mounted"); _react.useEffect.call(void 0, () => { if (!domReady) return; if (!mounted) return; if (!mayHideOnHoverOutside && !mayDisablePointerEvents) return; const element = ref.current; if (!element) return; const onMouseMove = (event) => { if (!store) return; if (!isMouseMoving()) return; const { anchorElement, hideTimeout, timeout } = store.getState(); const enterPoint = enterPointRef.current; const [target] = event.composedPath(); const anchor = anchorElement; if (isMovingOnHovercard(target, element, anchor, nestedHovercards)) { enterPointRef.current = target && anchor && _dom.contains.call(void 0, anchor, target) ? _L6CLLK7Rcjs.getEventPoint.call(void 0, event) : null; window.clearTimeout(hideTimeoutRef.current); hideTimeoutRef.current = 0; return; } if (hideTimeoutRef.current) return; if (enterPoint) { const currentPoint = _L6CLLK7Rcjs.getEventPoint.call(void 0, event); const polygon = _L6CLLK7Rcjs.getElementPolygon.call(void 0, element, enterPoint); if (_L6CLLK7Rcjs.isPointInPolygon.call(void 0, currentPoint, polygon)) { enterPointRef.current = currentPoint; if (!disablePointerEventsProp(event)) return; event.preventDefault(); event.stopPropagation(); return; } } if (!hideOnHoverOutsideProp(event)) return; hideTimeoutRef.current = window.setTimeout(() => { hideTimeoutRef.current = 0; store == null ? void 0 : store.hide(); }, hideTimeout != null ? hideTimeout : timeout); }; return _misc.chain.call(void 0, _events.addGlobalEventListener.call(void 0, "mousemove", onMouseMove, true), () => clearTimeout(hideTimeoutRef.current) ); }, [ store, isMouseMoving, domReady, mounted, mayHideOnHoverOutside, mayDisablePointerEvents, nestedHovercards, disablePointerEventsProp, hideOnHoverOutsideProp ]); _react.useEffect.call(void 0, () => { if (!domReady) return; if (!mounted) return; if (!mayDisablePointerEvents) return; const disableEvent = (event) => { const element = ref.current; if (!element) return; const enterPoint = enterPointRef.current; if (!enterPoint) return; const polygon = _L6CLLK7Rcjs.getElementPolygon.call(void 0, element, enterPoint); if (_L6CLLK7Rcjs.isPointInPolygon.call(void 0, _L6CLLK7Rcjs.getEventPoint.call(void 0, event), polygon)) { if (!disablePointerEventsProp(event)) return; event.preventDefault(); event.stopPropagation(); } }; return _misc.chain.call(void 0, // Note: we may need to add pointer events here in the future. _events.addGlobalEventListener.call(void 0, "mouseenter", disableEvent, true), _events.addGlobalEventListener.call(void 0, "mouseover", disableEvent, true), _events.addGlobalEventListener.call(void 0, "mouseout", disableEvent, true), _events.addGlobalEventListener.call(void 0, "mouseleave", disableEvent, true) ); }, [domReady, mounted, mayDisablePointerEvents, disablePointerEventsProp]); _react.useEffect.call(void 0, () => { if (!domReady) return; if (open) return; store == null ? void 0 : store.setAutoFocusOnShow(false); }, [store, domReady, open]); const openRef = _MZ2HG624cjs.useLiveRef.call(void 0, open); _react.useEffect.call(void 0, () => { if (!domReady) return; return () => { if (!openRef.current) { store == null ? void 0 : store.setAutoFocusOnShow(false); } }; }, [store, domReady]); const registerOnParent = _react.useContext.call(void 0, NestedHovercardContext); _MZ2HG624cjs.useSafeLayoutEffect.call(void 0, () => { if (modal) return; if (!portal) return; if (!mounted) return; if (!domReady) return; const element = ref.current; if (!element) return; return registerOnParent == null ? void 0 : registerOnParent(element); }, [modal, portal, mounted, domReady]); const registerNestedHovercard = _react.useCallback.call(void 0, (element) => { setNestedHovercards((prevElements) => [...prevElements, element]); const parentUnregister = registerOnParent == null ? void 0 : registerOnParent(element); return () => { setNestedHovercards( (prevElements) => prevElements.filter((item) => item !== element) ); parentUnregister == null ? void 0 : parentUnregister(); }; }, [registerOnParent] ); props = _MZ2HG624cjs.useWrapElement.call(void 0, props, (element) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _TPPZG3JZcjs.HovercardScopedContextProvider, { value: store, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, NestedHovercardContext.Provider, { value: registerNestedHovercard, children: element }) }), [store, registerNestedHovercard] ); props = { ...props, ref: _MZ2HG624cjs.useMergeRefs.call(void 0, ref, props.ref) }; props = useAutoFocusOnHide({ store, ...props }); const autoFocusOnShow = store.useState( (state) => modal || state.autoFocusOnShow ); props = _3OWJJMJRcjs.usePopover.call(void 0, { store, modal, portal, autoFocusOnShow, ...props, portalRef, hideOnEscape(event) { if (_misc.isFalsyBooleanCallback.call(void 0, hideOnEscape, event)) return false; requestAnimationFrame(() => { requestAnimationFrame(() => { store == null ? void 0 : store.hide(); }); }); return true; } }); return props; } ); var Hovercard = _7PVRUA4Ccjs.createDialogComponent.call(void 0, _WBFXWJUHcjs.forwardRef.call(void 0, function Hovercard2(props) { const htmlProps = useHovercard(props); return _WBFXWJUHcjs.createElement.call(void 0, TagName, htmlProps); }), _TPPZG3JZcjs.useHovercardProviderContext ); exports.useHovercard = useHovercard; exports.Hovercard = Hovercard;