Files
basiclean-webapp/hooks/useHeightVar.ts
T
2026-09-08 09:49:27 +02:00

36 lines
1023 B
TypeScript

"use client";
import { useLayoutEffect } from "react";
type Mode = "scroll" | "offset";
export function useHeightVar(
ref: React.RefObject<HTMLElement | null>,
cssVarName: string,
mode: Mode = "scroll",
trigger?: unknown,
targetRef?: React.RefObject<HTMLElement | null>,
) {
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]);
}