@ariakit/react-core
Version:
Ariakit React core
282 lines (242 loc) • 9.88 kB
JavaScript
"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;