UNPKG

@lobehub/ui

Version:

Lobe UI is an open-source UI component library for building AIGC web apps

62 lines (61 loc) • 1.85 kB
import { useLayoutEffect, useRef, useState } from "react"; const REPOP_ANIMATION = [[{ opacity: 0, scale: .97 }, { opacity: 1, scale: 1 }], { duration: 200, easing: "cubic-bezier(0.33, 1, 0.68, 1)" }]; const centerOf = (el) => { const rect = el.getBoundingClientRect(); return { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 }; }; const prefersReducedMotion = () => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches; const useRepopOnFarTriggerSwitch = (store, options) => { const enabled = options?.enabled ?? true; const threshold = options?.threshold ?? 280; const activeTrigger = store.useState?.("activeTriggerElement") ?? store.state.activeTriggerElement ?? null; const open = store.useState?.("open") ?? Boolean(store.state.open); const popupElement = store.useState?.("popupElement") ?? store.state.popupElement ?? null; const lastRef = useRef({ center: null, el: null }); const [repop, setRepop] = useState(false); useLayoutEffect(() => { if (!open || !enabled) { lastRef.current = { center: null, el: null }; setRepop(false); return; } const last = lastRef.current; if (activeTrigger === last.el) return; const center = activeTrigger ? centerOf(activeTrigger) : null; const far = Boolean(last.el && last.center && center && Math.hypot(center.x - last.center.x, center.y - last.center.y) > threshold); lastRef.current = { center, el: activeTrigger }; setRepop(far); if (far && popupElement && !prefersReducedMotion()) popupElement.animate?.(...REPOP_ANIMATION); }, [ activeTrigger, enabled, open, popupElement, threshold ]); return repop; }; //#endregion export { useRepopOnFarTriggerSwitch }; //# sourceMappingURL=useRepopOnFarTriggerSwitch.mjs.map