Use Auto Resize Textarea

Automatically adjust the height of a textarea.

 
import { useEffect, useRef, useCallback } from "react";
 
interface UseAutoResizeTextareaProps {
    minHeight: number;
    maxHeight?: number;
}
 
export function useAutoResizeTextarea({
    minHeight,
    maxHeight,
}: UseAutoResizeTextareaProps) {
    const textareaRef = useRef<HTMLTextAreaElement>(null);
 
    const adjustHeight = useCallback(
        (reset?: boolean) => {
            const textarea = textareaRef.current;
            if (!textarea) return;
 
            if (reset) {
                textarea.style.height = `${minHeight}px`;
                return;
            }
 
            // Temporarily shrink to get the right scrollHeight
            textarea.style.height = `${minHeight}px`;
 
            // Calculate new height
            const newHeight = Math.max(
                minHeight,
                Math.min(
                    textarea.scrollHeight,
                    maxHeight ?? Number.POSITIVE_INFINITY
                )
            );
 
            textarea.style.height = `${newHeight}px`;
        },
        [minHeight, maxHeight]
    );
 
    useEffect(() => {
        // Set initial height
        const textarea = textareaRef.current;
        if (textarea) {
            textarea.style.height = `${minHeight}px`;
        }
    }, [minHeight]);
 
    // Adjust height on window resize
    useEffect(() => {
        const handleResize = () => adjustHeight();
        window.addEventListener("resize", handleResize);
        return () => window.removeEventListener("resize", handleResize);
    }, [adjustHeight]);
 
    return { textareaRef, adjustHeight };
}