"use strict";
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
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);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Input = void 0;
/* eslint-disable max-len */
var react_1 = __importDefault(require("react"));
var bem_react_classname_1 = require("bem-react-classname");
var icons_classic_1 = require("@alfalab/icons-classic");
var cn_1 = require("../cn");
var icon_button_1 = __importDefault(require("../icon-button/icon-button"));
var masked_input_1 = __importDefault(require("../masked-input/masked-input"));
var scroll_to_1 = __importDefault(require("../lib/scroll-to"));
var vars_1 = require("../vars");
var set_ref_1 = require("../lib/set-ref");
/**
 * Компонент текстового поля ввода.
 */
var Input = /** @class */ (function (_super) {
    __extends(Input, _super);
    function Input() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.cn = bem_react_classname_1.createCn('input');
        _this.state = {
            focused: false,
            error: _this.props.error || null,
            value: _this.props.defaultValue || '',
        };
        _this.handleFocus = function (event) {
            _this.setState({ focused: true });
            _this.enableMouseWheel();
            _this.resetError();
            if (_this.props.onFocus) {
                _this.props.onFocus(event);
            }
        };
        _this.handleClick = function (event) {
            if (_this.props.onClick) {
                _this.props.onClick(event);
            }
        };
        _this.handleBlur = function (event) {
            _this.setState({ focused: false });
            _this.disableMouseWheel();
            if (_this.props.onBlur) {
                _this.props.onBlur(event);
            }
        };
        _this.handleChange = function (event) {
            _this.changeValue(event.target.value, event);
        };
        _this.handleClearClick = function (event) {
            _this.changeValue('', event);
            if (_this.props.onClearClick) {
                _this.props.onClearClick(event);
            }
            _this.focus();
        };
        _this.handleKeyDown = function (event) {
            if (_this.props.onKeyDown) {
                _this.props.onKeyDown(event);
            }
        };
        _this.handleKeyUp = function (event) {
            if (_this.props.onKeyUp) {
                _this.props.onKeyUp(event);
            }
        };
        _this.handlePaste = function (event) {
            if (_this.props.onPaste) {
                _this.props.onPaste(event);
            }
        };
        _this.handleTouchStart = function (event) {
            if (_this.props.onTouchStart) {
                _this.props.onTouchStart(event);
            }
        };
        _this.handleTouchEnd = function (event) {
            if (_this.props.onTouchEnd) {
                _this.props.onTouchEnd(event);
            }
        };
        _this.handleTouchMove = function (event) {
            if (_this.props.onTouchMove) {
                _this.props.onTouchMove(event);
            }
        };
        _this.handleTouchCancel = function (event) {
            if (_this.props.onTouchCancel) {
                _this.props.onTouchCancel(event);
            }
        };
        return _this;
    }
    Input.prototype.componentDidUpdate = function (prevProps) {
        if (prevProps.error !== this.props.error) {
            // eslint-disable-next-line react/no-did-update-set-state
            this.setState({ error: this.props.error });
        }
    };
    Input.prototype.render = function () {
        var _this = this;
        var hasAddons = !!this.props.rightAddons || !!this.props.leftAddons;
        var hasLeftAddons = !!this.props.leftAddons;
        var value = this.props.value === undefined ? this.state.value : this.props.value;
        var focused = this.getFocused();
        return (react_1.default.createElement("span", { className: this.cn({
                type: this.props.type,
                view: this.props.view,
                disabled: this.props.disabled,
                focused: focused,
                size: this.props.size,
                width: this.props.width,
                'has-addons': hasAddons,
                'has-left-addons': hasLeftAddons,
                'has-clear': !!this.props.clear,
                'has-icon': !!this.props.icon,
                'has-label': !!this.props.label,
                'has-value': !!value,
                invalid: !!this.state.error,
            }), ref: function (root) {
                _this.root = root;
            }, "data-test-id": this.props['data-test-id'] },
            react_1.default.createElement("span", { className: this.cn('inner') },
                this.renderContent(),
                (this.state.error || this.props.hint)
                    && (react_1.default.createElement("span", { className: this.cn('sub') }, this.state.error || this.props.hint)))));
    };
    Input.prototype.renderContent = function () {
        var _this = this;
        var isMaskedInput = this.props.mask !== undefined;
        var value = this.props.value === undefined ? this.state.value : this.props.value;
        var inputProps = {
            className: this.cn('control'),
            type: this.props.type,
            view: this.props.view,
            formNoValidate: this.props.formNoValidate,
            autoComplete: this.getAutoCompleteValue(),
            disabled: this.props.disabled || this.props.disabledAttr,
            maxLength: this.props.maxLength,
            id: this.props.id,
            name: this.props.name,
            value: value,
            tabIndex: this.props.tabIndex,
            placeholder: this.props.placeholder,
            pattern: this.props.pattern,
            ref: function (control) {
                set_ref_1.setRef(_this.props.inputRef, control);
                _this.control = control;
            },
            title: this.props.title,
            onChange: this.handleChange,
            onFocus: this.handleFocus,
            onClick: this.handleClick,
            onBlur: this.handleBlur,
            onKeyDown: this.handleKeyDown,
            onKeyUp: this.handleKeyUp,
            onPaste: this.handlePaste,
            onTouchStart: this.handleTouchStart,
            onTouchEnd: this.handleTouchEnd,
            onTouchMove: this.handleTouchMove,
            onTouchCancel: this.handleTouchCancel,
        };
        return (react_1.default.createElement("span", { className: this.cn('box'), key: "input-wrapper", ref: function (box) {
                _this.box = box;
            } },
            this.props.leftAddons
                && (react_1.default.createElement("span", { className: this.cn('addons', { left: true }), key: "left-addons" }, this.props.leftAddons)),
            react_1.default.createElement("span", { className: this.cn('input-wrapper') },
                !!this.props.label
                    && (react_1.default.createElement("span", { className: this.cn('top') }, this.props.label)),
                isMaskedInput
                    ? (react_1.default.createElement(masked_input_1.default, __assign({}, inputProps, { mask: this.props.mask, formatCharacters: this.props.maskFormatCharacters, onProcessInputEvent: this.props.onProcessMaskInputEvent, useWhitespaces: this.props.useWhitespacesInMask })))
                    : react_1.default.createElement("input", __assign({}, inputProps))),
            this.props.clear && value
                && (react_1.default.createElement(icon_button_1.default, { className: this.cn('clear'), size: this.props.size, tabIndex: -1, onClick: this.handleClearClick }, this.renderIcon())),
            this.props.icon
                && (react_1.default.createElement("div", { className: this.cn('icon') }, this.props.icon)),
            this.props.rightAddons
                && (react_1.default.createElement("span", { className: this.cn('addons', { right: true }), key: "right-addons" }, this.props.rightAddons))));
    };
    Input.prototype.renderIcon = function () {
        switch (this.props.size) {
            case 's':
                return react_1.default.createElement(icons_classic_1.CloseSIcon, null);
            case 'l':
                return react_1.default.createElement(icons_classic_1.CloseLIcon, null);
            case 'xl':
                return react_1.default.createElement(icons_classic_1.CloseXlIcon, null);
            case 'm':
            default:
                return react_1.default.createElement(icons_classic_1.CloseMIcon, null);
        }
    };
    Input.prototype.getAutoCompleteValue = function () {
        if (typeof this.props.autocomplete === 'string') {
            return this.props.autocomplete;
        }
        return this.props.autocomplete === false ? 'off' : 'on';
    };
    /**
     * Разблокирует возможность скролла в поле ввода
     *
     */
    Input.prototype.enableMouseWheel = function () {
        var input = this.control instanceof masked_input_1.default ? this.control.input : this.control;
        if (input) {
            input.onwheel = function () { return true; };
        }
    };
    /**
     * Блокирует возможность скролла в поле ввода
     */
    Input.prototype.disableMouseWheel = function () {
        var input = this.control instanceof masked_input_1.default ? this.control.getControl() : this.control;
        if (input) {
            input.onwheel = function () { return false; };
        }
    };
    /**
     * Возвращает корневой `HTMLElement` компонента.
     */
    Input.prototype.getNode = function () {
        return this.root;
    };
    /**
     * Возвращает ссылку на инстанс контейнера для контрола.
     */
    Input.prototype.getBoxNode = function () {
        return this.box;
    };
    /**
     * Возвращает ссылку на HTMLElement инпута.
     */
    Input.prototype.getControl = function () {
        if (this.props.mask !== undefined) {
            return this.control.getControl();
        }
        return this.control;
    };
    /**
     * Возвращает ссылку на инстанс MaskedInput.
     * Если маска не была установлена, возвращает null.
     */
    Input.prototype.getMaskedInputInstance = function () {
        if (this.props.mask !== undefined) {
            return this.control;
        }
        return null;
    };
    /**
     * Устанавливает фокус на поле ввода.
     */
    Input.prototype.focus = function () {
        this.control.focus();
        this.setSelectionRange(this.getControl().value.length);
    };
    /**
     * Убирает фокус с поля ввода.
     */
    // eslint-disable-next-line class-methods-use-this
    Input.prototype.blur = function () {
        if (document.activeElement instanceof HTMLElement) {
            document.activeElement.blur();
        }
    };
    /**
     * Скроллит страницу до поля ввода.
     */
    Input.prototype.scrollTo = function () {
        scroll_to_1.default({
            targetY: (this.root.getBoundingClientRect().top + window.pageYOffset) - vars_1.SCROLL_TO_CORRECTION,
        });
    };
    /**
     * Устанавливает начальное и конечное положение выделения текста в элементе.
     * @param start Индекс первого выделенного символа.
     * @param end Индекс символа после последнего выделенного символа.
     */
    Input.prototype.setSelectionRange = function (start, end) {
        if (start === void 0) { start = 0; }
        if (end === void 0) { end = this.getControl().value.length; }
        if (this.props.type !== 'email') {
            this.getControl().setSelectionRange(start, end);
        }
    };
    /**
     * Изменяет текущение значение поля ввода и генерирует событие об этом.
     *
     * @param value Новое значение
     * @param event React SyntheticEvent
     */
    Input.prototype.changeValue = function (value, event) {
        if (this.props.value === undefined) {
            this.setState({ value: value });
        }
        if (this.props.onChange) {
            this.props.onChange(value, event);
        }
    };
    /**
     * Возвращает состояние фокуса.
     */
    Input.prototype.getFocused = function () {
        return this.props.focused === undefined ? this.state.focused : this.props.focused;
    };
    /**
     * Сбрасывает состояние ошибки.
     */
    Input.prototype.resetError = function () {
        if (this.props.resetError) {
            this.setState({
                error: null,
            });
        }
    };
    Input.defaultProps = {
        formNoValidate: false,
        size: 'm',
        type: 'text',
        view: 'default',
        resetError: true,
    };
    return Input;
}(react_1.default.PureComponent));
exports.Input = Input;
exports.default = cn_1.withTheme(Input);

//# sourceMappingURL=input.js.map
