"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.HELPER_TEXT_POSITION = void 0;
exports.default = FormField;
var _react = _interopRequireWildcard(require("react"));
var _classnames = _interopRequireDefault(require("classnames"));
var _get = _interopRequireDefault(require("lodash-es/get"));
var _faCircleNotch = require("@fortawesome/free-solid-svg-icons/faCircleNotch");
var _faCheck = require("@fortawesome/free-solid-svg-icons/faCheck");
var _faXmark = require("@fortawesome/free-solid-svg-icons/faXmark");
var _faRedoAlt = require("@fortawesome/free-solid-svg-icons/faRedoAlt");
var _fontAwesomeIcon = require("../font-awesome-icon");
var _button = require("../button");
var _tooltip = require("../tooltip");
var _formFieldLabel = require("./form-field-label");
var _passwordToggleButton = _interopRequireDefault(require("./password-toggle-button"));
var _validityMessages = _interopRequireDefault(require("./validity-messages"));
var _utilities = require("./utilities");
var _useTranslation = require("../hooks/use-translation");
var _constants = require("./constants");
var _jsxRuntime = require("react/jsx-runtime");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
// eslint-disable-next-line you-dont-need-lodash-underscore/get
let HELPER_TEXT_POSITION = exports.HELPER_TEXT_POSITION = /*#__PURE__*/function (HELPER_TEXT_POSITION) {
  HELPER_TEXT_POSITION["TOP"] = "top";
  HELPER_TEXT_POSITION["BOTTOM"] = "bottom";
  return HELPER_TEXT_POSITION;
}({});
function FormField({
  id,
  value = '',
  helperText = '',
  helperTextPosition = HELPER_TEXT_POSITION.TOP,
  label = '',
  readOnly,
  className = '',
  wrapperClass = '',
  isDisabled = false,
  isOptional = false,
  isHighlighted = false,
  disabledInfo = '',
  autoFocus = false,
  validity,
  asyncValidation = {
    isValidating: false,
    isRetryShown: false,
    onRetry: () => {}
  },
  touched = false,
  leftIcon = null,
  rightIcon = null,
  iconTooltipText = '',
  labelIcon = null,
  labelIconTestId,
  labelIconTooltipText,
  fieldClass,
  placeholder = '',
  required = false,
  onChange = () => {},
  onBlur = () => {},
  onSubmit = () => {},
  onCancel = () => {},
  submitAriaLabel,
  cancelAriaLabel,
  retryAriaLabel,
  clearAriaLabel,
  onKeyDown = () => {},
  onFocus = () => {},
  onWheel = () => {},
  onClear,
  children,
  fieldTestId = 'dr-field',
  validationTestId = 'dr-field-validation-result',
  disabledInfoTestId = 'dr-field-disabled-info',
  labelTestId,
  normalize = ({
    nextValue
  }) => nextValue,
  shouldDisplayControls,
  showPasswordToggle = true,
  type,
  spellCheck,
  isHorizontalLayout,
  disableApplyButton,
  passwordToggleButtonTexts: passwordToggleButtonTextsParams,
  validationValues: validationValuesParams,
  optionalLabelText,
  ...attrs
}) {
  const {
    t
  } = (0, _useTranslation.useTranslation)();
  const defaultValidationValues = (0, _constants.useDefaultValidationValues)();
  const validationValues = validationValuesParams ?? defaultValidationValues;
  const passwordToggleButtonTexts = passwordToggleButtonTextsParams ?? {
    show: t('Show password'),
    hide: t('Hide password')
  };
  const [localValue, setLocalValue] = (0, _react.useState)(value);
  const [isFocused, setFocus] = (0, _react.useState)(autoFocus);
  const [isTouched, setTouch] = (0, _react.useState)(touched);
  const [currentType, setCurrentType] = (0, _react.useState)(type);
  (0, _react.useEffect)(() => {
    setLocalValue(normalize({
      nextValue: value,
      prevValue: ''
    }));
  }, [value]);
  (0, _react.useEffect)(() => setTouch(touched), [touched]);
  (0, _react.useEffect)(
  // disabled elements might not receive onBlur event
  // https://github.com/facebook/react/issues/9142
  () => {
    if (isDisabled && isFocused) {
      setFocus(false);
    }
  }, [isDisabled, isFocused]);
  const validityType = (0, _get.default)(validity, 'type');
  let validityValue;
  if (validityType) {
    validityValue = (0, _get.default)(validity, 'value', validationValues[validityType]);
  }
  const validityDisplayLocation = (0, _get.default)(validity, 'displayLocation', _constants.MESSAGE_DISPLAY_LOCATION.INLINE);
  const isPasswordField = (0, _utilities.isPassword)(type);
  const showValidationResult = Boolean(validityValue) && isTouched;
  const icon = getIcon();
  const iconPosition = getIconPosition();
  const isValidationFailed = validityType === _constants.VALIDATION_RULE_TYPES.ERROR;
  const isValidationSucceeded = validityType === _constants.VALIDATION_RULE_TYPES.SUCCESS;
  const isValidationWarned = validityType === _constants.VALIDATION_RULE_TYPES.WARNING;
  const rootClasses = (0, _classnames.default)('dr-form-field', className, {
    [`with-${iconPosition}-icon`]: iconPosition,
    'dr-form-field-validation-error': showValidationResult && isValidationFailed,
    'dr-form-field-validation-warning': showValidationResult && isValidationWarned,
    'dr-form-field-validation-success': showValidationResult && isValidationSucceeded,
    focused: isFocused,
    disabled: isDisabled,
    highlighted: isHighlighted,
    required,
    'horizontal-layout': isHorizontalLayout
  });
  function handleChange(e) {
    const normalizedValue = normalize({
      nextValue: e.target.value,
      prevValue: localValue
    });
    setLocalValue(normalizedValue);
    onChange(e, {
      normalizedValue
    });
  }
  function handleFocus(e) {
    setFocus(true);
    onFocus(e);
  }
  function handleBlur(e) {
    setFocus(false);
    setTouch(true);
    onBlur(e);
  }
  function getIconPosition() {
    if (isPasswordField || asyncValidation.isRetryShown) {
      return _constants.ICON_POSITION.CENTER_RIGHT;
    }
    if (asyncValidation.isValidating || rightIcon) {
      return _constants.ICON_POSITION.RIGHT;
    }
    if (leftIcon) {
      return _constants.ICON_POSITION.LEFT;
    }
  }
  function getIcon() {
    if (asyncValidation.isRetryShown) {
      return;
    }
    if (asyncValidation.isValidating) {
      return _faCircleNotch.faCircleNotch;
    }
    return leftIcon || rightIcon;
  }
  const validationMessagesIds = showValidationResult ? (0, _utilities.getValidationMessagesIds)({
    validity,
    validationValues,
    fieldId: id
  }) : '';
  const ariaDescribedByIds = `${validationMessagesIds} ${attrs['aria-describedby'] ?? ''}`.trim();
  const ariaAttrs = {
    'aria-required': required,
    ...(ariaDescribedByIds && {
      'aria-describedby': ariaDescribedByIds
    }),
    ...(showValidationResult && {
      'aria-invalid': isValidationFailed
    })
  };
  const props = {
    id,
    disabled: isDisabled,
    autoFocus,
    placeholder,
    spellCheck: JSON.stringify(spellCheck),
    onKeyDown,
    type: currentType,
    value: localValue,
    onChange: handleChange,
    onBlur: handleBlur,
    onFocus: handleFocus,
    onWheel,
    readOnly,
    className: (0, _classnames.default)(fieldClass, {
      'dr-form-field-control-validated': showValidationResult
    }),
    'test-id': fieldTestId,
    ...attrs,
    ...ariaAttrs
  };
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
    className: rootClasses,
    "test-id": "dr-form-field-root",
    children: [label && /*#__PURE__*/(0, _jsxRuntime.jsx)(_formFieldLabel.FormFieldLabel, {
      label: label,
      id: id,
      labelTestId: labelTestId,
      labelIcon: labelIcon,
      labelIconTestId: labelIconTestId,
      labelIconTooltipText: labelIconTooltipText,
      isOptional: isOptional,
      isDisabled: isDisabled,
      isReadOnly: readOnly,
      optionalLabelText: optionalLabelText ?? t('Optional')
    }), helperText && helperTextPosition === HELPER_TEXT_POSITION.TOP && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
      className: (0, _classnames.default)('dr-form-field-text', {
        disabled: isDisabled
      }),
      children: helperText
    }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
      className: (0, _classnames.default)(wrapperClass, 'dr-form-field-wrapper'),
      children: [!isPasswordField && icon && /*#__PURE__*/(0, _jsxRuntime.jsx)(_tooltip.Tooltip, {
        content: iconTooltipText,
        placement: "top",
        children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_fontAwesomeIcon.FontAwesomeIcon, {
          "test-id": "form-field-icon",
          icon: icon,
          className: (0, _classnames.default)('dr-form-field-icon', {
            disabled: isDisabled
          }),
          spin: asyncValidation.isValidating
        })
      }), children ? /*#__PURE__*/(0, _react.cloneElement)(children, props) : null, shouldDisplayControls && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
        children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
          "test-id": "cancel-button",
          className: "button editable-icon cancel",
          onClick: onCancel,
          type: _button.BUTTON_TYPES.BUTTON,
          "aria-label": cancelAriaLabel ?? t('Cancel'),
          children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_fontAwesomeIcon.FontAwesomeIcon, {
            icon: _faXmark.faXmark
          })
        }), /*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
          "test-id": "apply-button",
          className: (0, _classnames.default)('button editable-icon apply', {
            disabled: disableApplyButton
          }),
          onClick: onSubmit,
          type: _button.BUTTON_TYPES.BUTTON,
          disabled: disableApplyButton,
          "aria-label": submitAriaLabel ?? t('Submit'),
          children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_fontAwesomeIcon.FontAwesomeIcon, {
            icon: _faCheck.faCheck
          })
        })]
      }), isPasswordField && showPasswordToggle && /*#__PURE__*/(0, _jsxRuntime.jsx)(_passwordToggleButton.default, {
        isDisabled: isDisabled,
        onClick: setCurrentType,
        fieldType: currentType,
        passwordToggleButtonTexts: passwordToggleButtonTexts
      }), asyncValidation.isRetryShown && /*#__PURE__*/(0, _jsxRuntime.jsx)(_button.Button, {
        accentType: _button.ACCENT_TYPES.ROUND_ICON,
        className: "toggle-password-button",
        onClick: asyncValidation.onRetry,
        testId: "retry-async-validation",
        size: _button.BUTTON_SIZES.XS,
        "aria-label": retryAriaLabel ?? t('Retry'),
        children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_fontAwesomeIcon.FontAwesomeIcon, {
          icon: _faRedoAlt.faRedoAlt
        })
      }), !!onClear && /*#__PURE__*/(0, _jsxRuntime.jsx)(_button.Button, {
        accentType: _button.ACCENT_TYPES.ROUND_ICON,
        className: "toggle-password-button",
        onClick: onClear,
        testId: "clear-button",
        size: _button.BUTTON_SIZES.XS,
        "aria-label": clearAriaLabel ?? t('Clear'),
        children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_fontAwesomeIcon.FontAwesomeIcon, {
          icon: _faXmark.faXmark
        })
      })]
    }), helperText && helperTextPosition === HELPER_TEXT_POSITION.BOTTOM && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
      className: (0, _classnames.default)('dr-form-field-text helper-text-bottom', {
        disabled: isDisabled
      }),
      children: helperText
    }), isDisabled && /*#__PURE__*/(0, _jsxRuntime.jsx)(_validityMessages.default, {
      validity: {
        type: _constants.VALIDATION_RULE_TYPES.INFO,
        value: disabledInfo
      },
      validationTestId: disabledInfoTestId,
      validationValues: validationValues
    }), showValidationResult && validityDisplayLocation === _constants.MESSAGE_DISPLAY_LOCATION.INLINE && /*#__PURE__*/(0, _jsxRuntime.jsx)(_validityMessages.default, {
      validity: validity,
      validationTestId: validationTestId,
      validationValues: validationValues,
      fieldId: id
    })]
  });
}