/**
 * @license MIT
 * author: Cube Dev Team
 * @cube-dev/ui-kit v0.0.0-canary-5e810c3
 * Released under the MIT license.
 */

import { jsx as _jsx } from "react/jsx-runtime";
import { useControlledState } from '@react-stately/utils';
import { forwardRef, useEffect, useLayoutEffect, useRef, } from 'react';
import { useTextField } from 'react-aria';
import { useEvent } from '../../../_internal/index.js';
import { useProviderProps } from '../../../provider.js';
import { chain, mergeProps } from '../../../utils/react/index.js';
import { castNullableStringValue, } from '../../../utils/react/nullableValue.js';
import { useFieldProps } from '../../form/index.js';
import { TextInputBase } from '../TextInput/index.js';
function TextArea(props, ref) {
    props = castNullableStringValue(props);
    props = useProviderProps(props);
    props = useFieldProps(props, {
        defaultValidationTrigger: 'onBlur',
        valuePropsMapper: ({ value, onChange }) => ({
            onChange,
            value: value?.toString() ?? '',
        }),
    });
    let { autoSize = false, isDisabled = false, isReadOnly = false, isRequired = false, onChange, maxRows = 10, rows = 3, mods, labelProps: userLabelProps, inputRef: propsInputRef, ...otherProps } = props;
    rows = Math.max(rows, 1);
    maxRows = Math.max(maxRows, rows);
    let [inputValue, setInputValue] = useControlledState(props.value, props.defaultValue, () => { });
    let localInputRef = useRef(null);
    let inputRef = propsInputRef ?? localInputRef;
    let { labelProps, inputProps } = useTextField({
        ...otherProps,
        isDisabled,
        isReadOnly,
        isRequired,
        onChange: chain(onChange, setInputValue),
        inputElementType: 'textarea',
    }, inputRef);
    // Merge user-provided labelProps with aria labelProps
    const mergedLabelProps = mergeProps(labelProps, userLabelProps);
    const adjustHeight = useEvent(() => {
        const textarea = inputRef.current;
        if (!textarea || !autoSize)
            return;
        // Reset height to get the correct scrollHeight
        textarea.style.height = 'auto';
        // Get computed styles to account for padding
        const computedStyle = getComputedStyle(textarea);
        const paddingTop = parseFloat(computedStyle.paddingTop) || 0;
        const paddingBottom = parseFloat(computedStyle.paddingBottom) || 0;
        const borderTop = parseFloat(computedStyle.borderTopWidth) || 0;
        const borderBottom = parseFloat(computedStyle.borderBottomWidth) || 0;
        // Calculate line height (approximately)
        const lineHeight = parseInt(computedStyle.lineHeight) || 20;
        // Calculate content height (excluding padding and border)
        const contentHeight = textarea.scrollHeight - paddingTop - paddingBottom;
        // Calculate rows based on content height
        const computedRows = Math.ceil(contentHeight / lineHeight);
        // Apply min/max constraints
        const targetRows = Math.max(Math.min(computedRows, maxRows), rows);
        // Set the height including padding and border
        const totalHeight = targetRows * lineHeight +
            paddingTop +
            paddingBottom +
            borderTop +
            borderBottom;
        textarea.style.height = `${totalHeight}px`;
    });
    const useEnvironmentalEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
    // Call adjustHeight on content change
    useEnvironmentalEffect(() => {
        adjustHeight();
    }, [inputValue]);
    // Also call it on element resize as that can affect wrapping
    useEnvironmentalEffect(() => {
        if (!autoSize || !inputRef.current)
            return;
        adjustHeight();
        const resizeObserver = new ResizeObserver(adjustHeight);
        resizeObserver.observe(inputRef?.current);
        return () => resizeObserver.disconnect();
    }, [autoSize, inputRef?.current]);
    return (_jsx(TextInputBase, { ref: ref, ...otherProps, multiLine: true, inputRef: inputRef, labelProps: mergedLabelProps, inputProps: { ...inputProps, 'data-input-type': 'textarea' }, isDisabled: isDisabled, isReadOnly: isReadOnly, isRequired: isRequired, rows: rows }));
}
/**
 * TextInputs are text inputs that allow users to input custom text entries
 * with a keyboard. Various decorations can be displayed around the field to
 * communicate the entry requirements.
 */
const _TextArea = forwardRef(TextArea);
_TextArea.cubeInputType = 'Text';
_TextArea.displayName = 'TextArea';
export { _TextArea as TextArea };

        