"use strict";var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;exports.__esModule = true;exports.selectionErrorMessage = exports.selectionAllowedTypes = exports.maskForbiddenTypes = exports.maskErrorMessage = exports.maskAllowedTypes = exports.inputTypes = exports.calculateClearCrossShowedState = exports.InputDataTids = exports.Input = void 0;var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose"));
var _invariant = _interopRequireDefault(require("invariant"));

var _react = _interopRequireWildcard(require("react"));
var _warning = _interopRequireDefault(require("warning"));
var _globalObject = require("@skbkontur/global-object");

var _client = require("../../lib/client");
var _identifiers = require("../../lib/events/keyboard/identifiers");
var _needsPolyfillPlaceholder = require("../../lib/needsPolyfillPlaceholder");

var _InternalMaskedInput = require("../../internal/InternalMaskedInput");
var _ThemeContext = require("../../lib/theming/ThemeContext");


var _CommonWrapper = require("../../internal/CommonWrapper");
var _Emotion = require("../../lib/theming/Emotion");

var _rootNode = require("../../lib/rootNode");
var _createPropsGetter = require("../../lib/createPropsGetter");

var _FocusControlWrapper = require("../../internal/FocusControlWrapper");
var _ClearCrossIcon = require("../../internal/ClearCrossIcon/ClearCrossIcon");
var _typeGuards = require("../../lib/typeGuards");
var _blink2 = require("../../lib/blink");
var _SizeDecorator = require("../../lib/size/SizeDecorator");


var _Input2 = require("./Input.styles");
var _InputLayout = require("./InputLayout/InputLayout");
var _PolyfillPlaceholder = require("./InputLayout/PolyfillPlaceholder");var _excluded = ["onMouseEnter", "onMouseLeave", "onMouseOver", "onKeyDown", "onKeyPress", "onValueChange", "width", "error", "role", "warning", "leftIcon", "rightIcon", "borderless", "value", "align", "type", "mask", "maskChar", "alwaysShowMask", "size", "placeholder", "selectAllOnFocus", "disabled", "onUnexpectedInput", "prefix", "suffix", "formatChars", "corners", "aria-describedby", "aria-controls", "aria-label", "element", "showClearIcon"];var _class, _Input; // TODO: Enable this rule in functional components.

var inputTypes = exports.inputTypes = ['password', 'text', 'number', 'tel', 'search', 'time', 'date', 'url', 'email'];






var selectionAllowedTypes = exports.selectionAllowedTypes = ['text', 'password', 'tel', 'search', 'url'];
var selectionErrorMessage = exports.selectionErrorMessage = function selectionErrorMessage(type, allowedTypes) {if (allowedTypes === void 0) {allowedTypes = selectionAllowedTypes;}
  return "<Input />. Selection is not supported by the type \"" + type + "\". Types that support selection: " + allowedTypes.
  map(function (i) {return "\"" + i + "\"";}).
  join(', ') + ". Reason: https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange.";
};

var maskForbiddenTypes = exports.maskForbiddenTypes = ['number', 'date', 'time'];
var maskAllowedTypes = exports.maskAllowedTypes = inputTypes.filter(function (type) {
  return !maskForbiddenTypes.includes(type);
});
var maskErrorMessage = exports.maskErrorMessage = function maskErrorMessage(type, allowedTypes) {if (allowedTypes === void 0) {allowedTypes = maskAllowedTypes;}
  return "<Input />. Prop \"mask\" does not support type \"" + type + "\". Supported types: " + allowedTypes.
  map(function (i) {return "\"" + i + "\"";}).
  join(', ') + ".";
};
var calculateClearCrossShowedState = exports.calculateClearCrossShowedState = function calculateClearCrossShowedState(_ref)









{var showClearIcon = _ref.showClearIcon,notEmptyValue = _ref.notEmptyValue,focused = _ref.focused,hovered = _ref.hovered;
  switch (showClearIcon) {
    case 'always':
      return notEmptyValue;
    case 'auto':
      return Boolean((focused || hovered) && notEmptyValue);
    case 'never':
      return false;
    default:
      return (0, _typeGuards.catchUnreachableWarning)(showClearIcon, false);
  }
};
















































































































