@koi-design/uxd-ui 13.1.9 → 13.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19,6 +19,7 @@ const _sfc_main = defineComponent({
19
19
  styleMap: { default: () => ({}) },
20
20
  config: { default: () => ({}) },
21
21
  resizable: { type: Boolean, default: false },
22
+ optEmptyTip: { default: "" },
22
23
  prefix: { default: "uui" },
23
24
  triggerSign: { default: () => ["@"] },
24
25
  mentionClass: { default: "mention" },
@@ -446,9 +447,10 @@ const _sfc_main = defineComponent({
446
447
  const startY = e.clientY;
447
448
  const startHeight = (_b = (_a = editorWrap.value) == null ? void 0 : _a.offsetHeight) != null ? _b : 100;
448
449
  const handleMouseMove = (moveEvent) => {
450
+ var _a2;
449
451
  const deltaY = moveEvent.clientY - startY;
450
452
  const newHeight = startHeight + deltaY;
451
- const minHeight = 100;
453
+ const minHeight = (_a2 = props.minHeight) != null ? _a2 : 40;
452
454
  resizedHeight.value = Math.max(minHeight, newHeight);
453
455
  };
454
456
  const handleMouseUp = () => {
@@ -492,6 +494,7 @@ const _sfc_main = defineComponent({
492
494
  }, [
493
495
  state.measuring ? (openBlock(), createElementBlock("div", _hoisted_2, [
494
496
  createVNode(MentionsSelect, {
497
+ "empty-tip": _ctx.optEmptyTip,
495
498
  prefix: prefixCls.value,
496
499
  options: options.value,
497
500
  onClose: handleClose
@@ -500,7 +503,7 @@ const _sfc_main = defineComponent({
500
503
  renderSlot(_ctx.$slots, "label", { data })
501
504
  ]),
502
505
  _: 3
503
- }, 8, ["prefix", "options"])
506
+ }, 8, ["empty-tip", "prefix", "options"])
504
507
  ])) : createCommentVNode("v-if", true)
505
508
  ], 2),
506
509
  _ctx.resizable ? (openBlock(), createElementBlock("div", {
@@ -1 +1 @@
1
- {"version":3,"file":"Mention.mjs","sources":["../../../../src/components/Mention/Mention.vue"],"sourcesContent":["<template>\n <div\n ref=\"editorWrap\"\n :class=\"[\n prefixCls,\n {\n disabled\n }\n ]\"\n :style=\"computedStyle\"\n >\n <div\n ref=\"divEditor\"\n :class=\"[`${prefixCls}-editor`]\"\n :contenteditable=\"!disabled\"\n :data-placeholder=\"placeholder\"\n @input=\"handleInput\"\n @keydown=\"handleKeyDown\"\n @keyup=\"handkeKeyUp\"\n @focus=\"onInputFocus\"\n @blur=\"onInputBlur\"\n @compositionstart=\"handleCompositionstart\"\n @compositionend=\"handleCompositionend\"\n @paste=\"onPaste\"\n />\n <div ref=\"popper\" :class=\"`${prefixCls}-popper-wrap`\">\n <div v-if=\"state.measuring\">\n <MentionsSelect :prefix=\"prefixCls\" :options=\"options\" @close=\"handleClose\">\n <template #label=\"{ data }\">\n <slot :data=\"data\" name=\"label\" />\n </template>\n </MentionsSelect>\n </div>\n </div>\n <div\n v-if=\"resizable\"\n class=\"resize-handle\"\n :style=\"{\n backgroundImage: `url('data:image/svg+xml;charset=utf-8,${encodeURIComponent(resizeSvg)}')`\n }\"\n @mousedown=\"startResize\"\n />\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport type { Instance as PopperInstance } from '@popperjs/core';\nimport { createPopper } from '@popperjs/core';\nimport { ref, shallowRef, reactive, onMounted, provide, toRef, nextTick, watch, computed, onBeforeUnmount } from 'vue';\nimport { getCursorPosition, generateGetBoundingClientRect, getOffsetText, deleteContentAfterAtSign, insertMention } from './utils';\nimport KeyCode from './keyCode';\nimport { MentionsContextKey } from './mentionsTypes';\nimport MentionsSelect from './MentionsSelect.vue';\nimport type { MentionProps, MentionState, OptionProps } from './Mentions.type';\n\nconst props = withDefaults(defineProps<MentionProps>(), {\n placeholder: '',\n disabled: false,\n prefix: 'uui',\n triggerSign: () => ['@'],\n mentionClass: 'mention',\n styleMap: () => ({}),\n config: () => ({}),\n transformFn: (item: OptionProps) => item.label,\n resizable: false\n});\n\nconst emit = defineEmits<{\n (e: 'change', value: string): void;\n (e: 'focus', event: FocusEvent): void;\n (e: 'blur', event: FocusEvent): void;\n (e: 'pressenter'): void;\n (e: 'select', option: OptionProps): void;\n (e: 'openDialog', item: any): void;\n (e: 'update:modelValue', value: string): void;\n}>();\n\nconst resizedHeight = ref<number>(100);\n\nconst prefix = computed(() => Object.keys(props.config));\n\nconst resizeSvg = ref<string>(\n '<?xml version=\"1.0\" standalone=\"no\"?><!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"><svg t=\"1733799380257\" class=\"icon\" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" p-id=\"6697\" width=\"16\" height=\"16\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><path d=\"M925.631795 576.639028L580.680138 921.590686c-21.563778 21.563778-21.563778 53.880784 0 75.456025s53.880784 21.552314 75.444561 0l344.963122-344.928729c21.552314-21.552314 21.552314-53.880784 0-75.444562-10.776157-21.563778-53.892248-21.563778-75.456026-0.034392z m86.232183-560.474793c-21.552314-21.552314-53.880784-21.552314-75.456026 0L20.205345 932.366842c-21.552314 21.563778-21.552314 53.880784 0 75.456026s53.880784 21.563778 75.456025 0l916.202608-916.202607c10.776157-21.552314 10.776157-53.892248 0-75.456026z\" fill=\"#CCCCCC\" p-id=\"6698\"></path></svg>'\n);\n\ndefineOptions({\n name: 'UMentions'\n});\n\nconst prefixCls = computed(() => {\n return `${props.prefix}-mention`;\n});\n\nconst divEditor = ref<HTMLDivElement | null>(null);\nconst computedStyle = computed(() => {\n return {\n height: resizedHeight.value ? `${resizedHeight.value}px` : typeof props.height === 'number' ? `${props.height}px` : props.height,\n maxHeight: props.maxHeight,\n minHeight: props.minHeight\n };\n});\n\nconst popper = ref<HTMLElement | null>(null);\nconst isInput = ref(false);\nconst popperIns = shallowRef<PopperInstance | null>(null);\nconst lastRange = shallowRef<Range | null>(null);\nconst composing = shallowRef(false);\nconst options = ref<OptionProps[]>([]);\n\ninterface VirtualElement {\n getBoundingClientRect: () => DOMRect;\n}\n\nconst virtualElement: VirtualElement = {\n getBoundingClientRect: generateGetBoundingClientRect(0, 0)\n};\n\nconst state = reactive<MentionState>({\n value: '',\n measuring: false,\n measureLocation: 0,\n measureText: null,\n measurePrefix: '',\n activeIndex: 0,\n isFocus: false\n});\n\nconst startMeasure = (measureText: string, measurePrefix: string, measureLocation: number) => {\n Object.assign(state, {\n measuring: true,\n measureText,\n measurePrefix,\n measureLocation,\n activeIndex: 0\n });\n};\n\nconst stopMeasure = (callback?: () => void) => {\n Object.assign(state, {\n measuring: false,\n measureLocation: 0,\n measureText: null\n });\n callback?.();\n};\n\nconst triggerChange = (val: string) => {\n emit('change', val);\n};\n\nconst setFocus = () => {\n if (divEditor.value) {\n divEditor.value.focus();\n }\n};\n\nonMounted(() => {\n const popperOptions = toRef(props, 'popperOptions');\n if (popperOptions.value && popper.value) {\n popperIns.value = createPopper(virtualElement as any, popper.value as HTMLElement, popperOptions.value);\n } else {\n popperIns.value = createPopper(virtualElement as any, popper.value as HTMLElement, {\n placement: 'auto',\n strategy: 'fixed'\n });\n }\n});\n\nconst handleCusClick = (item: any) => {\n emit('openDialog', item);\n};\n\nconst handleCompositionstart = () => {\n composing.value = true;\n};\nconst handleInput = () => {\n if (composing.value || props.disabled) {\n return;\n }\n // 检查光标位置和输入情况\n const selection = window.getSelection();\n if (selection && selection.rangeCount > 0) {\n const range = selection.getRangeAt(0);\n const container = range.startContainer;\n\n // 检查是否在 mention span 内\n let mentionSpan: Node | null = container;\n while (mentionSpan && !(mentionSpan as HTMLElement).classList?.contains(props.mentionClass)) {\n mentionSpan = mentionSpan.parentNode;\n }\n\n // 如果在 mention span 内\n if (mentionSpan && (mentionSpan as HTMLElement).classList) {\n // 获取原始的 mention 文本\n const originalText = (mentionSpan as HTMLElement).getAttribute('data-name');\n const currentText = mentionSpan.textContent;\n\n if (currentText !== originalText && originalText !== null) {\n // 找出新输入的文本\n const newText = currentText?.replace(originalText, '') || '';\n\n // 恢复 mention 的原始文本\n mentionSpan.textContent = originalText;\n\n // 建新的文本节点,放在 mention span 的父元素中\n const textNode = document.createTextNode(newText);\n const { parentNode } = mentionSpan;\n // 如果 mention 后面已经有文本节点,就合并内容\n const nextNode = mentionSpan.nextSibling;\n if (nextNode && nextNode.nodeType === Node.TEXT_NODE) {\n nextNode.textContent = newText + (nextNode.textContent || '');\n // 设置光标位置到新文本的开始处\n const newRange = document.createRange();\n newRange.setStart(nextNode, newText.length);\n newRange.collapse(true);\n selection.removeAllRanges();\n selection.addRange(newRange);\n } else {\n // 否则插入新的文本节点\n parentNode.insertBefore(textNode, mentionSpan.nextSibling);\n // 设置光标位置到新文本节点\n const newRange = document.createRange();\n newRange.setStart(textNode, newText.length);\n newRange.collapse(true);\n selection.removeAllRanges();\n selection.addRange(newRange);\n }\n }\n }\n }\n\n const content = divEditor.value?.innerHTML || '';\n triggerChange(content);\n emit('update:modelValue', content);\n};\n\nconst handleCompositionend = () => {\n composing.value = false;\n\n handleInput();\n};\n\nconst selectOption = (option: OptionProps) => {\n const selecttion = window.getSelection();\n if (document.activeElement !== (divEditor.value as unknown as Node)) {\n setFocus();\n\n if (selecttion) {\n selecttion.removeAllRanges();\n selecttion.addRange(lastRange.value);\n }\n }\n\n if (selecttion) {\n const range = selecttion.getRangeAt(0);\n\n deleteContentAfterAtSign(range, state.measurePrefix);\n\n const r = selecttion.getRangeAt(0);\n const { value } = option;\n const text = props.transformFn(option);\n\n // Add zero-width spaces before and after the mention text\n const mentionText = `${text}`;\n\n insertMention(r, mentionText, value, props.mentionClass, props.styleMap[state.measurePrefix]);\n\n handleInput();\n triggerChange(divEditor.value.innerHTML);\n\n composing.value = false;\n stopMeasure();\n }\n};\n\nconst onPaste = (event: ClipboardEvent) => {\n event.preventDefault();\n\n const { clipboardData } = event;\n const selection = window.getSelection();\n\n if (selection && clipboardData) {\n // 清理粘贴内容中的零宽空格(包括 HTML 实体形式)\n const pastedData = clipboardData.getData('text/plain');\n\n const range = selection.getRangeAt(0);\n\n // Remove the selected content before inserting the pasted data\n range.deleteContents();\n\n const currentNode = range.startContainer;\n const { startOffset } = range;\n if (currentNode.nodeType === Node.TEXT_NODE) {\n const currentText = currentNode.textContent;\n const beforeText = currentText.slice(0, startOffset);\n const afterText = currentText.slice(startOffset);\n currentNode.textContent = beforeText + pastedData + afterText;\n const newRange = document.createRange();\n newRange.setStart(currentNode, startOffset + pastedData.length);\n newRange.collapse(true);\n selection.removeAllRanges();\n selection.addRange(newRange);\n } else {\n const textNode = document.createTextNode(pastedData);\n range.insertNode(textNode);\n\n // 设置光标位置到新文本的末尾\n const newRange = document.createRange();\n newRange.setStart(textNode, pastedData.length);\n newRange.collapse(true);\n selection.removeAllRanges();\n selection.addRange(newRange);\n }\n\n handleInput();\n }\n};\n\nconst handkeKeyUp = (event: KeyboardEvent) => {\n const { which } = event;\n\n if ([KeyCode.ESC, KeyCode.UP, KeyCode.DOWN, KeyCode.ENTER].indexOf(which) !== -1) {\n return;\n }\n\n const selection = window.getSelection();\n if (!selection || !selection.rangeCount) return;\n\n const range = selection.getRangeAt(0);\n const { startContainer, startOffset } = range;\n\n // 检查光标前面的字符是否是提及符号\n let beforeText = '';\n if (startContainer.nodeType === Node.TEXT_NODE) {\n beforeText = startContainer.textContent.slice(0, startOffset);\n }\n\n // 如果光标前没有文,检查前一个节点\n if (!beforeText && startOffset === 0) {\n const prevNode = startContainer.previousSibling;\n if (prevNode && prevNode.nodeType === Node.TEXT_NODE) {\n beforeText = prevNode.textContent;\n }\n }\n\n // 检查光标前最后一个字符是否是提及符号\n const lastChar = beforeText.slice(-1);\n const isPrefixChar = prefix.value.includes(lastChar);\n\n if (isPrefixChar) {\n // 获取当前输入框的完整文本\n const innerText = getOffsetText();\n options.value = props.config[lastChar] || [];\n\n // 检查是否在mention span内\n let inMentionSpan = false;\n let currentNode = startContainer;\n while (currentNode && currentNode !== (divEditor.value as unknown as Node)) {\n if ((currentNode as HTMLElement).classList?.contains(props.mentionClass)) {\n inMentionSpan = true;\n break;\n }\n currentNode = currentNode.parentNode;\n }\n\n if (!inMentionSpan) {\n const { x, y } = getCursorPosition();\n virtualElement.getBoundingClientRect = generateGetBoundingClientRect(x, y);\n popperIns.value?.update();\n lastRange.value = range;\n\n // 获取@后面的搜索文本\n const afterText = innerText.slice(beforeText.length);\n const searchText = afterText.split(/[\\s\\n]/)[0] || '';\n\n startMeasure(searchText, lastChar, beforeText.length - 1);\n }\n } else if (state.measuring) {\n // 如果光标前不是提及符号且列表正在显示,则关闭列表\n stopMeasure();\n }\n};\n\nconst handleKeyDown = (event: KeyboardEvent) => {\n const { which } = event;\n\n // 处理回车键\n if (which === KeyCode.ENTER) {\n event.preventDefault();\n const selection = window.getSelection();\n if (selection && selection.rangeCount > 0) {\n const range = selection.getRangeAt(0);\n range.collapse(false);\n const div = document.createElement('div');\n div.innerHTML = '<br>';\n\n // 获取当前节点和其父节点\n const currentNode = range.startContainer;\n const { parentNode } = currentNode;\n\n if ((parentNode as HTMLElement).classList?.contains(props.mentionClass)) {\n // 如果在mention内,将mention后的内容一起移到新行\n const afterContent = parentNode.nextSibling;\n if (afterContent) {\n div.appendChild(afterContent.cloneNode(true));\n afterContent.remove();\n }\n parentNode.parentNode.insertBefore(div, parentNode.nextSibling);\n } else if ((currentNode.previousSibling as HTMLElement)?.classList?.contains(props.mentionClass)) {\n // 如果在mention后,将当前位置后的内容起移到新行\n const afterContent = currentNode.textContent.substring(range.startOffset);\n if (afterContent) {\n div.textContent = afterContent;\n currentNode.textContent = currentNode.textContent.substring(0, range.startOffset);\n }\n currentNode.parentNode.insertBefore(div, currentNode.nextSibling);\n } else {\n // 普通文本节点的处理\n const { startOffset } = range;\n const currentContent = currentNode.textContent || '';\n\n if (startOffset > 0) {\n const beforeText = currentContent.substring(0, startOffset);\n const afterText = currentContent.substring(startOffset);\n\n if (afterText) {\n div.textContent = afterText;\n }\n\n if (currentNode.nodeType === Node.TEXT_NODE) {\n currentNode.textContent = beforeText;\n }\n }\n\n // 找到当前行的父级块级元素\n let blockParent: Node | null = currentNode;\n while (blockParent && blockParent.parentNode !== (divEditor.value as unknown)) {\n blockParent = blockParent.parentNode;\n }\n\n // 插入新行\n if (blockParent) {\n blockParent.parentNode.insertBefore(div, blockParent.nextSibling);\n } else {\n divEditor.value.appendChild(div);\n }\n }\n\n // 将光标移动到新div的开始位置\n const newRange = document.createRange();\n newRange.setStart(div, 0);\n newRange.collapse(true);\n selection.removeAllRanges();\n selection.addRange(newRange);\n\n handleInput();\n }\n return;\n }\n\n if (!state.measuring) {\n // 处理删除键\n if (which === KeyCode.BACKSPACE) {\n const selection = window.getSelection();\n if (selection && selection.rangeCount > 0) {\n const range = selection.getRangeAt(0);\n\n // 检查是否选中了内容\n if (!range.collapsed) {\n event.preventDefault();\n range.deleteContents();\n handleInput();\n } else {\n // 检查当前节点是否在 mention span 内部\n let mentionSpan = range.startContainer;\n while (mentionSpan && !(mentionSpan as HTMLElement).classList?.contains(props.mentionClass)) {\n mentionSpan = mentionSpan.parentNode;\n }\n\n // 如果在 mention span 内部\n if (mentionSpan) {\n event.preventDefault();\n const text = mentionSpan.textContent;\n // 创建新的文本节点,内容是去掉最后一个字符的文本\n const newText = text.slice(0, -1);\n const textNode = document.createTextNode(newText);\n mentionSpan.parentNode.insertBefore(textNode, mentionSpan);\n (mentionSpan as HTMLElement).remove();\n\n // 设置光标位置到新文本的末尾\n const newRange = document.createRange();\n newRange.setStart(textNode, newText.length);\n newRange.collapse(true);\n selection.removeAllRanges();\n selection.addRange(newRange);\n\n handleInput();\n return;\n }\n\n // 处理光标在mention前的删除操作\n const offset = range.startOffset;\n if (offset === 0) {\n const prevNode = range.startContainer.previousSibling;\n if (prevNode && (prevNode as HTMLElement).classList?.contains(props.mentionClass)) {\n event.preventDefault();\n prevNode.remove();\n handleInput();\n }\n }\n }\n }\n }\n return;\n }\n if (which === KeyCode.ESC) {\n stopMeasure();\n }\n};\n\nconst onFocus = (event: FocusEvent) => {\n const { isFocus } = state;\n if (!isFocus && event) {\n emit('focus', event);\n }\n state.isFocus = true;\n};\nconst onBlur = () => {\n const focusTimer = setTimeout(() => {\n state.isFocus = false;\n stopMeasure();\n }, 100);\n clearTimeout(focusTimer);\n};\n\nconst onInputFocus = (event: FocusEvent) => {\n isInput.value = true;\n composing.value = false;\n onFocus(event);\n};\nconst onInputBlur = () => {\n isInput.value = false;\n composing.value = false;\n\n onBlur();\n};\n\nconst setActiveIndex = (activeIndex: number) => {\n state.activeIndex = activeIndex;\n};\n\nprovide(MentionsContextKey, {\n activeIndex: toRef(state, 'activeIndex'),\n setActiveIndex,\n selectOption,\n onFocus,\n onBlur,\n handleCusClick,\n loading: toRef(props, 'loading')\n});\n\nconst initEditor = ({ html }: { html: string }) => {\n nextTick(() => {\n divEditor.value.innerHTML = html;\n });\n};\nonMounted(() => {\n divEditor.value.innerHTML = String(props.modelValue);\n});\nconst handleClose = () => {\n state.measuring = false;\n};\nwatch(\n () => props.modelValue,\n (val) => {\n if (isInput.value) {\n return;\n }\n if (divEditor.value) {\n divEditor.value.innerHTML = String(val);\n }\n }\n);\nonBeforeUnmount(() => {\n if (popperIns.value) {\n popperIns.value.destroy();\n popperIns.value = null;\n }\n});\ndefineExpose({\n selectOption,\n setFocus,\n divEditor,\n initEditor,\n onPaste,\n computedStyle\n});\n\nconst editorWrap = ref<HTMLDivElement | null>(null);\n\nconst startResize = (e: MouseEvent) => {\n e.preventDefault();\n\n const startY = e.clientY;\n const startHeight = editorWrap.value?.offsetHeight ?? 100;\n\n const handleMouseMove = (moveEvent: MouseEvent) => {\n const deltaY = moveEvent.clientY - startY;\n const newHeight = startHeight + deltaY;\n\n // 设置最小高度限制\n const minHeight = 100;\n resizedHeight.value = Math.max(minHeight, newHeight);\n };\n\n const handleMouseUp = () => {\n document.removeEventListener('mousemove', handleMouseMove);\n document.removeEventListener('mouseup', handleMouseUp);\n };\n\n document.addEventListener('mousemove', handleMouseMove);\n document.addEventListener('mouseup', handleMouseUp);\n};\n</script>\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAuDM,QAAQ;UAYR,OAAO;UAUP,gBAAgB,IAAY,GAAG;UAE/B,SAAS,SAAS,MAAM,OAAO,KAAK,MAAM,MAAM,CAAC;UAEjD,YAAY;AAAA,MAChB;AAAA;UAOI,YAAY,SAAS,MAAM;aACxB,GAAG,MAAM;AAAA,KACjB;UAEK,YAAY,IAA2B,IAAI;UAC3C,gBAAgB,SAAS,MAAM;aAC5B;AAAA,QACL,QAAQ,cAAc,QAAQ,GAAG,cAAc,YAAY,OAAO,MAAM,WAAW,WAAW,GAAG,MAAM,aAAa,MAAM;AAAA,QAC1H,WAAW,MAAM;AAAA,QACjB,WAAW,MAAM;AAAA;AACnB,KACD;UAEK,SAAS,IAAwB,IAAI;UACrC,UAAU,IAAI,KAAK;UACnB,YAAY,WAAkC,IAAI;UAClD,YAAY,WAAyB,IAAI;UACzC,YAAY,WAAW,KAAK;UAC5B,UAAU,IAAmB,EAAE;UAM/B,iBAAiC;AAAA,MACrC,uBAAuB,8BAA8B,GAAG,CAAC;AAAA;UAGrD,QAAQ,SAAuB;AAAA,MACnC,OAAO;AAAA,MACP,WAAW;AAAA,MACX,iBAAiB;AAAA,MACjB,aAAa;AAAA,MACb,eAAe;AAAA,MACf,aAAa;AAAA,MACb,SAAS;AAAA,KACV;UAEK,eAAe,CAAC,aAAqB,eAAuB,oBAA4B;aACrF,OAAO,OAAO;AAAA,QACnB,WAAW;AAAA,QACX;AAAA,QACA;AAAA,QACA;AAAA,QACA,aAAa;AAAA,OACd;AAAA;UAGG,cAAc,CAAC,aAA0B;aACtC,OAAO,OAAO;AAAA,QACnB,WAAW;AAAA,QACX,iBAAiB;AAAA,QACjB,aAAa;AAAA,OACd;;;UAIG,gBAAgB,CAAC,QAAgB;WAChC,UAAU,GAAG;AAAA;UAGd,WAAW,MAAM;UACjB,UAAU,OAAO;kBACT,MAAM;AAAM;AACxB;cAGQ,MAAM;YACR,gBAAgB,MAAM,OAAO,eAAe;UAC9C,cAAc,SAAS,OAAO,OAAO;kBAC7B,QAAQ,aAAa,gBAAuB,OAAO,OAAsB,cAAc,KAAK;AAAA,aACjG;kBACK,QAAQ,aAAa,gBAAuB,OAAO,OAAsB;AAAA,UACjF,WAAW;AAAA,UACX,UAAU;AAAA,SACX;AAAA;AACH,KACD;UAEK,iBAAiB,CAAC,SAAc;WAC/B,cAAc,IAAI;AAAA;UAGnB,yBAAyB,MAAM;gBACzB,QAAQ;AAAA;UAEd,cAAc,MAAM;;UACpB,UAAU,SAAS,MAAM,UAAU;;;YAIjC,YAAY,OAAO;UACrB,aAAa,UAAU,aAAa,GAAG;cACnC,QAAQ,UAAU,WAAW,CAAC;cAC9B,YAAY,MAAM;YAGpB,cAA2B;eACxB,eAAe,GAAE,iBAA4B,cAA5B,mBAAuC,SAAS,MAAM,gBAAe;wBAC7E,YAAY;AAAA;YAIxB,eAAgB,YAA4B,WAAW;gBAEnD,eAAgB,YAA4B,aAAa,WAAW;gBACpE,cAAc,YAAY;cAE5B,gBAAgB,gBAAgB,iBAAiB,MAAM;kBAEnD,WAAU,2CAAa,QAAQ,cAAc,QAAO;wBAG9C,cAAc;kBAGpB,WAAW,SAAS,eAAe,OAAO;kBAC1C,EAAE,eAAe;kBAEjB,WAAW,YAAY;gBACzB,YAAY,SAAS,aAAa,KAAK,WAAW;uBAC3C,cAAc,WAAW,SAAS,eAAe;oBAEpD,WAAW,SAAS;uBACjB,SAAS,UAAU,QAAQ,MAAM;uBACjC,SAAS,IAAI;wBACZ;wBACA,SAAS,QAAQ;AAAA,mBACtB;yBAEM,aAAa,UAAU,YAAY,WAAW;oBAEnD,WAAW,SAAS;uBACjB,SAAS,UAAU,QAAQ,MAAM;uBACjC,SAAS,IAAI;wBACZ;wBACA,SAAS,QAAQ;AAAA;AAC7B;AACF;AACF;YAGI,YAAU,eAAU,UAAV,mBAAiB,cAAa;oBAChC,OAAO;WAChB,qBAAqB,OAAO;AAAA;UAG7B,uBAAuB,MAAM;gBACvB,QAAQ;;AAEN;UAGR,eAAe,CAAC,WAAwB;YACtC,aAAa,OAAO;UACtB,SAAS,kBAAmB,UAAU,OAA2B;;YAG/D,YAAY;qBACH;qBACA,SAAS,UAAU,KAAK;AAAA;AACrC;UAGE,YAAY;cACR,QAAQ,WAAW,WAAW,CAAC;iCAEZ,OAAO,MAAM,aAAa;cAE7C,IAAI,WAAW,WAAW,CAAC;cAC3B,EAAE,UAAU;cACZ,OAAO,MAAM,YAAY,MAAM;cAG/B,cAAc,GAAG;sBAET,GAAG,aAAa,OAAO,MAAM,cAAc,MAAM,SAAS,MAAM,cAAc;;sBAG9E,UAAU,MAAM,SAAS;kBAE7B,QAAQ;;AACN;AACd;UAGI,UAAU,CAAC,UAA0B;YACnC;YAEA,EAAE,kBAAkB;YACpB,YAAY,OAAO;UAErB,aAAa,eAAe;cAExB,aAAa,cAAc,QAAQ,YAAY;cAE/C,QAAQ,UAAU,WAAW,CAAC;cAG9B;cAEA,cAAc,MAAM;cACpB,EAAE,gBAAgB;YACpB,YAAY,aAAa,KAAK,WAAW;gBACrC,cAAc,YAAY;gBAC1B,aAAa,YAAY,MAAM,GAAG,WAAW;gBAC7C,YAAY,YAAY,MAAM,WAAW;sBACnC,cAAc,aAAa,aAAa;gBAC9C,WAAW,SAAS;mBACjB,SAAS,aAAa,cAAc,WAAW,MAAM;mBACrD,SAAS,IAAI;oBACZ;oBACA,SAAS,QAAQ;AAAA,eACtB;gBACC,WAAW,SAAS,eAAe,UAAU;gBAC7C,WAAW,QAAQ;gBAGnB,WAAW,SAAS;mBACjB,SAAS,UAAU,WAAW,MAAM;mBACpC,SAAS,IAAI;oBACZ;oBACA,SAAS,QAAQ;AAAA;;AAGjB;AACd;UAGI,cAAc,CAAC,UAAyB;;YACtC,EAAE,UAAU;UAEd,CAAC,QAAQ,KAAK,QAAQ,IAAI,QAAQ,MAAM,QAAQ,KAAK,EAAE,QAAQ,KAAK,MAAM,IAAI;;;YAI5E,YAAY,OAAO;UACrB,CAAC,aAAa,CAAC,UAAU;;YAEvB,QAAQ,UAAU,WAAW,CAAC;YAC9B,EAAE,gBAAgB,gBAAgB;UAGpC,aAAa;UACb,eAAe,aAAa,KAAK,WAAW;qBACjC,eAAe,YAAY,MAAM,GAAG,WAAW;AAAA;UAI1D,CAAC,cAAc,gBAAgB,GAAG;cAC9B,WAAW,eAAe;YAC5B,YAAY,SAAS,aAAa,KAAK,WAAW;uBACvC,SAAS;AAAA;AACxB;YAII,WAAW,WAAW,MAAM,EAAE;YAC9B,eAAe,OAAO,MAAM,SAAS,QAAQ;UAE/C,cAAc;cAEV,YAAY;gBACV,QAAQ,MAAM,OAAO,aAAa;YAGtC,gBAAgB;YAChB,cAAc;eACX,eAAe,gBAAiB,UAAU,OAA2B;eACrE,iBAA4B,cAA5B,mBAAuC,SAAS,MAAM,eAAe;4BACxD;;;wBAGJ,YAAY;AAAA;YAGxB,CAAC,eAAe;gBACZ,EAAE,GAAG,MAAM;yBACF,wBAAwB,8BAA8B,GAAG,CAAC;0BAC/D,6BAAO;oBACP,QAAQ;gBAGZ,YAAY,UAAU,MAAM,WAAW,MAAM;gBAC7C,aAAa,UAAU,MAAM,QAAQ,EAAE,MAAM;uBAEtC,YAAY,UAAU,WAAW,SAAS,CAAC;AAAA;AAC1D,iBACS,MAAM,WAAW;;AAEd;AACd;UAGI,gBAAgB,CAAC,UAAyB;;YACxC,EAAE,UAAU;UAGd,UAAU,QAAQ,OAAO;cACrB;cACA,YAAY,OAAO;YACrB,aAAa,UAAU,aAAa,GAAG;gBACnC,QAAQ,UAAU,WAAW,CAAC;gBAC9B,SAAS,KAAK;gBACd,MAAM,SAAS,cAAc,KAAK;cACpC,YAAY;gBAGV,cAAc,MAAM;gBACpB,EAAE,eAAe;eAElB,gBAA2B,cAA3B,mBAAsC,SAAS,MAAM,eAAe;kBAEjE,eAAe,WAAW;gBAC5B,cAAc;kBACZ,YAAY,aAAa,UAAU,IAAI,CAAC;2BAC/B;AAAO;uBAEX,WAAW,aAAa,KAAK,WAAW,WAAW;AAAA,sBACpD,uBAAY,oBAAZ,mBAA6C,cAA7C,mBAAwD,SAAS,MAAM,eAAe;kBAE1F,eAAe,YAAY,YAAY,UAAU,MAAM,WAAW;gBACpE,cAAc;kBACZ,cAAc;0BACN,cAAc,YAAY,YAAY,UAAU,GAAG,MAAM,WAAW;AAAA;wBAEtE,WAAW,aAAa,KAAK,YAAY,WAAW;AAAA,iBAC3D;kBAEC,EAAE,gBAAgB;kBAClB,iBAAiB,YAAY,eAAe;gBAE9C,cAAc,GAAG;oBACb,aAAa,eAAe,UAAU,GAAG,WAAW;oBACpD,YAAY,eAAe,UAAU,WAAW;kBAElD,WAAW;oBACT,cAAc;AAAA;kBAGhB,YAAY,aAAa,KAAK,WAAW;4BAC/B,cAAc;AAAA;AAC5B;gBAIE,cAA2B;mBACxB,eAAe,YAAY,eAAgB,UAAU,OAAmB;4BAC/D,YAAY;AAAA;gBAIxB,aAAa;0BACH,WAAW,aAAa,KAAK,YAAY,WAAW;AAAA,mBAC3D;wBACK,MAAM,YAAY,GAAG;AAAA;AACjC;gBAII,WAAW,SAAS;mBACjB,SAAS,KAAK,CAAC;mBACf,SAAS,IAAI;oBACZ;oBACA,SAAS,QAAQ;;AAEf;;;UAKZ,CAAC,MAAM,WAAW;YAEhB,UAAU,QAAQ,WAAW;gBACzB,YAAY,OAAO;cACrB,aAAa,UAAU,aAAa,GAAG;kBACnC,QAAQ,UAAU,WAAW,CAAC;gBAGhC,CAAC,MAAM,WAAW;oBACd;oBACA;;AACM,mBACP;kBAED,cAAc,MAAM;qBACjB,eAAe,GAAE,iBAA4B,cAA5B,mBAAuC,SAAS,MAAM,gBAAe;8BAC7E,YAAY;AAAA;kBAIxB,aAAa;sBACT;sBACA,OAAO,YAAY;sBAEnB,UAAU,KAAK,MAAM,GAAG,EAAE;sBAC1B,WAAW,SAAS,eAAe,OAAO;4BACpC,WAAW,aAAa,UAAU,WAAW;AACxD,4BAA4B;sBAGvB,WAAW,SAAS;yBACjB,SAAS,UAAU,QAAQ,MAAM;yBACjC,SAAS,IAAI;0BACZ;0BACA,SAAS,QAAQ;;;;oBAOvB,SAAS,MAAM;kBACjB,WAAW,GAAG;sBACV,WAAW,MAAM,eAAe;oBAClC,cAAa,cAAyB,cAAzB,mBAAoC,SAAS,MAAM,gBAAe;wBAC3E;2BACG;;AACG;AACd;AACF;AACF;AACF;;;UAIA,UAAU,QAAQ,KAAK;;AACb;AACd;UAGI,UAAU,CAAC,UAAsB;YAC/B,EAAE,YAAY;UAChB,CAAC,WAAW,OAAO;aAChB,SAAS,KAAK;AAAA;YAEf,UAAU;AAAA;UAEZ,SAAS,MAAM;YACb,aAAa,WAAW,MAAM;cAC5B,UAAU;;AACJ,SACX,GAAG;mBACO,UAAU;AAAA;UAGnB,eAAe,CAAC,UAAsB;cAClC,QAAQ;gBACN,QAAQ;cACV,KAAK;AAAA;UAET,cAAc,MAAM;cAChB,QAAQ;gBACN,QAAQ;;AAEX;UAGH,iBAAiB,CAAC,gBAAwB;YACxC,cAAc;AAAA;YAGd,oBAAoB;AAAA,MAC1B,aAAa,MAAM,OAAO,aAAa;AAAA,MACvC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS,MAAM,OAAO,SAAS;AAAA,KAChC;UAEK,aAAa,CAAC,EAAE,WAA6B;eACxC,MAAM;kBACH,MAAM,YAAY;AAAA,OAC7B;AAAA;cAEO,MAAM;gBACJ,MAAM,YAAY,OAAO,MAAM,UAAU;AAAA,KACpD;UACK,cAAc,MAAM;YAClB,YAAY;AAAA;;MAGlB,MAAM,MAAM;AAAA,MACZ,CAAC,QAAQ;YACH,QAAQ,OAAO;;;YAGf,UAAU,OAAO;oBACT,MAAM,YAAY,OAAO,GAAG;AAAA;AACxC;AACF;oBAEc,MAAM;UAChB,UAAU,OAAO;kBACT,MAAM;kBACN,QAAQ;AAAA;AACpB,KACD;aACY;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,KACD;UAEK,aAAa,IAA2B,IAAI;UAE5C,cAAc,CAAC,MAAkB;;QACnC;YAEI,SAAS,EAAE;YACX,eAAc,sBAAW,UAAX,mBAAkB,iBAAlB,YAAkC;YAEhD,kBAAkB,CAAC,cAA0B;cAC3C,SAAS,UAAU,UAAU;cAC7B,YAAY,cAAc;cAG1B,YAAY;sBACJ,QAAQ,KAAK,IAAI,WAAW,SAAS;AAAA;YAG/C,gBAAgB,MAAM;iBACjB,oBAAoB,aAAa,eAAe;iBAChD,oBAAoB,WAAW,aAAa;AAAA;eAG9C,iBAAiB,aAAa,eAAe;eAC7C,iBAAiB,WAAW,aAAa;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"Mention.mjs","sources":["../../../../src/components/Mention/Mention.vue"],"sourcesContent":["<template>\n <div\n ref=\"editorWrap\"\n :class=\"[\n prefixCls,\n {\n disabled\n }\n ]\"\n :style=\"computedStyle\"\n >\n <div\n ref=\"divEditor\"\n :class=\"[`${prefixCls}-editor`]\"\n :contenteditable=\"!disabled\"\n :data-placeholder=\"placeholder\"\n @input=\"handleInput\"\n @keydown=\"handleKeyDown\"\n @keyup=\"handkeKeyUp\"\n @focus=\"onInputFocus\"\n @blur=\"onInputBlur\"\n @compositionstart=\"handleCompositionstart\"\n @compositionend=\"handleCompositionend\"\n @paste=\"onPaste\"\n />\n <div ref=\"popper\" :class=\"`${prefixCls}-popper-wrap`\">\n <div v-if=\"state.measuring\">\n <MentionsSelect :empty-tip=\"optEmptyTip\" :prefix=\"prefixCls\" :options=\"options\" @close=\"handleClose\">\n <template #label=\"{ data }\">\n <slot :data=\"data\" name=\"label\" />\n </template>\n </MentionsSelect>\n </div>\n </div>\n <div\n v-if=\"resizable\"\n class=\"resize-handle\"\n :style=\"{\n backgroundImage: `url('data:image/svg+xml;charset=utf-8,${encodeURIComponent(resizeSvg)}')`\n }\"\n @mousedown=\"startResize\"\n />\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport type { Instance as PopperInstance } from '@popperjs/core';\nimport { createPopper } from '@popperjs/core';\nimport { ref, shallowRef, reactive, onMounted, provide, toRef, nextTick, watch, computed, onBeforeUnmount } from 'vue';\nimport { getCursorPosition, generateGetBoundingClientRect, getOffsetText, deleteContentAfterAtSign, insertMention } from './utils';\nimport KeyCode from './keyCode';\nimport { MentionsContextKey } from './mentionsTypes';\nimport MentionsSelect from './MentionsSelect.vue';\nimport type { MentionProps, MentionState, OptionProps } from './Mentions.type';\n\nconst props = withDefaults(defineProps<MentionProps>(), {\n placeholder: '',\n disabled: false,\n prefix: 'uui',\n optEmptyTip: '',\n triggerSign: () => ['@'],\n mentionClass: 'mention',\n styleMap: () => ({}),\n config: () => ({}),\n transformFn: (item: OptionProps) => item.label,\n resizable: false\n});\n\nconst emit = defineEmits<{\n (e: 'change', value: string): void;\n (e: 'focus', event: FocusEvent): void;\n (e: 'blur', event: FocusEvent): void;\n (e: 'pressenter'): void;\n (e: 'select', option: OptionProps): void;\n (e: 'openDialog', item: any): void;\n (e: 'update:modelValue', value: string): void;\n}>();\n\nconst resizedHeight = ref<number>(100);\n\nconst prefix = computed(() => Object.keys(props.config));\n\nconst resizeSvg = ref<string>(\n '<?xml version=\"1.0\" standalone=\"no\"?><!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"><svg t=\"1733799380257\" class=\"icon\" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" p-id=\"6697\" width=\"16\" height=\"16\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><path d=\"M925.631795 576.639028L580.680138 921.590686c-21.563778 21.563778-21.563778 53.880784 0 75.456025s53.880784 21.552314 75.444561 0l344.963122-344.928729c21.552314-21.552314 21.552314-53.880784 0-75.444562-10.776157-21.563778-53.892248-21.563778-75.456026-0.034392z m86.232183-560.474793c-21.552314-21.552314-53.880784-21.552314-75.456026 0L20.205345 932.366842c-21.552314 21.563778-21.552314 53.880784 0 75.456026s53.880784 21.563778 75.456025 0l916.202608-916.202607c10.776157-21.552314 10.776157-53.892248 0-75.456026z\" fill=\"#CCCCCC\" p-id=\"6698\"></path></svg>'\n);\n\ndefineOptions({\n name: 'UMentions'\n});\n\nconst prefixCls = computed(() => {\n return `${props.prefix}-mention`;\n});\n\nconst divEditor = ref<HTMLDivElement | null>(null);\nconst computedStyle = computed(() => {\n return {\n height: resizedHeight.value ? `${resizedHeight.value}px` : typeof props.height === 'number' ? `${props.height}px` : props.height,\n maxHeight: props.maxHeight,\n minHeight: props.minHeight\n };\n});\n\nconst popper = ref<HTMLElement | null>(null);\nconst isInput = ref(false);\nconst popperIns = shallowRef<PopperInstance | null>(null);\nconst lastRange = shallowRef<Range | null>(null);\nconst composing = shallowRef(false);\nconst options = ref<OptionProps[]>([]);\n\ninterface VirtualElement {\n getBoundingClientRect: () => DOMRect;\n}\n\nconst virtualElement: VirtualElement = {\n getBoundingClientRect: generateGetBoundingClientRect(0, 0)\n};\n\nconst state = reactive<MentionState>({\n value: '',\n measuring: false,\n measureLocation: 0,\n measureText: null,\n measurePrefix: '',\n activeIndex: 0,\n isFocus: false\n});\n\nconst startMeasure = (measureText: string, measurePrefix: string, measureLocation: number) => {\n Object.assign(state, {\n measuring: true,\n measureText,\n measurePrefix,\n measureLocation,\n activeIndex: 0\n });\n};\n\nconst stopMeasure = (callback?: () => void) => {\n Object.assign(state, {\n measuring: false,\n measureLocation: 0,\n measureText: null\n });\n callback?.();\n};\n\nconst triggerChange = (val: string) => {\n emit('change', val);\n};\n\nconst setFocus = () => {\n if (divEditor.value) {\n divEditor.value.focus();\n }\n};\n\nonMounted(() => {\n const popperOptions = toRef(props, 'popperOptions');\n if (popperOptions.value && popper.value) {\n popperIns.value = createPopper(virtualElement as any, popper.value as HTMLElement, popperOptions.value);\n } else {\n popperIns.value = createPopper(virtualElement as any, popper.value as HTMLElement, {\n placement: 'auto',\n strategy: 'fixed'\n });\n }\n});\n\nconst handleCusClick = (item: any) => {\n emit('openDialog', item);\n};\n\nconst handleCompositionstart = () => {\n composing.value = true;\n};\nconst handleInput = () => {\n if (composing.value || props.disabled) {\n return;\n }\n const selection = window.getSelection();\n if (selection && selection.rangeCount > 0) {\n const range = selection.getRangeAt(0);\n const container = range.startContainer;\n\n let mentionSpan: Node | null = container;\n while (mentionSpan && !(mentionSpan as HTMLElement).classList?.contains(props.mentionClass)) {\n mentionSpan = mentionSpan.parentNode;\n }\n\n if (mentionSpan && (mentionSpan as HTMLElement).classList) {\n const originalText = (mentionSpan as HTMLElement).getAttribute('data-name');\n const currentText = mentionSpan.textContent;\n\n if (currentText !== originalText && originalText !== null) {\n const newText = currentText?.replace(originalText, '') || '';\n\n mentionSpan.textContent = originalText;\n\n const textNode = document.createTextNode(newText);\n const { parentNode } = mentionSpan;\n const nextNode = mentionSpan.nextSibling;\n if (nextNode && nextNode.nodeType === Node.TEXT_NODE) {\n nextNode.textContent = newText + (nextNode.textContent || '');\n const newRange = document.createRange();\n newRange.setStart(nextNode, newText.length);\n newRange.collapse(true);\n selection.removeAllRanges();\n selection.addRange(newRange);\n } else {\n parentNode.insertBefore(textNode, mentionSpan.nextSibling);\n const newRange = document.createRange();\n newRange.setStart(textNode, newText.length);\n newRange.collapse(true);\n selection.removeAllRanges();\n selection.addRange(newRange);\n }\n }\n }\n }\n\n const content = divEditor.value?.innerHTML || '';\n triggerChange(content);\n emit('update:modelValue', content);\n};\n\nconst handleCompositionend = () => {\n composing.value = false;\n\n handleInput();\n};\n\nconst selectOption = (option: OptionProps) => {\n const selecttion = window.getSelection();\n if (document.activeElement !== (divEditor.value as unknown as Node)) {\n setFocus();\n\n if (selecttion) {\n selecttion.removeAllRanges();\n selecttion.addRange(lastRange.value);\n }\n }\n\n if (selecttion) {\n const range = selecttion.getRangeAt(0);\n\n deleteContentAfterAtSign(range, state.measurePrefix);\n\n const r = selecttion.getRangeAt(0);\n const { value } = option;\n const text = props.transformFn(option);\n\n // Add zero-width spaces before and after the mention text\n const mentionText = `${text}`;\n\n insertMention(r, mentionText, value, props.mentionClass, props.styleMap[state.measurePrefix]);\n\n handleInput();\n triggerChange(divEditor.value.innerHTML);\n\n composing.value = false;\n stopMeasure();\n }\n};\n\nconst onPaste = (event: ClipboardEvent) => {\n event.preventDefault();\n\n const { clipboardData } = event;\n const selection = window.getSelection();\n\n if (selection && clipboardData) {\n const pastedData = clipboardData.getData('text/plain');\n\n const range = selection.getRangeAt(0);\n\n // Remove the selected content before inserting the pasted data\n range.deleteContents();\n\n const currentNode = range.startContainer;\n const { startOffset } = range;\n if (currentNode.nodeType === Node.TEXT_NODE) {\n const currentText = currentNode.textContent;\n const beforeText = currentText.slice(0, startOffset);\n const afterText = currentText.slice(startOffset);\n currentNode.textContent = beforeText + pastedData + afterText;\n const newRange = document.createRange();\n newRange.setStart(currentNode, startOffset + pastedData.length);\n newRange.collapse(true);\n selection.removeAllRanges();\n selection.addRange(newRange);\n } else {\n const textNode = document.createTextNode(pastedData);\n range.insertNode(textNode);\n\n const newRange = document.createRange();\n newRange.setStart(textNode, pastedData.length);\n newRange.collapse(true);\n selection.removeAllRanges();\n selection.addRange(newRange);\n }\n\n handleInput();\n }\n};\n\nconst handkeKeyUp = (event: KeyboardEvent) => {\n const { which } = event;\n\n if ([KeyCode.ESC, KeyCode.UP, KeyCode.DOWN, KeyCode.ENTER].indexOf(which) !== -1) {\n return;\n }\n\n const selection = window.getSelection();\n if (!selection || !selection.rangeCount) return;\n\n const range = selection.getRangeAt(0);\n const { startContainer, startOffset } = range;\n\n let beforeText = '';\n if (startContainer.nodeType === Node.TEXT_NODE) {\n beforeText = startContainer.textContent.slice(0, startOffset);\n }\n\n if (!beforeText && startOffset === 0) {\n const prevNode = startContainer.previousSibling;\n if (prevNode && prevNode.nodeType === Node.TEXT_NODE) {\n beforeText = prevNode.textContent;\n }\n }\n\n const lastChar = beforeText.slice(-1);\n const isPrefixChar = prefix.value.includes(lastChar);\n\n if (isPrefixChar) {\n const innerText = getOffsetText();\n options.value = props.config[lastChar] || [];\n\n let inMentionSpan = false;\n let currentNode = startContainer;\n while (currentNode && currentNode !== (divEditor.value as unknown as Node)) {\n if ((currentNode as HTMLElement).classList?.contains(props.mentionClass)) {\n inMentionSpan = true;\n break;\n }\n currentNode = currentNode.parentNode;\n }\n\n if (!inMentionSpan) {\n const { x, y } = getCursorPosition();\n virtualElement.getBoundingClientRect = generateGetBoundingClientRect(x, y);\n popperIns.value?.update();\n lastRange.value = range;\n\n const afterText = innerText.slice(beforeText.length);\n const searchText = afterText.split(/[\\s\\n]/)[0] || '';\n\n startMeasure(searchText, lastChar, beforeText.length - 1);\n }\n } else if (state.measuring) {\n stopMeasure();\n }\n};\n\nconst handleKeyDown = (event: KeyboardEvent) => {\n const { which } = event;\n\n if (which === KeyCode.ENTER) {\n event.preventDefault();\n const selection = window.getSelection();\n if (selection && selection.rangeCount > 0) {\n const range = selection.getRangeAt(0);\n range.collapse(false);\n const div = document.createElement('div');\n div.innerHTML = '<br>';\n\n const currentNode = range.startContainer;\n const { parentNode } = currentNode;\n\n if ((parentNode as HTMLElement).classList?.contains(props.mentionClass)) {\n const afterContent = parentNode.nextSibling;\n if (afterContent) {\n div.appendChild(afterContent.cloneNode(true));\n afterContent.remove();\n }\n parentNode.parentNode.insertBefore(div, parentNode.nextSibling);\n } else if ((currentNode.previousSibling as HTMLElement)?.classList?.contains(props.mentionClass)) {\n const afterContent = currentNode.textContent.substring(range.startOffset);\n if (afterContent) {\n div.textContent = afterContent;\n currentNode.textContent = currentNode.textContent.substring(0, range.startOffset);\n }\n currentNode.parentNode.insertBefore(div, currentNode.nextSibling);\n } else {\n const { startOffset } = range;\n const currentContent = currentNode.textContent || '';\n\n if (startOffset > 0) {\n const beforeText = currentContent.substring(0, startOffset);\n const afterText = currentContent.substring(startOffset);\n\n if (afterText) {\n div.textContent = afterText;\n }\n\n if (currentNode.nodeType === Node.TEXT_NODE) {\n currentNode.textContent = beforeText;\n }\n }\n\n let blockParent: Node | null = currentNode;\n while (blockParent && blockParent.parentNode !== (divEditor.value as unknown)) {\n blockParent = blockParent.parentNode;\n }\n\n if (blockParent) {\n blockParent.parentNode.insertBefore(div, blockParent.nextSibling);\n } else {\n divEditor.value.appendChild(div);\n }\n }\n\n const newRange = document.createRange();\n newRange.setStart(div, 0);\n newRange.collapse(true);\n selection.removeAllRanges();\n selection.addRange(newRange);\n\n handleInput();\n }\n return;\n }\n\n if (!state.measuring) {\n if (which === KeyCode.BACKSPACE) {\n const selection = window.getSelection();\n if (selection && selection.rangeCount > 0) {\n const range = selection.getRangeAt(0);\n\n if (!range.collapsed) {\n event.preventDefault();\n range.deleteContents();\n handleInput();\n } else {\n let mentionSpan = range.startContainer;\n while (mentionSpan && !(mentionSpan as HTMLElement).classList?.contains(props.mentionClass)) {\n mentionSpan = mentionSpan.parentNode;\n }\n\n if (mentionSpan) {\n event.preventDefault();\n const text = mentionSpan.textContent;\n const newText = text.slice(0, -1);\n const textNode = document.createTextNode(newText);\n mentionSpan.parentNode.insertBefore(textNode, mentionSpan);\n (mentionSpan as HTMLElement).remove();\n\n const newRange = document.createRange();\n newRange.setStart(textNode, newText.length);\n newRange.collapse(true);\n selection.removeAllRanges();\n selection.addRange(newRange);\n\n handleInput();\n return;\n }\n\n const offset = range.startOffset;\n if (offset === 0) {\n const prevNode = range.startContainer.previousSibling;\n if (prevNode && (prevNode as HTMLElement).classList?.contains(props.mentionClass)) {\n event.preventDefault();\n prevNode.remove();\n handleInput();\n }\n }\n }\n }\n }\n return;\n }\n if (which === KeyCode.ESC) {\n stopMeasure();\n }\n};\n\nconst onFocus = (event: FocusEvent) => {\n const { isFocus } = state;\n if (!isFocus && event) {\n emit('focus', event);\n }\n state.isFocus = true;\n};\nconst onBlur = () => {\n const focusTimer = setTimeout(() => {\n state.isFocus = false;\n stopMeasure();\n }, 100);\n clearTimeout(focusTimer);\n};\n\nconst onInputFocus = (event: FocusEvent) => {\n isInput.value = true;\n composing.value = false;\n onFocus(event);\n};\nconst onInputBlur = () => {\n isInput.value = false;\n composing.value = false;\n\n onBlur();\n};\n\nconst setActiveIndex = (activeIndex: number) => {\n state.activeIndex = activeIndex;\n};\n\nprovide(MentionsContextKey, {\n activeIndex: toRef(state, 'activeIndex'),\n setActiveIndex,\n selectOption,\n onFocus,\n onBlur,\n handleCusClick,\n loading: toRef(props, 'loading')\n});\n\nconst initEditor = ({ html }: { html: string }) => {\n nextTick(() => {\n divEditor.value.innerHTML = html;\n });\n};\nonMounted(() => {\n divEditor.value.innerHTML = String(props.modelValue);\n});\nconst handleClose = () => {\n state.measuring = false;\n};\nwatch(\n () => props.modelValue,\n (val) => {\n if (isInput.value) {\n return;\n }\n if (divEditor.value) {\n divEditor.value.innerHTML = String(val);\n }\n }\n);\nonBeforeUnmount(() => {\n if (popperIns.value) {\n popperIns.value.destroy();\n popperIns.value = null;\n }\n});\ndefineExpose({\n selectOption,\n setFocus,\n divEditor,\n initEditor,\n onPaste,\n computedStyle\n});\n\nconst editorWrap = ref<HTMLDivElement | null>(null);\n\nconst startResize = (e: MouseEvent) => {\n e.preventDefault();\n\n const startY = e.clientY;\n const startHeight = editorWrap.value?.offsetHeight ?? 100;\n\n const handleMouseMove = (moveEvent: MouseEvent) => {\n const deltaY = moveEvent.clientY - startY;\n const newHeight = startHeight + deltaY;\n\n const minHeight = (props.minHeight as number) ?? 40;\n resizedHeight.value = Math.max(minHeight, newHeight);\n };\n\n const handleMouseUp = () => {\n document.removeEventListener('mousemove', handleMouseMove);\n document.removeEventListener('mouseup', handleMouseUp);\n };\n\n document.addEventListener('mousemove', handleMouseMove);\n document.addEventListener('mouseup', handleMouseUp);\n};\n</script>\n"],"names":["_a"],"mappings":"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"}
@@ -54,6 +54,7 @@ export interface MentionProps {
54
54
  styleMap?: Record<string, string>;
55
55
  config: Record<string, any>;
56
56
  resizable?: boolean;
57
+ optEmptyTip?: string;
57
58
  prefix?: string;
58
59
  triggerSign?: string[];
59
60
  mentionClass?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"Mentions.type.mjs","sources":["../../../../src/components/Mention/Mentions.type.ts"],"sourcesContent":["import type { InjectionKey, PropType, VNode, Ref } from 'vue';\n\nexport type VNodeChildAtom = VNode | string | number | boolean | null | undefined | void;\nexport type VueNode = VNodeChildAtom | VNodeChildAtom[];\n\nexport function anyType<T = any>(defaultVal?: T, required?: boolean) {\n const type = { validator: () => true, default: defaultVal as T } as unknown;\n return required\n ? (type as {\n type: PropType<T>;\n default: T;\n required: true;\n })\n : (type as {\n default: T;\n type: PropType<T>;\n });\n}\n\nexport function arrayType<T extends any[]>(defaultVal?: T) {\n return { type: Array as unknown as PropType<T>, default: defaultVal as T };\n}\n\nexport function objectType<T = any>(defaultVal?: T) {\n return { type: Object as PropType<T>, default: defaultVal as T };\n}\n\nexport const baseOptionsProps = {\n value: String,\n disabled: Boolean,\n payload: objectType<Record<string, any>>()\n};\n\nexport interface OptionProps {\n label: string;\n value: string;\n [key: string]: any;\n}\n\nexport type EventHandler = (...args: any[]) => void;\n\nexport interface MentionsContext {\n activeIndex: Ref<number>;\n setActiveIndex?: (index: number) => void;\n selectOption?: (option: OptionProps) => void;\n onFocus?: EventListener;\n onBlur?: EventListener;\n loading?: Ref<boolean>;\n handleCusClick?: <T>(item?: T) => void;\n}\n\nexport interface MentionConfig {\n html: string;\n}\n\nexport interface MentionState {\n value: string;\n measuring: boolean;\n measureLocation: number;\n measureText: string | null;\n measurePrefix: string;\n activeIndex: number;\n isFocus: boolean;\n}\n\nexport interface MentionProps {\n placeholder?: string;\n disabled?: boolean;\n styleMap?: Record<string, string>;\n config: Record<string, any>;\n resizable?: boolean;\n prefix?: string;\n triggerSign?: string[];\n mentionClass?: string;\n popperOptions?: any;\n transformFn?: (item: OptionProps) => string;\n modelValue: string | number;\n height?: number | string;\n maxHeight?: number | string;\n minHeight?: number | string;\n loading?: boolean;\n}\n\nexport const MentionsopenDialogValue: InjectionKey<any> = Symbol('MentionsopenDialogValue');\n"],"names":[],"mappings":"SAKgB,QAAiB,YAAgB,UAAoB;AACnE,QAAM,OAAO,EAAE,WAAW,MAAM,MAAM,SAAS;AAC/C,SAAO,WACF,OAKA;AAIP;SAEgB,UAA2B,YAAgB;AACzD,SAAO,EAAE,MAAM,OAAiC,SAAS;AAC3D;SAEgB,WAAoB,YAAgB;AAClD,SAAO,EAAE,MAAM,QAAuB,SAAS;AACjD;MAEa,mBAAmB;AAAA,EAC9B,OAAO;AAAA,EACP,UAAU;AAAA,EACV,SAAS;AACX;MAoDa,0BAA6C,OAAO,yBAAyB;;;;"}
1
+ {"version":3,"file":"Mentions.type.mjs","sources":["../../../../src/components/Mention/Mentions.type.ts"],"sourcesContent":["import type { InjectionKey, PropType, VNode, Ref } from 'vue';\n\nexport type VNodeChildAtom = VNode | string | number | boolean | null | undefined | void;\nexport type VueNode = VNodeChildAtom | VNodeChildAtom[];\n\nexport function anyType<T = any>(defaultVal?: T, required?: boolean) {\n const type = { validator: () => true, default: defaultVal as T } as unknown;\n return required\n ? (type as {\n type: PropType<T>;\n default: T;\n required: true;\n })\n : (type as {\n default: T;\n type: PropType<T>;\n });\n}\n\nexport function arrayType<T extends any[]>(defaultVal?: T) {\n return { type: Array as unknown as PropType<T>, default: defaultVal as T };\n}\n\nexport function objectType<T = any>(defaultVal?: T) {\n return { type: Object as PropType<T>, default: defaultVal as T };\n}\n\nexport const baseOptionsProps = {\n value: String,\n disabled: Boolean,\n payload: objectType<Record<string, any>>()\n};\n\nexport interface OptionProps {\n label: string;\n value: string;\n [key: string]: any;\n}\n\nexport type EventHandler = (...args: any[]) => void;\n\nexport interface MentionsContext {\n activeIndex: Ref<number>;\n setActiveIndex?: (index: number) => void;\n selectOption?: (option: OptionProps) => void;\n onFocus?: EventListener;\n onBlur?: EventListener;\n loading?: Ref<boolean>;\n handleCusClick?: <T>(item?: T) => void;\n}\n\nexport interface MentionConfig {\n html: string;\n}\n\nexport interface MentionState {\n value: string;\n measuring: boolean;\n measureLocation: number;\n measureText: string | null;\n measurePrefix: string;\n activeIndex: number;\n isFocus: boolean;\n}\n\nexport interface MentionProps {\n placeholder?: string;\n disabled?: boolean;\n styleMap?: Record<string, string>;\n config: Record<string, any>;\n resizable?: boolean;\n optEmptyTip?: string;\n prefix?: string;\n triggerSign?: string[];\n mentionClass?: string;\n popperOptions?: any;\n transformFn?: (item: OptionProps) => string;\n modelValue: string | number;\n height?: number | string;\n maxHeight?: number | string;\n minHeight?: number | string;\n loading?: boolean;\n}\n\nexport const MentionsopenDialogValue: InjectionKey<any> = Symbol('MentionsopenDialogValue');\n"],"names":[],"mappings":"SAKgB,QAAiB,YAAgB,UAAoB;AACnE,QAAM,OAAO,EAAE,WAAW,MAAM,MAAM,SAAS;AAC/C,SAAO,WACF,OAKA;AAIP;SAEgB,UAA2B,YAAgB;AACzD,SAAO,EAAE,MAAM,OAAiC,SAAS;AAC3D;SAEgB,WAAoB,YAAgB;AAClD,SAAO,EAAE,MAAM,QAAuB,SAAS;AACjD;MAEa,mBAAmB;AAAA,EAC9B,OAAO;AAAA,EACP,UAAU;AAAA,EACV,SAAS;AACX;MAqDa,0BAA6C,OAAO,yBAAyB;;;;"}
@@ -12,6 +12,10 @@ const _hoisted_2 = {
12
12
  const _sfc_main = {
13
13
  __name: "MentionsSelect",
14
14
  props: {
15
+ emptyTip: {
16
+ type: String,
17
+ default: ""
18
+ },
15
19
  options: {
16
20
  type: Array,
17
21
  default: () => []
@@ -101,7 +105,7 @@ const _sfc_main = {
101
105
  _: 3
102
106
  })
103
107
  ], 2),
104
- showNoData.value ? (openBlock(), createElementBlock("div", _hoisted_2, "\u6682\u65E0\u53EF\u9009\u9879")) : createCommentVNode("v-if", true)
108
+ showNoData.value ? (openBlock(), createElementBlock("div", _hoisted_2, toDisplayString(__props.emptyTip), 1)) : createCommentVNode("v-if", true)
105
109
  ], 2);
106
110
  };
107
111
  }
@@ -1 +1 @@
1
- {"version":3,"file":"MentionsSelect.mjs","sources":["../../../../src/components/Mention/MentionsSelect.vue"],"sourcesContent":["<template>\n <div ref=\"mentionSelect\" :class=\"`${prefix}-select-wrap`\">\n <u-input v-model=\"search\" clearable>\n <template #suffix>\n <u-icon :size=\"14\">\n <ULineSearch />\n </u-icon>\n </template>\n </u-input>\n <div :class=\"`${prefix}-select-content`\">\n <u-scrollbar max-height=\"200px\">\n <div v-for=\"(item, index) in filterOptions\" :key=\"index\">\n <div :class=\"`${prefix}-item`\" @click=\"handleClick(item, index)\">\n <div :class=\"`${prefix}-text`\">\n <slot :data=\"item\" name=\"label\">\n <span>{{ item?.label }}</span>\n </slot>\n </div>\n </div>\n </div>\n </u-scrollbar>\n </div>\n\n <div v-if=\"showNoData\" class=\"no-more-wrap\">暂无可选项</div>\n </div>\n</template>\n\n<script setup>\nimport { shallowRef, inject, computed, nextTick, ref } from 'vue';\nimport { isEmpty } from 'lodash-es';\nimport { MentionsContextKey } from './mentionsTypes';\nimport { setupClickOutside } from './utils';\n\nconst props = defineProps({\n options: {\n type: Array,\n default: () => []\n },\n prefix: {\n type: String,\n default: ''\n }\n});\n\nconst emits = defineEmits(['close']);\nconst { setActiveIndex, selectOption } = inject(MentionsContextKey, {\n activeIndex: shallowRef()\n});\n\nconst showNoData = computed(() => {\n return isEmpty(props.options);\n});\nconst search = ref('');\nconst mentionSelect = ref(null);\n\nconst filterOptions = computed(() => {\n return props.options.filter((item) => {\n return item.label.includes(search.value);\n });\n});\nsetupClickOutside(mentionSelect, () => {\n emits('close');\n});\nconst handleClick = (item, index) => {\n if (setActiveIndex) {\n setActiveIndex(index);\n }\n\n nextTick(() => {\n if (selectOption) {\n selectOption(item);\n }\n });\n};\n</script>\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAiCA,UAAM,QAAQ;AAWd,UAAM,QAAQ;AACd,UAAM,EAAE,gBAAgB,iBAAiB,OAAO,oBAAoB;AAAA,MAClE,aAAa;AAAW,KACzB;AAED,UAAM,aAAa,SAAS,MAAM;AAChC,aAAO,QAAQ,MAAM,OAAO;AAAA,KAC7B;AACD,UAAM,SAAS,IAAI,EAAE;AACrB,UAAM,gBAAgB,IAAI,IAAI;AAE9B,UAAM,gBAAgB,SAAS,MAAM;AACnC,aAAO,MAAM,QAAQ,OAAO,CAAC,SAAS;AACpC,eAAO,KAAK,MAAM,SAAS,OAAO,KAAK;AAAA,OACxC;AAAA,KACF;AACD,sBAAkB,eAAe,MAAM;AACrC,YAAM,OAAO;AAAA,KACd;AACD,UAAM,cAAc,CAAC,MAAM,UAAU;AACnC,UAAI,gBAAgB;AAClB,uBAAe,KAAK;AAAA;AAGtB,eAAS,MAAM;AACb,YAAI,cAAc;AAChB,uBAAa,IAAI;AAAA;AACnB,OACD;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"MentionsSelect.mjs","sources":["../../../../src/components/Mention/MentionsSelect.vue"],"sourcesContent":["<template>\n <div ref=\"mentionSelect\" :class=\"`${prefix}-select-wrap`\">\n <u-input v-model=\"search\" clearable>\n <template #suffix>\n <u-icon :size=\"14\">\n <ULineSearch />\n </u-icon>\n </template>\n </u-input>\n <div :class=\"`${prefix}-select-content`\">\n <u-scrollbar max-height=\"200px\">\n <div v-for=\"(item, index) in filterOptions\" :key=\"index\">\n <div :class=\"`${prefix}-item`\" @click=\"handleClick(item, index)\">\n <div :class=\"`${prefix}-text`\">\n <slot :data=\"item\" name=\"label\">\n <span>{{ item?.label }}</span>\n </slot>\n </div>\n </div>\n </div>\n </u-scrollbar>\n </div>\n <div v-if=\"showNoData\" class=\"no-more-wrap\">{{ emptyTip }}</div>\n </div>\n</template>\n\n<script setup>\nimport { shallowRef, inject, computed, nextTick, ref } from 'vue';\nimport { isEmpty } from 'lodash-es';\nimport { MentionsContextKey } from './mentionsTypes';\nimport { setupClickOutside } from './utils';\n\nconst props = defineProps({\n emptyTip: {\n type: String,\n default: ''\n },\n options: {\n type: Array,\n default: () => []\n },\n prefix: {\n type: String,\n default: ''\n }\n});\n\nconst emits = defineEmits(['close']);\nconst { setActiveIndex, selectOption } = inject(MentionsContextKey, {\n activeIndex: shallowRef()\n});\n\nconst showNoData = computed(() => {\n return isEmpty(props.options);\n});\nconst search = ref('');\nconst mentionSelect = ref(null);\n\nconst filterOptions = computed(() => {\n return props.options.filter((item) => {\n return item.label.includes(search.value);\n });\n});\nsetupClickOutside(mentionSelect, () => {\n emits('close');\n});\nconst handleClick = (item, index) => {\n if (setActiveIndex) {\n setActiveIndex(index);\n }\n\n nextTick(() => {\n if (selectOption) {\n selectOption(item);\n }\n });\n};\n</script>\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,UAAM,QAAQ;AAed,UAAM,QAAQ;AACd,UAAM,EAAE,gBAAgB,iBAAiB,OAAO,oBAAoB;AAAA,MAClE,aAAa;AAAW,KACzB;AAED,UAAM,aAAa,SAAS,MAAM;AAChC,aAAO,QAAQ,MAAM,OAAO;AAAA,KAC7B;AACD,UAAM,SAAS,IAAI,EAAE;AACrB,UAAM,gBAAgB,IAAI,IAAI;AAE9B,UAAM,gBAAgB,SAAS,MAAM;AACnC,aAAO,MAAM,QAAQ,OAAO,CAAC,SAAS;AACpC,eAAO,KAAK,MAAM,SAAS,OAAO,KAAK;AAAA,OACxC;AAAA,KACF;AACD,sBAAkB,eAAe,MAAM;AACrC,YAAM,OAAO;AAAA,KACd;AACD,UAAM,cAAc,CAAC,MAAM,UAAU;AACnC,UAAI,gBAAgB;AAClB,uBAAe,KAAK;AAAA;AAGtB,eAAS,MAAM;AACb,YAAI,cAAc;AAChB,uBAAa,IAAI;AAAA;AACnB,OACD;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -23,6 +23,7 @@ const _sfc_main = vue.defineComponent({
23
23
  styleMap: { default: () => ({}) },
24
24
  config: { default: () => ({}) },
25
25
  resizable: { type: Boolean, default: false },
26
+ optEmptyTip: { default: "" },
26
27
  prefix: { default: "uui" },
27
28
  triggerSign: { default: () => ["@"] },
28
29
  mentionClass: { default: "mention" },
@@ -450,9 +451,10 @@ const _sfc_main = vue.defineComponent({
450
451
  const startY = e.clientY;
451
452
  const startHeight = (_b = (_a = editorWrap.value) == null ? void 0 : _a.offsetHeight) != null ? _b : 100;
452
453
  const handleMouseMove = (moveEvent) => {
454
+ var _a2;
453
455
  const deltaY = moveEvent.clientY - startY;
454
456
  const newHeight = startHeight + deltaY;
455
- const minHeight = 100;
457
+ const minHeight = (_a2 = props.minHeight) != null ? _a2 : 40;
456
458
  resizedHeight.value = Math.max(minHeight, newHeight);
457
459
  };
458
460
  const handleMouseUp = () => {
@@ -496,6 +498,7 @@ const _sfc_main = vue.defineComponent({
496
498
  }, [
497
499
  state.measuring ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2, [
498
500
  vue.createVNode(MentionsSelect["default"], {
501
+ "empty-tip": _ctx.optEmptyTip,
499
502
  prefix: prefixCls.value,
500
503
  options: options.value,
501
504
  onClose: handleClose
@@ -504,7 +507,7 @@ const _sfc_main = vue.defineComponent({
504
507
  vue.renderSlot(_ctx.$slots, "label", { data })
505
508
  ]),
506
509
  _: 3
507
- }, 8, ["prefix", "options"])
510
+ }, 8, ["empty-tip", "prefix", "options"])
508
511
  ])) : vue.createCommentVNode("v-if", true)
509
512
  ], 2),
510
513
  _ctx.resizable ? (vue.openBlock(), vue.createElementBlock("div", {
@@ -1 +1 @@
1
- {"version":3,"file":"Mention.js","sources":["../../../../src/components/Mention/Mention.vue"],"sourcesContent":["<template>\n <div\n ref=\"editorWrap\"\n :class=\"[\n prefixCls,\n {\n disabled\n }\n ]\"\n :style=\"computedStyle\"\n >\n <div\n ref=\"divEditor\"\n :class=\"[`${prefixCls}-editor`]\"\n :contenteditable=\"!disabled\"\n :data-placeholder=\"placeholder\"\n @input=\"handleInput\"\n @keydown=\"handleKeyDown\"\n @keyup=\"handkeKeyUp\"\n @focus=\"onInputFocus\"\n @blur=\"onInputBlur\"\n @compositionstart=\"handleCompositionstart\"\n @compositionend=\"handleCompositionend\"\n @paste=\"onPaste\"\n />\n <div ref=\"popper\" :class=\"`${prefixCls}-popper-wrap`\">\n <div v-if=\"state.measuring\">\n <MentionsSelect :prefix=\"prefixCls\" :options=\"options\" @close=\"handleClose\">\n <template #label=\"{ data }\">\n <slot :data=\"data\" name=\"label\" />\n </template>\n </MentionsSelect>\n </div>\n </div>\n <div\n v-if=\"resizable\"\n class=\"resize-handle\"\n :style=\"{\n backgroundImage: `url('data:image/svg+xml;charset=utf-8,${encodeURIComponent(resizeSvg)}')`\n }\"\n @mousedown=\"startResize\"\n />\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport type { Instance as PopperInstance } from '@popperjs/core';\nimport { createPopper } from '@popperjs/core';\nimport { ref, shallowRef, reactive, onMounted, provide, toRef, nextTick, watch, computed, onBeforeUnmount } from 'vue';\nimport { getCursorPosition, generateGetBoundingClientRect, getOffsetText, deleteContentAfterAtSign, insertMention } from './utils';\nimport KeyCode from './keyCode';\nimport { MentionsContextKey } from './mentionsTypes';\nimport MentionsSelect from './MentionsSelect.vue';\nimport type { MentionProps, MentionState, OptionProps } from './Mentions.type';\n\nconst props = withDefaults(defineProps<MentionProps>(), {\n placeholder: '',\n disabled: false,\n prefix: 'uui',\n triggerSign: () => ['@'],\n mentionClass: 'mention',\n styleMap: () => ({}),\n config: () => ({}),\n transformFn: (item: OptionProps) => item.label,\n resizable: false\n});\n\nconst emit = defineEmits<{\n (e: 'change', value: string): void;\n (e: 'focus', event: FocusEvent): void;\n (e: 'blur', event: FocusEvent): void;\n (e: 'pressenter'): void;\n (e: 'select', option: OptionProps): void;\n (e: 'openDialog', item: any): void;\n (e: 'update:modelValue', value: string): void;\n}>();\n\nconst resizedHeight = ref<number>(100);\n\nconst prefix = computed(() => Object.keys(props.config));\n\nconst resizeSvg = ref<string>(\n '<?xml version=\"1.0\" standalone=\"no\"?><!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"><svg t=\"1733799380257\" class=\"icon\" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" p-id=\"6697\" width=\"16\" height=\"16\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><path d=\"M925.631795 576.639028L580.680138 921.590686c-21.563778 21.563778-21.563778 53.880784 0 75.456025s53.880784 21.552314 75.444561 0l344.963122-344.928729c21.552314-21.552314 21.552314-53.880784 0-75.444562-10.776157-21.563778-53.892248-21.563778-75.456026-0.034392z m86.232183-560.474793c-21.552314-21.552314-53.880784-21.552314-75.456026 0L20.205345 932.366842c-21.552314 21.563778-21.552314 53.880784 0 75.456026s53.880784 21.563778 75.456025 0l916.202608-916.202607c10.776157-21.552314 10.776157-53.892248 0-75.456026z\" fill=\"#CCCCCC\" p-id=\"6698\"></path></svg>'\n);\n\ndefineOptions({\n name: 'UMentions'\n});\n\nconst prefixCls = computed(() => {\n return `${props.prefix}-mention`;\n});\n\nconst divEditor = ref<HTMLDivElement | null>(null);\nconst computedStyle = computed(() => {\n return {\n height: resizedHeight.value ? `${resizedHeight.value}px` : typeof props.height === 'number' ? `${props.height}px` : props.height,\n maxHeight: props.maxHeight,\n minHeight: props.minHeight\n };\n});\n\nconst popper = ref<HTMLElement | null>(null);\nconst isInput = ref(false);\nconst popperIns = shallowRef<PopperInstance | null>(null);\nconst lastRange = shallowRef<Range | null>(null);\nconst composing = shallowRef(false);\nconst options = ref<OptionProps[]>([]);\n\ninterface VirtualElement {\n getBoundingClientRect: () => DOMRect;\n}\n\nconst virtualElement: VirtualElement = {\n getBoundingClientRect: generateGetBoundingClientRect(0, 0)\n};\n\nconst state = reactive<MentionState>({\n value: '',\n measuring: false,\n measureLocation: 0,\n measureText: null,\n measurePrefix: '',\n activeIndex: 0,\n isFocus: false\n});\n\nconst startMeasure = (measureText: string, measurePrefix: string, measureLocation: number) => {\n Object.assign(state, {\n measuring: true,\n measureText,\n measurePrefix,\n measureLocation,\n activeIndex: 0\n });\n};\n\nconst stopMeasure = (callback?: () => void) => {\n Object.assign(state, {\n measuring: false,\n measureLocation: 0,\n measureText: null\n });\n callback?.();\n};\n\nconst triggerChange = (val: string) => {\n emit('change', val);\n};\n\nconst setFocus = () => {\n if (divEditor.value) {\n divEditor.value.focus();\n }\n};\n\nonMounted(() => {\n const popperOptions = toRef(props, 'popperOptions');\n if (popperOptions.value && popper.value) {\n popperIns.value = createPopper(virtualElement as any, popper.value as HTMLElement, popperOptions.value);\n } else {\n popperIns.value = createPopper(virtualElement as any, popper.value as HTMLElement, {\n placement: 'auto',\n strategy: 'fixed'\n });\n }\n});\n\nconst handleCusClick = (item: any) => {\n emit('openDialog', item);\n};\n\nconst handleCompositionstart = () => {\n composing.value = true;\n};\nconst handleInput = () => {\n if (composing.value || props.disabled) {\n return;\n }\n // 检查光标位置和输入情况\n const selection = window.getSelection();\n if (selection && selection.rangeCount > 0) {\n const range = selection.getRangeAt(0);\n const container = range.startContainer;\n\n // 检查是否在 mention span 内\n let mentionSpan: Node | null = container;\n while (mentionSpan && !(mentionSpan as HTMLElement).classList?.contains(props.mentionClass)) {\n mentionSpan = mentionSpan.parentNode;\n }\n\n // 如果在 mention span 内\n if (mentionSpan && (mentionSpan as HTMLElement).classList) {\n // 获取原始的 mention 文本\n const originalText = (mentionSpan as HTMLElement).getAttribute('data-name');\n const currentText = mentionSpan.textContent;\n\n if (currentText !== originalText && originalText !== null) {\n // 找出新输入的文本\n const newText = currentText?.replace(originalText, '') || '';\n\n // 恢复 mention 的原始文本\n mentionSpan.textContent = originalText;\n\n // 建新的文本节点,放在 mention span 的父元素中\n const textNode = document.createTextNode(newText);\n const { parentNode } = mentionSpan;\n // 如果 mention 后面已经有文本节点,就合并内容\n const nextNode = mentionSpan.nextSibling;\n if (nextNode && nextNode.nodeType === Node.TEXT_NODE) {\n nextNode.textContent = newText + (nextNode.textContent || '');\n // 设置光标位置到新文本的开始处\n const newRange = document.createRange();\n newRange.setStart(nextNode, newText.length);\n newRange.collapse(true);\n selection.removeAllRanges();\n selection.addRange(newRange);\n } else {\n // 否则插入新的文本节点\n parentNode.insertBefore(textNode, mentionSpan.nextSibling);\n // 设置光标位置到新文本节点\n const newRange = document.createRange();\n newRange.setStart(textNode, newText.length);\n newRange.collapse(true);\n selection.removeAllRanges();\n selection.addRange(newRange);\n }\n }\n }\n }\n\n const content = divEditor.value?.innerHTML || '';\n triggerChange(content);\n emit('update:modelValue', content);\n};\n\nconst handleCompositionend = () => {\n composing.value = false;\n\n handleInput();\n};\n\nconst selectOption = (option: OptionProps) => {\n const selecttion = window.getSelection();\n if (document.activeElement !== (divEditor.value as unknown as Node)) {\n setFocus();\n\n if (selecttion) {\n selecttion.removeAllRanges();\n selecttion.addRange(lastRange.value);\n }\n }\n\n if (selecttion) {\n const range = selecttion.getRangeAt(0);\n\n deleteContentAfterAtSign(range, state.measurePrefix);\n\n const r = selecttion.getRangeAt(0);\n const { value } = option;\n const text = props.transformFn(option);\n\n // Add zero-width spaces before and after the mention text\n const mentionText = `${text}`;\n\n insertMention(r, mentionText, value, props.mentionClass, props.styleMap[state.measurePrefix]);\n\n handleInput();\n triggerChange(divEditor.value.innerHTML);\n\n composing.value = false;\n stopMeasure();\n }\n};\n\nconst onPaste = (event: ClipboardEvent) => {\n event.preventDefault();\n\n const { clipboardData } = event;\n const selection = window.getSelection();\n\n if (selection && clipboardData) {\n // 清理粘贴内容中的零宽空格(包括 HTML 实体形式)\n const pastedData = clipboardData.getData('text/plain');\n\n const range = selection.getRangeAt(0);\n\n // Remove the selected content before inserting the pasted data\n range.deleteContents();\n\n const currentNode = range.startContainer;\n const { startOffset } = range;\n if (currentNode.nodeType === Node.TEXT_NODE) {\n const currentText = currentNode.textContent;\n const beforeText = currentText.slice(0, startOffset);\n const afterText = currentText.slice(startOffset);\n currentNode.textContent = beforeText + pastedData + afterText;\n const newRange = document.createRange();\n newRange.setStart(currentNode, startOffset + pastedData.length);\n newRange.collapse(true);\n selection.removeAllRanges();\n selection.addRange(newRange);\n } else {\n const textNode = document.createTextNode(pastedData);\n range.insertNode(textNode);\n\n // 设置光标位置到新文本的末尾\n const newRange = document.createRange();\n newRange.setStart(textNode, pastedData.length);\n newRange.collapse(true);\n selection.removeAllRanges();\n selection.addRange(newRange);\n }\n\n handleInput();\n }\n};\n\nconst handkeKeyUp = (event: KeyboardEvent) => {\n const { which } = event;\n\n if ([KeyCode.ESC, KeyCode.UP, KeyCode.DOWN, KeyCode.ENTER].indexOf(which) !== -1) {\n return;\n }\n\n const selection = window.getSelection();\n if (!selection || !selection.rangeCount) return;\n\n const range = selection.getRangeAt(0);\n const { startContainer, startOffset } = range;\n\n // 检查光标前面的字符是否是提及符号\n let beforeText = '';\n if (startContainer.nodeType === Node.TEXT_NODE) {\n beforeText = startContainer.textContent.slice(0, startOffset);\n }\n\n // 如果光标前没有文,检查前一个节点\n if (!beforeText && startOffset === 0) {\n const prevNode = startContainer.previousSibling;\n if (prevNode && prevNode.nodeType === Node.TEXT_NODE) {\n beforeText = prevNode.textContent;\n }\n }\n\n // 检查光标前最后一个字符是否是提及符号\n const lastChar = beforeText.slice(-1);\n const isPrefixChar = prefix.value.includes(lastChar);\n\n if (isPrefixChar) {\n // 获取当前输入框的完整文本\n const innerText = getOffsetText();\n options.value = props.config[lastChar] || [];\n\n // 检查是否在mention span内\n let inMentionSpan = false;\n let currentNode = startContainer;\n while (currentNode && currentNode !== (divEditor.value as unknown as Node)) {\n if ((currentNode as HTMLElement).classList?.contains(props.mentionClass)) {\n inMentionSpan = true;\n break;\n }\n currentNode = currentNode.parentNode;\n }\n\n if (!inMentionSpan) {\n const { x, y } = getCursorPosition();\n virtualElement.getBoundingClientRect = generateGetBoundingClientRect(x, y);\n popperIns.value?.update();\n lastRange.value = range;\n\n // 获取@后面的搜索文本\n const afterText = innerText.slice(beforeText.length);\n const searchText = afterText.split(/[\\s\\n]/)[0] || '';\n\n startMeasure(searchText, lastChar, beforeText.length - 1);\n }\n } else if (state.measuring) {\n // 如果光标前不是提及符号且列表正在显示,则关闭列表\n stopMeasure();\n }\n};\n\nconst handleKeyDown = (event: KeyboardEvent) => {\n const { which } = event;\n\n // 处理回车键\n if (which === KeyCode.ENTER) {\n event.preventDefault();\n const selection = window.getSelection();\n if (selection && selection.rangeCount > 0) {\n const range = selection.getRangeAt(0);\n range.collapse(false);\n const div = document.createElement('div');\n div.innerHTML = '<br>';\n\n // 获取当前节点和其父节点\n const currentNode = range.startContainer;\n const { parentNode } = currentNode;\n\n if ((parentNode as HTMLElement).classList?.contains(props.mentionClass)) {\n // 如果在mention内,将mention后的内容一起移到新行\n const afterContent = parentNode.nextSibling;\n if (afterContent) {\n div.appendChild(afterContent.cloneNode(true));\n afterContent.remove();\n }\n parentNode.parentNode.insertBefore(div, parentNode.nextSibling);\n } else if ((currentNode.previousSibling as HTMLElement)?.classList?.contains(props.mentionClass)) {\n // 如果在mention后,将当前位置后的内容起移到新行\n const afterContent = currentNode.textContent.substring(range.startOffset);\n if (afterContent) {\n div.textContent = afterContent;\n currentNode.textContent = currentNode.textContent.substring(0, range.startOffset);\n }\n currentNode.parentNode.insertBefore(div, currentNode.nextSibling);\n } else {\n // 普通文本节点的处理\n const { startOffset } = range;\n const currentContent = currentNode.textContent || '';\n\n if (startOffset > 0) {\n const beforeText = currentContent.substring(0, startOffset);\n const afterText = currentContent.substring(startOffset);\n\n if (afterText) {\n div.textContent = afterText;\n }\n\n if (currentNode.nodeType === Node.TEXT_NODE) {\n currentNode.textContent = beforeText;\n }\n }\n\n // 找到当前行的父级块级元素\n let blockParent: Node | null = currentNode;\n while (blockParent && blockParent.parentNode !== (divEditor.value as unknown)) {\n blockParent = blockParent.parentNode;\n }\n\n // 插入新行\n if (blockParent) {\n blockParent.parentNode.insertBefore(div, blockParent.nextSibling);\n } else {\n divEditor.value.appendChild(div);\n }\n }\n\n // 将光标移动到新div的开始位置\n const newRange = document.createRange();\n newRange.setStart(div, 0);\n newRange.collapse(true);\n selection.removeAllRanges();\n selection.addRange(newRange);\n\n handleInput();\n }\n return;\n }\n\n if (!state.measuring) {\n // 处理删除键\n if (which === KeyCode.BACKSPACE) {\n const selection = window.getSelection();\n if (selection && selection.rangeCount > 0) {\n const range = selection.getRangeAt(0);\n\n // 检查是否选中了内容\n if (!range.collapsed) {\n event.preventDefault();\n range.deleteContents();\n handleInput();\n } else {\n // 检查当前节点是否在 mention span 内部\n let mentionSpan = range.startContainer;\n while (mentionSpan && !(mentionSpan as HTMLElement).classList?.contains(props.mentionClass)) {\n mentionSpan = mentionSpan.parentNode;\n }\n\n // 如果在 mention span 内部\n if (mentionSpan) {\n event.preventDefault();\n const text = mentionSpan.textContent;\n // 创建新的文本节点,内容是去掉最后一个字符的文本\n const newText = text.slice(0, -1);\n const textNode = document.createTextNode(newText);\n mentionSpan.parentNode.insertBefore(textNode, mentionSpan);\n (mentionSpan as HTMLElement).remove();\n\n // 设置光标位置到新文本的末尾\n const newRange = document.createRange();\n newRange.setStart(textNode, newText.length);\n newRange.collapse(true);\n selection.removeAllRanges();\n selection.addRange(newRange);\n\n handleInput();\n return;\n }\n\n // 处理光标在mention前的删除操作\n const offset = range.startOffset;\n if (offset === 0) {\n const prevNode = range.startContainer.previousSibling;\n if (prevNode && (prevNode as HTMLElement).classList?.contains(props.mentionClass)) {\n event.preventDefault();\n prevNode.remove();\n handleInput();\n }\n }\n }\n }\n }\n return;\n }\n if (which === KeyCode.ESC) {\n stopMeasure();\n }\n};\n\nconst onFocus = (event: FocusEvent) => {\n const { isFocus } = state;\n if (!isFocus && event) {\n emit('focus', event);\n }\n state.isFocus = true;\n};\nconst onBlur = () => {\n const focusTimer = setTimeout(() => {\n state.isFocus = false;\n stopMeasure();\n }, 100);\n clearTimeout(focusTimer);\n};\n\nconst onInputFocus = (event: FocusEvent) => {\n isInput.value = true;\n composing.value = false;\n onFocus(event);\n};\nconst onInputBlur = () => {\n isInput.value = false;\n composing.value = false;\n\n onBlur();\n};\n\nconst setActiveIndex = (activeIndex: number) => {\n state.activeIndex = activeIndex;\n};\n\nprovide(MentionsContextKey, {\n activeIndex: toRef(state, 'activeIndex'),\n setActiveIndex,\n selectOption,\n onFocus,\n onBlur,\n handleCusClick,\n loading: toRef(props, 'loading')\n});\n\nconst initEditor = ({ html }: { html: string }) => {\n nextTick(() => {\n divEditor.value.innerHTML = html;\n });\n};\nonMounted(() => {\n divEditor.value.innerHTML = String(props.modelValue);\n});\nconst handleClose = () => {\n state.measuring = false;\n};\nwatch(\n () => props.modelValue,\n (val) => {\n if (isInput.value) {\n return;\n }\n if (divEditor.value) {\n divEditor.value.innerHTML = String(val);\n }\n }\n);\nonBeforeUnmount(() => {\n if (popperIns.value) {\n popperIns.value.destroy();\n popperIns.value = null;\n }\n});\ndefineExpose({\n selectOption,\n setFocus,\n divEditor,\n initEditor,\n onPaste,\n computedStyle\n});\n\nconst editorWrap = ref<HTMLDivElement | null>(null);\n\nconst startResize = (e: MouseEvent) => {\n e.preventDefault();\n\n const startY = e.clientY;\n const startHeight = editorWrap.value?.offsetHeight ?? 100;\n\n const handleMouseMove = (moveEvent: MouseEvent) => {\n const deltaY = moveEvent.clientY - startY;\n const newHeight = startHeight + deltaY;\n\n // 设置最小高度限制\n const minHeight = 100;\n resizedHeight.value = Math.max(minHeight, newHeight);\n };\n\n const handleMouseUp = () => {\n document.removeEventListener('mousemove', handleMouseMove);\n document.removeEventListener('mouseup', handleMouseUp);\n };\n\n document.addEventListener('mousemove', handleMouseMove);\n document.addEventListener('mouseup', handleMouseUp);\n};\n</script>\n"],"names":["ref","computed","shallowRef","generateGetBoundingClientRect","reactive","toRef","createPopper","KeyCode","getOffsetText","getCursorPosition","MentionsContextKey"],"mappings":"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"}
1
+ {"version":3,"file":"Mention.js","sources":["../../../../src/components/Mention/Mention.vue"],"sourcesContent":["<template>\n <div\n ref=\"editorWrap\"\n :class=\"[\n prefixCls,\n {\n disabled\n }\n ]\"\n :style=\"computedStyle\"\n >\n <div\n ref=\"divEditor\"\n :class=\"[`${prefixCls}-editor`]\"\n :contenteditable=\"!disabled\"\n :data-placeholder=\"placeholder\"\n @input=\"handleInput\"\n @keydown=\"handleKeyDown\"\n @keyup=\"handkeKeyUp\"\n @focus=\"onInputFocus\"\n @blur=\"onInputBlur\"\n @compositionstart=\"handleCompositionstart\"\n @compositionend=\"handleCompositionend\"\n @paste=\"onPaste\"\n />\n <div ref=\"popper\" :class=\"`${prefixCls}-popper-wrap`\">\n <div v-if=\"state.measuring\">\n <MentionsSelect :empty-tip=\"optEmptyTip\" :prefix=\"prefixCls\" :options=\"options\" @close=\"handleClose\">\n <template #label=\"{ data }\">\n <slot :data=\"data\" name=\"label\" />\n </template>\n </MentionsSelect>\n </div>\n </div>\n <div\n v-if=\"resizable\"\n class=\"resize-handle\"\n :style=\"{\n backgroundImage: `url('data:image/svg+xml;charset=utf-8,${encodeURIComponent(resizeSvg)}')`\n }\"\n @mousedown=\"startResize\"\n />\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport type { Instance as PopperInstance } from '@popperjs/core';\nimport { createPopper } from '@popperjs/core';\nimport { ref, shallowRef, reactive, onMounted, provide, toRef, nextTick, watch, computed, onBeforeUnmount } from 'vue';\nimport { getCursorPosition, generateGetBoundingClientRect, getOffsetText, deleteContentAfterAtSign, insertMention } from './utils';\nimport KeyCode from './keyCode';\nimport { MentionsContextKey } from './mentionsTypes';\nimport MentionsSelect from './MentionsSelect.vue';\nimport type { MentionProps, MentionState, OptionProps } from './Mentions.type';\n\nconst props = withDefaults(defineProps<MentionProps>(), {\n placeholder: '',\n disabled: false,\n prefix: 'uui',\n optEmptyTip: '',\n triggerSign: () => ['@'],\n mentionClass: 'mention',\n styleMap: () => ({}),\n config: () => ({}),\n transformFn: (item: OptionProps) => item.label,\n resizable: false\n});\n\nconst emit = defineEmits<{\n (e: 'change', value: string): void;\n (e: 'focus', event: FocusEvent): void;\n (e: 'blur', event: FocusEvent): void;\n (e: 'pressenter'): void;\n (e: 'select', option: OptionProps): void;\n (e: 'openDialog', item: any): void;\n (e: 'update:modelValue', value: string): void;\n}>();\n\nconst resizedHeight = ref<number>(100);\n\nconst prefix = computed(() => Object.keys(props.config));\n\nconst resizeSvg = ref<string>(\n '<?xml version=\"1.0\" standalone=\"no\"?><!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"><svg t=\"1733799380257\" class=\"icon\" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" p-id=\"6697\" width=\"16\" height=\"16\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><path d=\"M925.631795 576.639028L580.680138 921.590686c-21.563778 21.563778-21.563778 53.880784 0 75.456025s53.880784 21.552314 75.444561 0l344.963122-344.928729c21.552314-21.552314 21.552314-53.880784 0-75.444562-10.776157-21.563778-53.892248-21.563778-75.456026-0.034392z m86.232183-560.474793c-21.552314-21.552314-53.880784-21.552314-75.456026 0L20.205345 932.366842c-21.552314 21.563778-21.552314 53.880784 0 75.456026s53.880784 21.563778 75.456025 0l916.202608-916.202607c10.776157-21.552314 10.776157-53.892248 0-75.456026z\" fill=\"#CCCCCC\" p-id=\"6698\"></path></svg>'\n);\n\ndefineOptions({\n name: 'UMentions'\n});\n\nconst prefixCls = computed(() => {\n return `${props.prefix}-mention`;\n});\n\nconst divEditor = ref<HTMLDivElement | null>(null);\nconst computedStyle = computed(() => {\n return {\n height: resizedHeight.value ? `${resizedHeight.value}px` : typeof props.height === 'number' ? `${props.height}px` : props.height,\n maxHeight: props.maxHeight,\n minHeight: props.minHeight\n };\n});\n\nconst popper = ref<HTMLElement | null>(null);\nconst isInput = ref(false);\nconst popperIns = shallowRef<PopperInstance | null>(null);\nconst lastRange = shallowRef<Range | null>(null);\nconst composing = shallowRef(false);\nconst options = ref<OptionProps[]>([]);\n\ninterface VirtualElement {\n getBoundingClientRect: () => DOMRect;\n}\n\nconst virtualElement: VirtualElement = {\n getBoundingClientRect: generateGetBoundingClientRect(0, 0)\n};\n\nconst state = reactive<MentionState>({\n value: '',\n measuring: false,\n measureLocation: 0,\n measureText: null,\n measurePrefix: '',\n activeIndex: 0,\n isFocus: false\n});\n\nconst startMeasure = (measureText: string, measurePrefix: string, measureLocation: number) => {\n Object.assign(state, {\n measuring: true,\n measureText,\n measurePrefix,\n measureLocation,\n activeIndex: 0\n });\n};\n\nconst stopMeasure = (callback?: () => void) => {\n Object.assign(state, {\n measuring: false,\n measureLocation: 0,\n measureText: null\n });\n callback?.();\n};\n\nconst triggerChange = (val: string) => {\n emit('change', val);\n};\n\nconst setFocus = () => {\n if (divEditor.value) {\n divEditor.value.focus();\n }\n};\n\nonMounted(() => {\n const popperOptions = toRef(props, 'popperOptions');\n if (popperOptions.value && popper.value) {\n popperIns.value = createPopper(virtualElement as any, popper.value as HTMLElement, popperOptions.value);\n } else {\n popperIns.value = createPopper(virtualElement as any, popper.value as HTMLElement, {\n placement: 'auto',\n strategy: 'fixed'\n });\n }\n});\n\nconst handleCusClick = (item: any) => {\n emit('openDialog', item);\n};\n\nconst handleCompositionstart = () => {\n composing.value = true;\n};\nconst handleInput = () => {\n if (composing.value || props.disabled) {\n return;\n }\n const selection = window.getSelection();\n if (selection && selection.rangeCount > 0) {\n const range = selection.getRangeAt(0);\n const container = range.startContainer;\n\n let mentionSpan: Node | null = container;\n while (mentionSpan && !(mentionSpan as HTMLElement).classList?.contains(props.mentionClass)) {\n mentionSpan = mentionSpan.parentNode;\n }\n\n if (mentionSpan && (mentionSpan as HTMLElement).classList) {\n const originalText = (mentionSpan as HTMLElement).getAttribute('data-name');\n const currentText = mentionSpan.textContent;\n\n if (currentText !== originalText && originalText !== null) {\n const newText = currentText?.replace(originalText, '') || '';\n\n mentionSpan.textContent = originalText;\n\n const textNode = document.createTextNode(newText);\n const { parentNode } = mentionSpan;\n const nextNode = mentionSpan.nextSibling;\n if (nextNode && nextNode.nodeType === Node.TEXT_NODE) {\n nextNode.textContent = newText + (nextNode.textContent || '');\n const newRange = document.createRange();\n newRange.setStart(nextNode, newText.length);\n newRange.collapse(true);\n selection.removeAllRanges();\n selection.addRange(newRange);\n } else {\n parentNode.insertBefore(textNode, mentionSpan.nextSibling);\n const newRange = document.createRange();\n newRange.setStart(textNode, newText.length);\n newRange.collapse(true);\n selection.removeAllRanges();\n selection.addRange(newRange);\n }\n }\n }\n }\n\n const content = divEditor.value?.innerHTML || '';\n triggerChange(content);\n emit('update:modelValue', content);\n};\n\nconst handleCompositionend = () => {\n composing.value = false;\n\n handleInput();\n};\n\nconst selectOption = (option: OptionProps) => {\n const selecttion = window.getSelection();\n if (document.activeElement !== (divEditor.value as unknown as Node)) {\n setFocus();\n\n if (selecttion) {\n selecttion.removeAllRanges();\n selecttion.addRange(lastRange.value);\n }\n }\n\n if (selecttion) {\n const range = selecttion.getRangeAt(0);\n\n deleteContentAfterAtSign(range, state.measurePrefix);\n\n const r = selecttion.getRangeAt(0);\n const { value } = option;\n const text = props.transformFn(option);\n\n // Add zero-width spaces before and after the mention text\n const mentionText = `${text}`;\n\n insertMention(r, mentionText, value, props.mentionClass, props.styleMap[state.measurePrefix]);\n\n handleInput();\n triggerChange(divEditor.value.innerHTML);\n\n composing.value = false;\n stopMeasure();\n }\n};\n\nconst onPaste = (event: ClipboardEvent) => {\n event.preventDefault();\n\n const { clipboardData } = event;\n const selection = window.getSelection();\n\n if (selection && clipboardData) {\n const pastedData = clipboardData.getData('text/plain');\n\n const range = selection.getRangeAt(0);\n\n // Remove the selected content before inserting the pasted data\n range.deleteContents();\n\n const currentNode = range.startContainer;\n const { startOffset } = range;\n if (currentNode.nodeType === Node.TEXT_NODE) {\n const currentText = currentNode.textContent;\n const beforeText = currentText.slice(0, startOffset);\n const afterText = currentText.slice(startOffset);\n currentNode.textContent = beforeText + pastedData + afterText;\n const newRange = document.createRange();\n newRange.setStart(currentNode, startOffset + pastedData.length);\n newRange.collapse(true);\n selection.removeAllRanges();\n selection.addRange(newRange);\n } else {\n const textNode = document.createTextNode(pastedData);\n range.insertNode(textNode);\n\n const newRange = document.createRange();\n newRange.setStart(textNode, pastedData.length);\n newRange.collapse(true);\n selection.removeAllRanges();\n selection.addRange(newRange);\n }\n\n handleInput();\n }\n};\n\nconst handkeKeyUp = (event: KeyboardEvent) => {\n const { which } = event;\n\n if ([KeyCode.ESC, KeyCode.UP, KeyCode.DOWN, KeyCode.ENTER].indexOf(which) !== -1) {\n return;\n }\n\n const selection = window.getSelection();\n if (!selection || !selection.rangeCount) return;\n\n const range = selection.getRangeAt(0);\n const { startContainer, startOffset } = range;\n\n let beforeText = '';\n if (startContainer.nodeType === Node.TEXT_NODE) {\n beforeText = startContainer.textContent.slice(0, startOffset);\n }\n\n if (!beforeText && startOffset === 0) {\n const prevNode = startContainer.previousSibling;\n if (prevNode && prevNode.nodeType === Node.TEXT_NODE) {\n beforeText = prevNode.textContent;\n }\n }\n\n const lastChar = beforeText.slice(-1);\n const isPrefixChar = prefix.value.includes(lastChar);\n\n if (isPrefixChar) {\n const innerText = getOffsetText();\n options.value = props.config[lastChar] || [];\n\n let inMentionSpan = false;\n let currentNode = startContainer;\n while (currentNode && currentNode !== (divEditor.value as unknown as Node)) {\n if ((currentNode as HTMLElement).classList?.contains(props.mentionClass)) {\n inMentionSpan = true;\n break;\n }\n currentNode = currentNode.parentNode;\n }\n\n if (!inMentionSpan) {\n const { x, y } = getCursorPosition();\n virtualElement.getBoundingClientRect = generateGetBoundingClientRect(x, y);\n popperIns.value?.update();\n lastRange.value = range;\n\n const afterText = innerText.slice(beforeText.length);\n const searchText = afterText.split(/[\\s\\n]/)[0] || '';\n\n startMeasure(searchText, lastChar, beforeText.length - 1);\n }\n } else if (state.measuring) {\n stopMeasure();\n }\n};\n\nconst handleKeyDown = (event: KeyboardEvent) => {\n const { which } = event;\n\n if (which === KeyCode.ENTER) {\n event.preventDefault();\n const selection = window.getSelection();\n if (selection && selection.rangeCount > 0) {\n const range = selection.getRangeAt(0);\n range.collapse(false);\n const div = document.createElement('div');\n div.innerHTML = '<br>';\n\n const currentNode = range.startContainer;\n const { parentNode } = currentNode;\n\n if ((parentNode as HTMLElement).classList?.contains(props.mentionClass)) {\n const afterContent = parentNode.nextSibling;\n if (afterContent) {\n div.appendChild(afterContent.cloneNode(true));\n afterContent.remove();\n }\n parentNode.parentNode.insertBefore(div, parentNode.nextSibling);\n } else if ((currentNode.previousSibling as HTMLElement)?.classList?.contains(props.mentionClass)) {\n const afterContent = currentNode.textContent.substring(range.startOffset);\n if (afterContent) {\n div.textContent = afterContent;\n currentNode.textContent = currentNode.textContent.substring(0, range.startOffset);\n }\n currentNode.parentNode.insertBefore(div, currentNode.nextSibling);\n } else {\n const { startOffset } = range;\n const currentContent = currentNode.textContent || '';\n\n if (startOffset > 0) {\n const beforeText = currentContent.substring(0, startOffset);\n const afterText = currentContent.substring(startOffset);\n\n if (afterText) {\n div.textContent = afterText;\n }\n\n if (currentNode.nodeType === Node.TEXT_NODE) {\n currentNode.textContent = beforeText;\n }\n }\n\n let blockParent: Node | null = currentNode;\n while (blockParent && blockParent.parentNode !== (divEditor.value as unknown)) {\n blockParent = blockParent.parentNode;\n }\n\n if (blockParent) {\n blockParent.parentNode.insertBefore(div, blockParent.nextSibling);\n } else {\n divEditor.value.appendChild(div);\n }\n }\n\n const newRange = document.createRange();\n newRange.setStart(div, 0);\n newRange.collapse(true);\n selection.removeAllRanges();\n selection.addRange(newRange);\n\n handleInput();\n }\n return;\n }\n\n if (!state.measuring) {\n if (which === KeyCode.BACKSPACE) {\n const selection = window.getSelection();\n if (selection && selection.rangeCount > 0) {\n const range = selection.getRangeAt(0);\n\n if (!range.collapsed) {\n event.preventDefault();\n range.deleteContents();\n handleInput();\n } else {\n let mentionSpan = range.startContainer;\n while (mentionSpan && !(mentionSpan as HTMLElement).classList?.contains(props.mentionClass)) {\n mentionSpan = mentionSpan.parentNode;\n }\n\n if (mentionSpan) {\n event.preventDefault();\n const text = mentionSpan.textContent;\n const newText = text.slice(0, -1);\n const textNode = document.createTextNode(newText);\n mentionSpan.parentNode.insertBefore(textNode, mentionSpan);\n (mentionSpan as HTMLElement).remove();\n\n const newRange = document.createRange();\n newRange.setStart(textNode, newText.length);\n newRange.collapse(true);\n selection.removeAllRanges();\n selection.addRange(newRange);\n\n handleInput();\n return;\n }\n\n const offset = range.startOffset;\n if (offset === 0) {\n const prevNode = range.startContainer.previousSibling;\n if (prevNode && (prevNode as HTMLElement).classList?.contains(props.mentionClass)) {\n event.preventDefault();\n prevNode.remove();\n handleInput();\n }\n }\n }\n }\n }\n return;\n }\n if (which === KeyCode.ESC) {\n stopMeasure();\n }\n};\n\nconst onFocus = (event: FocusEvent) => {\n const { isFocus } = state;\n if (!isFocus && event) {\n emit('focus', event);\n }\n state.isFocus = true;\n};\nconst onBlur = () => {\n const focusTimer = setTimeout(() => {\n state.isFocus = false;\n stopMeasure();\n }, 100);\n clearTimeout(focusTimer);\n};\n\nconst onInputFocus = (event: FocusEvent) => {\n isInput.value = true;\n composing.value = false;\n onFocus(event);\n};\nconst onInputBlur = () => {\n isInput.value = false;\n composing.value = false;\n\n onBlur();\n};\n\nconst setActiveIndex = (activeIndex: number) => {\n state.activeIndex = activeIndex;\n};\n\nprovide(MentionsContextKey, {\n activeIndex: toRef(state, 'activeIndex'),\n setActiveIndex,\n selectOption,\n onFocus,\n onBlur,\n handleCusClick,\n loading: toRef(props, 'loading')\n});\n\nconst initEditor = ({ html }: { html: string }) => {\n nextTick(() => {\n divEditor.value.innerHTML = html;\n });\n};\nonMounted(() => {\n divEditor.value.innerHTML = String(props.modelValue);\n});\nconst handleClose = () => {\n state.measuring = false;\n};\nwatch(\n () => props.modelValue,\n (val) => {\n if (isInput.value) {\n return;\n }\n if (divEditor.value) {\n divEditor.value.innerHTML = String(val);\n }\n }\n);\nonBeforeUnmount(() => {\n if (popperIns.value) {\n popperIns.value.destroy();\n popperIns.value = null;\n }\n});\ndefineExpose({\n selectOption,\n setFocus,\n divEditor,\n initEditor,\n onPaste,\n computedStyle\n});\n\nconst editorWrap = ref<HTMLDivElement | null>(null);\n\nconst startResize = (e: MouseEvent) => {\n e.preventDefault();\n\n const startY = e.clientY;\n const startHeight = editorWrap.value?.offsetHeight ?? 100;\n\n const handleMouseMove = (moveEvent: MouseEvent) => {\n const deltaY = moveEvent.clientY - startY;\n const newHeight = startHeight + deltaY;\n\n const minHeight = (props.minHeight as number) ?? 40;\n resizedHeight.value = Math.max(minHeight, newHeight);\n };\n\n const handleMouseUp = () => {\n document.removeEventListener('mousemove', handleMouseMove);\n document.removeEventListener('mouseup', handleMouseUp);\n };\n\n document.addEventListener('mousemove', handleMouseMove);\n document.addEventListener('mouseup', handleMouseUp);\n};\n</script>\n"],"names":["ref","computed","shallowRef","generateGetBoundingClientRect","reactive","toRef","createPopper","KeyCode","getOffsetText","getCursorPosition","MentionsContextKey","_a"],"mappings":"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"}
@@ -54,6 +54,7 @@ export interface MentionProps {
54
54
  styleMap?: Record<string, string>;
55
55
  config: Record<string, any>;
56
56
  resizable?: boolean;
57
+ optEmptyTip?: string;
57
58
  prefix?: string;
58
59
  triggerSign?: string[];
59
60
  mentionClass?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"Mentions.type.js","sources":["../../../../src/components/Mention/Mentions.type.ts"],"sourcesContent":["import type { InjectionKey, PropType, VNode, Ref } from 'vue';\n\nexport type VNodeChildAtom = VNode | string | number | boolean | null | undefined | void;\nexport type VueNode = VNodeChildAtom | VNodeChildAtom[];\n\nexport function anyType<T = any>(defaultVal?: T, required?: boolean) {\n const type = { validator: () => true, default: defaultVal as T } as unknown;\n return required\n ? (type as {\n type: PropType<T>;\n default: T;\n required: true;\n })\n : (type as {\n default: T;\n type: PropType<T>;\n });\n}\n\nexport function arrayType<T extends any[]>(defaultVal?: T) {\n return { type: Array as unknown as PropType<T>, default: defaultVal as T };\n}\n\nexport function objectType<T = any>(defaultVal?: T) {\n return { type: Object as PropType<T>, default: defaultVal as T };\n}\n\nexport const baseOptionsProps = {\n value: String,\n disabled: Boolean,\n payload: objectType<Record<string, any>>()\n};\n\nexport interface OptionProps {\n label: string;\n value: string;\n [key: string]: any;\n}\n\nexport type EventHandler = (...args: any[]) => void;\n\nexport interface MentionsContext {\n activeIndex: Ref<number>;\n setActiveIndex?: (index: number) => void;\n selectOption?: (option: OptionProps) => void;\n onFocus?: EventListener;\n onBlur?: EventListener;\n loading?: Ref<boolean>;\n handleCusClick?: <T>(item?: T) => void;\n}\n\nexport interface MentionConfig {\n html: string;\n}\n\nexport interface MentionState {\n value: string;\n measuring: boolean;\n measureLocation: number;\n measureText: string | null;\n measurePrefix: string;\n activeIndex: number;\n isFocus: boolean;\n}\n\nexport interface MentionProps {\n placeholder?: string;\n disabled?: boolean;\n styleMap?: Record<string, string>;\n config: Record<string, any>;\n resizable?: boolean;\n prefix?: string;\n triggerSign?: string[];\n mentionClass?: string;\n popperOptions?: any;\n transformFn?: (item: OptionProps) => string;\n modelValue: string | number;\n height?: number | string;\n maxHeight?: number | string;\n minHeight?: number | string;\n loading?: boolean;\n}\n\nexport const MentionsopenDialogValue: InjectionKey<any> = Symbol('MentionsopenDialogValue');\n"],"names":[],"mappings":";;;;SAKgB,QAAiB,YAAgB,UAAoB;AACnE,QAAM,OAAO,EAAE,WAAW,MAAM,MAAM,SAAS;AAC/C,SAAO,WACF,OAKA;AAIP;SAEgB,UAA2B,YAAgB;AACzD,SAAO,EAAE,MAAM,OAAiC,SAAS;AAC3D;SAEgB,WAAoB,YAAgB;AAClD,SAAO,EAAE,MAAM,QAAuB,SAAS;AACjD;MAEa,mBAAmB;AAAA,EAC9B,OAAO;AAAA,EACP,UAAU;AAAA,EACV,SAAS;AACX;MAoDa,0BAA6C,OAAO,yBAAyB;;;;;;;;"}
1
+ {"version":3,"file":"Mentions.type.js","sources":["../../../../src/components/Mention/Mentions.type.ts"],"sourcesContent":["import type { InjectionKey, PropType, VNode, Ref } from 'vue';\n\nexport type VNodeChildAtom = VNode | string | number | boolean | null | undefined | void;\nexport type VueNode = VNodeChildAtom | VNodeChildAtom[];\n\nexport function anyType<T = any>(defaultVal?: T, required?: boolean) {\n const type = { validator: () => true, default: defaultVal as T } as unknown;\n return required\n ? (type as {\n type: PropType<T>;\n default: T;\n required: true;\n })\n : (type as {\n default: T;\n type: PropType<T>;\n });\n}\n\nexport function arrayType<T extends any[]>(defaultVal?: T) {\n return { type: Array as unknown as PropType<T>, default: defaultVal as T };\n}\n\nexport function objectType<T = any>(defaultVal?: T) {\n return { type: Object as PropType<T>, default: defaultVal as T };\n}\n\nexport const baseOptionsProps = {\n value: String,\n disabled: Boolean,\n payload: objectType<Record<string, any>>()\n};\n\nexport interface OptionProps {\n label: string;\n value: string;\n [key: string]: any;\n}\n\nexport type EventHandler = (...args: any[]) => void;\n\nexport interface MentionsContext {\n activeIndex: Ref<number>;\n setActiveIndex?: (index: number) => void;\n selectOption?: (option: OptionProps) => void;\n onFocus?: EventListener;\n onBlur?: EventListener;\n loading?: Ref<boolean>;\n handleCusClick?: <T>(item?: T) => void;\n}\n\nexport interface MentionConfig {\n html: string;\n}\n\nexport interface MentionState {\n value: string;\n measuring: boolean;\n measureLocation: number;\n measureText: string | null;\n measurePrefix: string;\n activeIndex: number;\n isFocus: boolean;\n}\n\nexport interface MentionProps {\n placeholder?: string;\n disabled?: boolean;\n styleMap?: Record<string, string>;\n config: Record<string, any>;\n resizable?: boolean;\n optEmptyTip?: string;\n prefix?: string;\n triggerSign?: string[];\n mentionClass?: string;\n popperOptions?: any;\n transformFn?: (item: OptionProps) => string;\n modelValue: string | number;\n height?: number | string;\n maxHeight?: number | string;\n minHeight?: number | string;\n loading?: boolean;\n}\n\nexport const MentionsopenDialogValue: InjectionKey<any> = Symbol('MentionsopenDialogValue');\n"],"names":[],"mappings":";;;;SAKgB,QAAiB,YAAgB,UAAoB;AACnE,QAAM,OAAO,EAAE,WAAW,MAAM,MAAM,SAAS;AAC/C,SAAO,WACF,OAKA;AAIP;SAEgB,UAA2B,YAAgB;AACzD,SAAO,EAAE,MAAM,OAAiC,SAAS;AAC3D;SAEgB,WAAoB,YAAgB;AAClD,SAAO,EAAE,MAAM,QAAuB,SAAS;AACjD;MAEa,mBAAmB;AAAA,EAC9B,OAAO;AAAA,EACP,UAAU;AAAA,EACV,SAAS;AACX;MAqDa,0BAA6C,OAAO,yBAAyB;;;;;;;;"}
@@ -16,6 +16,10 @@ const _hoisted_2 = {
16
16
  const _sfc_main = {
17
17
  __name: "MentionsSelect",
18
18
  props: {
19
+ emptyTip: {
20
+ type: String,
21
+ default: ""
22
+ },
19
23
  options: {
20
24
  type: Array,
21
25
  default: () => []
@@ -105,7 +109,7 @@ const _sfc_main = {
105
109
  _: 3
106
110
  })
107
111
  ], 2),
108
- showNoData.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2, "\u6682\u65E0\u53EF\u9009\u9879")) : vue.createCommentVNode("v-if", true)
112
+ showNoData.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2, vue.toDisplayString(__props.emptyTip), 1)) : vue.createCommentVNode("v-if", true)
109
113
  ], 2);
110
114
  };
111
115
  }
