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 (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        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 __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import React from 'react';
import { getRandomID, isNonNullable } from '../../lib/utils.js';
import { Input } from '../../components/Input/index.js';
import { InputLikeText } from '../InputLikeText/index.js';
import { RenderLayer } from '../RenderLayer/index.js';
import { Spinner } from '../../components/Spinner/index.js';
import { CommonWrapper } from '../CommonWrapper/index.js';
import { MobilePopup } from '../MobilePopup/index.js';
import { responsiveLayout } from '../../components/ResponsiveLayout/decorator.js';
import { rootNode, getRootNode } from '../../lib/rootNode/index.js';
import { createPropsGetter } from '../../lib/createPropsGetter.js';
import { ThemeContext } from '../../lib/theming/ThemeContext.js';
import { LoadingIcon } from '../icons2022/LoadingIcon.js';
import { Popup } from '../Popup/index.js';
import { getMenuPositions } from '../../lib/getMenuPositions.js';
import { ZIndex } from '../ZIndex/index.js';
import { MaskedInput } from '../../components/MaskedInput/index.js';
import { getStyles as getMaskedInputStyles } from '../../components/MaskedInput/MaskedInput.styles.js';
import { InternalTextareaWithLayout } from '../InternalTextareaWithLayout/InternalTextareaWithLayout.js';
import { withSize } from '../../lib/size/SizeDecorator.js';
import { withRenderEnvironment } from '../../lib/renderEnvironment/index.js';
import { ArrowDownIcon } from './ArrowDownIcon.js';
import { ComboBoxMenu } from './ComboBoxMenu.js';
import { ComboBoxRequestStatus } from './CustomComboBoxTypes.js';
import { getStyles } from './CustomComboBox.styles.js';
import { CustomComboBoxDataTids } from './CustomComboBox.js';
import { getComboBoxTheme } from './getComboBoxTheme.js';
export var ComboBoxViewIds = {
    menu: 'ComboBoxView__menu',
};
var ComboBoxView = /** @class */ (function (_super) {
    __extends(ComboBoxView, _super);
    function ComboBoxView() {
        var _a;
        var _this = _super.apply(this, arguments) || this;
        _this.getProps = createPropsGetter(ComboBoxView_1.defaultProps);
        _this.mobileInput = null;
        _this.dropdownContainerRef = React.createRef();
        _this.menuId = ComboBoxViewIds.menu + getRandomID();
        _this.state = {
            anchorElement: null,
            clearCrossShowed: _this.props.showClearIcon === 'always' && !!((_a = _this.props.value) === null || _a === void 0 ? void 0 : _a.toString()),
        };
        _this.getComboBoxMenu = function () {
            var _a = _this.props, items = _a.items, loading = _a.loading, opened = _a.opened, refMenu = _a.refMenu, maxMenuHeight = _a.maxMenuHeight, renderTotalCount = _a.renderTotalCount, renderNotFound = _a.renderNotFound, totalCount = _a.totalCount;
            var _b = _this.getProps(), repeatRequest = _b.repeatRequest, requestStatus = _b.requestStatus, renderItem = _b.renderItem, itemWrapper = _b.itemWrapper;
            return (React.createElement(ComboBoxMenu, { hasMargin: false, menuId: _this.menuId, items: items, loading: loading, maxMenuHeight: maxMenuHeight, onValueChange: _this.handleItemSelect, opened: opened, refMenu: refMenu, renderTotalCount: renderTotalCount, renderItem: renderItem, renderNotFound: renderNotFound, itemWrapper: itemWrapper, renderAddButton: _this.renderAddButton, repeatRequest: repeatRequest, requestStatus: requestStatus, totalCount: totalCount, isMobile: _this.isMobileLayout, size: _this.size }));
        };
        _this.renderMenu = function () {
            var _a = _this.getProps(), opened = _a.opened, menuPos = _a.menuPos, menuAlign = _a.menuAlign;
            var anchorElement = _this.state.anchorElement;
            return (opened &&
                anchorElement && (React.createElement(Popup, { opened: true, hasShadow: true, tryBestFallbackPosition: true, minWidth: "100%", anchorElement: anchorElement, priority: ZIndex.priorities.PopupMenu, positions: getMenuPositions(menuPos, menuAlign), disablePortal: _this.props.disablePortal, margin: parseInt(_this.theme.menuOffsetY) - 1, ref: _this.dropdownContainerRef }, _this.getComboBoxMenu())));
        };
        _this.renderMobileMenu = function () {
            var rightIcon = null;
            var _a = _this.props, loading = _a.loading, items = _a.items, opened = _a.opened, onFocus = _a.onFocus, onInputValueChange = _a.onInputValueChange, onInputKeyDown = _a.onInputKeyDown, placeholder = _a.placeholder, textValue = _a.textValue;
            if (loading && items && !!items.length) {
                rightIcon = _this.renderSpinner();
            }
            var inputProps = {
                autoComplete: 'off',
                autoFocus: true,
                width: '100%',
                onFocus: onFocus,
                onValueChange: onInputValueChange,
                onKeyDown: onInputKeyDown,
                value: textValue,
                placeholder: placeholder,
                rightIcon: rightIcon,
            };
            return (opened && (React.createElement(MobilePopup, { headerChildComponent: React.createElement(Input, __assign({ ref: _this.refMobileInput }, inputProps)), onCloseRequest: _this.props.onMobileClose, opened: true }, _this.getComboBoxMenu())));
        };
        _this.getParent = function () {
            return getRootNode(_this);
        };
        _this.renderAddButton = function () {
            return _this.getProps().renderAddButton(_this.props.textValue);
        };
        _this.handleMobileFocus = function () {
            var _a, _b, _c;
            (_b = (_a = _this.props).onInputClick) === null || _b === void 0 ? void 0 : _b.call(_a);
            (_c = _this.mobileInput) === null || _c === void 0 ? void 0 : _c.focus();
        };
        _this.handleItemSelect = function (item) {
            var _a, _b;
            if (_this.props.onValueChange) {
                _this.props.onValueChange(item);
            }
            if (_this.isMobileLayout) {
                (_b = (_a = _this.props).onMobileClose) === null || _b === void 0 ? void 0 : _b.call(_a);
            }
        };
        _this.refInput = function (input) {
            if (_this.props.refInput) {
                _this.props.refInput(input);
            }
            _this.input = input;
        };
        _this.renderSpinner = function () { return (React.createElement("span", { className: _this.styles.spinnerWrapper() },
            React.createElement(Spinner, { type: "mini", caption: "", dimmed: true }))); };
        _this.getRightIcon = function () {
            var _a = _this.props, loading = _a.loading, items = _a.items, drawArrow = _a.drawArrow, rightIcon = _a.rightIcon;
            var size = _this.size;
            if (loading && items && !!items.length) {
                return React.createElement(LoadingIcon, { size: size });
            }
            if (rightIcon || drawArrow) {
                return rightIcon || React.createElement(ArrowDownIcon, { size: size });
            }
            return null;
        };
        _this.refMobileInput = function (input) {
            _this.mobileInput = input;
        };
        return _this;
    }
    ComboBoxView_1 = ComboBoxView;
    ComboBoxView.prototype.componentDidMount = function () {
        this.updateAnchorElement();
        if (this.props.autoFocus && this.props.onFocus) {
            this.props.onFocus();
        }
    };
    ComboBoxView.prototype.updateAnchorElement = function () {
        var parent = this.getParent();
        var anchorElement = this.state.anchorElement;
        if (anchorElement !== parent) {
            this.setState({
                anchorElement: parent,
            });
        }
    };
    ComboBoxView.prototype.componentDidUpdate = function (prevProps) {
        var _a = this, input = _a.input, props = _a.props;
        this.updateAnchorElement();
        if (props.editing && !prevProps.editing && input) {
            input.focus();
        }
    };
    ComboBoxView.prototype.render = function () {
        var _this = this;
        this.styles = getStyles(this.emotion);
        this.maskedInputStyles = getMaskedInputStyles(this.emotion);
        return (React.createElement(ThemeContext.Consumer, null, function (theme) {
            _this.theme = getComboBoxTheme(theme);
            return React.createElement(ThemeContext.Provider, { value: _this.theme }, _this.renderMain());
        }));
    };
    ComboBoxView.prototype.renderMain = function () {
        var _a = this.props, onMouseEnter = _a.onMouseEnter, onMouseLeave = _a.onMouseLeave, onMouseOver = _a.onMouseOver, opened = _a.opened;
        var _b = this.getProps(), onClickOutside = _b.onClickOutside, onFocusOutside = _b.onFocusOutside, width = _b.width;
        var isMobile = this.isMobileLayout;
        var input = this.renderInput();
        return (React.createElement(CommonWrapper, __assign({}, this.props),
            React.createElement(RenderLayer, { onClickOutside: onClickOutside, onFocusOutside: onFocusOutside, active: opened },
                React.createElement("span", { "data-tid": CustomComboBoxDataTids.comboBoxView, style: { width: width }, className: this.styles.root(), onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseOver: onMouseOver, ref: this.setRootNode },
                    input,
                    isMobile ? this.renderMobileMenu() : this.renderMenu()))));
    };
    ComboBoxView.prototype.renderInput = function () {
        var isMobile = this.isMobileLayout;
        var _a = this.props, id = _a.id, align = _a.align, borderless = _a.borderless, disabled = _a.disabled, editing = _a.editing, error = _a.error, onFocus = _a.onFocus, onInputBlur = _a.onInputBlur, onInputValueChange = _a.onInputValueChange, onInputFocus = _a.onInputFocus, onInputClick = _a.onInputClick, onInputKeyDown = _a.onInputKeyDown, placeholder = _a.placeholder, textValue = _a.textValue, value = _a.value, warning = _a.warning, refInputLikeText = _a.refInputLikeText, leftIcon = _a.leftIcon, inputMode = _a.inputMode, ariaDescribedby = _a["aria-describedby"], ariaLabel = _a["aria-label"], showClearIcon = _a.showClearIcon, mask = _a.mask, maskChar = _a.maskChar, formatChars = _a.formatChars, onBeforePasteInMask = _a.onBeforePasteInMask;
        var rightIcon = this.getRightIcon();
        var inputProps = {
            id: id,
            align: align,
            borderless: borderless,
            disabled: disabled,
            error: error,
            maxLength: this.props.maxLength,
            onBlur: isMobile ? undefined : onInputBlur,
            onValueChange: onInputValueChange,
            onFocus: onInputFocus,
            onClick: isMobile ? this.handleMobileFocus : onInputClick,
            leftIcon: leftIcon,
            rightIcon: rightIcon,
            value: textValue || '',
            onKeyDown: onInputKeyDown,
            placeholder: placeholder,
            width: '100%',
            ref: this.refInput,
            warning: warning,
            inputMode: inputMode,
            autoComplete: 'off',
            'aria-describedby': ariaDescribedby,
            'aria-controls': this.menuId,
            'aria-label': ariaLabel,
            showClearIcon: showClearIcon,
            size: this.size,
        };
        var multilineTextareaProps = {
            autoResize: true,
            rows: 1,
            extraRow: false,
            maxRows: this.props.maxRows,
        };
        if (this.props.viewMode === 'multiline' && !mask) {
            return React.createElement(InternalTextareaWithLayout, __assign({}, inputProps, multilineTextareaProps));
        }
        if (editing) {
            if (mask) {
                return (React.createElement(MaskedInput, __assign({}, inputProps, { type: "text", mask: mask, maskChar: maskChar, formatChars: formatChars, onBeforePasteValue: onBeforePasteInMask })));
            }
            if (this.props.viewMode === 'multiline-editing') {
                return React.createElement(InternalTextareaWithLayout, __assign({}, inputProps, multilineTextareaProps));
            }
            return React.createElement(Input, __assign({}, inputProps));
        }
        var renderValue = this.getProps().renderValue;
        return (React.createElement(InputLikeText, { id: id, align: align, borderless: borderless, error: error, onFocus: onFocus, leftIcon: leftIcon, rightIcon: rightIcon, disabled: disabled, warning: warning, placeholder: placeholder, size: this.size, width: "100%", ref: refInputLikeText, "aria-describedby": ariaDescribedby, "aria-controls": this.menuId, showClearIcon: showClearIcon, className: this.cx(mask && this.maskedInputStyles.root(this.theme)), onClearCrossClick: this.props.onClearCrossClick }, isNonNullable(value) && renderValue ? renderValue(value) : null));
    };
    var ComboBoxView_1;
    ComboBoxView.__KONTUR_REACT_UI__ = 'ComboBoxView';
    ComboBoxView.displayName = 'ComboBoxView';
    ComboBoxView.defaultProps = {
        renderItem: function (item) { return item; },
        renderValue: function (item) { return item; },
        renderAddButton: function () { return null; },
        repeatRequest: function () { return undefined; },
        requestStatus: ComboBoxRequestStatus.Unknown,
        onClickOutside: function () {
            /**/
        },
        onFocusOutside: function () {
            /**/
        },
        width: 250,
        showClearIcon: 'never',
    };
    ComboBoxView = ComboBoxView_1 = __decorate([
        withRenderEnvironment,
        responsiveLayout,
        rootNode,
        withSize
    ], ComboBoxView);
    return ComboBoxView;
}(React.Component));
export { ComboBoxView };
//# sourceMappingURL=ComboBoxView.js.map