@ariakit/react-core
Version:
Ariakit React core
125 lines (122 loc) • 3.71 kB
JavaScript
"use client";
import {
useCompositeContext
} from "./APTFW6PT.js";
import {
createElement,
createHook,
forwardRef,
memo
} from "./VOQWLFSQ.js";
import {
useBooleanEvent,
useEvent,
useIsMouseMoving,
useMergeRefs
} from "./5GGHRIN3.js";
import {
__objRest,
__spreadProps,
__spreadValues
} from "./3YLGPPWQ.js";
// src/composite/composite-hover.tsx
import { contains } from "@ariakit/core/utils/dom";
import { hasFocus, hasFocusWithin } from "@ariakit/core/utils/focus";
import {
hasOwnProperty,
invariant,
removeUndefinedValues
} from "@ariakit/core/utils/misc";
import { useCallback } from "react";
var TagName = "div";
function getMouseDestination(event) {
const relatedTarget = event.relatedTarget;
if ((relatedTarget == null ? void 0 : relatedTarget.nodeType) === Node.ELEMENT_NODE) {
return relatedTarget;
}
return null;
}
function hoveringInside(event) {
const nextElement = getMouseDestination(event);
if (!nextElement) return false;
return contains(event.currentTarget, nextElement);
}
var symbol = Symbol("composite-hover");
function movingToAnotherItem(event) {
let dest = getMouseDestination(event);
if (!dest) return false;
do {
if (hasOwnProperty(dest, symbol) && dest[symbol]) return true;
dest = dest.parentElement;
} while (dest);
return false;
}
var useCompositeHover = createHook(
function useCompositeHover2(_a) {
var _b = _a, {
store,
focusOnHover = true,
blurOnHoverEnd = !!focusOnHover
} = _b, props = __objRest(_b, [
"store",
"focusOnHover",
"blurOnHoverEnd"
]);
const context = useCompositeContext();
store = store || context;
invariant(
store,
process.env.NODE_ENV !== "production" && "CompositeHover must be wrapped in a Composite component."
);
const isMouseMoving = useIsMouseMoving();
const onMouseMoveProp = props.onMouseMove;
const focusOnHoverProp = useBooleanEvent(focusOnHover);
const onMouseMove = useEvent((event) => {
onMouseMoveProp == null ? void 0 : onMouseMoveProp(event);
if (event.defaultPrevented) return;
if (!isMouseMoving()) return;
if (!focusOnHoverProp(event)) return;
if (!hasFocusWithin(event.currentTarget)) {
const baseElement = store == null ? void 0 : store.getState().baseElement;
if (baseElement && !hasFocus(baseElement)) {
baseElement.focus();
}
}
store == null ? void 0 : store.setActiveId(event.currentTarget.id);
});
const onMouseLeaveProp = props.onMouseLeave;
const blurOnHoverEndProp = useBooleanEvent(blurOnHoverEnd);
const onMouseLeave = useEvent((event) => {
var _a2;
onMouseLeaveProp == null ? void 0 : onMouseLeaveProp(event);
if (event.defaultPrevented) return;
if (!isMouseMoving()) return;
if (hoveringInside(event)) return;
if (movingToAnotherItem(event)) return;
if (!focusOnHoverProp(event)) return;
if (!blurOnHoverEndProp(event)) return;
store == null ? void 0 : store.setActiveId(null);
(_a2 = store == null ? void 0 : store.getState().baseElement) == null ? void 0 : _a2.focus();
});
const ref = useCallback((element) => {
if (!element) return;
element[symbol] = true;
}, []);
props = __spreadProps(__spreadValues({}, props), {
ref: useMergeRefs(ref, props.ref),
onMouseMove,
onMouseLeave
});
return removeUndefinedValues(props);
}
);
var CompositeHover = memo(
forwardRef(function CompositeHover2(props) {
const htmlProps = useCompositeHover(props);
return createElement(TagName, htmlProps);
})
);
export {
useCompositeHover,
CompositeHover
};