import { jsxs, jsx } from 'react/jsx-runtime';
import * as React from 'react';
import React__default, { useLayoutEffect, forwardRef, useRef, useState, useMemo, useEffect, useId, isValidElement } from 'react';
import { F as FieldLabel } from './FieldLabel-DZWu5dMp.js';
import { w as warnDeprecatedErrorUsage } from './utils-CM48ODEJ.js';
import { c as cx } from './index-De1g9FRV.js';
import { _ as _objectWithoutPropertiesLoose, a as _extends } from './extends-Bg2s_OKl.js';
import { c as childrenToString } from './childrenToString-Bz9MqbHb.js';
import { useTrackingId } from './useTrackingId.js';
import { u as useLayoutPropsUtil } from './useLayoutPropsUtil-CB_zHDbW.js';
import { u as useOptionallyControlledState } from './useOptionallyControlledState-DbDuos5L.js';
import { w as warnOnce } from './warnOnce-Y9PRHcU4.js';
import { s as stripInlineMarkdown } from './stripInlineMarkdown-BWbMy7r_.js';
import { u as useMergeRefs } from './useMergeRefs-Dfmtq9cI.js';
import { H as Helper } from './Helper-DtDeaYTn.js';

import './Textarea.css';const textarea = "_textarea_1jyzu_1";
const input = "_input_1jyzu_18";
const error = "_error_1jyzu_66";
const disabled = "_disabled_1jyzu_71";
const readonly = "_readonly_1jyzu_79";
const styles = {
	textarea: textarea,
	input: input,
	"has-cols": "_has-cols_1jyzu_60",
	error: error,
	disabled: disabled,
	readonly: readonly,
	"disable-resize": "_disable-resize_1jyzu_83"
};

var index$1 = useLayoutEffect ;

var useLatest = function useLatest(value) {
  var ref = React__default.useRef(value);
  index$1(function () {
    ref.current = value;
  });
  return ref;
};

// basically Exclude<React.ClassAttributes<T>["ref"], string>

var updateRef = function updateRef(ref, value) {
  if (typeof ref === 'function') {
    ref(value);
    return;
  }
  ref.current = value;
};
var useComposedRef = function useComposedRef(libRef, userRef) {
  var prevUserRef = React__default.useRef();
  return React__default.useCallback(function (instance) {
    libRef.current = instance;
    if (prevUserRef.current) {
      updateRef(prevUserRef.current, null);
    }
    prevUserRef.current = userRef;
    if (!userRef) {
      return;
    }
    updateRef(userRef, instance);
  }, [userRef]);
};

var HIDDEN_TEXTAREA_STYLE = {
  'min-height': '0',
  'max-height': 'none',
  height: '0',
  visibility: 'hidden',
  overflow: 'hidden',
  position: 'absolute',
  'z-index': '-1000',
  top: '0',
  right: '0',
  display: 'block'
};
var forceHiddenStyles = function forceHiddenStyles(node) {
  Object.keys(HIDDEN_TEXTAREA_STYLE).forEach(function (key) {
    node.style.setProperty(key, HIDDEN_TEXTAREA_STYLE[key], 'important');
  });
};
var forceHiddenStyles$1 = forceHiddenStyles;

var hiddenTextarea = null;
var getHeight = function getHeight(node, sizingData) {
  var height = node.scrollHeight;
  if (sizingData.sizingStyle.boxSizing === 'border-box') {
    // border-box: add border, since height = content + padding + border
    return height + sizingData.borderSize;
  }

  // remove padding, since height = content
  return height - sizingData.paddingSize;
};
function calculateNodeHeight(sizingData, value, minRows, maxRows) {
  if (minRows === void 0) {
    minRows = 1;
  }
  if (maxRows === void 0) {
    maxRows = Infinity;
  }
  if (!hiddenTextarea) {
    hiddenTextarea = document.createElement('textarea');
    hiddenTextarea.setAttribute('tabindex', '-1');
    hiddenTextarea.setAttribute('aria-hidden', 'true');
    forceHiddenStyles$1(hiddenTextarea);
  }
  if (hiddenTextarea.parentNode === null) {
    document.body.appendChild(hiddenTextarea);
  }
  var paddingSize = sizingData.paddingSize,
    borderSize = sizingData.borderSize,
    sizingStyle = sizingData.sizingStyle;
  var boxSizing = sizingStyle.boxSizing;
  Object.keys(sizingStyle).forEach(function (_key) {
    var key = _key;
    hiddenTextarea.style[key] = sizingStyle[key];
  });
  forceHiddenStyles$1(hiddenTextarea);
  hiddenTextarea.value = value;
  var height = getHeight(hiddenTextarea, sizingData);
  // Double set and calc due to Firefox bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1795904
  hiddenTextarea.value = value;
  height = getHeight(hiddenTextarea, sizingData);

  // measure height of a textarea with a single row
  hiddenTextarea.value = 'x';
  var rowHeight = hiddenTextarea.scrollHeight - paddingSize;
  var minHeight = rowHeight * minRows;
  if (boxSizing === 'border-box') {
    minHeight = minHeight + paddingSize + borderSize;
  }
  height = Math.max(minHeight, height);
  var maxHeight = rowHeight * maxRows;
  if (boxSizing === 'border-box') {
    maxHeight = maxHeight + paddingSize + borderSize;
  }
  height = Math.min(maxHeight, height);
  return [height, rowHeight];
}

