"use client" import * as React from "react" import { cn } from "@/lib/utils" export type TextareaProps = React.ComponentProps<"textarea"> & { onValueChange?: (value: string) => void helperText?: React.ReactNode errorText?: React.ReactNode showCharacterCount?: boolean countFormatter?: (currentLength: number, maxLength?: number) => React.ReactNode wrapperClassName?: string textareaClassName?: string } function getTextareaLength(value: TextareaProps["value"] | TextareaProps["defaultValue"]) { if (typeof value === "string") return value.length if (typeof value === "number") return String(value).length if (Array.isArray(value)) return value.join("").length return 0 } const Textarea = React.forwardRef( ( { className, value, defaultValue, onChange, onValueChange, helperText, errorText, showCharacterCount = false, countFormatter, wrapperClassName, textareaClassName, maxLength, "aria-invalid": ariaInvalid, ...props }, ref ) => { const isControlled = value !== undefined const [uncontrolledLength, setUncontrolledLength] = React.useState(() => getTextareaLength(defaultValue)) const currentLength = isControlled ? getTextareaLength(value) : uncontrolledLength const helperMessage = errorText ?? helperText const invalid = Boolean(errorText) || ariaInvalid === true || ariaInvalid === "true" const handleChange: React.ChangeEventHandler = (event) => { if (!isControlled) { setUncontrolledLength(event.target.value.length) } onChange?.(event) onValueChange?.(event.target.value) } const textarea = (