import React, { forwardRef, useCallback, useMemo, useState } from "react"; import cx from "classnames"; import { getTestId } from "../../tests/test-ids-utils"; import { ComponentDefaultTestId } from "../../tests/constants"; import styles from "./TextArea.module.scss"; import { TextAreaProps, TextAreaSize } from "./TextArea.types"; import Text from "../Text/Text"; import { Flex } from "../Flex"; import { HiddenText } from "../HiddenText"; const DEFAULT_ROWS: Record = { small: 3, large: 4 }; const TextArea = forwardRef( ( { size = "small", rows, label, helpText, success, error, className, "data-testid": dataTestId, id, disabled, readOnly, required, maxLength, allowExceedingMaxLength, onChange, value, resize = true, showCharCount = false, ...rest }: TextAreaProps, ref: React.ForwardedRef ) => { const numRows = rows || DEFAULT_ROWS[size]; const helpTextId = helpText && `${id}-help-text`; const allowExceedingMaxLengthTextId = allowExceedingMaxLength && `${id}-allow-exceeding-max-length`; const ariaDescribedby = useMemo( () => [helpTextId, allowExceedingMaxLengthTextId].filter(id => !!id).join(" ") || undefined, [helpTextId, allowExceedingMaxLengthTextId] ); const [characterCount, setCharacterCount] = useState(value?.length || 0); const isErrorState = error || (typeof maxLength === "number" && characterCount > maxLength); const handleOnChange = useCallback( (event: React.ChangeEvent) => { setCharacterCount(event.target.value.length); onChange?.(event); }, [onChange] ); return (
{label && ( )}