"use client"; import React, { useRef, useEffect, ReactNode, useState } from "react"; // Smoothly animates its container to match the natural height of its content. // Fixes previous behavior where the component observed itself, causing height 0 // with overflow hidden (content clipped) or visible overflow that overlapped // following sections like the footer. export default function AnimatedHeight({ children, overflow = true, }: { children: ReactNode; overflow?: boolean; }) { const containerRef = useRef(null); const contentRef = useRef(null); const [measuredHeight, setMeasuredHeight] = useState(null); const hasAnimatedOnceRef = useRef(false); useEffect(() => { const contentEl = contentRef.current; const containerEl = containerRef.current; if (!contentEl || !containerEl) return; const updateHeight = () => { // Use scrollHeight to capture full natural height, including overflowed content const height = contentEl.scrollHeight; setMeasuredHeight((prev) => (prev === height ? prev : height)); // Enable transition after the first measurement to avoid initial jank if (!hasAnimatedOnceRef.current) { containerEl.style.transition = "height 300ms ease-in-out"; hasAnimatedOnceRef.current = true; } }; // Initial measure updateHeight(); const resizeObserver = new ResizeObserver(() => updateHeight()); resizeObserver.observe(contentEl); return () => resizeObserver.disconnect(); }, []); return (
{children}
); }