This commit is contained in:
2025-09-19 14:25:20 +08:00
parent 269893a435
commit fbf3f77229
24949 changed files with 2839404 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
import Mention from './src/mention.vue';
import type { SFCWithInstall } from 'element-plus/es/utils';
export declare const ElMention: SFCWithInstall<typeof Mention>;
export default ElMention;
export * from './src/mention';

View File

@@ -0,0 +1,16 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var mention$1 = require('./src/mention2.js');
var mention = require('./src/mention.js');
var install = require('../../utils/vue/install.js');
const ElMention = install.withInstall(mention$1["default"]);
exports.mentionDefaultProps = mention.mentionDefaultProps;
exports.mentionEmits = mention.mentionEmits;
exports.mentionProps = mention.mentionProps;
exports.ElMention = ElMention;
exports["default"] = ElMention;
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sources":["../../../../../packages/components/mention/index.ts"],"sourcesContent":["import { withInstall } from '@element-plus/utils'\nimport Mention from './src/mention.vue'\n\nimport type { SFCWithInstall } from '@element-plus/utils'\n\nexport const ElMention: SFCWithInstall<typeof Mention> = withInstall(Mention)\nexport default ElMention\n\nexport * from './src/mention'\n"],"names":["withInstall","Mention"],"mappings":";;;;;;;;AAEY,MAAC,SAAS,GAAGA,mBAAW,CAACC,oBAAO;;;;;;;;"}

View File

