@mantine/core
Version:
React components library focused on usability, accessibility and developer experience
111 lines (110 loc) • 4.52 kB
JavaScript
"use client";
require("../../_virtual/_rolldown/runtime.cjs");
const require_get_env = require("../../core/utils/get-env/get-env.cjs");
const require_to_int = require("../ScrollArea/utils/to-int.cjs");
let react = require("react");
let _mantine_hooks = require("@mantine/hooks");
//#region packages/@mantine/core/src/components/FloatingIndicator/use-floating-indicator.ts
function isParent(parentElement, childElement) {
if (!childElement || !parentElement) return false;
let parent = childElement.parentNode;
while (parent != null) {
if (parent === parentElement) return true;
parent = parent.parentNode;
}
return false;
}
function useFloatingIndicator({ target, parent, ref, displayAfterTransitionEnd, onTransitionStart, onTransitionEnd }) {
const transitionTimeout = (0, react.useRef)(-1);
const previousTarget = (0, react.useRef)(target);
const [initialized, setInitialized] = (0, react.useState)(false);
const [hidden, setHidden] = (0, react.useState)(typeof displayAfterTransitionEnd === "boolean" ? displayAfterTransitionEnd : false);
const updatePosition = () => {
if (!target || !parent || !ref.current) return;
const targetRect = target.getBoundingClientRect();
const parentRect = parent.getBoundingClientRect();
const targetComputedStyle = window.getComputedStyle(target);
const parentComputedStyle = window.getComputedStyle(parent);
const borderTopWidth = require_to_int.toInt(targetComputedStyle.borderTopWidth) + require_to_int.toInt(parentComputedStyle.borderTopWidth);
const borderLeftWidth = require_to_int.toInt(targetComputedStyle.borderLeftWidth) + require_to_int.toInt(parentComputedStyle.borderLeftWidth);
const position = {
top: targetRect.top - parentRect.top - borderTopWidth,
left: targetRect.left - parentRect.left - borderLeftWidth,
width: targetRect.width,
height: targetRect.height
};
ref.current.style.transform = `translateY(${position.top}px) translateX(${position.left}px)`;
ref.current.style.width = `${position.width}px`;
ref.current.style.height = `${position.height}px`;
};
const updatePositionWithoutAnimation = () => {
window.clearTimeout(transitionTimeout.current);
if (ref.current) ref.current.style.transitionDuration = "0ms";
updatePosition();
transitionTimeout.current = window.setTimeout(() => {
if (ref.current) ref.current.style.transitionDuration = "";
}, 30);
};
const targetResizeObserver = (0, react.useRef)(null);
const parentResizeObserver = (0, react.useRef)(null);
(0, react.useEffect)(() => {
if (initialized && previousTarget.current !== target && onTransitionStart) onTransitionStart();
previousTarget.current = target;
updatePosition();
if (target) {
targetResizeObserver.current = new ResizeObserver(updatePositionWithoutAnimation);
targetResizeObserver.current.observe(target);
if (parent) {
parentResizeObserver.current = new ResizeObserver(updatePositionWithoutAnimation);
parentResizeObserver.current.observe(parent);
}
return () => {
targetResizeObserver.current?.disconnect();
parentResizeObserver.current?.disconnect();
};
}
}, [parent, target]);
(0, react.useEffect)(() => {
if (parent) {
const handleTransitionEnd = (event) => {
if (isParent(event.target, parent)) {
updatePositionWithoutAnimation();
setHidden(false);
}
};
parent.addEventListener("transitionend", handleTransitionEnd);
return () => {
parent.removeEventListener("transitionend", handleTransitionEnd);
};
}
}, [parent]);
(0, react.useEffect)(() => {
if (ref.current && onTransitionEnd) {
const handleIndicatorTransitionEnd = (event) => {
if (event.propertyName === "transform") onTransitionEnd();
};
ref.current.addEventListener("transitionend", handleIndicatorTransitionEnd);
return () => {
ref.current?.removeEventListener("transitionend", handleIndicatorTransitionEnd);
};
}
}, [onTransitionEnd]);
(0, _mantine_hooks.useTimeout)(() => {
if (require_get_env.getEnv() !== "test") setInitialized(true);
}, 20, { autoInvoke: true });
(0, _mantine_hooks.useMutationObserverTarget)((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === "attributes" && mutation.attributeName === "dir") updatePositionWithoutAnimation();
});
}, {
attributes: true,
attributeFilter: ["dir"]
}, () => document.documentElement);
return {
initialized,
hidden
};
}
//#endregion
exports.useFloatingIndicator = useFloatingIndicator;
//# sourceMappingURL=use-floating-indicator.cjs.map