framer-motion
Version:
A simple and powerful JavaScript animation library
53 lines (50 loc) • 1.83 kB
JavaScript
"use client";
import { useRef, useInsertionEffect, useCallback } from 'react';
/**
* Creates a ref function that, when called, hydrates the provided
* external ref and VisualElement.
*/
function useMotionRef(visualState, visualElement, externalRef) {
/**
* Store externalRef in a ref to avoid including it in the useCallback
* dependency array. Including externalRef in dependencies causes issues
* with libraries like Radix UI that create new callback refs on each render
* when using asChild - this would cause the callback to be recreated,
* triggering element remounts and breaking AnimatePresence exit animations.
*/
const externalRefContainer = useRef(externalRef);
useInsertionEffect(() => {
externalRefContainer.current = externalRef;
});
// Store cleanup function returned by callback refs (React 19 feature)
const refCleanup = useRef(null);
return useCallback((instance) => {
if (instance) {
visualState.onMount?.(instance);
}
if (visualElement) {
instance ? visualElement.mount(instance) : visualElement.unmount();
}
const ref = externalRefContainer.current;
if (typeof ref === "function") {
if (instance) {
const cleanup = ref(instance);
if (typeof cleanup === "function") {
refCleanup.current = cleanup;
}
}
else if (refCleanup.current) {
refCleanup.current();
refCleanup.current = null;
}
else {
ref(instance);
}
}
else if (ref) {
ref.current = instance;
}
}, [visualElement]);
}
export { useMotionRef };
//# sourceMappingURL=use-motion-ref.mjs.map