var noop = function noop() {};
var pick = function pick(props, obj) {
  return props.reduce(function (acc, prop) {
    acc[prop] = obj[prop];
    return acc;
  }, {});
};

var SIZING_STYLE = ['borderBottomWidth', 'borderLeftWidth', 'borderRightWidth', 'borderTopWidth', 'boxSizing', 'fontFamily', 'fontSize', 'fontStyle', 'fontWeight', 'letterSpacing', 'lineHeight', 'paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop',
// non-standard
'tabSize', 'textIndent',
// non-standard
'textRendering', 'textTransform', 'width', 'wordBreak', 'wordSpacing', 'scrollbarGutter'];
var isIE = !!document.documentElement.currentStyle ;
var getSizingData = function getSizingData(node) {
  var style = window.getComputedStyle(node);
  if (style === null) {
    return null;
  }
  var sizingStyle = pick(SIZING_STYLE, style);
  var boxSizing = sizingStyle.boxSizing;

  // probably node is detached from DOM, can't read computed dimensions
  if (boxSizing === '') {
    return null;
  }

  // IE (Edge has already correct behaviour) returns content width as computed width
  // so we need to add manually padding and border widths
  if (isIE && boxSizing === 'border-box') {
    sizingStyle.width = parseFloat(sizingStyle.width) + parseFloat(sizingStyle.borderRightWidth) + parseFloat(sizingStyle.borderLeftWidth) + parseFloat(sizingStyle.paddingRight) + parseFloat(sizingStyle.paddingLeft) + 'px';
  }
  var paddingSize = parseFloat(sizingStyle.paddingBottom) + parseFloat(sizingStyle.paddingTop);
  var borderSize = parseFloat(sizingStyle.borderBottomWidth) + parseFloat(sizingStyle.borderTopWidth);
  return {
    sizingStyle: sizingStyle,
    paddingSize: paddingSize,
    borderSize: borderSize
  };
};
var getSizingData$1 = getSizingData;

function useListener(target, type, listener) {
  var latestListener = useLatest(listener);
  React.useLayoutEffect(function () {
    var handler = function handler(ev) {
      return latestListener.current(ev);
    };

    // might happen if document.fonts is not defined, for instance
    if (!target) {
      return;
    }
    target.addEventListener(type, handler);
    return function () {
      return target.removeEventListener(type, handler);
    };
  }, []);
}
var useWindowResizeListener = function useWindowResizeListener(listener) {
  useListener(window, 'resize', listener);
};
var useFontsLoadedListener = function useFontsLoadedListener(listener) {
  useListener(document.fonts, 'loadingdone', listener);
};

var _excluded = ["cacheMeasurements", "maxRows", "minRows", "onChange", "onHeightChange"];
var TextareaAutosize = function TextareaAutosize(_ref, userRef) {
  var cacheMeasurements = _ref.cacheMeasurements,
    maxRows = _ref.maxRows,
    minRows = _ref.minRows,
    _ref$onChange = _ref.onChange,
    onChange = _ref$onChange === void 0 ? noop : _ref$onChange,
    _ref$onHeightChange = _ref.onHeightChange,
    onHeightChange = _ref$onHeightChange === void 0 ? noop : _ref$onHeightChange,
    props = _objectWithoutPropertiesLoose(_ref, _excluded);
  var isControlled = props.value !== undefined;
  var libRef = React.useRef(null);
  var ref = useComposedRef(libRef, userRef);
  var heightRef = React.useRef(0);
  var measurementsCacheRef = React.useRef();
  var resizeTextarea = function resizeTextarea() {
    var node = libRef.current;
    var nodeSizingData = cacheMeasurements && measurementsCacheRef.current ? measurementsCacheRef.current : getSizingData$1(node);
    if (!nodeSizingData) {
      return;
    }
    measurementsCacheRef.current = nodeSizingData;
    var _calculateNodeHeight = calculateNodeHeight(nodeSizingData, node.value || node.placeholder || 'x', minRows, maxRows),
      height = _calculateNodeHeight[0],
      rowHeight = _calculateNodeHeight[1];
    if (heightRef.current !== height) {
      heightRef.current = height;
      node.style.setProperty('height', height + "px", 'important');
      onHeightChange(height, {
        rowHeight: rowHeight
      });
    }
  };
  var handleChange = function handleChange(event) {
    if (!isControlled) {
      resizeTextarea();
    }
    onChange(event);
  };
  {
    React.useLayoutEffect(resizeTextarea);
    useWindowResizeListener(resizeTextarea);
    useFontsLoadedListener(resizeTextarea);
    return /*#__PURE__*/React.createElement("textarea", _extends({}, props, {
      onChange: handleChange,
      ref: ref
    }));
  }
};
var index = /* #__PURE__ */React.forwardRef(TextareaAutosize);