var InputDataTids = exports.InputDataTids = {
  root: 'Input__root',
  clearCross: 'Input__clearCross'
};



/**
 * Поле ввода позволяет ввести или отредактировать значение.
 */var


Input = exports.Input = (0, _rootNode.rootNode)(_class = (0, _SizeDecorator.withSize)(_class = (_Input = /*#__PURE__*/function (_React$Component) {function Input() {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.









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

    selectAllId = null;_this.

    input = null;_this.
    labelRef = /*#__PURE__*/(0, _react.createRef)();_this.



    getClearCrossShowed = function (_ref2)







    {var _this$input;var focused = _ref2.focused,hovered = _ref2.hovered,hasInitialValue = _ref2.hasInitialValue;
      if (_this.props.disabled) {
        return false;
      }
      return calculateClearCrossShowedState({
        showClearIcon: _this.getProps().showClearIcon,
        notEmptyValue: Boolean(((_this$input = _this.input) == null ? void 0 : _this$input.value) || hasInitialValue),
        focused: focused,
        hovered: hovered
      });
    };_this.

    state = {
      needsPolyfillPlaceholder: _needsPolyfillPlaceholder.needsPolyfillPlaceholder,
      focused: false,
      hovered: false,
      clearCrossShowed: _this.getClearCrossShowed({
        focused: false,
        hasInitialValue: Boolean(_this.props.value || _this.props.defaultValue)
      })
    };










































































































    /**
     * Переводит фокус в поле (если ещё не в фокусе) и выделяет весь текст в нём.
     * Работает с типами `text`, `password`, `tel`, `search`, `url`.
     * @public
     */_this.
    selectAll = function () {return _this._selectAll();};_this.

    delaySelectAll = function () {var _globalObject$request;
      return _this.selectAllId = (_globalObject$request = _globalObject.globalObject.requestAnimationFrame == null ? void 0 : _globalObject.globalObject.requestAnimationFrame(_this._selectAll)) != null ? _globalObject$request : null;
    };_this.

    _selectAll = function () {
      if (_this.input) {
        _this.setSelectionRange(0, _this.input.value.length);
      }
    };_this.

    cancelDelayedSelectAll = function () {
      if (_this.selectAllId) {
        _globalObject.globalObject.cancelAnimationFrame == null || _globalObject.globalObject.cancelAnimationFrame(_this.selectAllId);
        _this.selectAllId = null;
      }
    };_this.

    getInput = function (inputProps) {
      if (_this.props.element) {
        return /*#__PURE__*/_react.default.cloneElement(_this.props.element, inputProps);
      }

      return _this.props.mask && !_this.canBeUsedWithMask ?
      _this.renderMaskedInput(inputProps, _this.props.mask) : /*#__PURE__*/
      _react.default.createElement('input', inputProps);
    };_this.

    renderMain = function (props) {var _cx, _cx2;
      var
        onMouseEnter =

































        props.onMouseEnter,onMouseLeave = props.onMouseLeave,onMouseOver = props.onMouseOver,onKeyDown = props.onKeyDown,onKeyPress = props.onKeyPress,onValueChange = props.onValueChange,width = props.width,error = props.error,role = props.role,warning = props.warning,leftIcon = props.leftIcon,rightIcon = props.rightIcon,borderless = props.borderless,value = props.value,align = props.align,type = props.type,mask = props.mask,maskChar = props.maskChar,alwaysShowMask = props.alwaysShowMask,size = props.size,placeholder = props.placeholder,selectAllOnFocus = props.selectAllOnFocus,disabled = props.disabled,onUnexpectedInput = props.onUnexpectedInput,prefix = props.prefix,suffix = props.suffix,formatChars = props.formatChars,corners = props.corners,ariaDescribedby = props['aria-describedby'],ariaControls = props['aria-controls'],ariaLabel = props['aria-label'],element = props.element,showClearIcon = props.showClearIcon,rest = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded);

      var focused = _this.state.focused;

      var labelProps = {
        className: (0, _Emotion.cx)(_Input2.styles.root(_this.theme), _this.getSizeClassName(), (_cx = {}, _cx[
        _Input2.styles.focus(_this.theme)] = focused && !warning && !error, _cx[
        _Input2.styles.hovering(_this.theme)] = !focused && !disabled && !warning && !error && !borderless, _cx[
        _Input2.styles.borderless()] = borderless && !focused, _cx[
        _Input2.styles.disabled(_this.theme)] = disabled, _cx[
        _Input2.styles.warning(_this.theme)] = warning, _cx[
        _Input2.styles.error(_this.theme)] = error, _cx[
        _Input2.styles.focusFallback(_this.theme)] = focused && (_client.isIE11 || _client.isEdge), _cx[
        _Input2.styles.warningFallback(_this.theme)] = warning && (_client.isIE11 || _client.isEdge), _cx[
        _Input2.styles.errorFallback(_this.theme)] = error && (_client.isIE11 || _client.isEdge), _cx)
        ),
        'aria-controls': ariaControls,
        style: (0, _extends2.default)({ width: width }, corners),
        onMouseEnter: _this.handleMouseEnter,
        onMouseLeave: _this.handleMouseLeave,
        onMouseOver: onMouseOver,
        ref: _this.labelRef
      };

      var inputProps = (0, _extends2.default)({},
      rest, {
        className: (0, _Emotion.cx)(_Input2.styles.input(_this.theme), (_cx2 = {}, _cx2[
        _Input2.styles.inputFocus(_this.theme)] = focused, _cx2[
        _Input2.styles.inputDisabled(_this.theme)] = disabled, _cx2)
        ),
        value: value,
        role: role,
        onChange: _this.handleChange,
        onFocus: _this.handleFocus,
        onKeyDown: _this.handleKeyDown,
        onKeyPress: _this.handleKeyPress,
        onBlur: _this.handleBlur,
        style: { textAlign: align },
        ref: _this.refInput,
        type: type,
        placeholder: !_this.isMaskVisible && !_needsPolyfillPlaceholder.needsPolyfillPlaceholder ? placeholder : undefined,
        disabled: disabled,
        'aria-describedby': ariaDescribedby,
        'aria-label': ariaLabel });


      var input = /*#__PURE__*/
      _react.default.createElement(_FocusControlWrapper.FocusControlWrapper, { onBlurWhenDisabled: _this.resetFocus }, _this.getInput(inputProps));


      var getRightIcon = function getRightIcon() {
        return _this.state.clearCrossShowed ? /*#__PURE__*/
        _react.default.createElement(_ClearCrossIcon.ClearCrossIcon, { "data-tid": InputDataTids.clearCross, size: _this.size, onClick: _this.handleClearInput }) :

        rightIcon;

      };
      return /*#__PURE__*/(
        _react.default.createElement(_InputLayout.InputLayout, {
          leftIcon: leftIcon,
          rightIcon: getRightIcon(),
          prefix: prefix,
          suffix: suffix,
          labelProps: labelProps,
          context: { disabled: Boolean(disabled), focused: focused, size: _this.size } },

        input,
        _this.state.needsPolyfillPlaceholder && /*#__PURE__*/
        _react.default.createElement(_PolyfillPlaceholder.PolyfillPlaceholder, {
          isMaskVisible: _this.isMaskVisible,
          value: value,
          defaultValue: _this.props.defaultValue,
          align: align },

        placeholder
        )

        ));

    };_this.





































    refInput = function (element) {
      if (element instanceof _InternalMaskedInput.InternalMaskedInput || element && 'input' in element) {
        _this.input = element.input;
      } else {
        _this.input = element;
      }
    };_this.

    handleClearInput = function () {
      if (_this.input) {
        _this.input.value = '';
      }

      _this.setState({ clearCrossShowed: false });

      if (_this.props.onValueChange) {
        _this.props.onValueChange('');
      }
    };_this.

    handleChange = function (event) {
      if (_needsPolyfillPlaceholder.needsPolyfillPlaceholder) {
        var fieldIsEmpty = event.target.value === '';
        if (_this.state.needsPolyfillPlaceholder !== fieldIsEmpty) {
          _this.setState({ needsPolyfillPlaceholder: fieldIsEmpty });
        }
      }

      if (_this.props.onValueChange) {
        _this.props.onValueChange(event.target.value);
      }

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

      _this.setState({
        clearCrossShowed: _this.getClearCrossShowed({ focused: _this.state.focused, hovered: _this.state.hovered })
      });
    };_this.

    handleMouseEnter = function (e) {
      _this.setState({
        hovered: true,
        clearCrossShowed: _this.getClearCrossShowed({ focused: _this.state.focused, hovered: true })
      });
      if (_this.props.onMouseEnter) {
        _this.props.onMouseEnter(e);
      }
    };_this.
    handleMouseLeave = function (e) {
      _this.setState({
        hovered: false,
        clearCrossShowed: _this.getClearCrossShowed({ focused: _this.state.focused, hovered: false })
      });
      if (_this.props.onMouseLeave) {
        _this.props.onMouseLeave(e);
      }
    };_this.

    handleFocus = function (event) {
      _this.setState({
        focused: true,
        clearCrossShowed: _this.getClearCrossShowed({ focused: true, hovered: _this.state.hovered })
      });

      if (_this.props.selectAllOnFocus) {
        _this.input && !_client.isIE11 ? _this.selectAll() : _this.delaySelectAll();
      }

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

    handleKeyDown = function (e) {
      if (_this.props.onKeyDown) {
        _this.props.onKeyDown(e);
      }

      var isDeleteKey = (0, _identifiers.someKeys)(_identifiers.isKeyBackspace, _identifiers.isKeyDelete)(e);

      if (!e.currentTarget.value && isDeleteKey && !e.repeat) {
        _this.handleUnexpectedInput();
      }
    };_this.

    handleKeyPress = function (event) {
      if (_this.props.onKeyPress) {
        _this.props.onKeyPress(event);
      }

      if (_this.props.maxLength === event.currentTarget.value.length) {
        _this.handleUnexpectedInput(event.currentTarget.value);
      }
    };_this.

    handleMaskedValueChange = function (value) {
      if (_this.props.onValueChange) {
        _this.props.onValueChange(value);
      }
    };_this.

    handleUnexpectedInput = function (value) {if (value === void 0) {value = _this.props.value || '';}
      if (_this.props.onUnexpectedInput) {
        _this.props.onUnexpectedInput(value);
      } else {
        _this.blink();
      }
    };_this.

    resetFocus = function () {return _this.setState({ focused: false });};_this.

    handleBlur = function (event) {var _getRootNode;
      var showClearIcon = _this.props.showClearIcon;
      if (showClearIcon && (_getRootNode = (0, _rootNode.getRootNode)(_this)) != null && _getRootNode.contains(event.relatedTarget)) {
        _this.setState({ focused: false });
      } else {
        var clearCrossShowed = _this.getClearCrossShowed({ focused: false, hovered: _this.state.hovered });
        _this.setState({
          focused: false,
          clearCrossShowed: clearCrossShowed
        });
        _this.props.onBlur == null || _this.props.onBlur(event);
      }
    };return _this;}(0, _inheritsLoose2.default)(Input, _React$Component);var _proto = Input.prototype;_proto.outputMaskError = function outputMaskError() {(0, _warning.default)(!(this.props.mask && this.canBeUsedWithMask), maskErrorMessage(this.getProps().type));};_proto.componentDidMount = function componentDidMount() {this.outputMaskError();};_proto.componentDidUpdate = function componentDidUpdate(prevProps) {if (this.props.type !== prevProps.type || this.props.mask !== prevProps.mask) {this.outputMaskError();}};_proto.componentWillUnmount = function componentWillUnmount() {this.cancelDelayedSelectAll();} /** Программно устанавливает фокус на поле.
   * Появляется фокусная рамка, элемент получает клавиатурные события и воспринимается как текущий элемент для чтения скринридерами.
   * @public
   */;_proto.focus = function focus() {(0, _invariant.default)(this.input, 'Cannot call "focus" because Input is not mounted');this.input.focus();} /** Программно снимает фокус с поля.
   * @public
   */;_proto.blur = function blur() {(0, _invariant.default)(this.input, 'Cannot call "blur" because Input is not mounted');this.input.blur();} /** Возвращает DOM-узел поля ввода.
   * @public
   */;_proto.getNode = function getNode() {return this.input;} /** Кратковременно визуально подсвечивает поле ввода, чтобы привлечь внимание пользователя.
   * @public
   */;_proto.blink = function blink() {(0, _blink2.blink)({ el: this.labelRef.current, blinkColor: this.theme.inputBlinkColor });} /** start - инициирует последовательное изменение числового значения: начинает повторяющееся увеличение/уменьшение, обычно используется при удерживании кнопки «+» или «−» для числового Input. end - останавливает ранее запущенное числоизменение, инициируемое numberStart.
   * [Документация](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange)
   * @public
   * @param {number} start
   * @param {number} end
   */;_proto.setSelectionRange = function setSelectionRange(start, end) {var _globalObject$documen,_this$props$value,_this2 = this; // https://github.com/facebook/react/issues/7769
    // https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange
    if (!selectionAllowedTypes.includes(this.getProps().type)) {(0, _warning.default)(false, selectionErrorMessage(this.getProps().type));return;}if (!this.input) {throw new Error('Cannot call "setSelectionRange" on unmounted Input');}if (((_globalObject$documen = _globalObject.globalObject.document) == null ? void 0 : _globalObject$documen.activeElement) !== this.input) {this.focus();}if (this.props.mask && this.props.value && ((_this$props$value = this.props.value) == null ? void 0 : _this$props$value.length) < this.props.mask.length) {_globalObject.globalObject.setTimeout(function () {var _this2$input;(_this2$input = _this2.input) == null || _this2$input.setSelectionRange(start, end);}, 150);} else {var _this$input2;(_this$input2 = this.input) == null || _this$input2.setSelectionRange(start, end);}};_proto.render = function render() {var _this3 = this;return /*#__PURE__*/_react.default.createElement(_ThemeContext.ThemeContext.Consumer, null, function (theme) {_this3.theme = theme;return /*#__PURE__*/_react.default.createElement(_CommonWrapper.CommonWrapper, (0, _extends2.default)({ rootNodeRef: _this3.setRootNode }, _this3.getProps()), _this3.renderMain);});};_proto.renderMaskedInput = function renderMaskedInput(inputProps, mask) {return /*#__PURE__*/_react.default.createElement(_InternalMaskedInput.InternalMaskedInput, (0, _extends2.default)({}, inputProps, { mask: mask, maskChar: this.props.maskChar, alwaysShowMask: this.props.alwaysShowMask, formatChars: this.props.formatChars, onChange: this.props.onChange, onValueChange: this.handleMaskedValueChange, onUnexpectedInput: this.handleUnexpectedInput }));};_proto.getSizeClassName = function getSizeClassName() {var _cx3, _cx4, _cx5;switch (this.size) {case 'large':return (0, _Emotion.cx)((_cx3 = {}, _cx3[_Input2.styles.sizeLarge(this.theme)] = true, _cx3[_Input2.styles.sizeLargeFallback(this.theme)] = _client.isIE11 || _client.isEdge, _cx3));case 'medium':return (0, _Emotion.cx)((_cx4 = {}, _cx4[_Input2.styles.sizeMedium(this.theme)] = true, _cx4[_Input2.styles.sizeMediumFallback(this.theme)] = _client.isIE11 || _client.isEdge, _cx4));case 'small':default:return (0, _Emotion.cx)((_cx5 = {}, _cx5[_Input2.styles.sizeSmall(this.theme)] = true, _cx5[_Input2.styles.sizeSmallFallback(this.theme)] = _client.isIE11 || _client.isEdge, _cx5));}};return (0, _createClass2.default)(Input, [{ key: "isMaskVisible", get: function get() {var _this$props = this.props,mask = _this$props.mask,alwaysShowMask = _this$props.alwaysShowMask;var focused = this.state.focused;return Boolean(mask && (focused || alwaysShowMask));} }, { key: "canBeUsedWithMask", get: function get() {return maskForbiddenTypes.includes(this.getProps().type);} }]);}(_react.default.Component), _Input.__KONTUR_REACT_UI__ = 'Input', _Input.displayName = 'Input', _Input.defaultProps = { type: 'text', showClearIcon: 'never' }, _Input)) || _class) || _class;