"use strict";var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;exports.__esModule = true;exports.AutocompleteIds = exports.AutocompleteDataTids = exports.Autocomplete = void 0;var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose"));
var _react = _interopRequireDefault(require("react"));
var _globalObject = require("@skbkontur/global-object");

var _MenuMessage = require("../../internal/MenuMessage");
var _decorators = require("../../lib/locale/decorators");
var _utils = require("../../lib/utils");
var _ThemeContext = require("../../lib/theming/ThemeContext");

var _Emotion = require("../../lib/theming/Emotion");
var _identifiers = require("../../lib/events/keyboard/identifiers");

var _Input = require("../Input");
var _Menu = require("../../internal/Menu");
var _MenuItem = require("../MenuItem");
var _RenderLayer = require("../../internal/RenderLayer");
var _createPropsGetter = require("../../lib/createPropsGetter");

var _fixClickFocusIE = require("../../lib/events/fixClickFocusIE");

var _CommonWrapper = require("../../internal/CommonWrapper");
var _MobilePopup = require("../../internal/MobilePopup");
var _decorator = require("../ResponsiveLayout/decorator");

var _rootNode = require("../../lib/rootNode");
var _getDOMRect = require("../../lib/dom/getDOMRect");

var _Popup = require("../../internal/Popup");
var _getMenuPositions = require("../../lib/getMenuPositions");
var _ZIndex = require("../../internal/ZIndex");
var _MaskedInput = require("../MaskedInput");

var _ReactUIFeatureFlagsContext = require("../../lib/featureFlagsContext/ReactUIFeatureFlagsContext");
var _FeatureFlagsHelpers = require("../../lib/featureFlagsContext/FeatureFlagsHelpers");
var _SizeDecorator = require("../../lib/size/SizeDecorator");

var _Autocomplete2 = require("./Autocomplete.styles");

var _locale = require("./locale");
var _getAutocompleteTheme = require("./getAutocompleteTheme");var _excluded = ["onValueChange", "onKeyDown", "onFocus", "onBlur", "renderItem", "disablePortal", "hasShadow", "menuAlign", "menuMaxHeight", "preventWindowScroll", "source", "menuPos", "width", "mobileMenuHeaderText", "type"];var _dec, _class, _Autocomplete;

function match(pattern, items) {
  if (!pattern || !items) {
    return Promise.resolve([]);
  }

  var lowerCasedPattern = pattern.toLowerCase();
  var itemsMatchingPattern = items.filter(function (item) {
    return item.toLowerCase().includes(lowerCasedPattern);
  });

  return Promise.resolve(itemsMatchingPattern);
}

function renderItem(item) {
  return item;
}



























































var AutocompleteDataTids = exports.AutocompleteDataTids = {
  root: 'Autocomplete__root',
  menu: 'Autocomplete__menu'
};

var AutocompleteIds = exports.AutocompleteIds = {
  menu: AutocompleteDataTids.menu
};





/**
 * Автокомплит — поле ввода с выпадающим списком подсказок. Подсказки отображаются пользователю, когда он начинает вводить значение в поле. */var