const Textarea = forwardRef(
  (props, ref) => {
    const { aiMark, ...labelPropsWithoutAiMark } = props.labelProps || {};
    const data = {
      label: childrenToString(props.label),
      labelProps: labelPropsWithoutAiMark,
      prefix: childrenToString(props.prefix),
      hint: childrenToString(props.hint),
      description: childrenToString(props.description)
    };
    const trackingId = useTrackingId({
      name: "Textarea",
      data,
      hasOverride: !!props["data-tracking-id"]
    });
    const { layoutStyles, componentProps } = useLayoutPropsUtil(props);
    const {
      value: valueProp,
      defaultValue: defaultValueProp,
      className,
      disableResize,
      error,
      errorAriaLive: _errorAriaLive,
      hint,
      description,
      label,
      moreInfo,
      onChange,
      required,
      showCounter,
      onFocus,
      onBlur,
      id: idProp,
      maxLength,
      autoHeight,
      minRows,
      maxRows,
      labelProps,
      placeholder,
      warning,
      style,
      hideLabel = false,
      ...rest
    } = componentProps;
    const textareaRef = useRef(null);
    const [isTyping, setIsTyping] = useState(false);
    const [ssr, setSSR] = useState(true);
    const [value, setValue] = useOptionallyControlledState({
      controlledValue: valueProp,
      defaultValue: defaultValueProp
    });
    const length = useMemo(() => {
      if (typeof value === "string" || typeof value === "number" || Array.isArray(value)) {
        return String(value).length;
      }
      return 0;
    }, [value]);
    useEffect(() => {
      setSSR(false);
    }, []);
    const onChangeHandler = (e) => {
      setValue(e.target.value);
      onChange?.(e, { value: e.target.value });
      if (!isTyping) {
        setIsTyping(true);
      }
    };
    const blurHandler = (e) => {
      onBlur?.(e);
      if (isTyping) {
        setIsTyping(false);
      }
    };
    const labelUid = useId();
    const id = idProp ?? labelUid;
    const helperUid = useId();
    const moreInfoUid = useId();
    warnDeprecatedErrorUsage("Textarea", error);
    if (label === void 0) {
      warnOnce(
        "Textarea: label will be required in v4.0.0. Use hideLabel to visually hide the label."
      );
    } else if (typeof label !== "string") {
      warnOnce(
        "Textarea: Passing ReactNode to label is deprecated. Use a plain string with inline markdown instead."
      );
    }
    const errorMessages = typeof error === "boolean" || error === void 0 ? void 0 : error;
    const hasHelperText = hint || showCounter || errorMessages || warning || description;
    const ariaDescribedBy = [hasHelperText && helperUid, moreInfo && moreInfoUid].filter(Boolean).join(" ") || void 0;
    const textareaClassNames = cx([styles["textarea"]], className, {
      [styles["error"]]: error,
      [styles["disable-resize"]]: disableResize,
      [styles["disabled"]]: rest.disabled,
      [styles["readonly"]]: rest.readOnly,
      [styles["has-cols"]]: rest.cols != null
    });
    const styleCombined = { ...style, ...layoutStyles };
    const shouldUseAutosize = autoHeight && !ssr;
    const TextareaComponent = shouldUseAutosize ? index : "textarea";
    return /* @__PURE__ */ jsxs(
      "div",
      {
        className: textareaClassNames,
        "data-anv": "textarea",
        style: styleCombined,
        children: [
          label && !hideLabel && /* @__PURE__ */ jsx(
            FieldLabel,
            {
              htmlFor: id,
              moreInfo,
              moreInfoId: moreInfo ? moreInfoUid : void 0,
              required,
              ...labelProps,
              children: label
            }
          ),
          /* @__PURE__ */ jsx(
            TextareaComponent,
            {
              rows: 3,
              onChange: onChangeHandler,
              onFocus,
              onBlur: blurHandler,
              ref: useMergeRefs([ref, textareaRef]),
              required,
              maxLength,
              id,
              placeholder,
              value: value ?? "",
              "data-tracking-id": trackingId,
              ...rest,
              ...shouldUseAutosize ? { minRows, maxRows } : {},
              "aria-label": (
                // TODO(v4.0.0): remove typeof check — label will always be string
                hideLabel && typeof label === "string" ? stripInlineMarkdown(label) : label ? void 0 : placeholder
              ),
              "aria-describedby": ariaDescribedBy,
              "aria-invalid": error ? !!error : void 0,
              className: styles["input"]
            }
          ),
          hasHelperText ? /* @__PURE__ */ jsx(
            Helper,
            {
              id: helperUid,
              hint,
              maxLength,
              inputLength: length,
              isTyping,
              showCounter,
              error: typeof errorMessages === "string" || Array.isArray(errorMessages) ? errorMessages : void 0,
              warning,
              errorMessage: isValidElement(errorMessages) ? errorMessages : void 0,
              description
            }
          ) : null
        ]
      }
    );
  }
);
Textarea.displayName = "Textarea";

export { Textarea as T };
//# sourceMappingURL=Textarea-CxXmr_Gx.js.map
