import { cn } from '@/lib/utils'; import { ChangeEventHandler, ComponentProps, FocusEventHandler, forwardRef, TextareaHTMLAttributes, useCallback, useEffect, useRef, useState, } from 'react'; interface TextareaProps extends Omit, 'autoSize'> { autoSize?: { minRows?: number; maxRows?: number; }; } const Textarea = forwardRef( ({ className, autoSize, ...props }, ref) => { const textareaRef = useRef(null); const getLineHeight = (element: HTMLElement): number => { const style = window.getComputedStyle(element); return parseInt(style.lineHeight, 10) || 20; }; const adjustHeight = useCallback(() => { if (!textareaRef.current) return; const lineHeight = getLineHeight(textareaRef.current); const maxHeight = (autoSize?.maxRows || 3) * lineHeight; textareaRef.current.style.height = 'auto'; requestAnimationFrame(() => { if (!textareaRef.current) return; const scrollHeight = textareaRef.current.scrollHeight; textareaRef.current.style.height = `${Math.min(scrollHeight, maxHeight)}px`; }); }, [autoSize]); useEffect(() => { if (autoSize) { adjustHeight(); } }, [textareaRef, autoSize, adjustHeight]); useEffect(() => { if (typeof ref === 'function') { ref(textareaRef.current); } else if (ref) { ref.current = textareaRef.current; } }, [ref]); return ( ); });