@@ -1 +1 @@
1
- {"version":3,"file":"MentionsSelect.js","sources":["../../../../src/components/Mention/MentionsSelect.vue"],"sourcesContent":["<template>\n <div ref=\"mentionSelect\" :class=\"`${prefix}-select-wrap`\">\n <u-input v-model=\"search\" clearable>\n <template #suffix>\n <u-icon :size=\"14\">\n <ULineSearch />\n </u-icon>\n </template>\n </u-input>\n <div :class=\"`${prefix}-select-content`\">\n <u-scrollbar max-height=\"200px\">\n <div v-for=\"(item, index) in filterOptions\" :key=\"index\">\n <div :class=\"`${prefix}-item`\" @click=\"handleClick(item, index)\">\n <div :class=\"`${prefix}-text`\">\n <slot :data=\"item\" name=\"label\">\n <span>{{ item?.label }}</span>\n </slot>\n </div>\n </div>\n </div>\n </u-scrollbar>\n </div>\n\n <div v-if=\"showNoData\" class=\"no-more-wrap\">暂无可选项</div>\n </div>\n</template>\n\n<script setup>\nimport { shallowRef, inject, computed, nextTick, ref } from 'vue';\nimport { isEmpty } from 'lodash-es';\nimport { MentionsContextKey } from './mentionsTypes';\nimport { setupClickOutside } from './utils';\n\nconst props = defineProps({\n options: {\n type: Array,\n default: () => []\n },\n prefix: {\n type: String,\n default: ''\n }\n});\n\nconst emits = defineEmits(['close']);\nconst { setActiveIndex, selectOption } = inject(MentionsContextKey, {\n activeIndex: shallowRef()\n});\n\nconst showNoData = computed(() => {\n return isEmpty(props.options);\n});\nconst search = ref('');\nconst mentionSelect = ref(null);\n\nconst filterOptions = computed(() => {\n return props.options.filter((item) => {\n return item.label.includes(search.value);\n });\n});\nsetupClickOutside(mentionSelect, () => {\n emits('close');\n});\nconst handleClick = (item, index) => {\n if (setActiveIndex) {\n setActiveIndex(index);\n }\n\n nextTick(() => {\n if (selectOption) {\n selectOption(item);\n }\n });\n};\n</script>\n"],"names":["inject","MentionsContextKey","shallowRef","computed","isEmpty","ref"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCA,UAAM,QAAQ;AAWd,UAAM,QAAQ;AACd,UAAM,EAAE,gBAAgB,iBAAiBA,WAAOC,kCAAoB;AAAA,MAClE,aAAaC;AAAW,KACzB;AAED,UAAM,aAAaC,aAAS,MAAM;AAChC,aAAOC,iBAAQ,MAAM,OAAO;AAAA,KAC7B;AACD,UAAM,SAASC,QAAI,EAAE;AACrB,UAAM,gBAAgBA,QAAI,IAAI;AAE9B,UAAM,gBAAgBF,aAAS,MAAM;AACnC,aAAO,MAAM,QAAQ,OAAO,CAAC,SAAS;AACpC,eAAO,KAAK,MAAM,SAAS,OAAO,KAAK;AAAA,OACxC;AAAA,KACF;AACD,4BAAkB,eAAe,MAAM;AACrC,YAAM,OAAO;AAAA,KACd;AACD,UAAM,cAAc,CAAC,MAAM,UAAU;AACnC,UAAI,gBAAgB;AAClB,uBAAe,KAAK;AAAA;AAGtB,mBAAS,MAAM;AACb,YAAI,cAAc;AAChB,uBAAa,IAAI;AAAA;AACnB,OACD;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"MentionsSelect.js","sources":["../../../../src/components/Mention/MentionsSelect.vue"],"sourcesContent":["<template>\n <div ref=\"mentionSelect\" :class=\"`${prefix}-select-wrap`\">\n <u-input v-model=\"search\" clearable>\n <template #suffix>\n <u-icon :size=\"14\">\n <ULineSearch />\n </u-icon>\n </template>\n </u-input>\n <div :class=\"`${prefix}-select-content`\">\n <u-scrollbar max-height=\"200px\">\n <div v-for=\"(item, index) in filterOptions\" :key=\"index\">\n <div :class=\"`${prefix}-item`\" @click=\"handleClick(item, index)\">\n <div :class=\"`${prefix}-text`\">\n <slot :data=\"item\" name=\"label\">\n <span>{{ item?.label }}</span>\n </slot>\n </div>\n </div>\n </div>\n </u-scrollbar>\n </div>\n <div v-if=\"showNoData\" class=\"no-more-wrap\">{{ emptyTip }}</div>\n </div>\n</template>\n\n<script setup>\nimport { shallowRef, inject, computed, nextTick, ref } from 'vue';\nimport { isEmpty } from 'lodash-es';\nimport { MentionsContextKey } from './mentionsTypes';\nimport { setupClickOutside } from './utils';\n\nconst props = defineProps({\n emptyTip: {\n type: String,\n default: ''\n },\n options: {\n type: Array,\n default: () => []\n },\n prefix: {\n type: String,\n default: ''\n }\n});\n\nconst emits = defineEmits(['close']);\nconst { setActiveIndex, selectOption } = inject(MentionsContextKey, {\n activeIndex: shallowRef()\n});\n\nconst showNoData = computed(() => {\n return isEmpty(props.options);\n});\nconst search = ref('');\nconst mentionSelect = ref(null);\n\nconst filterOptions = computed(() => {\n return props.options.filter((item) => {\n return item.label.includes(search.value);\n });\n});\nsetupClickOutside(mentionSelect, () => {\n emits('close');\n});\nconst handleClick = (item, index) => {\n if (setActiveIndex) {\n setActiveIndex(index);\n }\n\n nextTick(() => {\n if (selectOption) {\n selectOption(item);\n }\n });\n};\n</script>\n"],"names":["inject","MentionsContextKey","shallowRef","computed","isEmpty","ref"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,UAAM,QAAQ;AAed,UAAM,QAAQ;AACd,UAAM,EAAE,gBAAgB,iBAAiBA,WAAOC,kCAAoB;AAAA,MAClE,aAAaC;AAAW,KACzB;AAED,UAAM,aAAaC,aAAS,MAAM;AAChC,aAAOC,iBAAQ,MAAM,OAAO;AAAA,KAC7B;AACD,UAAM,SAASC,QAAI,EAAE;AACrB,UAAM,gBAAgBA,QAAI,IAAI;AAE9B,UAAM,gBAAgBF,aAAS,MAAM;AACnC,aAAO,MAAM,QAAQ,OAAO,CAAC,SAAS;AACpC,eAAO,KAAK,MAAM,SAAS,OAAO,KAAK;AAAA,OACxC;AAAA,KACF;AACD,4BAAkB,eAAe,MAAM;AACrC,YAAM,OAAO;AAAA,KACd;AACD,UAAM,cAAc,CAAC,MAAM,UAAU;AACnC,UAAI,gBAAgB;AAClB,uBAAe,KAAK;AAAA;AAGtB,mBAAS,MAAM;AACb,YAAI,cAAc;AAChB,uBAAa,IAAI;AAAA;AACnB,OACD;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@koi-design/uxd-ui",
3
- "version": "13.1.9",
3
+ "version": "13.2.0",
4
4
  "description": "uxd ui component with vue3.0",
5
5
  "license": "MIT",
6
6
  "maintainers": [],
@@ -1 +1 @@
1
- .dark,.dark-theme,.light,.light-theme,:root{--animation-time:0.3s;--animation-time-fast:0.15s;--animation-time-short:0.2s;--animation-time-long:0.5s;--default-font-color:var(--gray-12);--secondary-font-color:var(--gray-11);--heading-color:var(--gray-12);--placeholder-color:var(--gray-10);--placeholder-disabled-color:var(--gray-7);--border-width-base:1px;--border-style-base:solid;--border-color-base:var(--color-border-base);--border-split-color:var(--color-border-split);--disabled-font-color:var(--color-disabled-font);--validate-error-border-color:var(--error-8);--validate-error-hover-border-color:var(--error-9);--validate-error-background-color:transparent;--validate-error-hover-background-color:transparent;--control-disabled-background-color:var(--gray-2);--control-disabled-border-color:var(--color-border-disabled);--control-surface-border-color:var(--color-border-base);--control-surface-hover-border-color:var(--color-border-hover);--control-surface-background-color:var(--color-background);--control-soft-background-color:var(--color-soft-control-background);--control-soft-hover-background-color:var(--color-soft-control-hover-background);--control-height-small:var(--space-5);--control-height-base:var(--space-6);--control-height-large:var(--space-7);--control-font-size-small:var(--font-size-1);--control-font-size-base:var(--default-font-size);--control-font-size-large:var(--font-size-3);--link-decoration:none;--link-hover-decoration:underline;--zindex-badge:auto;--zindex-table-fixed:10;--zindex-affix:10;--zindex-back-top:10;--zindex-picker-panel:10;--zindex-popup-close:10;--zindex-spin:10;--zindex-modal:1000;--zindex-modal-mask:1000;--zindex-message:1010;--zindex-notice:1010;--zindex-popover:1030;--zindex-dropdown:1050;--zindex-tooltip:1060;--zindex-loading-bar:2000;--dropdown-shadow:var(--shadow-5);--popover-shadow:var(--shadow-5);--modal-shadow:var(--shadow-6);--message-shadow:var(--shadow-5);--notice-shadow:var(--shadow-5);--card-shadow:var(--shadow-2);--icon-width-base:var(--space-4);--icon-font-size:var(--font-size-3);--icon-button-color:var(--gray-a11);--icon-button-padding:var(--space-1);--icon-button-hover-color:var(--gray-a11);--icon-button-hover-background-color:var(--gray-a3);--required-color:var(--error-9);--required-font-size:var(--font-size-2);--required-font-family:'SimSun',sans-serif;--mask-background-color:var(--color-overlay);--ease-base-out:cubic-bezier(0.7, 0.3, 0.1, 1);--ease-base-in:cubic-bezier(0.9, 0, 0.3, 0.7);--ease-out:cubic-bezier(0.215, 0.61, 0.355, 1);--ease-in:cubic-bezier(0.55, 0.055, 0.675, 0.19);--ease-in-out:cubic-bezier(0.645, 0.045, 0.355, 1);--ease-out-back:cubic-bezier(0.12, 0.4, 0.29, 1.46);--ease-in-back:cubic-bezier(0.71, -0.46, 0.88, 0.6);--ease-in-out-back:cubic-bezier(0.71, -0.46, 0.29, 1.46);--ease-out-circ:cubic-bezier(0.08, 0.82, 0.17, 1);--ease-in-circ:cubic-bezier(0.6, 0.04, 0.98, 0.34);--ease-in-out-circ:cubic-bezier(0.78, 0.14, 0.15, 0.86);--ease-out-quint:cubic-bezier(0.23, 1, 0.32, 1);--ease-in-quint:cubic-bezier(0.755, 0.05, 0.855, 0.06);--ease-in-out-quint:cubic-bezier(0.86, 0, 0.07, 1)}.dark,.dark-theme,.light,.light-theme,:root,[data-color],[data-theme-color]{--link-color:var(--primary-9);--link-hover-color:var(--primary-10);--link-active-color:var(--primary-11);--dropdown-item-selected-color:var(--default-font-color);--dropdown-item-hover-background-color:var(--primary-a3);--dropdown-item-hover-font-color:var(--default-font-color);--highlight-color:var(--primary-10)}[data-color=error]{--link-color:var(--error-9);--link-hover-color:var(--error-10);--link-active-color:var(--error-11)}[data-color=warning]{--link-color:var(--warning-9);--link-hover-color:var(--warning-10);--link-active-color:var(--warning-11)}[data-color=success]{--link-color:var(--success-9);--link-hover-color:var(--success-10);--link-active-color:var(--success-11)}[data-color]{--primary-shadow-3:0 0 0 1px var(--primary-a3),0 2px 3px -2px var(--primary-a3),0 3px 12px -4px var(--primary-a3),0 4px 16px -8px var(--primary-a3);--primary-shadow-5:0 0 0 1px var(--primary-a3),0 12px 24px var(--primary-2),0 12px 24px -16px var(--primary-a5)}:root,[data-radius]{--dropdown-border-radius:var(--radius-4);--icon-button-radius:var(--radius-2);--modal-border-radius:var(--radius-4);--control-radius:var(--radius-4);--control-radius-small:var(--radius-2);--control-radius-large:var(--radius-4)}:root,[data-theme-color]{--primary-color:var(--primary-9)}.uui-mention{--mentions-background-color:var(--color-surface);--mentions-border-color:var(--control-surface-border-color);--mentions-padding-vertical:var(--space-2);--mentions-padding-horizontal:var(--space-2);--mentions-hover-border-color:var(--control-surface-hover-border-color);--mentions-hover-background-color:var(--color-surface);--mentions-dropdown-border-radius:var(--radius-2);--mentions-dropdown-background-color:var(--color-background);--mentions-dropdown-box-shadow:var(--dropdown-shadow);--mentions-dropdown-padding-vertical:var(--space-2);--mentions-dropdown-padding-horizontal:var(--space-2);--mentions-dropdown-item-border-radius:var(--radius-2);--mentions-dropdown-item-height:var(--control-height-base);--mentions-dropdown-item-padding-horizontal:var(--space-2);--mentions-focus-border-color:var(--primary-9);--mentions-dropdown-item-hover-background-color:var(--dropdown-item-hover-background-color);--mentions-dropdown-item-hover-font-color:var(--dropdown-item-hover-font-color);--mentions-border-radius:var(--control-radius);--mentions-resize-handle-color:var(--placeholder-color);--mentions-resize-handle-hover-color:var(--theme-color);--mentions-warp-hover-background-color:var(--color-surface);--mentions-disabled-background-color:var(--gray-2)}.uui-mention{width:100%;display:inline-flex;position:relative;align-items:center;border-radius:var(--mentions-border-radius);height:auto;line-height:var(--mentions-height-base);font-size:var(--default-font-size);color:var(--default-font-color);white-space:pre-line;box-shadow:0 0 0 1px var(--mentions-border-color) inset;transition:box-shadow var(--animation-time) linear;background-color:var(--mentions-background-color);padding:var(--mentions-padding-vertical) var(--mentions-padding-horizontal)}.uui-mention.disabled{background-color:var(--mentions-disabled-background-color)}.uui-mention:not(.disabled):hover{background-color:var(--mentions-warp-hover-background-color)}.uui-mention:not(.disabled):focus-within{border:1px solid var(--theme-color)}.uui-mention:focus-within{outline:1px solid var(--mentions-focus-outer-color);box-shadow:0 0 0 1px var(--mentions-focus-border-color) inset}.uui-mention-editor{width:100%;border:none;outline:0;min-height:50px;padding:var(--mentions-textarea-padding-horizontal);font-size:var(--default-font-size);height:100%;overflow-y:auto;color:var(--default-font-color)}.uui-mention-editor.disabled{-webkit-user-modify:unset;cursor:not-allowed}.uui-mention-editor:empty::before{content:attr(data-placeholder);color:var(--placeholder-color)}.uui-mention-editor[contenteditable=false]{cursor:not-allowed}.uui-mention-popper-wrap{z-index:99}.uui-mention-select-wrap{width:200px;background-color:var(--mentions-dropdown-background-color);font-size:var(--default-font-size);overflow:hidden;border-radius:var(--mentions-dropdown-border-radius);z-index:100;padding:var(--mentions-dropdown-padding-vertical) var(--mentions-dropdown-padding-horizontal);box-shadow:var(--mentions-dropdown-box-shadow);color:var(--default-font-color)}.uui-mention-select-wrap .no-more-wrap{padding-top:12px;padding-bottom:10px;display:flex;justify-content:center;align-items:center}.uui-mention-item{line-height:var(--mentions-dropdown-item-height);padding-left:var(--mentions-dropdown-item-padding-horizontal);cursor:pointer;margin-bottom:4px;background-color:var(--mentions-dropdown-background-color);height:var(--mentions-dropdown-item-height);border-radius:var(--mentions-dropdown-item-border-radius)}.uui-mention-item:hover{background-color:var(--mentions-dropdown-item-hover-background-color);color:var(--mentions-dropdown-item-hover-font-color)}.uui-mention-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.uui-mention .resize-handle{position:absolute;right:3px;bottom:3px;width:8px;height:8px;cursor:se-resize;background-repeat:no-repeat;background-position:center;background-size:contain;color:var(--mentions-resize-handle-color)}.uui-mention .resize-handle:hover{color:var(--mentions-resize-handle-hover-color)}
1
+ .dark,.dark-theme,.light,.light-theme,:root{--animation-time:0.3s;--animation-time-fast:0.15s;--animation-time-short:0.2s;--animation-time-long:0.5s;--default-font-color:var(--gray-12);--secondary-font-color:var(--gray-11);--heading-color:var(--gray-12);--placeholder-color:var(--gray-10);--placeholder-disabled-color:var(--gray-7);--border-width-base:1px;--border-style-base:solid;--border-color-base:var(--color-border-base);--border-split-color:var(--color-border-split);--disabled-font-color:var(--color-disabled-font);--validate-error-border-color:var(--error-8);--validate-error-hover-border-color:var(--error-9);--validate-error-background-color:transparent;--validate-error-hover-background-color:transparent;--control-disabled-background-color:var(--gray-2);--control-disabled-border-color:var(--color-border-disabled);--control-surface-border-color:var(--color-border-base);--control-surface-hover-border-color:var(--color-border-hover);--control-surface-background-color:var(--color-background);--control-soft-background-color:var(--color-soft-control-background);--control-soft-hover-background-color:var(--color-soft-control-hover-background);--control-height-small:var(--space-5);--control-height-base:var(--space-6);--control-height-large:var(--space-7);--control-font-size-small:var(--font-size-1);--control-font-size-base:var(--default-font-size);--control-font-size-large:var(--font-size-3);--link-decoration:none;--link-hover-decoration:underline;--zindex-badge:auto;--zindex-table-fixed:10;--zindex-affix:10;--zindex-back-top:10;--zindex-picker-panel:10;--zindex-popup-close:10;--zindex-spin:10;--zindex-modal:1000;--zindex-modal-mask:1000;--zindex-message:1010;--zindex-notice:1010;--zindex-popover:1030;--zindex-dropdown:1050;--zindex-tooltip:1060;--zindex-loading-bar:2000;--dropdown-shadow:var(--shadow-5);--popover-shadow:var(--shadow-5);--modal-shadow:var(--shadow-6);--message-shadow:var(--shadow-5);--notice-shadow:var(--shadow-5);--card-shadow:var(--shadow-2);--icon-width-base:var(--space-4);--icon-font-size:var(--font-size-3);--icon-button-color:var(--gray-a11);--icon-button-padding:var(--space-1);--icon-button-hover-color:var(--gray-a11);--icon-button-hover-background-color:var(--gray-a3);--required-color:var(--error-9);--required-font-size:var(--font-size-2);--required-font-family:'SimSun',sans-serif;--mask-background-color:var(--color-overlay);--ease-base-out:cubic-bezier(0.7, 0.3, 0.1, 1);--ease-base-in:cubic-bezier(0.9, 0, 0.3, 0.7);--ease-out:cubic-bezier(0.215, 0.61, 0.355, 1);--ease-in:cubic-bezier(0.55, 0.055, 0.675, 0.19);--ease-in-out:cubic-bezier(0.645, 0.045, 0.355, 1);--ease-out-back:cubic-bezier(0.12, 0.4, 0.29, 1.46);--ease-in-back:cubic-bezier(0.71, -0.46, 0.88, 0.6);--ease-in-out-back:cubic-bezier(0.71, -0.46, 0.29, 1.46);--ease-out-circ:cubic-bezier(0.08, 0.82, 0.17, 1);--ease-in-circ:cubic-bezier(0.6, 0.04, 0.98, 0.34);--ease-in-out-circ:cubic-bezier(0.78, 0.14, 0.15, 0.86);--ease-out-quint:cubic-bezier(0.23, 1, 0.32, 1);--ease-in-quint:cubic-bezier(0.755, 0.05, 0.855, 0.06);--ease-in-out-quint:cubic-bezier(0.86, 0, 0.07, 1)}.dark,.dark-theme,.light,.light-theme,:root,[data-color],[data-theme-color]{--link-color:var(--primary-9);--link-hover-color:var(--primary-10);--link-active-color:var(--primary-11);--dropdown-item-selected-color:var(--default-font-color);--dropdown-item-hover-background-color:var(--primary-a3);--dropdown-item-hover-font-color:var(--default-font-color);--highlight-color:var(--primary-10)}[data-color=error]{--link-color:var(--error-9);--link-hover-color:var(--error-10);--link-active-color:var(--error-11)}[data-color=warning]{--link-color:var(--warning-9);--link-hover-color:var(--warning-10);--link-active-color:var(--warning-11)}[data-color=success]{--link-color:var(--success-9);--link-hover-color:var(--success-10);--link-active-color:var(--success-11)}[data-color]{--primary-shadow-3:0 0 0 1px var(--primary-a3),0 2px 3px -2px var(--primary-a3),0 3px 12px -4px var(--primary-a3),0 4px 16px -8px var(--primary-a3);--primary-shadow-5:0 0 0 1px var(--primary-a3),0 12px 24px var(--primary-2),0 12px 24px -16px var(--primary-a5)}:root,[data-radius]{--dropdown-border-radius:var(--radius-4);--icon-button-radius:var(--radius-2);--modal-border-radius:var(--radius-4);--control-radius:var(--radius-4);--control-radius-small:var(--radius-2);--control-radius-large:var(--radius-4)}:root,[data-theme-color]{--primary-color:var(--primary-9)}.uui-mention{--mentions-background-color:var(--color-surface);--mentions-border-color:var(--control-surface-border-color);--mentions-padding-vertical:var(--space-2);--mentions-padding-horizontal:var(--space-2);--mentions-hover-border-color:var(--control-surface-hover-border-color);--mentions-hover-background-color:var(--color-surface);--mentions-dropdown-border-radius:var(--radius-2);--mentions-dropdown-background-color:var(--color-background);--mentions-dropdown-box-shadow:var(--dropdown-shadow);--mentions-dropdown-padding-vertical:var(--space-2);--mentions-dropdown-padding-horizontal:var(--space-2);--mentions-dropdown-item-border-radius:var(--radius-2);--mentions-dropdown-item-height:var(--control-height-base);--mentions-dropdown-item-padding-horizontal:var(--space-2);--mentions-focus-border-color:var(--primary-9);--mentions-dropdown-item-hover-background-color:var(--dropdown-item-hover-background-color);--mentions-dropdown-item-hover-font-color:var(--dropdown-item-hover-font-color);--mentions-border-radius:var(--control-radius);--mentions-resize-handle-color:var(--placeholder-color);--mentions-resize-handle-hover-color:var(--theme-color);--mentions-warp-hover-background-color:var(--color-surface);--mentions-disabled-background-color:var(--gray-2)}.uui-mention{width:100%;display:inline-flex;position:relative;align-items:center;border-radius:var(--mentions-border-radius);height:auto;line-height:var(--mentions-height-base);font-size:var(--default-font-size);color:var(--default-font-color);white-space:pre-line;box-shadow:0 0 0 1px var(--mentions-border-color) inset;transition:box-shadow var(--animation-time) linear;background-color:var(--mentions-background-color);padding:var(--mentions-padding-vertical) var(--mentions-padding-horizontal)}.uui-mention.disabled{background-color:var(--mentions-disabled-background-color)}.uui-mention:not(.disabled):hover{background-color:var(--mentions-warp-hover-background-color)}.uui-mention:not(.disabled):focus-within{border:1px solid var(--theme-color)}.uui-mention:focus-within{outline:1px solid var(--mentions-focus-outer-color);box-shadow:0 0 0 1px var(--mentions-focus-border-color) inset}.uui-mention-editor{width:100%;border:none;outline:0;min-height:22px;padding:var(--mentions-textarea-padding-horizontal);font-size:var(--default-font-size);height:100%;overflow-y:auto;color:var(--default-font-color)}.uui-mention-editor.disabled{-webkit-user-modify:unset;cursor:not-allowed}.uui-mention-editor:empty::before{content:attr(data-placeholder);color:var(--placeholder-color)}.uui-mention-editor[contenteditable=false]{cursor:not-allowed}.uui-mention-popper-wrap{z-index:99}.uui-mention-select-wrap{width:200px;background-color:var(--mentions-dropdown-background-color);font-size:var(--default-font-size);overflow:hidden;border-radius:var(--mentions-dropdown-border-radius);z-index:100;padding:var(--mentions-dropdown-padding-vertical) var(--mentions-dropdown-padding-horizontal);box-shadow:var(--mentions-dropdown-box-shadow);color:var(--default-font-color)}.uui-mention-select-wrap .no-more-wrap{padding-top:12px;padding-bottom:10px;display:flex;justify-content:center;align-items:center}.uui-mention-item{line-height:var(--mentions-dropdown-item-height);padding-left:var(--mentions-dropdown-item-padding-horizontal);cursor:pointer;margin-bottom:4px;background-color:var(--mentions-dropdown-background-color);height:var(--mentions-dropdown-item-height);border-radius:var(--mentions-dropdown-item-border-radius)}.uui-mention-item:hover{background-color:var(--mentions-dropdown-item-hover-background-color);color:var(--mentions-dropdown-item-hover-font-color)}.uui-mention-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.uui-mention .resize-handle{position:absolute;right:3px;bottom:3px;width:8px;height:8px;cursor:se-resize;background-repeat:no-repeat;background-position:center;background-size:contain;color:var(--mentions-resize-handle-color)}.uui-mention .resize-handle:hover{color:var(--mentions-resize-handle-hover-color)}
@@ -39,7 +39,7 @@
39
39
  width: 100%;
40
40
  border: none;
41
41
  outline: none;
42
- min-height: 50px;
42
+ min-height: 22px;
43
43
  padding: var(--mentions-textarea-padding-horizontal);
44
44
  font-size: var(--default-font-size);
45
45
  height: 100%;