choerodon-ui
Version:
An enterprise-class UI design language and React-based implementation
466 lines (398 loc) • 17 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _get2 = _interopRequireDefault(require("@babel/runtime/helpers/get"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _createSuper2 = _interopRequireDefault(require("@babel/runtime/helpers/createSuper"));
var _tslib = require("tslib");
var _react = _interopRequireDefault(require("react"));
var _mobxReact = require("mobx-react");
var _mobx = require("mobx");
var _isNil = _interopRequireDefault(require("lodash/isNil"));
var _spin = _interopRequireDefault(require("../../../lib/spin"));
var _KeyCode = _interopRequireDefault(require("../../../lib/_util/KeyCode"));
var _enum = require("../data-set/enum");
var _textArea = _interopRequireDefault(require("../text-area"));
var _autobind = _interopRequireDefault(require("../_util/autobind"));
var _KeywordTrigger = _interopRequireDefault(require("./KeywordTrigger"));
var _MentionsContext = require("./MentionsContext");
var _Option = _interopRequireDefault(require("./Option"));
var _utils = require("./utils");
var Mentions = /*#__PURE__*/function (_TextArea) {
(0, _inherits2["default"])(Mentions, _TextArea);
var _super = (0, _createSuper2["default"])(Mentions);
function Mentions(props, context) {
var _this;
(0, _classCallCheck2["default"])(this, Mentions);
_this = _super.call(this, props, context);
_this.focusId = undefined;
_this.selectionLocation = -1;
_this.initObservableObj();
return _this;
}
(0, _createClass2["default"])(Mentions, [{
key: "initObservableObj",
value: function initObservableObj() {
this.measuring = false;
this.measureLocation = 0;
this.measureText = null;
this.measurePrefix = '';
this.activeIndex = 0;
}
}, {
key: "componentDidUpdate",
value: function componentDidUpdate() {
(0, _get2["default"])((0, _getPrototypeOf2["default"])(Mentions.prototype), "componentDidUpdate", this).call(this); // Sync measure div top with textarea for trigger usage
if (this.measuring && this.measure && this.element) {
this.measure.scrollTop = this.element.scrollTop;
} // 选择选项后设置输入框光标位置
if (this.selectionLocation !== -1 && this.element) {
(0, _utils.setInputSelection)(this.element, this.selectionLocation);
this.selectionLocation = -1;
}
}
}, {
key: "getNotFoundContent",
value: function getNotFoundContent() {
if ('notFoundContent' in this.props) {
return this.props.notFoundContent;
}
return this.getContextConfig('renderEmpty')('Select');
}
}, {
key: "getOtherProps",
value: function getOtherProps() {
var otherProps = (0, _get2["default"])((0, _getPrototypeOf2["default"])(Mentions.prototype), "getOtherProps", this).call(this);
otherProps.onKeyUp = this.handleKeyUp;
return otherProps;
}
}, {
key: "getOmitPropsKeys",
value: function getOmitPropsKeys() {
return (0, _get2["default"])((0, _getPrototypeOf2["default"])(Mentions.prototype), "getOmitPropsKeys", this).call(this).concat(['notFoundContent', 'split', 'transitionName', 'placement', 'prefix', 'validateSearch', 'filterOption', 'onSelect', 'onSearch', 'getPopupContainer', 'loading', 'mentionsKey']);
}
}, {
key: "select",
value: function select() {// noop
} // Check if hit the measure keyword
}, {
key: "handleKeyDown",
value: function handleKeyDown(event) {
var _this2 = this;
var which = event.which;
var activeIndex = this.activeIndex,
measuring = this.measuring; // Skip if not measuring
if (!measuring) {
(0, _get2["default"])((0, _getPrototypeOf2["default"])(Mentions.prototype), "handleKeyDown", this).call(this, event);
return;
}
if (which === _KeyCode["default"].UP || which === _KeyCode["default"].DOWN) {
// Control arrow function
var optionLen = this.getOptions().length;
var offset = which === _KeyCode["default"].UP ? -1 : 1;
var newActiveIndex = (activeIndex + offset + optionLen) % optionLen;
(0, _mobx.runInAction)(function () {
_this2.activeIndex = newActiveIndex;
});
event.preventDefault();
} else if (which === _KeyCode["default"].ESC) {
this.stopMeasure();
} else if (which === _KeyCode["default"].ENTER) {
// Measure hit
event.preventDefault();
var options = this.getOptions();
if (!options.length) {
this.stopMeasure();
(0, _get2["default"])((0, _getPrototypeOf2["default"])(Mentions.prototype), "handleKeyDown", this).call(this, event);
return;
}
var option = options[activeIndex];
this.selectOption(option);
}
(0, _get2["default"])((0, _getPrototypeOf2["default"])(Mentions.prototype), "handleKeyDown", this).call(this, event);
}
/**
* When to start measure:
* 1. When user press `mentionsKey`
* 2. When measureText !== prevMeasureText
* - If measure hit
* - If measuring
*
* When to stop measure:
* 1. Selection is out of range
* 2. Contains `space`
* 3. ESC or select one
*/
}, {
key: "handleKeyUp",
value: function handleKeyUp(event) {
var key = event.key,
which = event.which;
var prevMeasureText = this.measureText,
measuring = this.measuring;
var _this$props = this.props,
_this$props$mentionsK = _this$props.mentionsKey,
mentionsKey = _this$props$mentionsK === void 0 ? '' : _this$props$mentionsK,
clientOnKeyUp = _this$props.onKeyUp,
onSearch = _this$props.onSearch,
validateSearch = _this$props.validateSearch;
var target = event.target;
var selectionStartText = (0, _utils.getBeforeSelectionText)(target);
var _getLastMeasureIndex = (0, _utils.getLastMeasureIndex)(selectionStartText, mentionsKey),
measureIndex = _getLastMeasureIndex.location,
measurePrefix = _getLastMeasureIndex.mentionsKey; // If the client implements an onKeyUp handler, call it
if (clientOnKeyUp) {
clientOnKeyUp(event);
} // Skip if match the white key list
if ([_KeyCode["default"].ESC, _KeyCode["default"].UP, _KeyCode["default"].DOWN, _KeyCode["default"].ENTER].indexOf(which) !== -1) {
return;
}
if (measureIndex !== -1) {
var measureText = selectionStartText.slice(measureIndex + measurePrefix.length);
var validateMeasure = validateSearch ? validateSearch(measureText, this.props) : false;
var matchOption = !!this.getOptions(measureText).length;
if (validateMeasure) {
if (key === measurePrefix || key === 'Shift' || measuring || measureText !== prevMeasureText && matchOption) {
this.startMeasure(measureText, measurePrefix, measureIndex);
}
} else if (measuring) {
// Stop if measureText is invalidate
this.stopMeasure();
}
/**
* We will trigger `onSearch` to developer since they may use for async update.
* If met `space` means user finished searching.
*/
if (onSearch && validateMeasure) {
onSearch(measureText, measurePrefix);
}
} else if (measuring) {
this.stopMeasure();
}
}
}, {
key: "onDropdownFocus",
value: function onDropdownFocus() {
this.handleFocus();
}
}, {
key: "onDropdownBlur",
value: function onDropdownBlur() {
this.handleBlur();
}
}, {
key: "handleFocus",
value: function handleFocus(event) {
window.clearTimeout(this.focusId);
if (event) {
(0, _get2["default"])((0, _getPrototypeOf2["default"])(Mentions.prototype), "handleFocus", this).call(this, event);
}
}
}, {
key: "handleBlur",
value: function handleBlur(event) {
var _this3 = this;
this.focusId = window.setTimeout(function () {
_this3.stopMeasure();
}, 0);
if (event) {
(0, _get2["default"])((0, _getPrototypeOf2["default"])(Mentions.prototype), "handleBlur", this).call(this, event);
}
}
}, {
key: "selectOption",
value: function selectOption(option) {
var measureLocation = this.measureLocation,
measurePrefix = this.measurePrefix;
var value = (0, _isNil["default"])(this.text) ? this.getValue() : this.text;
value = (0, _isNil["default"])(value) ? '' : value;
var _this$props2 = this.props,
split = _this$props2.split,
onSelect = _this$props2.onSelect;
var _option$value = option.value,
mentionValue = _option$value === void 0 ? '' : _option$value;
var _replaceWithMeasure = (0, _utils.replaceWithMeasure)(value, {
measureLocation: measureLocation,
targetText: mentionValue,
mentionsKey: measurePrefix,
selectionStart: this.element ? this.element.selectionStart : -1,
split: String(split || '')
}),
text = _replaceWithMeasure.text,
selectionLocation = _replaceWithMeasure.selectionLocation;
this.selectionLocation = selectionLocation;
this.prepareSetValue(text);
this.stopMeasure();
if (onSelect) {
onSelect(option, measurePrefix);
}
}
}, {
key: "setActiveIndex",
value: function setActiveIndex(activeIndex) {
this.activeIndex = activeIndex;
}
}, {
key: "setMeasureRef",
value: function setMeasureRef(element) {
this.measure = element;
}
}, {
key: "getOptions",
value: function getOptions(measureText) {
var targetMeasureText = measureText || this.measureText || '';
var _this$props3 = this.props,
children = _this$props3.children,
filterOption = _this$props3.filterOption,
loading = _this$props3.loading;
if (loading) {
return [{
key: 'loading',
children: /*#__PURE__*/_react["default"].createElement(_spin["default"], null),
disabled: true,
style: {
minWidth: '0.8rem',
display: 'flex',
justifyContent: 'center'
}
}];
}
var list = (0, _utils.toArray)(children).map(function (_ref) {
var props = _ref.props,
key = _ref.key;
return (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, props), {}, {
key: key || props.value
});
}).filter(function (option) {
/** Return all result if `filterOption` is false. */
if (filterOption === false) {
return true;
}
return filterOption ? filterOption(targetMeasureText, option) : true;
});
return list;
}
}, {
key: "startMeasure",
value: function startMeasure(measureText, measurePrefix, measureLocation) {
this.measuring = true;
this.measureText = measureText;
this.measurePrefix = measurePrefix;
this.measureLocation = measureLocation;
this.activeIndex = 0;
}
}, {
key: "stopMeasure",
value: function stopMeasure() {
this.measuring = false;
this.measureLocation = 0;
this.measureText = null;
}
}, {
key: "wrapperInputNode",
value: function wrapperInputNode() {
var measureLocation = this.measureLocation,
measurePrefix = this.measurePrefix,
measuring = this.measuring,
activeIndex = this.activeIndex,
prefixCls = this.prefixCls;
var value = (0, _isNil["default"])(this.text) ? this.getValue() : this.text;
var _this$props4 = this.props,
placement = _this$props4.placement,
transitionName = _this$props4.transitionName,
getPopupContainer = _this$props4.getPopupContainer;
var options = measuring ? this.getOptions() : [];
var renderedValue = this.renderRenderedValue(undefined, {});
return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, (0, _get2["default"])((0, _getPrototypeOf2["default"])(Mentions.prototype), "wrapperInputNode", this).call(this, renderedValue), measuring && /*#__PURE__*/_react["default"].createElement("div", {
ref: this.setMeasureRef,
className: "".concat(prefixCls, "-measure")
}, value.slice(0, measureLocation), /*#__PURE__*/_react["default"].createElement(_MentionsContext.MentionsContextProvider, {
value: {
notFoundContent: this.getNotFoundContent(),
activeIndex: activeIndex,
setActiveIndex: this.setActiveIndex,
selectOption: this.selectOption,
onFocus: this.onDropdownFocus,
onBlur: this.onDropdownBlur
}
}, /*#__PURE__*/_react["default"].createElement(_KeywordTrigger["default"], {
prefixCls: prefixCls,
transitionName: transitionName,
placement: placement,
options: options,
visible: true,
getPopupContainer: getPopupContainer
}, /*#__PURE__*/_react["default"].createElement("span", null, measurePrefix))), value.slice(measureLocation + measurePrefix.length)));
}
}]);
return Mentions;
}(_textArea["default"]);
Mentions.displayName = 'Mentions';
Mentions.Option = _Option["default"];
Mentions.defaultProps = (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, _textArea["default"].defaultProps), {}, {
suffixCls: 'mentions',
rows: 1,
trim: _enum.FieldTrim.left,
mentionsKey: '@',
split: ' ',
validateSearch: _utils.validateSearch,
filterOption: _utils.filterOption
});
(0, _tslib.__decorate)([_mobx.observable], Mentions.prototype, "measuring", void 0);
(0, _tslib.__decorate)([_mobx.observable], Mentions.prototype, "measureText", void 0);
(0, _tslib.__decorate)([_mobx.observable], Mentions.prototype, "measurePrefix", void 0);
(0, _tslib.__decorate)([_mobx.observable], Mentions.prototype, "measureLocation", void 0);
(0, _tslib.__decorate)([_mobx.observable], Mentions.prototype, "activeIndex", void 0);
(0, _tslib.__decorate)([_mobx.action], Mentions.prototype, "initObservableObj", null);
(0, _tslib.__decorate)([_autobind["default"]], Mentions.prototype, "handleKeyDown", null);
(0, _tslib.__decorate)([_autobind["default"]], Mentions.prototype, "handleKeyUp", null);
(0, _tslib.__decorate)([_autobind["default"]], Mentions.prototype, "onDropdownFocus", null);
(0, _tslib.__decorate)([_autobind["default"]], Mentions.prototype, "onDropdownBlur", null);
(0, _tslib.__decorate)([_autobind["default"]], Mentions.prototype, "handleFocus", null);
(0, _tslib.__decorate)([_autobind["default"]], Mentions.prototype, "handleBlur", null);
(0, _tslib.__decorate)([_autobind["default"]], Mentions.prototype, "selectOption", null);
(0, _tslib.__decorate)([_autobind["default"], _mobx.action], Mentions.prototype, "setActiveIndex", null);
(0, _tslib.__decorate)([_autobind["default"]], Mentions.prototype, "setMeasureRef", null);
(0, _tslib.__decorate)([_mobx.action], Mentions.prototype, "startMeasure", null);
(0, _tslib.__decorate)([_mobx.action], Mentions.prototype, "stopMeasure", null);
Mentions = (0, _tslib.__decorate)([_mobxReact.observer], Mentions);
Mentions.getMentions = function () {
var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var _config$mentionsKey = config.mentionsKey,
mentionsKey = _config$mentionsKey === void 0 ? '@' : _config$mentionsKey,
_config$split = config.split,
split = _config$split === void 0 ? ' ' : _config$split;
var prefixList = Array.isArray(mentionsKey) ? mentionsKey : [mentionsKey];
return value.split(split).map(function () {
var str = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var hitPrefix = null;
prefixList.some(function (prefixStr) {
var startStr = str.slice(0, prefixStr.length);
if (startStr === prefixStr) {
hitPrefix = prefixStr;
return true;
}
return false;
});
if (hitPrefix !== null) {
return {
mentionsKey: hitPrefix,
value: str.slice(hitPrefix.length)
};
}
return null;
}).filter(function (entity) {
return !!entity && !!entity.value;
});
};
var _default = Mentions;
exports["default"] = _default;
//# sourceMappingURL=Mentions.js.map