Skip to content

fix: open image previews from touchend so iOS taps don't raise the keyboard#263

Merged
ocavue merged 2 commits into
prosekit:masterfrom
maccman:fix/ios-image-tap-keyboard
Jul 8, 2026
Merged

fix: open image previews from touchend so iOS taps don't raise the keyboard#263
ocavue merged 2 commits into
prosekit:masterfrom
maccman:fix/ios-image-tap-keyboard

Conversation

@maccman

@maccman maccman commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Problem

#253 prevented pointerdown on image previews so a touch tap wouldn't focus the editor. That suppresses the compatibility mouse events, but on iOS WebKit tap-to-focus is a native gesture default action tied to the touch event stream: tapping an image preview still focuses the surrounding contenteditable and briefly raises the software keyboard, right as the click handler opens its own surface (e.g. a lightbox) — a visible keyboard show/hide flash on every image tap.

Fix

The only thing that stops WebKit's synthetic-click/focus path is cancelling the tap's touchend. That also suppresses the synthetic click, so defineImageClickHandler now recognizes taps itself:

  • touchstart records a single-finger touch on a preview (touches on the resize handle are excluded — they start a resize, never a tap)
  • touchmove past a 10px tolerance invalidates it (scroll/drag)
  • touchend on a still-valid tap calls preventDefault() and fires onClick directly

Mouse clicks keep going through handleClick unchanged, and the #253 pointerdown guard stays for non-WebKit touch surfaces.

ImageClickPayload.event widens to MouseEvent | TouchEvent since the touch path hands the handler the originating touchend.

Testing

  • 3 new browser tests: a stationary tap fires onClick once with the touchend cancelled; a moved touch is ignored and left uncancelled; a tap on the resize handle is left alone.
  • pnpm exec vitest run --project @meowdown/core image — 27/27 pass.
  • pnpm typecheck clean; changed files lint clean.
  • Manual verification in the Reflect iOS app (where the flash reproduces) is in progress on the consumer side.

🤖 Generated with Claude Code

…yboard

Preventing pointerdown (prosekit#253) suppresses the compatibility mouse events,
but iOS WebKit's tap-to-focus is a native gesture default action: tapping
an image preview still focuses the surrounding contenteditable and briefly
raises the software keyboard before the click handler opens its surface
(e.g. a lightbox). Only cancelling the tap's touchend stops it — which
also suppresses the synthetic click, so the image click handler now tracks
single-finger taps on previews itself (movement tolerance, resize-handle
and multi-touch exclusions) and fires onClick from touchend.

ImageClickPayload.event widens to MouseEvent | TouchEvent accordingly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 8, 2026

Copy link
Copy Markdown

@maccman is attempting to deploy a commit to the ocavue's projects Team on Vercel.

A member of the Team first needs to authorize it.

@pkg-pr-new

pkg-pr-new Bot commented Jul 8, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/prosekit/meowdown/@meowdown/core@263
npm i https://pkg.pr.new/prosekit/meowdown/@meowdown/react@263

commit: 2d6eba6

Desktop WebKit exposes the Touch interface but its constructor throws
("Illegal constructor"); the tap logic stays covered by chromium and
firefox.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@maccman maccman requested a review from ocavue July 8, 2026 10:24
@ocavue ocavue merged commit 89aa7e7 into prosekit:master Jul 8, 2026
10 checks passed
maccman added a commit to team-reflect/reflect-open that referenced this pull request Jul 8, 2026
prosekit/meowdown#263 landed as 89aa7e7 and shipped in 0.40.0 (0.40.1
is the latest patch). Bumping the pinned range since ^0.39.0 does not
resolve past 0.39.x for a 0.x package.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants