Repository navigation
fix(useLongPress): ignore emulated mouse events after a touch - #576
Conversation
🦋 Changeset detectedLatest commit: e49d856 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #576 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 70 70
Lines 2291 2307 +16
Branches 739 747 +8
=========================================
+ Hits 2291 2307 +16 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Thanks for the contribution!
Could you strengthen one test? In "calls onClick once for a tap followed by emulated mouse events", onLongPress is asserted without advancing the timers, so it passes even if the emulated mousedown starts the long-press timer. Advancing past delay first catches that:
await act(async () => {
vi.advanceTimersByTime(600);
});
Longer term, Pointer Events seem a better fit than a 1-second window, so I opened #580 for v1. Would you be interested in picking that up as well? The issue has the notes and references.
…ulated mouse test Co-authored-by: park gun hyung <qkrrjsgud49@gmail.com>
|
Thanks! I updated the test to advance past the delay before asserting onLongPress, so it now catches the long-press timer starting from the emulated mousedown. Happy to take #580 as well. |
Overview
On touch devices,
useLongPresscallsonClicktwice for one tap.After
touchend, browsers fire emulatedmousedown/mouseup(thenclick) on the same element. The hook attaches both touch and mouse handlers, so the emulatedmousedownstarts a second press and the emulatedmouseupcallsonClickagain. After a long press from touch, the same emulated events callonClickright afteronLongPressEnd.Repro (Chromium via Playwright with
hasTouch/isMobile,page.tap()on a button usinguseLongPress(onLongPress, { onClick, onLongPressEnd })):mainclick, clickclicklongPress, longPressEnd, clicklongPress, longPressEndclickclickThe event order Chromium dispatches for the tap is
touchstart, touchend, mousedown, mouseup, click.Fix: the hook records the time of the last
touchstart/touchendit handled, and a mouse press that starts less than 1 second after that is ignored. Ignoring themousedownis enough: the followingmouseupthen finds no pending press and does nothing. Mouse input more than 1 second after a touch works as before, so hybrid touch/mouse devices keep both inputs.Tests added:
mousedown/mouseup→onClickonce (fails onmain: called 2 times)onClick(fails onmain: called once)Added a patch changeset.
Checklist
yarn run fixto format and lint the code and docs? (ranyarn lintandprettier --list-differenton the changed files; no new warnings)yarn run test:coverageto make sure there is no uncovered line? (100%;test:compiledalso passes)