diff --git a/packages/super-editor/src/editors/v1/components/popovers/Mentions.test.ts b/packages/super-editor/src/editors/v1/components/popovers/Mentions.test.ts new file mode 100644 index 0000000000..8eebf8f5d4 --- /dev/null +++ b/packages/super-editor/src/editors/v1/components/popovers/Mentions.test.ts @@ -0,0 +1,39 @@ +import { afterEach, describe, expect, it, vi } from 'vitest'; +import { mount } from '@vue/test-utils'; +import Mentions from './Mentions.vue'; + +describe('Mentions.vue rendering', () => { + let wrapper: ReturnType | undefined; + let documentMousedown: ReturnType | undefined; + + afterEach(() => { + wrapper?.unmount(); + if (documentMousedown) document.removeEventListener('mousedown', documentMousedown); + }); + + it('keeps the user row mounted through the first click', () => { + const user = { name: 'Alice', email: 'alice@example.com', role: 'editor' }; + const insertMention = vi.fn(); + documentMousedown = vi.fn(); + document.addEventListener('mousedown', documentMousedown); + + wrapper = mount(Mentions, { + attachTo: document.body, + props: { + users: [user], + insertMention, + }, + }); + + const row = wrapper.get('.user-row'); + const mousedown = new MouseEvent('mousedown', { bubbles: true, cancelable: true }); + row.element.dispatchEvent(mousedown); + + expect(mousedown.defaultPrevented).toBe(true); + expect(documentMousedown).not.toHaveBeenCalled(); + + row.element.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true })); + expect(insertMention).toHaveBeenCalledOnce(); + expect(insertMention).toHaveBeenCalledWith(user); + }); +}); diff --git a/packages/super-editor/src/editors/v1/components/popovers/Mentions.vue b/packages/super-editor/src/editors/v1/components/popovers/Mentions.vue index 0eb3021500..999aed5459 100644 --- a/packages/super-editor/src/editors/v1/components/popovers/Mentions.vue +++ b/packages/super-editor/src/editors/v1/components/popovers/Mentions.vue @@ -10,7 +10,7 @@ const props = defineProps({ type: String, default: '', }, - inserMention: { + insertMention: { type: Function, required: true, }, @@ -33,7 +33,7 @@ const getFilteredUsers = computed(() => { }); const handleClick = (user) => { - props.inserMention(user); + props.insertMention(user); }; const handleKeydown = (event) => { @@ -50,7 +50,7 @@ const handleKeydown = (event) => { } else if (event.key === 'Enter') { const user = getFilteredUsers.value[activeUserIndex.value]; if (user) { - props.inserMention(user); + props.insertMention(user); } } }; @@ -70,6 +70,7 @@ const handleFocus = () => { >
{ + insertMention: (user) => { const { $from } = this.state.selection; const length = atMention.length; const attributes = { ...user };