@@ -0,0 +1,32 @@
import type { MentionCtx, MentionOption } from './types';
export declare const filterOption: (pattern: string, option: MentionOption) => boolean;
export declare const getMentionCtx: (inputEl: HTMLInputElement | HTMLTextAreaElement, prefix: string | string[], split: string) => MentionCtx | undefined;
/**
* fork from textarea-caret-position
* https://github.com/component/textarea-caret-position
* The MIT License (MIT)
* Copyright (c) 2015 Jonathan Ong me@jongleberry.com
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
export declare const getCursorPosition: (element: HTMLInputElement | HTMLTextAreaElement, options?: {
debug: boolean;
useSelectionEnd: boolean;
}) => {
top: number;
left: number;
height: number;
};

View File

@@ -0,0 +1,157 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var lodashUnified = require('lodash-unified');
var browser = require('../../../utils/browser.js');
const filterOption = (pattern, option) => {
const lowerCase = pattern.toLowerCase();
const label = option.label || option.value || "";
return label.toLowerCase().includes(lowerCase);
};
const getMentionCtx = (inputEl, prefix, split) => {
const { selectionEnd } = inputEl;
if (selectionEnd === null)
return;
const inputValue = inputEl.value;
const prefixArray = lodashUnified.castArray(prefix);
let splitIndex = -1;
let mentionCtx;
for (let i = selectionEnd - 1; i >= 0; --i) {
const char = inputValue[i];
if (char === split || char === "\n" || char === "\r") {
splitIndex = i;
continue;
}
if (prefixArray.includes(char)) {
const end = splitIndex === -1 ? selectionEnd : splitIndex;
const pattern = inputValue.slice(i + 1, end);
mentionCtx = {
pattern,
start: i + 1,
end,
prefix: char,
prefixIndex: i,
splitIndex,
selectionEnd
};
break;
}
}
return mentionCtx;
};
const getCursorPosition = (element, options = {
debug: false,
useSelectionEnd: false
}) => {
const selectionStart = element.selectionStart !== null ? element.selectionStart : 0;
const selectionEnd = element.selectionEnd !== null ? element.selectionEnd : 0;
const position = options.useSelectionEnd ? selectionEnd : selectionStart;
const properties = [
"direction",
"boxSizing",
"width",
"height",
"overflowX",
"overflowY",
"borderTopWidth",
"borderRightWidth",
"borderBottomWidth",
"borderLeftWidth",
"borderStyle",
"paddingTop",
"paddingRight",
"paddingBottom",
"paddingLeft",
"fontStyle",
"fontVariant",
"fontWeight",
"fontStretch",
"fontSize",
"fontSizeAdjust",
"lineHeight",
"fontFamily",
"textAlign",
"textTransform",
"textIndent",
"textDecoration",
"letterSpacing",
"wordSpacing",
"tabSize",
"MozTabSize"
];
if (options.debug) {
const el = document.querySelector("#input-textarea-caret-position-mirror-div");
if (el == null ? void 0 : el.parentNode)
el.parentNode.removeChild(el);
}
const div = document.createElement("div");
div.id = "input-textarea-caret-position-mirror-div";
document.body.appendChild(div);
const style = div.style;
const computed = window.getComputedStyle(element);
const isInput = element.nodeName === "INPUT";
style.whiteSpace = isInput ? "nowrap" : "pre-wrap";
if (!isInput)
style.wordWrap = "break-word";
style.position = "absolute";
if (!options.debug)
style.visibility = "hidden";
properties.forEach((prop) => {
if (isInput && prop === "lineHeight") {
if (computed.boxSizing === "border-box") {
const height = Number.parseInt(computed.height);
const outerHeight = Number.parseInt(computed.paddingTop) + Number.parseInt(computed.paddingBottom) + Number.parseInt(computed.borderTopWidth) + Number.parseInt(computed.borderBottomWidth);
const targetHeight = outerHeight + Number.parseInt(computed.lineHeight);
if (height > targetHeight) {
style.lineHeight = `${height - outerHeight}px`;
} else if (height === targetHeight) {
style.lineHeight = computed.lineHeight;
} else {
style.lineHeight = "0";
}
} else {
style.lineHeight = computed.height;
}
} else {
style[prop] = computed[prop];
}
});
if (browser.isFirefox()) {
if (element.scrollHeight > Number.parseInt(computed.height)) {
style.overflowY = "scroll";
}
} else {
style.overflow = "hidden";
}
div.textContent = element.value.slice(0, Math.max(0, position));
if (isInput && div.textContent) {
div.textContent = div.textContent.replace(/\s/g, "\xA0");
}
const span = document.createElement("span");
span.textContent = element.value.slice(Math.max(0, position)) || ".";
span.style.position = "relative";
span.style.left = `${-element.scrollLeft}px`;
span.style.top = `${-element.scrollTop}px`;
div.appendChild(span);
const relativePosition = {
top: span.offsetTop + Number.parseInt(computed.borderTopWidth),
left: span.offsetLeft + Number.parseInt(computed.borderLeftWidth),
height: Number.parseInt(computed.fontSize) * 1.5
};
if (options.debug) {
span.style.backgroundColor = "#aaa";
} else {
document.body.removeChild(div);
}
if (relativePosition.left >= element.clientWidth) {
relativePosition.left = element.clientWidth;
}
return relativePosition;
};
exports.filterOption = filterOption;
exports.getCursorPosition = getCursorPosition;
exports.getMentionCtx = getMentionCtx;
//# sourceMappingURL=helper.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,11 @@
import type { MentionOption } from './types';
export declare const mentionDropdownProps: {
options: import("element-plus/es/utils").EpPropFinalized<(new (...args: any[]) => MentionOption[]) | (() => MentionOption[]) | ((new (...args: any[]) => MentionOption[]) | (() => MentionOption[]))[], unknown, unknown, () => never[], boolean>;
loading: BooleanConstructor;
disabled: BooleanConstructor;
contentId: StringConstructor;
ariaLabel: StringConstructor;
};
export declare const mentionDropdownEmits: {
select: (option: MentionOption) => boolean;
};

View File

@@ -0,0 +1,24 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var runtime = require('../../../utils/vue/props/runtime.js');
var shared = require('@vue/shared');
const mentionDropdownProps = runtime.buildProps({
options: {
type: runtime.definePropType(Array),
default: () => []
},
loading: Boolean,
disabled: Boolean,
contentId: String,
ariaLabel: String
});
const mentionDropdownEmits = {
select: (option) => shared.isString(option.value)
};
exports.mentionDropdownEmits = mentionDropdownEmits;
exports.mentionDropdownProps = mentionDropdownProps;
//# sourceMappingURL=mention-dropdown.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"mention-dropdown.js","sources":["../../../../../../packages/components/mention/src/mention-dropdown.ts"],"sourcesContent":["import { buildProps, definePropType, isString } from '@element-plus/utils'\n\nimport type { MentionOption } from './types'\n\nexport const mentionDropdownProps = buildProps({\n options: {\n type: definePropType<MentionOption[]>(Array),\n default: () => [],\n },\n loading: Boolean,\n disabled: Boolean,\n contentId: String,\n ariaLabel: String,\n})\n\nexport const mentionDropdownEmits = {\n select: (option: MentionOption) => isString(option.value),\n}\n"],"names":["buildProps","definePropType","isString"],"mappings":";;;;;;;AACY,MAAC,oBAAoB,GAAGA,kBAAU,CAAC;AAC/C,EAAE,OAAO,EAAE;AACX,IAAI,IAAI,EAAEC,sBAAc,CAAC,KAAK,CAAC;AAC/B,IAAI,OAAO,EAAE,MAAM,EAAE;AACrB,GAAG;AACH,EAAE,OAAO,EAAE,OAAO;AAClB,EAAE,QAAQ,EAAE,OAAO;AACnB,EAAE,SAAS,EAAE,MAAM;AACnB,EAAE,SAAS,EAAE,MAAM;AACnB,CAAC,EAAE;AACS,MAAC,oBAAoB,GAAG;AACpC,EAAE,MAAM,EAAE,CAAC,MAAM,KAAKC,eAAQ,CAAC,MAAM,CAAC,KAAK,CAAC;AAC5C;;;;;"}

View File

@@ -0,0 +1,43 @@
import type { MentionOption } from './types';
declare function __VLS_template(): {
header?(_: {}): any;
label?(_: {
item: MentionOption;
index: number;
}): any;
loading?(_: {}): any;
footer?(_: {}): any;
};
declare const __VLS_component: import("vue").DefineComponent<{
options: import("element-plus/es/utils").EpPropFinalized<(new (...args: any[]) => MentionOption[]) | (() => MentionOption[]) | ((new (...args: any[]) => MentionOption[]) | (() => MentionOption[]))[], unknown, unknown, () => never[], boolean>;
loading: BooleanConstructor;
disabled: BooleanConstructor;
contentId: StringConstructor;
ariaLabel: StringConstructor;
}, {
hoveringIndex: import("vue").Ref<number>;
navigateOptions: (direction: "next" | "prev") => void;
selectHoverOption: () => void;
hoverOption: import("vue").ComputedRef<MentionOption>;
}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
select: (option: MentionOption) => void;
}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
options: import("element-plus/es/utils").EpPropFinalized<(new (...args: any[]) => MentionOption[]) | (() => MentionOption[]) | ((new (...args: any[]) => MentionOption[]) | (() => MentionOption[]))[], unknown, unknown, () => never[], boolean>;
loading: BooleanConstructor;
disabled: BooleanConstructor;
contentId: StringConstructor;
ariaLabel: StringConstructor;
}>> & {
onSelect?: ((option: MentionOption) => any) | undefined;
}, {
disabled: boolean;
loading: boolean;
options: MentionOption[];
}>;
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, ReturnType<typeof __VLS_template>>;
export default _default;
type __VLS_WithTemplateSlots<T, S> = T & {
new (): {
$slots: S;
};
};

View File

@@ -0,0 +1,174 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var vue = require('vue');
var index$2 = require('../../scrollbar/index.js');
var mentionDropdown = require('./mention-dropdown.js');
var pluginVue_exportHelper = require('../../../_virtual/plugin-vue_export-helper.js');
var index = require('../../../hooks/use-namespace/index.js');
var index$1 = require('../../../hooks/use-locale/index.js');
var scroll = require('../../../utils/dom/scroll.js');
const __default__ = vue.defineComponent({
name: "ElMentionDropdown"
});
const _sfc_main = /* @__PURE__ */ vue.defineComponent({
...__default__,
props: mentionDropdown.mentionDropdownProps,
emits: mentionDropdown.mentionDropdownEmits,
setup(__props, { expose, emit }) {
const props = __props;
const ns = index.useNamespace("mention");
const { t } = index$1.useLocale();
const hoveringIndex = vue.ref(-1);
const scrollbarRef = vue.ref();
const optionRefs = vue.ref();
const dropdownRef = vue.ref();
const optionkls = (item, index) => [
ns.be("dropdown", "item"),
ns.is("hovering", hoveringIndex.value === index),
ns.is("disabled", item.disabled || props.disabled)
];
const handleSelect = (item) => {
if (item.disabled || props.disabled)
return;
emit("select", item);
};
const handleMouseEnter = (index) => {
hoveringIndex.value = index;
};
const filteredAllDisabled = vue.computed(() => props.disabled || props.options.every((item) => item.disabled));
const hoverOption = vue.computed(() => props.options[hoveringIndex.value]);
const selectHoverOption = () => {
if (!hoverOption.value)
return;
emit("select", hoverOption.value);
};
const navigateOptions = (direction) => {
const { options } = props;
if (options.length === 0 || filteredAllDisabled.value)
return;
if (direction === "next") {
hoveringIndex.value++;
if (hoveringIndex.value === options.length) {
hoveringIndex.value = 0;
}
} else if (direction === "prev") {
hoveringIndex.value--;
if (hoveringIndex.value < 0) {
hoveringIndex.value = options.length - 1;
}
}
const option = options[hoveringIndex.value];
if (option.disabled) {
navigateOptions(direction);
return;
}
vue.nextTick(() => scrollToOption(option));
};
const scrollToOption = (option) => {
var _a, _b, _c, _d;
const { options } = props;
const index = options.findIndex((item) => item.value === option.value);
const target = (_a = optionRefs.value) == null ? void 0 : _a[index];
if (target) {
const menu = (_c = (_b = dropdownRef.value) == null ? void 0 : _b.querySelector) == null ? void 0 : _c.call(_b, `.${ns.be("dropdown", "wrap")}`);
if (menu) {
scroll.scrollIntoView(menu, target);
}
}
(_d = scrollbarRef.value) == null ? void 0 : _d.handleScroll();
};
const resetHoveringIndex = () => {
if (filteredAllDisabled.value || props.options.length === 0) {
hoveringIndex.value = -1;
} else {
hoveringIndex.value = 0;
}
};
vue.watch(() => props.options, resetHoveringIndex, {
immediate: true
});
expose({
hoveringIndex,
navigateOptions,
selectHoverOption,
hoverOption
});
return (_ctx, _cache) => {
return vue.openBlock(), vue.createElementBlock("div", {
ref_key: "dropdownRef",
ref: dropdownRef,
class: vue.normalizeClass(vue.unref(ns).b("dropdown"))
}, [
_ctx.$slots.header ? (vue.openBlock(), vue.createElementBlock("div", {
key: 0,
class: vue.normalizeClass(vue.unref(ns).be("dropdown", "header"))
}, [
vue.renderSlot(_ctx.$slots, "header")
], 2)) : vue.createCommentVNode("v-if", true),
vue.withDirectives(vue.createVNode(vue.unref(index$2.ElScrollbar), {
id: _ctx.contentId,
ref_key: "scrollbarRef",
ref: scrollbarRef,
tag: "ul",
"wrap-class": vue.unref(ns).be("dropdown", "wrap"),
"view-class": vue.unref(ns).be("dropdown", "list"),
role: "listbox",
"aria-label": _ctx.ariaLabel,
"aria-orientation": "vertical"
}, {
default: vue.withCtx(() => [
(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.options, (item, index) => {
return vue.openBlock(), vue.createElementBlock("li", {
id: `${_ctx.contentId}-${index}`,
ref_for: true,
ref_key: "optionRefs",
ref: optionRefs,
key: index,
class: vue.normalizeClass(optionkls(item, index)),
role: "option",
"aria-disabled": item.disabled || _ctx.disabled || void 0,
"aria-selected": hoveringIndex.value === index,
onMousemove: ($event) => handleMouseEnter(index),
onClick: vue.withModifiers(($event) => handleSelect(item), ["stop"])
}, [
vue.renderSlot(_ctx.$slots, "label", {
item,
index
}, () => {
var _a;
return [
vue.createElementVNode("span", null, vue.toDisplayString((_a = item.label) != null ? _a : item.value), 1)
];
})
], 42, ["id", "aria-disabled", "aria-selected", "onMousemove", "onClick"]);
}), 128))
]),
_: 3
}, 8, ["id", "wrap-class", "view-class", "aria-label"]), [
[vue.vShow, _ctx.options.length > 0 && !_ctx.loading]
]),
_ctx.loading ? (vue.openBlock(), vue.createElementBlock("div", {
key: 1,
class: vue.normalizeClass(vue.unref(ns).be("dropdown", "loading"))
}, [
vue.renderSlot(_ctx.$slots, "loading", {}, () => [
vue.createTextVNode(vue.toDisplayString(vue.unref(t)("el.mention.loading")), 1)
])
], 2)) : vue.createCommentVNode("v-if", true),
_ctx.$slots.footer ? (vue.openBlock(), vue.createElementBlock("div", {
key: 2,
class: vue.normalizeClass(vue.unref(ns).be("dropdown", "footer"))
}, [
vue.renderSlot(_ctx.$slots, "footer")
], 2)) : vue.createCommentVNode("v-if", true)
], 2);
};
}
});
var ElMentionDropdown = /* @__PURE__ */ pluginVue_exportHelper["default"](_sfc_main, [["__file", "mention-dropdown.vue"]]);
exports["default"] = ElMentionDropdown;
//# sourceMappingURL=mention-dropdown2.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,86 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var helper = require('./helper.js');
var runtime = require('../../../utils/vue/props/runtime.js');
var input = require('../../input/src/input.js');
var shared = require('@vue/shared');
var event = require('../../../constants/event.js');
const mentionProps = runtime.buildProps({
...input.inputProps,
options: {
type: runtime.definePropType(Array),
default: () => []
},
prefix: {
type: runtime.definePropType([String, Array]),
default: "@",
validator: (val) => {
if (shared.isString(val))
return val.length === 1;
return val.every((v) => shared.isString(v) && v.length === 1);
}
},
split: {
type: String,
default: " ",
validator: (val) => val.length === 1
},
filterOption: {
type: runtime.definePropType([Boolean, Function]),
default: () => helper.filterOption,
validator: (val) => {
if (val === false)
return true;
return shared.isFunction(val);
}
},
placement: {
type: runtime.definePropType(String),
default: "bottom"
},
showArrow: Boolean,
offset: {
type: Number,
default: 0
},
whole: Boolean,
checkIsWhole: {
type: runtime.definePropType(Function)
},
modelValue: String,
loading: Boolean,
popperClass: {
type: String,
default: ""
},
popperOptions: {
type: runtime.definePropType(Object),
default: () => ({})
},
props: {
type: runtime.definePropType(Object),
default: () => mentionDefaultProps
}
});
const mentionEmits = {
[event.UPDATE_MODEL_EVENT]: (value) => shared.isString(value),
"whole-remove": (pattern, prefix) => shared.isString(pattern) && shared.isString(prefix),
input: (value) => shared.isString(value),
search: (pattern, prefix) => shared.isString(pattern) && shared.isString(prefix),
select: (option, prefix) => shared.isObject(option) && shared.isString(prefix),
focus: (evt) => evt instanceof FocusEvent,
blur: (evt) => evt instanceof FocusEvent
};
const mentionDefaultProps = {
value: "value",
label: "label",
disabled: "disabled"
};
exports.mentionDefaultProps = mentionDefaultProps;
exports.mentionEmits = mentionEmits;
exports.mentionProps = mentionProps;
//# sourceMappingURL=mention.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,313 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var vue = require('vue');
var lodashUnified = require('lodash-unified');
var index$3 = require('../../input/index.js');
var index$4 = require('../../tooltip/index.js');
var mention = require('./mention.js');
var helper = require('./helper.js');
var mentionDropdown = require('./mention-dropdown2.js');
var pluginVue_exportHelper = require('../../../_virtual/plugin-vue_export-helper.js');
var input = require('../../input/src/input.js');
var index = require('../../../hooks/use-namespace/index.js');
var useFormCommonProps = require('../../form/src/hooks/use-form-common-props.js');
var index$1 = require('../../../hooks/use-id/index.js');
var index$2 = require('../../../hooks/use-focus-controller/index.js');
var event = require('../../../constants/event.js');
var aria = require('../../../constants/aria.js');
var shared = require('@vue/shared');
const __default__ = vue.defineComponent({
name: "ElMention",
inheritAttrs: false
});
const _sfc_main = /* @__PURE__ */ vue.defineComponent({
...__default__,
props: mention.mentionProps,
emits: mention.mentionEmits,
setup(__props, { expose, emit }) {
const props = __props;
const passInputProps = vue.computed(() => lodashUnified.pick(props, Object.keys(input.inputProps)));
const ns = index.useNamespace("mention");
const disabled = useFormCommonProps.useFormDisabled();
const contentId = index$1.useId();
const elInputRef = vue.ref();
const tooltipRef = vue.ref();
const dropdownRef = vue.ref();
const visible = vue.ref(false);
const cursorStyle = vue.ref();
const mentionCtx = vue.ref();
const computedPlacement = vue.computed(() => props.showArrow ? props.placement : `${props.placement}-start`);
const computedFallbackPlacements = vue.computed(() => props.showArrow ? ["bottom", "top"] : ["bottom-start", "top-start"]);
const aliasProps = vue.computed(() => ({
...mention.mentionDefaultProps,
...props.props
}));
const mapOption = (option) => {
const base = {
label: option[aliasProps.value.label],
value: option[aliasProps.value.value],
disabled: option[aliasProps.value.disabled]
};
return { ...option, ...base };
};
const options = vue.computed(() => props.options.map(mapOption));
const filteredOptions = vue.computed(() => {
const { filterOption } = props;
if (!mentionCtx.value || !filterOption)
return options.value;
return options.value.filter((option) => filterOption(mentionCtx.value.pattern, option));
});
const dropdownVisible = vue.computed(() => {
return visible.value && (!!filteredOptions.value.length || props.loading);
});
const hoveringId = vue.computed(() => {
var _a;
return `${contentId.value}-${(_a = dropdownRef.value) == null ? void 0 : _a.hoveringIndex}`;
});
const handleInputChange = (value) => {
emit(event.UPDATE_MODEL_EVENT, value);
emit(event.INPUT_EVENT, value);
syncAfterCursorMove();
};
const handleInputKeyDown = (event$1) => {
var _a, _b, _c, _d;
if (!("code" in event$1) || ((_a = elInputRef.value) == null ? void 0 : _a.isComposing))
return;
switch (event$1.code) {
case aria.EVENT_CODE.left:
case aria.EVENT_CODE.right:
syncAfterCursorMove();
break;
case aria.EVENT_CODE.up:
case aria.EVENT_CODE.down:
if (!visible.value)
return;
event$1.preventDefault();
(_b = dropdownRef.value) == null ? void 0 : _b.navigateOptions(event$1.code === aria.EVENT_CODE.up ? "prev" : "next");
break;
case aria.EVENT_CODE.enter:
case aria.EVENT_CODE.numpadEnter:
if (!visible.value)
return;
event$1.preventDefault();
if ((_c = dropdownRef.value) == null ? void 0 : _c.hoverOption) {
(_d = dropdownRef.value) == null ? void 0 : _d.selectHoverOption();
} else {
visible.value = false;
}
break;
case aria.EVENT_CODE.esc:
if (!visible.value)
return;
event$1.preventDefault();
visible.value = false;
break;
case aria.EVENT_CODE.backspace:
if (props.whole && mentionCtx.value) {
const { splitIndex, selectionEnd, pattern, prefixIndex, prefix } = mentionCtx.value;
const inputEl = getInputEl();
if (!inputEl)
return;
const inputValue = inputEl.value;
const matchOption = options.value.find((item) => item.value === pattern);
const isWhole = shared.isFunction(props.checkIsWhole) ? props.checkIsWhole(pattern, prefix) : matchOption;
if (isWhole && splitIndex !== -1 && splitIndex + 1 === selectionEnd) {
event$1.preventDefault();
const newValue = inputValue.slice(0, prefixIndex) + inputValue.slice(splitIndex + 1);
emit(event.UPDATE_MODEL_EVENT, newValue);
emit(event.INPUT_EVENT, newValue);
emit("whole-remove", pattern, prefix);
const newSelectionEnd = prefixIndex;
vue.nextTick(() => {
inputEl.selectionStart = newSelectionEnd;
inputEl.selectionEnd = newSelectionEnd;
syncDropdownVisible();
});
}
}
}
};
const { wrapperRef } = index$2.useFocusController(elInputRef, {
disabled,
afterFocus() {
syncAfterCursorMove();
},
beforeBlur(event) {
var _a;
return (_a = tooltipRef.value) == null ? void 0 : _a.isFocusInsideContent(event);
},
afterBlur() {
visible.value = false;
}
});
const handleInputMouseDown = () => {
syncAfterCursorMove();
};
const getOriginalOption = (mentionOption) => {
return props.options.find((option) => {
return mentionOption.value === option[aliasProps.value.value];
});
};
const handleSelect = (item) => {
if (!mentionCtx.value)
return;
const inputEl = getInputEl();
if (!inputEl)
return;
const inputValue = inputEl.value;
const { split } = props;
const newEndPart = inputValue.slice(mentionCtx.value.end);
const alreadySeparated = newEndPart.startsWith(split);
const newMiddlePart = `${item.value}${alreadySeparated ? "" : split}`;
const newValue = inputValue.slice(0, mentionCtx.value.start) + newMiddlePart + newEndPart;
emit(event.UPDATE_MODEL_EVENT, newValue);
emit(event.INPUT_EVENT, newValue);
emit("select", getOriginalOption(item), mentionCtx.value.prefix);
const newSelectionEnd = mentionCtx.value.start + newMiddlePart.length + (alreadySeparated ? 1 : 0);
vue.nextTick(() => {
inputEl.selectionStart = newSelectionEnd;
inputEl.selectionEnd = newSelectionEnd;
inputEl.focus();
syncDropdownVisible();
});
};
const getInputEl = () => {
var _a, _b;
return props.type === "textarea" ? (_a = elInputRef.value) == null ? void 0 : _a.textarea : (_b = elInputRef.value) == null ? void 0 : _b.input;
};
const syncAfterCursorMove = () => {
setTimeout(() => {
syncCursor();
syncDropdownVisible();
vue.nextTick(() => {
var _a;
return (_a = tooltipRef.value) == null ? void 0 : _a.updatePopper();
});
}, 0);
};
const syncCursor = () => {
const inputEl = getInputEl();
if (!inputEl)
return;
const caretPosition = helper.getCursorPosition(inputEl);
const inputRect = inputEl.getBoundingClientRect();
const wrapperRect = wrapperRef.value.getBoundingClientRect();
cursorStyle.value = {
position: "absolute",
width: 0,
height: `${caretPosition.height}px`,
left: `${caretPosition.left + inputRect.left - wrapperRect.left}px`,
top: `${caretPosition.top + inputRect.top - wrapperRect.top}px`
};
};
const syncDropdownVisible = () => {
const inputEl = getInputEl();
if (document.activeElement !== inputEl) {
visible.value = false;
return;
}
const { prefix, split } = props;
mentionCtx.value = helper.getMentionCtx(inputEl, prefix, split);
if (mentionCtx.value && mentionCtx.value.splitIndex === -1) {
visible.value = true;
emit("search", mentionCtx.value.pattern, mentionCtx.value.prefix);
return;
}
visible.value = false;
};
expose({
input: elInputRef,
tooltip: tooltipRef,
dropdownVisible
});
return (_ctx, _cache) => {
return vue.openBlock(), vue.createElementBlock("div", {
ref_key: "wrapperRef",
ref: wrapperRef,
class: vue.normalizeClass(vue.unref(ns).b())
}, [
vue.createVNode(vue.unref(index$3.ElInput), vue.mergeProps(vue.mergeProps(vue.unref(passInputProps), _ctx.$attrs), {
ref_key: "elInputRef",
ref: elInputRef,
"model-value": _ctx.modelValue,
disabled: vue.unref(disabled),
role: vue.unref(dropdownVisible) ? "combobox" : void 0,
"aria-activedescendant": vue.unref(dropdownVisible) ? vue.unref(hoveringId) || "" : void 0,
"aria-controls": vue.unref(dropdownVisible) ? vue.unref(contentId) : void 0,
"aria-expanded": vue.unref(dropdownVisible) || void 0,
"aria-label": _ctx.ariaLabel,
"aria-autocomplete": vue.unref(dropdownVisible) ? "none" : void 0,
"aria-haspopup": vue.unref(dropdownVisible) ? "listbox" : void 0,
onInput: handleInputChange,
onKeydown: handleInputKeyDown,
onMousedown: handleInputMouseDown
}), vue.createSlots({
_: 2
}, [
vue.renderList(_ctx.$slots, (_, name) => {
return {
name,
fn: vue.withCtx((slotProps) => [
vue.renderSlot(_ctx.$slots, name, vue.normalizeProps(vue.guardReactiveProps(slotProps)))
])
};
})
]), 1040, ["model-value", "disabled", "role", "aria-activedescendant", "aria-controls", "aria-expanded", "aria-label", "aria-autocomplete", "aria-haspopup"]),
vue.createVNode(vue.unref(index$4.ElTooltip), {
ref_key: "tooltipRef",
ref: tooltipRef,
visible: vue.unref(dropdownVisible),
"popper-class": [vue.unref(ns).e("popper"), _ctx.popperClass],
"popper-options": _ctx.popperOptions,
placement: vue.unref(computedPlacement),
"fallback-placements": vue.unref(computedFallbackPlacements),
effect: "light",
pure: "",
offset: _ctx.offset,
"show-arrow": _ctx.showArrow
}, {
default: vue.withCtx(() => [
vue.createElementVNode("div", {
style: vue.normalizeStyle(cursorStyle.value)
}, null, 4)
]),
content: vue.withCtx(() => {
var _a;
return [
vue.createVNode(mentionDropdown["default"], {
ref_key: "dropdownRef",
ref: dropdownRef,
options: vue.unref(filteredOptions),
disabled: vue.unref(disabled),
loading: _ctx.loading,
"content-id": vue.unref(contentId),
"aria-label": _ctx.ariaLabel,
onSelect: handleSelect,
onClick: vue.withModifiers((_a = elInputRef.value) == null ? void 0 : _a.focus, ["stop"])
}, vue.createSlots({
_: 2
}, [
vue.renderList(_ctx.$slots, (_, name) => {
return {
name,
fn: vue.withCtx((slotProps) => [
vue.renderSlot(_ctx.$slots, name, vue.normalizeProps(vue.guardReactiveProps(slotProps)))
])
};
})
]), 1032, ["options", "disabled", "loading", "content-id", "aria-label", "onClick"])
];
}),
_: 3
}, 8, ["visible", "popper-class", "popper-options", "placement", "fallback-placements", "offset", "show-arrow"])
], 2);
};
}
});
var Mention = /* @__PURE__ */ pluginVue_exportHelper["default"](_sfc_main, [["__file", "mention.vue"]]);
exports["default"] = Mention;
//# sourceMappingURL=mention2.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,15 @@
export type MentionOption = {
value?: string;
label?: string;
disabled?: boolean;
[key: string]: any;
};
export interface MentionCtx {
pattern: string;
start: number;
end: number;
prefix: string;
prefixIndex: number;
splitIndex: number;
selectionEnd: number;
}

