@codementor/ui-kit
Version: 
407 lines (341 loc) • 14.1 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.SEARCH_CATEGORY_DEBOUNCE_TIME = undefined;
var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
var _style = require('styled-jsx/style');
var _style2 = _interopRequireDefault(_style);
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _reactTagsinput = require('react-tagsinput');
var _reactTagsinput2 = _interopRequireDefault(_reactTagsinput);
var _reactAutosuggest = require('react-autosuggest');
var _reactAutosuggest2 = _interopRequireDefault(_reactAutosuggest);
var _classnames = require('classnames');
var _classnames2 = _interopRequireDefault(_classnames);
var _colors = require('./theme/colors');
var _debounce = require('lodash/debounce');
var _debounce2 = _interopRequireDefault(_debounce);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var SEARCH_CATEGORY_DEBOUNCE_TIME = exports.SEARCH_CATEGORY_DEBOUNCE_TIME = 40;
var TagsInput = function (_PureComponent) {
  (0, _inherits3.default)(TagsInput, _PureComponent);
  function TagsInput(props) {
    (0, _classCallCheck3.default)(this, TagsInput);
    var _this = (0, _possibleConstructorReturn3.default)(this, (TagsInput.__proto__ || (0, _getPrototypeOf2.default)(TagsInput)).call(this, props));
    var defaultValue = props.defaultValue,
        maxLength = props.maxLength,
        minLength = props.minLength,
        value = props.value;
    _this._onTagsUpdate = _this._onTagsUpdate.bind(_this);
    _this._updateSuggestions = _this._updateSuggestions.bind(_this);
    _this._clearSuggestions = _this._clearSuggestions.bind(_this);
    _this._renderAutoCompleteInput = _this._renderAutoCompleteInput.bind(_this);
    _this._handleInputChange = _this._handleInputChange.bind(_this);
    _this._controlled = Array.isArray(value);
    _this._hasDefaultProvided = defaultValue && defaultValue.length > 0;
    if (_this._controlled && _this._hasDefaultProvided) {
      throw new Error('TagsInput: should be provided either `value` or `defaultValue`, not both.\nhttps://reactjs.org/docs/forms.html#controlled-components');
    }
    var tags = _this._controlled ? value : props.defaultValue;
    var underMinLength = tags.length < minLength;
    var overMaxLength = tags.length > maxLength;
    _this.state = {
      tags: tags,
      inputValue: '',
      reachMaxLength: tags.length >= maxLength,
      validationFailed: underMinLength || overMaxLength
    };
    return _this;
  }
  (0, _createClass3.default)(TagsInput, [{
    key: 'componentDidMount',
    value: function componentDidMount() {
      var getSuggestions = this.props.getSuggestions;
      if (getSuggestions) {
        this._enableDebounceSearch();
      }
    }
  }, {
    key: 'render',
    value: function render() {
      var _props = this.props,
          name = _props.name,
          maxLength = _props.maxLength,
          addOnBlur = _props.addOnBlur,
          className = _props.className,
          value = _props.value,
          suggestions = _props.suggestions,
          renderTag = _props.renderTag,
          renderLayout = _props.renderLayout;
      var _state = this.state,
          tags = _state.tags,
          inputValue = _state.inputValue,
          validationFailed = _state.validationFailed;
      var tagsInputProps = {
        name: name,
        value: this._controlled ? value : tags,
        inputValue: inputValue,
        /* [enter, comma] */
        addKeys: [13, 188],
        maxTags: maxLength,
        onlyUnique: true,
        onChange: this._onTagsUpdate,
        addOnBlur: addOnBlur
      };
      if (suggestions) {
        tagsInputProps.renderInput = this._renderAutoCompleteInput;
      }
      if (renderTag) {
        tagsInputProps.renderTag = renderTag;
      }
      if (renderLayout) {
        tagsInputProps.renderLayout = renderLayout;
      }
      var classname = (0, _classnames2.default)('tags-input', className, {
        'tags-input--error': validationFailed
      });
      return _react2.default.createElement(
        'div',
        {
          className: _style2.default.dynamic([['384816995', [_colors.red]]]) + ' ' + (classname || '')
        },
        validationFailed && _react2.default.createElement(
          'small',
          {
            className: _style2.default.dynamic([['384816995', [_colors.red]]]) + ' ' + 'tags-input__error-message'
          },
          this._getErrorMessage()
        ),
        _react2.default.createElement(_reactTagsinput2.default, tagsInputProps),
        _react2.default.createElement(_style2.default, {
          styleId: '384816995',
          css: '.tags-input__error-message.__jsx-style-dynamic-selector{color:' + _colors.red + ';margin-bottom:5px;display:inline-block;}',
          dynamic: [_colors.red]
        })
      );
    }
  }, {
    key: '_getErrorMessage',
    value: function _getErrorMessage() {
      var _props2 = this.props,
          maxLength = _props2.maxLength,
          minLength = _props2.minLength;
      return 'Please add ' + minLength + '~' + maxLength + ' tags';
    }
  }, {
    key: '_renderAutoCompleteInput',
    value: function _renderAutoCompleteInput(props) {
      var _this2 = this;
      var name = props.name,
          addTag = props.addTag,
          _onKeyDown = props.onKeyDown,
          onFocus = props.onFocus,
          _onBlur = props.onBlur,
          ref = props.ref;
      var _state2 = this.state,
          reachMaxLength = _state2.reachMaxLength,
          inputValue = _state2.inputValue;
      var _props3 = this.props,
          placeholder = _props3.placeholder,
          autoFocus = _props3.autoFocus,
          suggestions = _props3.suggestions,
          addOnBlur = _props3.addOnBlur,
          onlyAllowSuggestions = _props3.onlyAllowSuggestions;
      var value = inputValue;
      var inputProps = {
        ref: ref,
        name: name,
        onFocus: onFocus,
        onKeyDown: function onKeyDown(e) {
          var keyCode = e.keyCode;
          // make backspace work properly
          if (_this2._isTryingToDeleteTag({ keyCode: keyCode, value: value })) {
            _onKeyDown(e); // handled by ReactTagsInput
          }
          // make comma & enter work properly
          if (_this2._isTryingToAddTag({ keyCode: keyCode }) && !onlyAllowSuggestions) {
            e.preventDefault();
            addTag(value);
            _this2._resetInput();
          }
        },
        onBlur: function onBlur() {
          if (addOnBlur) {
            addTag(value);
            _this2._resetInput();
          }
          _onBlur();
        },
        placeholder: placeholder,
        autoFocus: autoFocus,
        value: value,
        onChange: this._handleInputChange,
        className: reachMaxLength ? 'react-tagsinput-input--hidden' : 'react-tagsinput-input'
      };
      return _react2.default.createElement(
        'span',
        {
          className: 'jsx-1713218217' + ' ' + 'input-wrapper'
        },
        _react2.default.createElement(_reactAutosuggest2.default, {
          suggestions: suggestions,
          getSuggestionValue: function getSuggestionValue(s) {
            return s;
          },
          inputProps: inputProps,
          highlightFirstSuggestion: onlyAllowSuggestions,
          onSuggestionsClearRequested: this._clearSuggestions,
          onSuggestionsFetchRequested: this._updateSuggestions,
          onSuggestionSelected: function onSuggestionSelected(e, _ref) {
            var suggestion = _ref.suggestion;
            addTag(suggestion);
            _this2._resetInput();
          },
          renderSuggestion: function renderSuggestion(suggestion) {
            return _react2.default.createElement(
              'span',
              {
                className: 'jsx-1713218217'
              },
              suggestion
            );
          } }),
        _react2.default.createElement(_style2.default, {
          styleId: '3446248845',
          css: '.input-wrapper.jsx-1713218217{-webkit-flex:1;-ms-flex:1;flex:1;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.input-wrapper.jsx-1713218217 input{padding:0;border:none;color:#333;line-height:24px;font-size:14px;-webkit-transition:all .4s ease-out;transition:all .4s ease-out;outline:none;min-width:120px;max-width:100%;width:100%;background:none;}'
        }),
        _react2.default.createElement(_style2.default, {
          styleId: '3648829805',
          css: '.tags-input .react-tagsinput{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;position:relative;border-bottom:solid 1px rgba(0,0,0,0.42);}.tags-input .react-tagsinput>span{-webkit-flex:1;-ms-flex:1;flex:1;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;}.react-tagsinput-tag{background:#f2f2f2;display:inline-block;padding:5px 12px;margin:0 8px 6px 0;border-radius:3px;color:#666;font-size:.9em;}.react-tagsinput-tag i{margin-left:8px;cursor:pointer;}.react-tagsinput-remove:after{content:\'X\';font-size:85%;color:#888;cursor:pointer;margin-left:6px;}.react-tagsinput-input--hidden{display:none;}.react-autosuggest__suggestions-container{position:absolute;z-index:2;list-style-type:none;box-shadow:0.05em 0.01em 0.5em rgba(0,0,0,0.2);background:#fff;margin-top:4px;width:100%;}.react-autosuggest__container{display:inline-block;position:relative;padding-bottom:6px;width:100%;}.react-autosuggest__container ul{padding:0;list-style:none;margin:0;}.react-autosuggest__suggestion{border-bottom:1px solid #ececec;padding:8px 10px;margin:0;color:#666;}.react-autosuggest__suggestion--highlighted{background:#ddf1ff;cursor:pointer;}'
        })
      );
    }
  }, {
    key: '_isTryingToDeleteTag',
    value: function _isTryingToDeleteTag(_ref2) {
      var keyCode = _ref2.keyCode,
          value = _ref2.value;
      return keyCode === 8 && !value;
    }
  }, {
    key: '_isTryingToAddTag',
    value: function _isTryingToAddTag(_ref3) {
      var keyCode = _ref3.keyCode;
      return keyCode === 13 || // enter
      keyCode === 188 // comma
      ;
    }
  }, {
    key: '_handleInputChange',
    value: function _handleInputChange(e, _ref4) {
      var newValue = _ref4.newValue;
      this.setState({
        inputValue: newValue
      });
    }
  }, {
    key: '_resetInput',
    value: function _resetInput() {
      this.setState({
        inputValue: ''
      });
    }
  }, {
    key: '_updateSuggestions',
    value: function _updateSuggestions(_ref5) {
      var value = _ref5.value;
      var inputValue = this.state.inputValue;
      var getSuggestions = this.props.getSuggestions;
      if (inputValue !== value && value && getSuggestions) {
        this._getSuggestion(value);
      }
    }
  }, {
    key: '_clearSuggestions',
    value: function _clearSuggestions() {
      var clearSuggestions = this.props.clearSuggestions;
      if (clearSuggestions) {
        clearSuggestions();
      }
    }
  }, {
    key: '_getSuggestion',
    value: function _getSuggestion() {}
  }, {
    key: '_enableDebounceSearch',
    value: function _enableDebounceSearch() {
      var getSuggestions = this.props.getSuggestions;
      this._getSuggestion = (0, _debounce2.default)(getSuggestions, SEARCH_CATEGORY_DEBOUNCE_TIME);
    }
  }, {
    key: '_onTagsUpdate',
    value: function _onTagsUpdate(tags) {
      this._validate(tags);
      this._syncState(tags);
    }
  }, {
    key: '_validate',
    value: function _validate(tags) {
      var _props4 = this.props,
          maxLength = _props4.maxLength,
          minLength = _props4.minLength;
      var underMinLength = tags.length < minLength;
      var overMaxLength = tags.length > maxLength;
      var reachMaxLength = tags.length >= maxLength;
      this.setState({
        reachMaxLength: reachMaxLength,
        validationFailed: overMaxLength || underMinLength
      });
    }
  }, {
    key: '_syncState',
    value: function _syncState(tags) {
      this.setState({ tags: tags });
      this.props.onChange({
        value: tags
      });
    }
  }]);
  return TagsInput;
}(_react.PureComponent);
TagsInput.propTypes = {
  onChange: _propTypes2.default.func.isRequired,
  onlyAllowSuggestions: _propTypes2.default.bool,
  maxLength: _propTypes2.default.number,
  name: _propTypes2.default.string,
  className: _propTypes2.default.string,
  suggestions: _propTypes2.default.arrayOf(_propTypes2.default.string.isRequired),
  value: _propTypes2.default.arrayOf(_propTypes2.default.string.isRequired),
  defaultValue: _propTypes2.default.arrayOf(_propTypes2.default.string.isRequired),
  placeholder: _propTypes2.default.string,
  getSuggestions: _propTypes2.default.func,
  clearSuggestions: _propTypes2.default.func,
  autoFocus: _propTypes2.default.bool,
  addOnBlur: _propTypes2.default.bool,
  renderTag: _propTypes2.default.func,
  renderLayout: _propTypes2.default.func
};
TagsInput.defaultProps = {
  placeholder: 'Add a tag',
  defaultValue: [],
  name: 'tags',
  maxLength: 6,
  minLength: 0,
  autoFocus: false,
  addOnBlur: false,
  onlyAllowSuggestions: false
};
exports.default = TagsInput;