UNPKG

wix-style-react

Version:
377 lines (314 loc) • 14.2 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _get2 = _interopRequireDefault(require("@babel/runtime/helpers/get")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireDefault(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _classnames = _interopRequireDefault(require("classnames")); var _InputWithOptions2 = _interopRequireDefault(require("../InputWithOptions/InputWithOptions")); var _InputWithTags = _interopRequireDefault(require("./InputWithTags")); var _last = _interopRequireDefault(require("lodash/last")); var _difference = _interopRequireDefault(require("difference")); var _MultiSelectSt = require("./MultiSelect.st.css"); var _excluded = ["className", "data-ref"], _excluded2 = ["className", "ref"]; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } var MultiSelect = /*#__PURE__*/function (_InputWithOptions) { (0, _inherits2["default"])(MultiSelect, _InputWithOptions); var _super = _createSuper(MultiSelect); function MultiSelect(props) { var _this; (0, _classCallCheck2["default"])(this, MultiSelect); _this = _super.call(this, props); _this.onKeyDown = _this.onKeyDown.bind((0, _assertThisInitialized2["default"])(_this)); _this.onPaste = _this.onPaste.bind((0, _assertThisInitialized2["default"])(_this)); _this.state = _objectSpread(_objectSpread({}, _this.state), {}, { pasteDetected: false }); return _this; } (0, _createClass2["default"])(MultiSelect, [{ key: "hideOptions", value: function hideOptions() { (0, _get2["default"])((0, _getPrototypeOf2["default"])(MultiSelect.prototype), "hideOptions", this).call(this); if (this.props.clearOnBlur) { this.clearInput(); } } }, { key: "onClickOutside", value: function onClickOutside() { if (this.state.showOptions) { this.hideOptions(); } } }, { key: "getUnselectedOptions", value: function getUnselectedOptions() { var optionIds = this.props.options.map(function (option) { return option.id; }); var tagIds = this.props.tags.map(function (tag) { return tag.id; }); var unselectedOptionsIds = (0, _difference["default"])(optionIds, tagIds); return this.props.options.filter(function (option) { return unselectedOptionsIds.includes(option.id); }); } }, { key: "dropdownAdditionalProps", value: function dropdownAdditionalProps() { return { options: this.getUnselectedOptions().filter(this.props.predicate), closeOnSelect: false, selectedHighlight: false, selectedId: -1 }; } }, { key: "closeOnSelect", value: function closeOnSelect() { return false; } }, { key: "inputAdditionalProps", value: function inputAdditionalProps() { return { readOnly: false, disableEditing: true, inputElement: /*#__PURE__*/_react["default"].createElement(_InputWithTags["default"], { onReorder: this.props.onReorder, maxNumRows: this.props.maxNumRows, mode: this.props.mode, hideCustomSuffix: this.isDropdownLayoutVisible(), customSuffix: this.props.customSuffix }), onKeyDown: this.onKeyDown, delimiters: this.props.delimiters, onPaste: this.onPaste }; } }, { key: "onPaste", value: function onPaste() { this.setState({ pasteDetected: true }); } }, { key: "_splitByDelimitersAndTrim", value: function _splitByDelimitersAndTrim(value) { var delimitersRegexp = new RegExp(this.props.delimiters.join('|'), 'g'); return value.split(delimitersRegexp).map(function (str) { return str.trim(); }).filter(function (str) { return str; }); } }, { key: "_onChange", value: function _onChange(event) { var _this2 = this; if (this.state.pasteDetected) { var value = event.target.value; this.setState({ pasteDetected: false }, function () { _this2.submitValue(value); }); } else { this.setState({ inputValue: event.target.value }); this.props.onChange && this.props.onChange(event); } // If the input value is not empty, should show the options if (event.target.value.trim()) { this.showOptions(); } } }, { key: "_onSelect", value: function _onSelect(option) { this.onSelect(option); } }, { key: "_onManuallyInput", value: function _onManuallyInput(inputValue, event) { var value = this.props.value; // FIXME: InputWithOptions is not updating it's inputValue state when the `value` prop changes. // So using `value` here, covers for that bug. (This is tested) // BTW: Previously, `value` was used to trigger onSelect, and `inputValue` was used to trigger onManuallyInput. Which is crazy. // So now both of them trigger a submit (onManuallyInput). var _value = value && value.trim() || inputValue && inputValue.trim(); this.submitValue(_value); _value && event.preventDefault(); if (this.closeOnSelect()) { this.hideOptions(); } } }, { key: "getManualSubmitKeys", value: function getManualSubmitKeys() { return ['Enter', 'Tab'].concat(this.props.delimiters); } }, { key: "onKeyDown", value: function onKeyDown(event) { var _this$props = this.props, tags = _this$props.tags, value = _this$props.value, onRemoveTag = _this$props.onRemoveTag; if (tags.length > 0 && (event.key === 'Delete' || event.key === 'Backspace') && value.length === 0) { onRemoveTag((0, _last["default"])(tags).id); } if (event.key === 'Escape') { this.clearInput(); (0, _get2["default"])((0, _getPrototypeOf2["default"])(MultiSelect.prototype), "hideOptions", this).call(this); } if (this.props.onKeyDown) { this.props.onKeyDown(event); } } }, { key: "optionToTag", value: function optionToTag(_ref) { var id = _ref.id, value = _ref.value, tag = _ref.tag, theme = _ref.theme; return tag ? _objectSpread({ id: id }, tag) : { id: id, label: value, theme: theme }; } }, { key: "onSelect", value: function onSelect(option) { this.clearInput(); var onSelect = this.props.onSelect; if (onSelect) { onSelect(this.props.options.find(function (o) { return o.id === option.id; })); } } }, { key: "submitValue", value: function submitValue(inputValue) { if (!inputValue) { return; } var onManuallyInput = this.props.onManuallyInput; var values = this._splitByDelimitersAndTrim(inputValue); onManuallyInput && values.length && onManuallyInput(values); this.clearInput(); } }, { key: "clearInput", value: function clearInput() { this.input.current && this.input.current.clear(); if (this.props.onChange) { this.props.onChange({ target: { value: '' } }); } } }]); return MultiSelect; }(_InputWithOptions2["default"]); (0, _defineProperty2["default"])(MultiSelect, "autoSizeInput", function (_ref2) { var className = _ref2.className, dataRef = _ref2['data-ref'], rest = (0, _objectWithoutProperties2["default"])(_ref2, _excluded); var inputClassName = (0, _classnames["default"])(className, _MultiSelectSt.classes.autoSizeInput); return /*#__PURE__*/_react["default"].createElement("input", (0, _extends2["default"])({}, rest, { ref: dataRef, className: inputClassName })); }); (0, _defineProperty2["default"])(MultiSelect, "autoSizeInputWithRef", function () { return /*#__PURE__*/_react["default"].forwardRef(function (props, ref) { return function (_ref3) { var className = _ref3.className, ref = _ref3.ref, rest = (0, _objectWithoutProperties2["default"])(_ref3, _excluded2); var inputClassName = (0, _classnames["default"])(className, _MultiSelectSt.classes.autoSizeInput); return /*#__PURE__*/_react["default"].createElement("input", (0, _extends2["default"])({}, rest, { ref: ref, className: inputClassName })); }(_objectSpread(_objectSpread({}, props), {}, { ref: ref })); }); }); MultiSelect.displayName = 'MultiSelect'; MultiSelect.propTypes = { /** Closes list once list item is selected */ closeOnSelect: _propTypes["default"].bool, /** Callback predicate for the filtering options function */ predicate: _propTypes["default"].func, /** Optional list of strings that are selected suggestions. */ tags: _propTypes["default"].array, /** Max number of visible lines */ maxNumRows: _propTypes["default"].number, /** Delimiters that will trigger a Submit action (call to onTagsAdded). By default it is [,] but also enter and tab keys work. */ delimiters: _propTypes["default"].array, /** Passing 'select' will render a readOnly input with menuArrow suffix **/ mode: _propTypes["default"].string, /** The status of the Multiselect */ status: _propTypes["default"].oneOf(['loading', 'warning', 'error']), /** Text to be shown in the status icon tooltip */ statusMessage: _propTypes["default"].string, /** When this callback function is set, tags can be reordered. The expected callback signature is `onReorder({addedIndex: number, removedIndex: number}) => void` **/ onReorder: _propTypes["default"].func, /** A callback which is called when the user enters something in the input and then confirms the input with some action like Enter key or Tab. */ onManuallyInput: _propTypes["default"].func, /** A callback which is called when options dropdown is shown */ onOptionsShow: _propTypes["default"].func, /** A callback which is called when options dropdown is hidden */ onOptionsHide: _propTypes["default"].func, /** A callback which is called when the user selects an option from the list. `onSelect(option: Option): void` - Option is the original option from the provided options prop. */ onSelect: _propTypes["default"].func, /** Allows adding your own custom Input component instead of the one that is used by default internally. */ customInput: _propTypes["default"].elementType ? _propTypes["default"].oneOfType([_propTypes["default"].func, _propTypes["default"].elementType]) : _propTypes["default"].oneOfType([_propTypes["default"].func]), /** A node to display as input suffix when the dropdown is closed */ customSuffix: _propTypes["default"].node, /** When set to true this component is disabled */ disabled: _propTypes["default"].bool, /** When set to false, the input will not be cleared on blur */ clearOnBlur: _propTypes["default"].bool, /** A callback function to be called when a tag should be removed. The expected callback signature is `onRemoveTag(tagId: number | string) => void.` */ onRemoveTag: _propTypes["default"].func }; MultiSelect.defaultProps = _objectSpread(_objectSpread({}, _InputWithOptions2["default"].defaultProps), {}, { predicate: function predicate() { return true; }, tags: [], delimiters: [','], clearOnBlur: true, customInput: MultiSelect.autoSizeInputWithRef() }); var _default = MultiSelect; exports["default"] = _default;