File size: 1,321 Bytes
05c5ed5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
"use client";

import { motion } from "framer-motion";
import { ReactNode, useRef, useLayoutEffect, useState } from "react";
import { cn } from "@/lib/utils";

interface AutoHeightProps {
  children: ReactNode;
  className?: string;
  duration?: number;
  ease?: "easeIn" | "easeOut" | "easeInOut" | "linear";
}

export function AutoHeight({
  children,
  className,
  duration = 0.2,
  ease = "easeInOut",
}: AutoHeightProps) {
  const [height, setHeight] = useState<number | "auto">("auto");
  const contentRef = useRef<HTMLDivElement>(null);

  useLayoutEffect(() => {
    if (contentRef.current) {
      const resizeObserver = new ResizeObserver(() => {
        if (contentRef.current) {
          const newHeight = contentRef.current.scrollHeight;
          setHeight(newHeight);
        }
      });

      resizeObserver.observe(contentRef.current);

      // Initial height measurement
      const initialHeight = contentRef.current.scrollHeight;
      setHeight(initialHeight);

      return () => {
        resizeObserver.disconnect();
      };
    }
  }, [children]);

  return (
    <motion.div
      className={cn("overflow-hidden", className)}
      animate={{ height }}
      transition={{
        duration,
        ease,
      }}
    >
      <div ref={contentRef}>{children}</div>
    </motion.div>
  );
}