'use client' import * as React from 'react' import { cn } from '@/lib/utils' export interface TextareaProps extends React.TextareaHTMLAttributes { label?: string error?: string helper?: string maxCount?: number autoGrow?: boolean } const Textarea = React.forwardRef( ({ className, label, error, helper, maxCount, autoGrow = false, id, onChange, value, ...props }, ref) => { const textareaId = id ?? React.useId() const errorId = `${textareaId}-error` const helperId = `${textareaId}-helper` const internalRef = React.useRef(null) const resolvedRef = (ref as React.RefObject) ?? internalRef const [charCount, setCharCount] = React.useState( typeof value === 'string' ? value.length : 0 ) const handleChange = (e: React.ChangeEvent) => { setCharCount(e.target.value.length) if (autoGrow && resolvedRef.current) { resolvedRef.current.style.height = 'auto' resolvedRef.current.style.height = `${resolvedRef.current.scrollHeight}px` } onChange?.(e) } React.useEffect(() => { if (autoGrow && resolvedRef.current) { resolvedRef.current.style.height = 'auto' resolvedRef.current.style.height = `${resolvedRef.current.scrollHeight}px` } }, [value, autoGrow, resolvedRef]) const describedBy = [error ? errorId : null, helper ? helperId : null] .filter(Boolean) .join(' ') const isOverLimit = maxCount !== undefined && charCount > maxCount return (
{label && ( )}