import * as React from "react"; /** * One callback ref that keeps an incoming ref and a local ref on the same node. * * A React 19 callback ref may return a cleanup function; when the incoming ref * does, React runs that cleanup instead of calling the callback again with * `null`, so the local ref must be cleared inside the cleanup too. */ export const composedRefCallback = (outer: React.Ref | undefined, local: React.RefObject): React.RefCallback => (node) => { local.current = node; if (typeof outer === "function") { const cleanup = outer(node); if (typeof cleanup === "function") { return () => { local.current = null; cleanup(); }; } return undefined; } if (outer) outer.current = node; return undefined; }; /** `composedRefCallback`, kept stable across renders for stable inputs so the * incoming ref is not detached and reattached on every render. */ export const useComposedRef = ( outer: React.Ref | undefined, local: React.RefObject, ): React.RefCallback => React.useMemo(() => composedRefCallback(outer, local), [outer, local]);