"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TextArea = void 0;
var FontAwesome = require("react-fontawesome");
var React = require("react");
var PropTypes = require("prop-types");
var classnames = require("classnames");
var react_autosize_textarea_1 = require("react-autosize-textarea");
var Forms_1 = require("../utils/Forms");
var FileInput_1 = require("../FileInput/FileInput");
var flex_1 = require("../flex");
require("./TextArea.less");
require("../less/forms.less");
var propTypes = {
    disabled: PropTypes.bool,
    error: PropTypes.string,
    label: PropTypes.string,
    maxLength: PropTypes.number,
    minLength: PropTypes.number,
    name: PropTypes.string.isRequired,
    onBlur: PropTypes.func,
    onChange: PropTypes.func,
    onFocus: PropTypes.func,
    onKeyDown: PropTypes.func,
    onKeyPress: PropTypes.func,
    onKeyUp: PropTypes.func,
    optional: PropTypes.bool,
    placeholder: PropTypes.node,
    readOnly: PropTypes.bool,
    required: PropTypes.bool,
    spellCheck: PropTypes.bool,
    value: PropTypes.node,
    className: PropTypes.string,
    autoResize: PropTypes.bool,
    rows: PropTypes.number,
    size: PropTypes.oneOf(Object.values(Forms_1.FormElementSize)),
    showUploadAttachmentButton: PropTypes.bool,
    storeUpload: PropTypes.func,
    fileUploadCustomIcon: PropTypes.node,
};
var defaultProps = {
    rows: 1,
    size: Forms_1.FormElementSize.FULL_WIDTH,
};
var TextArea = /** @class */ (function (_super) {
    __extends(TextArea, _super);
    function TextArea(props) {
        var _this = _super.call(this, TextArea.validateProps(props)) || this;
        // eslint-disable-next-line react/sort-comp
        _this.textAreaEl = React.createRef();
        /* Insert any additional lifecycle methods,
           event handlers, and helper methods here */
        _this.onFocus = function (e) {
            var onFocus = _this.props.onFocus;
            _this.setState({ inFocus: true });
            if (onFocus) {
                onFocus(e);
            }
        };
        _this.onBlur = function (e) {
            var onBlur = _this.props.onBlur;
            _this.setState({ inFocus: false, hasBeenFocused: true });
            if (onBlur) {
                onBlur(e);
            }
        };
        _this.onKeyDown = function (e) {
            var onKeyDown = _this.props.onKeyDown;
            if (onKeyDown) {
                onKeyDown(e);
            }
        };
        _this.onKeyPress = function (e) {
            var onKeyPress = _this.props.onKeyPress;
            if (onKeyPress) {
                onKeyPress(e);
            }
        };
        _this.onKeyUp = function (e) {
            var onKeyUp = _this.props.onKeyUp;
            if (onKeyUp) {
                onKeyUp(e);
            }
        };
        _this.state = { inFocus: false, hasBeenFocused: false };
        return _this;
    }
    TextArea.validateProps = function (props) {
        if (props.required && props.optional) {
            console.warn("You should not pass both `required` and `optional` on a TextArea.");
        }
        if (props.readOnly && props.disabled) {
            console.warn("The readOnly, disabled props on a TextArea are mutually exclusive. If both are passed readOnly is used");
        }
        return props;
    };
    TextArea.prototype.focus = function () {
        this.textAreaEl.current.focus();
    };
    // Give consumers that set up a React ref access to the <textarea> height
    TextArea.prototype.textAreaHeight = function () {
        var _a;
        return ((_a = this.textAreaEl.current) === null || _a === void 0 ? void 0 : _a.offsetHeight) || undefined;
    };
    TextArea.prototype.currentErrorMessage = function () {
        var _a = this.props, error = _a.error, value = _a.value, required = _a.required;
        var hasBeenFocused = this.state.hasBeenFocused;
        var errorMessage = "";
        if (required && hasBeenFocused && !value) {
            errorMessage = "required";
        }
        if (error) {
            errorMessage = error;
        }
        return errorMessage;
    };
    TextArea.prototype.renderNote = function (errorMessage) {
        var _a = this.props, required = _a.required, optional = _a.optional;
        var inputNote;
        if (required) {
            inputNote = React.createElement("span", { className: "TextArea--required" }, "required");
        }
        if (optional) {
            inputNote = React.createElement("span", { className: "TextArea--optional" }, "optional");
        }
        if (errorMessage) {
            inputNote = (React.createElement("span", { className: "TextArea--error" },
                React.createElement(FontAwesome, { name: "exclamation-triangle" }),
                " ",
                errorMessage));
        }
        return inputNote;
    };
    TextArea.prototype.render = function () {
        var _a;
        var wrapperClass = "TextArea";
        var errorMessage = this.currentErrorMessage();
        var valid = errorMessage === "";
        if (errorMessage)
            wrapperClass += " TextArea--hasError";
        if (this.props.readOnly) {
            wrapperClass += " TextArea--readonly";
        }
        else if (this.props.disabled) {
            wrapperClass += " TextArea--disabled";
        }
        else if (this.state.inFocus) {
            wrapperClass += " TextArea--inFocus";
        }
        // placeholder shown
        if (!this.props.value && this.props.placeholder) {
            wrapperClass += " TextArea--placeholder-shown";
        }
        // note on the upper right corner
        var inputNote = this.renderNote(errorMessage);
        // (a11y) The 'for' attribute of the label tag and the 'id' attribute
        // of the textarea tag should match so screen readers can determine which
        // label goes with which form element. If an 'id' isn't specified, we
        // use 'name' instead for this purpose.
        var id = this.props.id || this.props.name;
        var textAreaProps = (_a = {},
            _a["aria-invalid"] = !valid,
            _a["aria-label"] = this.props.label || this.props.placeholder,
            _a.className = "TextArea--input",
            _a.disabled = this.props.disabled,
            _a.id = id,
            _a["data-testid"] = this.props.dataTestID,
            _a.maxLength = this.props.maxLength,
            _a.minLength = this.props.minLength,
            _a.name = this.props.name,
            _a.onBlur = this.onBlur,
            _a.onChange = this.props.onChange,
            _a.onFocus = this.onFocus,
            _a.onKeyDown = this.onKeyDown,
            _a.onKeyPress = this.onKeyPress,
            _a.onKeyUp = this.onKeyUp,
            _a.placeholder = this.props.placeholder,
            _a.readOnly = this.props.readOnly,
            _a.ref = this.textAreaEl,
            _a.required = this.props.required,
            _a.spellCheck = this.props.spellCheck,
            _a.value = this.props.value,
            _a.rows = this.props.rows,
            _a);
        // Don't increment rows in readOnly so that there is no extra spacing.
        var rows = this.props.rows;
        if ((this.props.placeholder || this.props.autoResize) && !this.props.readOnly) {
            // Need to add another row for autoGrow since it seems to collapse in a way that conflicts with the placeholder
            // margin
            rows = this.props.rows + 1;
        }
        var textarea = React.createElement("textarea", __assign({}, textAreaProps, { rows: rows }));
        if (this.props.autoResize) {
            textarea = React.createElement(react_autosize_textarea_1.default, __assign({}, textAreaProps, { rows: rows }));
        }
        return (React.createElement("div", { className: classnames(wrapperClass, Forms_1.formElementSizeClassName(this.props.size), this.props.className) },
            React.createElement("div", { className: "TextArea--infoRow" },
                this.props.label && (React.createElement("label", { className: "TextArea--label", htmlFor: id }, this.props.label)),
                React.createElement("span", { "aria-live": "polite" }, inputNote)),
            React.createElement(flex_1.FlexBox, null,
                textarea,
                this.props.showUploadAttachmentButton && (React.createElement(FileInput_1.FileInput, { store: this.props.storeUpload, customIcon: this.props.fileUploadCustomIcon, iconOnly: true }))),
            this.props.uploads));
    };
    TextArea.propTypes = propTypes;
    TextArea.defaultProps = defaultProps;
    return TextArea;
}(React.Component));
exports.TextArea = TextArea;
