mirror of
https://github.com/vercel/next.js.git
synced 2026-09-20 02:25:18 +08:00
c5741d5230
Fixes #98468 ## Claude explanation of the fix `useDrag` listened for `pointermove` and `pointerup`, but never `pointercancel`. When a user agent cancels a gesture — a browser or system gesture takes over, a second finger arrives — it fires `pointercancel` and no `pointerup`, implicitly releasing pointer capture as it does. So `cancel()` never ran: the state machine stayed `{ state: 'drag' }` and `cleanup.current` was never invoked, leaving the `pointermove`/`pointerup` listeners on `window`. The next `pointerup` anywhere on the page then hit those orphaned listeners, reached `cancel()` with the state still `'drag'`, and called `releasePointerCapture()` on a pointer that no longer existed — the reported `NotFoundError`. Each cancelled drag also leaked another listener pair. This registers `pointercancel` alongside `pointerup` and removes it in the same cleanup, so the machine unwinds when a gesture is cancelled; and it releases pointer capture only when `hasPointerCapture()` says it is still held, which is preferable to `try/catch` swallowing genuine faults too. Note `touch-action: none` (#97723) removed the common touch trigger, but not the defect: on canary a forced `touchCancel` still throws. https://github.com/user-attachments/assets/45a9524d-9ffa-40b6-b59a-5af9d947f8c7 ## Fixed version https://github.com/user-attachments/assets/b5ada68c-7442-42ef-a256-bacc512fbeca ## Browser checks - [x] Chrome, as describe by the bug report - [x] FF works fine pre and post fix (with and without the pointer simulation) - [x] iOS safari simulator, before the fix, I can't see an error, but, the drag gets frozen, with this fix it works correctly https://github.com/user-attachments/assets/bcfdc786-bada-4462-b530-299523fdca6d 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>