"use client"; import { useLayoutEffect } from "react"; type Mode = "scroll" | "offset"; export function useHeightVar( ref: React.RefObject, cssVarName: string, mode: Mode = "scroll", trigger?: unknown, targetRef?: React.RefObject, ) { useLayoutEffect(() => { const el = ref.current; if (!el) return; const target = targetRef?.current ?? el; const measure = () => { const h = mode === "scroll" ? el.scrollHeight : el.offsetHeight; target.style.setProperty(cssVarName, `${h}px`); }; measure(); // Observe el (the unclipped content), not target: if target is the // element whose max-height is being CSS-transitioned, observing it // directly re-triggers measure() on every layout step of the // transition, fighting the animation (visible as stutter in Firefox). const ro = new ResizeObserver(measure); ro.observe(el); return () => ro.disconnect(); }, [ref, targetRef, cssVarName, mode, trigger]); }