diff --git a/frontend/src/lib/shared/discussion/PersonMentionEditor.svelte.spec.ts b/frontend/src/lib/shared/discussion/PersonMentionEditor.svelte.spec.ts index 195da335..ae15e31d 100644 --- a/frontend/src/lib/shared/discussion/PersonMentionEditor.svelte.spec.ts +++ b/frontend/src/lib/shared/discussion/PersonMentionEditor.svelte.spec.ts @@ -1333,3 +1333,54 @@ describe('PersonMentionEditor — #628 editing announce', () => { }); }); }); + +// ─── #628 review fixes: hidden-pencil hit-testing + mid-session disable ─────── + +describe('PersonMentionEditor — #628 review fixes', () => { + it('keeps the hidden pencil out of hit-testing (pointer-events-none until revealed)', async () => { + // opacity-0 alone still hit-tests, and the 44px button overhangs adjacent + // text — so a click in the gap between mentions would otherwise land on the + // invisible pencil and open the dropdown (AC-8). It must be pointer-events-none + // while hidden and only become clickable together with the opacity reveal. + renderHost({ value: '@Aug ', mentionedPersons: [{ personId: 'p-aug', displayName: 'Aug' }] }); + await vi.waitFor(() => + expect(document.querySelector('[data-type="mention"] button')).not.toBeNull() + ); + const btn = document.querySelector('[data-type="mention"] button') as HTMLElement; + expect(btn.className).toContain('pointer-events-none'); + expect(btn.className).toContain('group-hover/mention:pointer-events-auto'); + expect(btn.className).toContain('group-focus-within/mention:pointer-events-auto'); + }); + + it('re-syncs the pencil to inert when the editor is disabled mid-session', async () => { + // editor.setEditable() emits "update", not a transaction — the NodeView must + // listen on "update" or a runtime disable flip leaves the pencil stale. + let setDisabled!: (value: boolean) => void; + render(PersonMentionEditorHost, { + initialValue: '@Aug ', + initialMentions: [{ personId: 'p-aug', displayName: 'Aug' }], + disabled: false, + onChange: () => {}, + onReady: (api: { setDisabled: (value: boolean) => void }) => { + setDisabled = api.setDisabled; + } + }); + + await vi.waitFor(() => { + const btn = document.querySelector( + '[data-type="mention"] button' + ) as HTMLButtonElement | null; + expect(btn).not.toBeNull(); + expect(btn!.disabled).toBe(false); + }); + + setDisabled(true); + + await vi.waitFor(() => { + const btn = document.querySelector('[data-type="mention"] button') as HTMLButtonElement; + expect(btn.disabled).toBe(true); + expect(btn.getAttribute('aria-disabled')).toBe('true'); + expect(btn.tabIndex).toBe(-1); + }); + }); +}); diff --git a/frontend/src/lib/shared/discussion/PersonMentionEditor.test-fixture.svelte b/frontend/src/lib/shared/discussion/PersonMentionEditor.test-fixture.svelte index cdc31df0..d59daa42 100644 --- a/frontend/src/lib/shared/discussion/PersonMentionEditor.test-fixture.svelte +++ b/frontend/src/lib/shared/discussion/PersonMentionEditor.test-fixture.svelte @@ -1,5 +1,5 @@