minwork / use-long-press

React hook for detecting click (or tap) and hold event
MIT License
120 stars 12 forks source link

Use events also on the document! let me explain... #48

Closed aPinix closed 1 year ago

aPinix commented 1 year ago

Imagine this dribbble example rating modal example...

  1. Long press opens a rating modal while mouse down
  2. Swipe to rate even outside the modal with screen coordinates from document
  3. Don't forget that the click does trigger another action, so I use the cancel to do this

I made a Stackblitz, which can be better, of course, but you get the idea (maybe I'll clean it later, it was just a quick prototype that was defined on the go).

Thanks in advance, and congrats on this awesome plugin!

CleanShot 2023-03-17 at 18 41 50

minwork commented 1 year ago

Hey, I am not sure what exactly you are trying to achieve, although if you want, you can bind events to any element or even call them manually since bind() returns object with callbacks like { onMouseDown: ..., onMouseMove: ..., onMouseUp: ..., ... } etc. so you can also do something like: const handlers = bind(); and then use handlers.onMouseDown(...(event here)...) anywhere in the code even like window.addEventListener('mousedown', (event) => { handlers.onMouseDown(...) });

Let me know if that addresses your case.

aPinix commented 1 year ago

Sorry for the late response, and thank you for your comment.

If you see, I am using bind twice, one for the Rating and another on an upper level to get the Screen coordinates on the Move action.

It works beautifully with Mouse but fails to succeed in Touch (tried in Chrome, Emulating a device, and on an iPhone).

My questions are:

  1. Could it be possible to target another element for a specific event? (e.g. document.body only on Move)
  2. How can I get Touch not to cancel and behave like Mouse on longPress?
minwork commented 1 year ago

Hey @aPinix,

  1. I think you could accomplish that by binding onMouseMove or onTouchMove directly to document.body listener by doing it like const bind = useLongPress(...); const {onMouseMove, onTouchMove, ...handlers} = bind(...); document.body.addEventListener('mousemove', (event) => { onMouseMove(event) /* you may need to wrap event in order to be accepted as react event */ } document.body.addEventListener('touchmove', ...)
  2. Have you tried using detect: LongPressDetectEvents.TOUCH or detect: LongPressDetectEvents.MOUSE only instead of BOTH?
github-actions[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

minwork commented 1 year ago

Hey @aPinix I think now understand your problem better. onMouseUp / onTouchEnd should be detected on window instead of on element so it will handle when mouse / touch is released outside it. I will address this issue in v3 along with adding support for pointer events which can use setPointerCapture.

I will let you know when it will be available.

aPinix commented 1 year ago

You're amazing dude. Awesome work here! Thanks a bunch in advance. Can't wait to hear from you.

minwork commented 1 year ago

@aPinix Try out use-long-press@3.0.0-rc.1 and let me know if that helps in your case.

minwork commented 1 year ago

Version 3 which addresses this issue is now available at use-long-press@latest