@fe6/water-pro
Version:
An enterprise-class UI design language and Vue-based implementation
381 lines (326 loc) • 13.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _vue = require("vue");
var _tslib = require("tslib");
var _classNames = _interopRequireDefault(require("../../_util/classNames"));
var _omit = _interopRequireDefault(require("omit.js"));
var _KeyCode = _interopRequireDefault(require("../../_util/KeyCode"));
var _BaseMixin = _interopRequireDefault(require("../../_util/BaseMixin"));
var _propsUtil = require("../../_util/props-util");
var _warning = _interopRequireDefault(require("../../_util/warning"));
var _util = require("./util");
var _KeywordTrigger = _interopRequireDefault(require("./KeywordTrigger"));
var _mentionsProps = require("./mentionsProps");
var _antInputDirective = _interopRequireDefault(require("../../_util/antInputDirective"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
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) { _defineProperty(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 _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function noop() {}
var Mentions = {
name: 'Mentions',
mixins: [_BaseMixin.default],
inheritAttrs: false,
props: (0, _propsUtil.initDefaultProps)(_mentionsProps.vcMentionsProps, _mentionsProps.defaultProps),
created: function created() {
this.mentionsContext = (0, _vue.provide)('mentionsContext', this);
},
data: function data() {
var _this$$props = this.$props,
_this$$props$value = _this$$props.value,
value = _this$$props$value === void 0 ? '' : _this$$props$value,
_this$$props$defaultV = _this$$props.defaultValue,
defaultValue = _this$$props$defaultV === void 0 ? '' : _this$$props$defaultV;
(0, _warning.default)(this.$props.children, 'please children prop replace slots.default');
return {
_value: !(0, _propsUtil.hasProp)(this, 'value') ? defaultValue : value,
measuring: false,
measureLocation: 0,
measureText: null,
measurePrefix: '',
activeIndex: 0,
isFocus: false
};
},
watch: {
value: function value(val) {
this.$data._value = val;
}
},
updated: function updated() {
var _this = this;
this.$nextTick(function () {
var measuring = _this.$data.measuring; // Sync measure div top with textarea for rc-trigger usage
if (measuring) {
_this.$refs.measure.scrollTop = _this.$refs.textarea.scrollTop;
}
});
},
methods: {
triggerChange: function triggerChange(value) {
var props = (0, _propsUtil.getOptionProps)(this);
if (!('value' in props)) {
this.setState({
_value: value
});
} else {
this.$forceUpdate();
}
this.__emit('change', value);
},
onChange: function onChange(_ref) {
var _ref$target = _ref.target,
value = _ref$target.value,
composing = _ref$target.composing,
isComposing = _ref.isComposing;
if (isComposing || composing) {
return;
}
this.triggerChange(value);
},
onKeyDown: function onKeyDown(event) {
var which = event.which;
var _this$$data = this.$data,
activeIndex = _this$$data.activeIndex,
measuring = _this$$data.measuring; // Skip if not measuring
if (!measuring) {
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;
this.setState({
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();
return;
}
var option = options[activeIndex];
this.selectOption(option);
}
},
/**
* When to start measure:
* 1. When user press `prefix`
* 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
*/
onKeyUp: function onKeyUp(event) {
var key = event.key,
which = event.which;
var _this$$data2 = this.$data,
prevMeasureText = _this$$data2.measureText,
measuring = _this$$data2.measuring;
var _this$$props2 = this.$props,
_this$$props2$prefix = _this$$props2.prefix,
prefix = _this$$props2$prefix === void 0 ? '' : _this$$props2$prefix,
validateSearch = _this$$props2.validateSearch;
var target = event.target;
var selectionStartText = (0, _util.getBeforeSelectionText)(target);
var _getLastMeasureIndex = (0, _util.getLastMeasureIndex)(selectionStartText, prefix),
measureIndex = _getLastMeasureIndex.location,
measurePrefix = _getLastMeasureIndex.prefix; // Skip if match the white key list
if ([_KeyCode.default.ESC, _KeyCode.default.UP, _KeyCode.default.DOWN, _KeyCode.default.ENTER].includes(which)) {
return;
}
if (measureIndex !== -1) {
var measureText = selectionStartText.slice(measureIndex + measurePrefix.length);
var validateMeasure = validateSearch(measureText, this.$props);
var matchOption = !!this.getOptions(measureText).length;
if (validateMeasure) {
if (key === measurePrefix || 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 (validateMeasure) {
this.__emit('search', measureText, measurePrefix);
}
} else if (measuring) {
this.stopMeasure();
}
},
onInputFocus: function onInputFocus(event) {
this.onFocus(event);
},
onInputBlur: function onInputBlur(event) {
this.onBlur(event);
},
onDropdownFocus: function onDropdownFocus() {
this.onFocus();
},
onDropdownBlur: function onDropdownBlur() {
this.onBlur();
},
onFocus: function onFocus(event) {
window.clearTimeout(this.focusId);
var isFocus = this.$data.isFocus;
if (!isFocus && event) {
this.__emit('focus', event);
}
this.setState({
isFocus: true
});
},
onBlur: function onBlur(event) {
var _this2 = this;
this.focusId = window.setTimeout(function () {
_this2.setState({
isFocus: false
});
_this2.stopMeasure();
_this2.__emit('blur', event);
}, 100);
},
selectOption: function selectOption(option) {
var _this3 = this;
var _this$$data3 = this.$data,
value = _this$$data3._value,
measureLocation = _this$$data3.measureLocation,
measurePrefix = _this$$data3.measurePrefix;
var split = this.$props.split;
var _option$value = option.value,
mentionValue = _option$value === void 0 ? '' : _option$value;
var _replaceWithMeasure = (0, _util.replaceWithMeasure)(value, {
measureLocation: measureLocation,
targetText: mentionValue,
prefix: measurePrefix,
selectionStart: this.$refs.textarea.selectionStart,
split: split
}),
text = _replaceWithMeasure.text,
selectionLocation = _replaceWithMeasure.selectionLocation;
this.triggerChange(text);
this.stopMeasure(function () {
// We need restore the selection position
(0, _util.setInputSelection)(_this3.$refs.textarea, selectionLocation);
});
this.__emit('select', option, measurePrefix);
},
setActiveIndex: function setActiveIndex(activeIndex) {
this.setState({
activeIndex: activeIndex
});
},
getOptions: function getOptions(measureText) {
var targetMeasureText = measureText || this.$data.measureText || '';
var _this$$props3 = this.$props,
filterOption = _this$$props3.filterOption,
_this$$props3$childre = _this$$props3.children,
children = _this$$props3$childre === void 0 ? [] : _this$$props3$childre;
var list = (Array.isArray(children) ? children : [children]).map(function (item) {
var _a, _b;
return _extends(_extends({}, (0, _propsUtil.getOptionProps)(item)), {
children: (_b = (_a = item.children).default) === null || _b === void 0 ? void 0 : _b.call(_a)
});
}).filter(function (option) {
/** Return all result if `filterOption` is false. */
if (filterOption === false) {
return true;
}
return filterOption(targetMeasureText, option);
});
return list;
},
startMeasure: function startMeasure(measureText, measurePrefix, measureLocation) {
this.setState({
measuring: true,
measureText: measureText,
measurePrefix: measurePrefix,
measureLocation: measureLocation,
activeIndex: 0
});
},
stopMeasure: function stopMeasure(callback) {
this.setState({
measuring: false,
measureLocation: 0,
measureText: null
}, callback);
},
focus: function focus() {
this.$refs.textarea.focus();
},
blur: function blur() {
this.$refs.textarea.blur();
}
},
render: function render() {
var _this$$data4 = this.$data,
value = _this$$data4._value,
measureLocation = _this$$data4.measureLocation,
measurePrefix = _this$$data4.measurePrefix,
measuring = _this$$data4.measuring;
var _a = (0, _propsUtil.getOptionProps)(this),
prefixCls = _a.prefixCls,
placement = _a.placement,
transitionName = _a.transitionName,
notFoundContent = _a.notFoundContent,
getPopupContainer = _a.getPopupContainer,
restProps = (0, _tslib.__rest)(_a, ["prefixCls", "placement", "transitionName", "notFoundContent", "getPopupContainer"]);
var _b = this.$attrs,
className = _b.class,
style = _b.style,
otherAttrs = (0, _tslib.__rest)(_b, ["class", "style"]);
var inputProps = (0, _omit.default)(restProps, ['value', 'defaultValue', 'prefix', 'split', 'children', 'validateSearch', 'filterOption']);
var options = measuring ? this.getOptions() : [];
var textareaProps = _extends(_extends(_extends({}, inputProps), otherAttrs), {
onChange: noop,
onSelect: noop,
value: value,
onInput: this.onChange,
onBlur: this.onInputBlur,
onKeydown: this.onKeyDown,
onKeyup: this.onKeyUp,
onFocus: this.onInputFocus
});
return (0, _vue.createVNode)("div", {
"class": (0, _classNames.default)(prefixCls, className),
"style": style
}, [(0, _vue.withDirectives)((0, _vue.createVNode)("textarea", _objectSpread({
"ref": "textarea"
}, textareaProps), null), [[_antInputDirective.default]]), measuring && (0, _vue.createVNode)("div", {
"ref": "measure",
"class": "".concat(prefixCls, "-measure")
}, [value.slice(0, measureLocation), (0, _vue.createVNode)(_KeywordTrigger.default, {
"prefixCls": prefixCls,
"transitionName": transitionName,
"placement": placement,
"options": options,
"visible": true,
"getPopupContainer": getPopupContainer
}, {
default: function _default() {
return [(0, _vue.createVNode)("span", null, [measurePrefix])];
}
}), value.slice(measureLocation + measurePrefix.length)])]);
}
};
var _default2 = (0, _vue.defineComponent)(Mentions);
exports.default = _default2;