import { computePosition, flip, shift } from '@floating-ui/dom' import { posToDOMRect, VueRenderer } from '@tiptap/vue-3' import MentionList from './MentionList.vue' import { defAvatar } from '@/constant/default' const updatePosition = (editor, element) => { const virtualElement = { getBoundingClientRect: () => posToDOMRect(editor.view, editor.state.selection.from, editor.state.selection.to), } computePosition(virtualElement, element, { placement: 'bottom-start', strategy: 'absolute', middleware: [shift(), flip()], }).then(({ x, y, strategy }) => { element.style.position = strategy if (window.__POWERED_BY_WUJIE__) { element.style.left = `${x + 200}px` element.style.top = `${y + 100}px` } else { element.style.left = `${x}px` element.style.top = `${y}px` } }) } export default { items: ({ query, editor, props }) => { if (!props.members || !props.members.length) { return [] } let list = [...props.members] // 如果是群组管理员,添加"所有人"选项 if (props.isGroupManager) { list.unshift({ id: 0, nickname: '所有人', avatar: defAvatar }) } // 排除掉自己 list.splice(list.findIndex((item) => item.id === props.uid), 1) const filteredItems = list.filter( (item) => item.nickname.toLowerCase().includes(query.toLowerCase()) ) // 如果没有匹配项,返回空数组以关闭弹窗 if (filteredItems.length === 0) { return [] } return filteredItems }, render: () => { let component return { onStart: props => { // 如果没有匹配项,不创建弹窗 if (!props.items || props.items.length === 0) { return } component = new VueRenderer(MentionList, { // Vue 3 props格式 props, editor: props.editor, }) if (!props.clientRect) { return } component.element.style.position = 'absolute' document.body.appendChild(component.element) updatePosition(props.editor, component.element) }, onUpdate(props) { component.updateProps(props) if (props.items.length === 0) { this.onExit() return } if (!props.clientRect) { return } updatePosition(props.editor, component.element) }, onKeyDown(props) { if (props.event.key === 'Escape') { this.onExit() return true } if(!component?.props.items?.length){ return false } return component.ref.onKeyDown(props) }, onExit() { console.log('component.element',component.element) component.element.remove() component.destroy() }, } }, }