import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { forwardRef, useCallback, useState, useEffect, useMemo } from 'react';
import FormField from '../FormField';
import { StyledFormControl } from '../FormControl';
import { hasProp, withTestIds } from '../../utils';
import { useConsolidatedRef, useI18n, useTestIds, useUID } from '../../hooks';
import Text from '../Text';
import VisuallyHiddenText from '../VisuallyHiddenText';
import StyledTextArea from './TextArea.styles';
import { getTextAreaTestIds } from './TextArea.test-ids';
const TextArea = forwardRef(function TextArea(props, ref) {
    const uid = useUID();
    const { testId, additionalInfo, id = uid, value, defaultValue, required = false, disabled = false, readOnly = false, label, labelHidden, info, status, resizable = false, autoResize = true, maxLength, displayCharCount = false, hardStop = true, onChange: onChangeProp, onResolveSuggestion, ...restProps } = props;
    const t = useI18n();
    const testIds = useTestIds(testId, getTextAreaTestIds);
    const [charCount, setCharCount] = useState(0);
    const textAreaRef = useConsolidatedRef(ref);
    const consolidatedRef = useConsolidatedRef(ref, textAreaRef);
    const controlProp = {};
    // Conditionally render component as controlled/uncontrolled
    if (hasProp(props, 'value')) {
        controlProp.value = value ?? '';
    }
    else if (hasProp(props, 'defaultValue')) {
        controlProp.defaultValue = defaultValue ?? '';
    }
    const onChange = useCallback((e) => {
        if (!hardStop || maxLength === undefined || e.target.value.length <= maxLength) {
            onChangeProp?.(e);
            setCharCount(e.target.value.length);
        }
    }, [onChangeProp, hardStop, maxLength]);
    const ariaDescribedBy = useMemo(() => {
        const idString = [];
        if (info) {
            idString.push(`${id}-info`);
        }
        if (displayCharCount && typeof maxLength === 'number') {
            idString.push(`${id}-charCount`);
        }
        return idString.length ? idString.join(' ') : undefined;
    }, [info, id, displayCharCount, maxLength]);
    useEffect(() => {
        if (!textAreaRef.current)
            return;
        if (autoResize) {
            textAreaRef.current.style.setProperty('--textarea-height', 'auto');
            // Remove scrollbar width to avoid interference with calculation.
            textAreaRef.current.style.setProperty('scrollbar-width', 'none');
            const scrollHeight = textAreaRef.current.scrollHeight;
            const borderWidth = textAreaRef.current.offsetHeight - textAreaRef.current.clientHeight;
            // Set height to auto then scrollHeight + borderWidth to resize TextArea to content
            textAreaRef.current.style.setProperty('--textarea-height', `${scrollHeight + borderWidth}px`);
            textAreaRef.current.style.removeProperty('scrollbar-width');
        }
        else {
            textAreaRef.current.style.removeProperty('--textarea-height');
        }
    }, [value, autoResize]);
    const TextAreaControl = (_jsx(StyledFormControl, { "data-testid": testIds.control, ref: consolidatedRef, id: id, "aria-describedby": ariaDescribedBy, required: required, disabled: disabled, status: status, readOnly: readOnly, autoResize: autoResize, resizable: autoResize ? false : resizable, maxLength: hardStop ? maxLength : undefined, hasSuggestion: status === 'pending' && !!onResolveSuggestion, ...controlProp, ...restProps, onChange: onChange, as: StyledTextArea }));
    return label || displayCharCount ? (_jsx(FormField, { testId: testIds, additionalInfo: additionalInfo, label: label, labelHidden: labelHidden, id: id, readOnly: readOnly, info: info, status: status, charLimitDisplay: displayCharCount && typeof maxLength === 'number' ? (_jsxs(Text, { id: `${id}-charCount`, readOnly: readOnly, variant: 'secondary', "aria-live": maxLength >= 0 && maxLength - charCount <= 20 ? 'polite' : 'off', children: [maxLength >= 0 ? t('x_of_y', [charCount || '0', maxLength]) : charCount, ' ', _jsx(VisuallyHiddenText, { children: t('characters_typed') })] })) : undefined, required: required, disabled: disabled, onResolveSuggestion: onResolveSuggestion, children: TextAreaControl })) : (TextAreaControl);
});
export default withTestIds(TextArea, getTextAreaTestIds);
//# sourceMappingURL=TextArea.js.map