diff --git a/artifacts/tx-os/src/hooks/use-scroll-focused-dialog-field.ts b/artifacts/tx-os/src/hooks/use-scroll-focused-dialog-field.ts index fc90bd36..939c074d 100644 --- a/artifacts/tx-os/src/hooks/use-scroll-focused-dialog-field.ts +++ b/artifacts/tx-os/src/hooks/use-scroll-focused-dialog-field.ts @@ -24,6 +24,15 @@ import { useEffect } from "react"; */ export function useScrollFocusedDialogField(): void { useEffect(() => { + // Gate strictly to touch devices. Desktop browsers (mouse pointer) + // never open a soft keyboard, so scrolling the focused field would + // be unwanted movement. `pointer: coarse` matches touch-primary + // devices (iPad, iPhone, Android) and is stable across orientation + // / split-view changes, unlike visualViewport heuristics. + if (typeof window === "undefined" || typeof window.matchMedia !== "function") return; + const isTouch = window.matchMedia("(pointer: coarse)").matches; + if (!isTouch) return; + const isEditable = (el: Element | null): el is HTMLElement => { if (!el || !(el instanceof HTMLElement)) return false; const tag = el.tagName;