diff --git a/.gitignore b/.gitignore index f0c8d3a..61098b5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ ref .DS_Store node_modules dist -notes.md \ No newline at end of file +notes.md +*.tgz \ No newline at end of file diff --git a/packages/react/src/hooks/__tests__/useSearchHotkey.test.ts b/packages/react/src/hooks/__tests__/useSearchHotkey.test.ts index 07bd538..5da5292 100644 --- a/packages/react/src/hooks/__tests__/useSearchHotkey.test.ts +++ b/packages/react/src/hooks/__tests__/useSearchHotkey.test.ts @@ -22,6 +22,13 @@ function appendTo(parent: HTMLElement, tag: string): HTMLElement { return el } +/** Viewport renders an , NodeRenderer a — canvas clicks are SVG. */ +function appendSvgTo(parent: Element, tag: string): SVGElement { + const el = document.createElementNS('http://www.w3.org/2000/svg', tag) + parent.appendChild(el) + return el +} + function click(target: EventTarget): void { target.dispatchEvent(new PointerEvent('pointerdown', { bubbles: true })) } @@ -211,4 +218,39 @@ describe('useSearchHotkey', () => { expect(first).not.toHaveBeenCalled() expect(second).toHaveBeenCalledTimes(1) }) + + it('toggles after a node is clicked', () => { + const onToggle = vi.fn() + mount(onToggle) + + const svg = appendSvgTo(container, 'svg') + click(appendSvgTo(svg, 'g')) + const prevented = pressCmdF(document.body) + + expect(onToggle).toHaveBeenCalledTimes(1) + expect(prevented).toBe(true) + }) + + it('toggles after the empty canvas surface is clicked', () => { + const onToggle = vi.fn() + mount(onToggle) + + click(appendSvgTo(container, 'svg')) + const prevented = pressCmdF(document.body) + + expect(onToggle).toHaveBeenCalledTimes(1) + expect(prevented).toBe(true) + }) + + it('still hands Cmd+F back after a canvas click then a host-app click', () => { + const onToggle = vi.fn() + mount(onToggle) + + click(appendSvgTo(container, 'svg')) + click(appendTo(chatPanel, 'div')) + const prevented = pressCmdF(document.body) + + expect(onToggle).not.toHaveBeenCalled() + expect(prevented).toBe(false) + }) }) diff --git a/packages/react/src/hooks/useSearchHotkey.ts b/packages/react/src/hooks/useSearchHotkey.ts index bb9e3d9..e1ea332 100644 --- a/packages/react/src/hooks/useSearchHotkey.ts +++ b/packages/react/src/hooks/useSearchHotkey.ts @@ -58,7 +58,10 @@ export function useSearchHotkey( useEffect(() => { const onPointerDown = (e: PointerEvent) => { const container = containerRef.current - const el = e.target instanceof HTMLElement ? e.target : null + // `Element`, not `HTMLElement`: the canvas surface is an , so a + // click on a node, an edge or the background targets an SVGElement and + // would otherwise read as a click *outside* the canvas. + const el = e.target instanceof Element ? e.target : null canvasActiveRef.current = !!container && !!el && container.contains(el) }