diff --git a/packages/web/src/components/ui/ContextMenuRenderer.tsx b/packages/web/src/components/ui/ContextMenuRenderer.tsx index c3980a72..cc7b7123 100644 --- a/packages/web/src/components/ui/ContextMenuRenderer.tsx +++ b/packages/web/src/components/ui/ContextMenuRenderer.tsx @@ -550,10 +550,10 @@ function useGlobalLongPress(isMobile: boolean) { }; const onTouchStart = (e: TouchEvent) => { - const target = e.target as HTMLElement; - if (target.closest('[data-context-menu]')) { - e.preventDefault(); - } + // NOTE: Do NOT call e.preventDefault() here — it kills the synthesized + // click event on mobile (touchstart → touchend → click chain). + // Text selection prevention is handled by CSS user-select: none on + // [data-context-menu] elements (see globals.css). if (e.touches.length !== 1) { cancel(); return; } const touch = e.touches[0]!; originX = touch.clientX; @@ -604,7 +604,7 @@ function useGlobalLongPress(isMobile: boolean) { } }; - document.addEventListener('touchstart', onTouchStart, { passive: false }); + document.addEventListener('touchstart', onTouchStart, { passive: true }); document.addEventListener('touchmove', onTouchMove, { passive: true }); document.addEventListener('touchend', onTouchEnd, { passive: true }); document.addEventListener('touchcancel', onTouchEnd, { passive: true });