Autocomplete = exports.Autocomplete = (_dec = (0, _decorators.locale)('Autocomplete', _locale.AutocompleteLocaleHelper), (0, _decorator.responsiveLayout)(_class = (0, _rootNode.rootNode)(_class = _dec(_class = (0, _SizeDecorator.withSize)(_class = (_Autocomplete = /*#__PURE__*/function (_React$Component) {function Autocomplete() {var _this;for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {args[_key] = arguments[_key];}_this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;_this.











    state = {
      items: null,
      selected: -1,
      focused: false,
      isMobileOpened: false
    };_this.





    opened = false;_this.
    input = null;_this.

    menuId = AutocompleteIds.menu + (0, _utils.getRandomID)();_this.




    requestId = 0;_this.

    getProps = (0, _createPropsGetter.createPropsGetter)(Autocomplete.defaultProps);_this.






















































    renderMain = function (props) {var _cx;
      var focused = _this.state.focused;

      var isMobile = _this.isMobileLayout;

      var
        onValueChange =















        props.onValueChange,onKeyDown = props.onKeyDown,onFocus = props.onFocus,onBlur = props.onBlur,_renderItem = props.renderItem,disablePortal = props.disablePortal,hasShadow = props.hasShadow,menuAlign = props.menuAlign,menuMaxHeight = props.menuMaxHeight,preventWindowScroll = props.preventWindowScroll,source = props.source,menuPos = props.menuPos,_props$width = props.width,width = _props$width === void 0 ? _this.theme.inputWidth : _props$width,mobileMenuHeaderText = props.mobileMenuHeaderText,type = props.type,rest = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded);

      var inputProps = (0, _extends2.default)({},
      rest, {
        width: '100%',
        autoComplete: 'off',
        'aria-controls': _this.menuId,
        onValueChange: _this.handleValueChange,
        onKeyDown: _this.handleKeyDown,
        onFocus: _this.handleFocus,
        ref: _this.refInput });


      return /*#__PURE__*/(
        _react.default.createElement(_RenderLayer.RenderLayer, { onFocusOutside: _this.handleBlur, onClickOutside: _this.handleClickOutside, active: focused }, /*#__PURE__*/
        _react.default.createElement("span", {
          "data-tid": AutocompleteDataTids.root,
          className: (0, _Emotion.cx)(_Autocomplete2.styles.root(_this.theme), (_cx = {}, _cx[
          _Autocomplete2.styles.noPortal()] = disablePortal, _cx)
          ),
          style: { width: width },
          ref: _this.refRootSpan },

        _this.getInput(inputProps),

        isMobile ? _this.renderMobileMenu() : _this.renderMenu()
        )
        ));

    };_this.























































    getInput = function (inputProps) {
      return _this.featureFlags.autocompleteUseMaskedInput && _this.props.mask ? /*#__PURE__*/
      _react.default.createElement(_MaskedInput.MaskedInput, (0, _extends2.default)({},
      inputProps, {
        type: (0, _MaskedInput.getSafeMaskInputType)(_this.props.type),
        mask: _this.props.mask,
        maskChar: _this.props.maskChar })
      ) : /*#__PURE__*/

      _react.default.createElement(_Input.Input, (0, _extends2.default)({}, inputProps, { mask: _this.props.mask, maskChar: _this.props.maskChar }));

    };_this.

    renderMobileMenu = function () {var _this$mobilePopup;
      var inputProps = {
        autoComplete: 'off',
        autoFocus: true,
        width: '100%',
        onValueChange: _this.handleValueChange,
        onKeyPress: _this.handleKeyPressMobile,
        value: _this.props.value,
        placeholder: _this.locale.enterValue,
        type: _this.props.type,
        inputMode: _this.props.inputMode,
        'aria-label': _this.props['aria-label'],
        'aria-controls': _this.menuId
      };

      var items = _this.state.items;

      return /*#__PURE__*/(
        _react.default.createElement(_MobilePopup.MobilePopup, {
          id: _this.menuId,
          headerChildComponent: _this.getInput(inputProps),
          caption: _this.props.mobileMenuHeaderText,
          opened: _this.state.isMobileOpened,
          onCloseRequest: _this.handleCloseMobile,
          ref: _this.refMobilePopup }, /*#__PURE__*/

        _react.default.createElement(_Menu.Menu, { ref: _this.refMenu, onItemClick: (_this$mobilePopup = _this.mobilePopup) == null ? void 0 : _this$mobilePopup.close, disableScrollContainer: true, maxHeight: 'auto' },
        items && items.length > 0 && _this.getItems(),
        _this.renderHints()
        )
        ));

    };_this.

    getItems = function () {
      var items = _this.state.items;
      var isMobile = _this.isMobileLayout;

      return items ?
      items.map(function (item, i) {
        return /*#__PURE__*/(
          _react.default.createElement(_MenuItem.MenuItem, { onClick: _this.handleMenuItemClick(i), key: i, isMobile: isMobile, size: _this.size },
          _this.getProps().renderItem(item)
          ));

      }) :
      null;
    };_this.

    handleValueChange = function (value) {
      _this.opened = true;

      _this.fireChange(value);
    };_this.

    handleCloseMobile = function () {
      _this.setState({
        isMobileOpened: false
      });

      _this.handleBlur();
    };_this.

    handleKeyPressMobile = function (e) {
      if (e.key === 'Enter') {var _this$mobilePopup2;
        (_this$mobilePopup2 = _this.mobilePopup) == null || _this$mobilePopup2.close();
      }
    };_this.

    handleFocus = function (event) {
      if (_this.isMobileLayout) {
        _this.setState({ isMobileOpened: true });
      }

      if (_this.state.focused) {
        return;
      }

      _this.setState({ focused: true });

      if (_this.props.onFocus) {
        _this.props.onFocus(event);
      }
    };_this.

    handleBlur = function () {
      if (!_this.state.focused) {
        return;
      }

      _this.opened = false;
      _this.setState({ items: null, focused: false });

      if (_this.input) {
        _this.input.blur();
      }

      if (_this.props.onBlur) {
        _this.props.onBlur();
      }
    };_this.

    handleClickOutside = function (e) {
      (0, _fixClickFocusIE.fixClickFocusIE)(e);
      _this.handleBlur();
    };_this.

    handleKeyDown = function (e) {
      if (_this.props.onKeyDown) {
        _this.props.onKeyDown(e);
      }
      switch (true) {
        case (0, _identifiers.isKeyEscape)(e):
          e.preventDefault();
          _this.setState({ items: null });
          return;
        case (0, _identifiers.isKeyArrowUp)(e):
          e.preventDefault();
          if (_this.menu) {
            _this.menu.up();
          }
          return;
        case (0, _identifiers.isKeyArrowDown)(e):
          e.preventDefault();
          if (_this.menu) {
            _this.menu.down();
          }
          return;
        case (0, _identifiers.isKeyEnter)(e):
          e.preventDefault(); // To prevent form submission.
          if (_this.menu) {
            _this.menu.enter(e);
          }
          return;
      }
    };_this.





    getAnchor = function () {
      return (0, _rootNode.getRootNode)(_this);
    };_this.


































































    refInput = function (el) {
      _this.input = el;
    };_this.

    refMenu = function (menu) {
      _this.menu = menu;
    };_this.

    refRootSpan = function (span) {
      _this.rootSpan = span;
    };_this.

    refMobilePopup = function (mobilePopup) {
      _this.mobilePopup = mobilePopup;
    };return _this;}(0, _inheritsLoose2.default)(Autocomplete, _React$Component);var _proto = Autocomplete.prototype; /** Программно устанавливает фокус на автокомплит.
   * @public
   * @example
   * <Autocomplete ref={autocompleteRef} />
   * <button onClick={() => autocompleteRef.current?.focus()}>Focus</button>
   */_proto.focus = function focus() {if (this.input) {this.input.focus();}} /** Программно снимает фокус с автокомплита.
   * @public
   * @example
   * <Autocomplete ref={autocompleteRef} />
   * <button onClick={() => autocompleteRef.current?.blur()}>Blur</button>
   */;_proto.blur = function blur() {this.handleBlur();};_proto.componentDidUpdate = function componentDidUpdate(prevProps) {if (prevProps.value !== this.props.value) {this.updateItems(this.props.value || '');}};_proto.render = function render() {var _this2 = this;return /*#__PURE__*/_react.default.createElement(_ReactUIFeatureFlagsContext.ReactUIFeatureFlagsContext.Consumer, null, function (flags) {_this2.featureFlags = (0, _FeatureFlagsHelpers.getFullReactUIFlagsContext)(flags);return /*#__PURE__*/_react.default.createElement(_ThemeContext.ThemeContext.Consumer, null, function (theme) {_this2.theme = (0, _getAutocompleteTheme.getAutocompleteTheme)(theme);return /*#__PURE__*/_react.default.createElement(_ThemeContext.ThemeContext.Provider, { value: _this2.theme }, /*#__PURE__*/_react.default.createElement(_CommonWrapper.CommonWrapper, (0, _extends2.default)({ rootNodeRef: _this2.setRootNode }, _this2.getProps()), _this2.renderMain));});});};_proto.renderHints = function renderHints() {var items = this.state.items;if (!this.props.value) {return /*#__PURE__*/_react.default.createElement(_MenuMessage.MenuMessage, null, this.locale.enterValue);}if ((items == null ? void 0 : items.length) === 0 && this.props.value) {return /*#__PURE__*/_react.default.createElement(_MenuMessage.MenuMessage, null, this.locale.notFound);}if ((0, _utils.isNullable)(items) && this.props.value) {return /*#__PURE__*/_react.default.createElement(_MenuMessage.MenuMessage, null, this.locale.updateValue);}return null;};_proto.renderMenu = function renderMenu() {var items = this.state.items;var _this$getProps = this.getProps(),menuPos = _this$getProps.menuPos,menuAlign = _this$getProps.menuAlign,menuMaxHeight = _this$getProps.menuMaxHeight,hasShadow = _this$getProps.hasShadow,menuWidth = _this$getProps.menuWidth,width = _this$getProps.width,preventWindowScroll = _this$getProps.preventWindowScroll,disablePortal = _this$getProps.disablePortal;var calculatedMenuWidth = menuWidth ? '100%' : width && (0, _getDOMRect.getDOMRect)(this.rootSpan).width;var menuProps = { ref: this.refMenu, maxHeight: menuMaxHeight, hasShadow: false, hasMargin: false, width: calculatedMenuWidth, preventWindowScroll: preventWindowScroll };if (!items || items.length === 0) {return null;}return /*#__PURE__*/_react.default.createElement(_Popup.Popup, { opened: true, hasShadow: hasShadow, id: this.menuId, priority: _ZIndex.ZIndex.priorities.PopupMenu, "data-tid": AutocompleteDataTids.menu, anchorElement: this.getAnchor(), disablePortal: disablePortal, width: menuWidth, minWidth: menuWidth === undefined ? '100%' : undefined, positions: (0, _getMenuPositions.getMenuPositions)(menuPos, menuAlign), margin: parseInt(this.theme.menuOffsetY) - 1 }, /*#__PURE__*/_react.default.createElement(_Menu.Menu, menuProps, this.getItems()));};_proto.handleMenuItemClick = function handleMenuItemClick(i) {var _this3 = this;return function (event) {return _this3.handleItemClick(event, i);};};_proto.handleItemClick = function handleItemClick(event, index) {if (event.button) {return;}event.preventDefault();this.choose(index);};_proto.choose = function choose(index) {var _this4 = this;if (!this.state.items) {return;}var value = this.state.items[index];this.opened = false;this.setState({ selected: -1, items: null });this.fireChange(value); // NOTE: этот таймаут - костыль. Проблема в старом ReactInputMask, он сеттит пустой value при потере фокуса.
    // Можно будет убрать после полного перехода на MaskedInput
    _globalObject.globalObject.setTimeout(function () {_this4.blur();}, 0);};_proto.updateItems = function updateItems(value) {var _this5 = this;if (!this.opened) {return;}var pattern = value.trim();var source = this.props.source;if (!source) {return;}var promise;this.requestId += 1;var expectingId = this.requestId;if (typeof source === 'function') {promise = source(pattern);} else {promise = match(pattern, source);}promise.then(function (items) {if (_this5.opened && expectingId === _this5.requestId) {_this5.setState({ items: items, selected: -1 });}});};_proto.fireChange = function fireChange(value) {if (this.props.onValueChange) {this.props.onValueChange(value);}};return Autocomplete;}(_react.default.Component), _Autocomplete.__KONTUR_REACT_UI__ = 'Autocomplete', _Autocomplete.displayName = 'Autocomplete', _Autocomplete.defaultProps = { renderItem: renderItem, disablePortal: false, hasShadow: true, menuMaxHeight: 300, preventWindowScroll: true }, _Autocomplete)) || _class) || _class) || _class) || _class);