UNPKG

react-tag-box

Version:

A tagging component in React. Select, create, and delete tags.

266 lines (221 loc) 8.35 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _classnames = require('classnames'); var _classnames2 = _interopRequireDefault(_classnames); var _utils = require('./utils'); var _utils2 = _interopRequireDefault(_utils); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var _class = function (_Component) { _inherits(_class, _Component); function _class() { _classCallCheck(this, _class); return _possibleConstructorReturn(this, (_class.__proto__ || Object.getPrototypeOf(_class)).apply(this, arguments)); } _createClass(_class, [{ key: 'componentWillReceiveProps', value: function componentWillReceiveProps(nextProps) { var _this2 = this; var tags = nextProps.tags, input = nextProps.input, consider = nextProps.consider, selected = nextProps.selected; if (this.props.input && !input) { consider(null); } var noChange = input === this.props.input && tags === this.props.tags; if (!input || noChange) { return; } var matches = tags.filter(function (t) { return _this2.props.search(t, input) && !selected.includes(t); }); if (matches.length) { consider(matches[0]); } else { consider(null); } } }, { key: 'matchingOptions', value: function matchingOptions() { var _props = this.props, tags = _props.tags, input = _props.input, selected = _props.selected, search = _props.search; var matches = tags.filter(function (t) { return search(t, input) && !selected.map(function (s) { return s.value; }).includes(t.value); }); var values = matches.map(function (t) { return t.value; }); return { matches: matches, values: values }; } }, { key: 'considerNext', value: function considerNext() { var _props2 = this.props, consider = _props2.consider, considering = _props2.considering; var _matchingOptions = this.matchingOptions(), matches = _matchingOptions.matches, values = _matchingOptions.values; if (!matches.length) { return; } if (!considering) { consider(matches[0]); } else { var nextIndex = Math.min(matches.length - 1, values.indexOf(considering.value) + 1); consider(matches[nextIndex]); } } }, { key: 'considerPrevious', value: function considerPrevious() { var _props3 = this.props, consider = _props3.consider, considering = _props3.considering; var _matchingOptions2 = this.matchingOptions(), matches = _matchingOptions2.matches, values = _matchingOptions2.values; if (!matches.length) { return; } var currentIndex = values.indexOf(considering.value); if (currentIndex === 0) { consider(null); } else { consider(matches[currentIndex - 1]); } } }, { key: 'render', value: function render() { var _props4 = this.props, input = _props4.input, select = _props4.select, create = _props4.create, considering = _props4.considering, consider = _props4.consider, renderNewOption = _props4.renderNewOption, loadingText = _props4.loadingText, selectedText = _props4.selectedText, loading = _props4.loading, selected = _props4.selected, exactMatch = _props4.exactMatch; if (loading) { return _react2.default.createElement( 'ul', { className: 'autocomplete' }, _react2.default.createElement( 'li', null, _react2.default.createElement( 'span', { className: 'option-text' }, loadingText ) ) ); } if (!input) { return false; } var _matchingOptions3 = this.matchingOptions(), matches = _matchingOptions3.matches; var foundExactMatch = matches.find(function (t) { return exactMatch(t, input); }); var alreadySelected = selected.find(function (t) { return exactMatch(t, input); }); var addNewOption = !foundExactMatch && _react2.default.createElement( 'li', { className: (0, _classnames2.default)('add-new', { considering: !considering }), onClick: create, onMouseOver: function onMouseOver() { return consider(null); } }, _react2.default.createElement( 'span', { className: 'option-text' }, renderNewOption(input) ) ); var selectedNotice = alreadySelected && _react2.default.createElement( 'li', null, _react2.default.createElement( 'span', { className: 'option-text' }, selectedText ) ); var content = alreadySelected ? selectedNotice : addNewOption; var matching = matches.map(function (t) { var className = (0, _classnames2.default)({ considering: considering === t }); return _react2.default.createElement( 'li', { key: t.value, className: className, onClick: function onClick() { return select(t); }, onMouseOver: function onMouseOver() { return consider(t); } }, _react2.default.createElement( 'span', { className: 'option-text' }, t.label ) ); }); return _react2.default.createElement( 'ul', { className: 'autocomplete' }, content, matching ); } }]); return _class; }(_react.Component); _class.propTypes = { input: _propTypes2.default.string, selected: _propTypes2.default.arrayOf(_utils2.default), tags: _propTypes2.default.arrayOf(_utils2.default).isRequired, select: _propTypes2.default.func.isRequired, create: _propTypes2.default.func.isRequired, considering: _utils2.default, consider: _propTypes2.default.func.isRequired, renderNewOption: _propTypes2.default.func.isRequired, loadingText: _propTypes2.default.string, selectedText: _propTypes2.default.string, loading: _propTypes2.default.bool, search: _propTypes2.default.func.isRequired, exactMatch: _propTypes2.default.func.isRequired }; _class.defaultProps = { selected: [] }; exports.default = _class;