View File

@@ -0,0 +1,3 @@
'use strict';
//# sourceMappingURL=types.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"types.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}

View File

@@ -0,0 +1,5 @@
import 'element-plus/es/components/base/style/css';
import 'element-plus/es/components/input/style/css';
import 'element-plus/es/components/tooltip/style/css';
import 'element-plus/es/components/scrollbar/style/css';
import 'element-plus/theme-chalk/el-mention.css';

View File

@@ -0,0 +1,9 @@
'use strict';
require('../../base/style/css.js');
require('../../input/style/css.js');
require('../../tooltip/style/css.js');
require('../../scrollbar/style/css.js');
require('element-plus/theme-chalk/el-mention.css');
//# sourceMappingURL=css.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}

View File

@@ -0,0 +1,5 @@
import 'element-plus/es/components/base/style';
import 'element-plus/es/components/input/style';
import 'element-plus/es/components/tooltip/style';
import 'element-plus/es/components/scrollbar/style';
import 'element-plus/theme-chalk/src/mention.scss';

View File

@@ -0,0 +1,9 @@
'use strict';
require('../../base/style/index.js');
require('../../input/style/index.js');
require('../../tooltip/style/index.js');
require('../../scrollbar/style/index.js');
require('element-plus/theme-chalk/src/mention.scss');
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}