atomiks / tippyjs

Tooltip, popover, dropdown, and menu library
https://atomiks.github.io/tippyjs/
MIT License
11.86k stars 520 forks source link

Touch does not close manually triggered tippy #1063

Open mmarczell-graphisoft opened 2 years ago

mmarczell-graphisoft commented 2 years ago

Bug description

I would like to use both mouse right click and touch screen long press to bring up a tippy popover, and use mouse click or tap to close it. The click event does close the popover as expected, but the touch event does not.

Reproduction

CodePen link: https://codepen.io/mmarczell-graphisoft/pen/RwQzvZb

Notes

It is the onDocumentPress function that closes the tippy in the mouse case. It is registered for both mousedown and touchend events. However, when the event is inside the trigger target or reference element, it returns early on touch, here: https://github.com/atomiks/tippyjs/blob/ad85f6feb79cf6c5853c43bf1b2a50c4fa98e7a1/src/createTippy.ts#L315-L322

My first attempt at a workaround was settings props.triggerTarget to some invisible dummy element, so that the event is never inside it, skipping this if block. That still did not work on touch, because of the discrepancy between mousedown (start of click and touchend (end of touch). The end of the longpress event immediately closes the tippy in this case after opened, which is undesired. Would it be a good idea to change touchend to touchstart, or even replace both mouse and touch with pointerdown?

caseymilne commented 2 years ago

I think I've found the same issue. Reported to me was that on mobile, click opens and closes as expected. Scroll does not close the tooltips made by Tippy. In this case these were not triggered manually or in code. They were opened using click. Clicking outside works fine.

When the page is scrolled with the tooltip opened, the tooltip scrolls with it's target element up the page. In our UI the element happens to be in a scrollable div, so the when the element itself disappears via scrolling, we have this ghost tooltip sitting above everything near the top of the mobile device.

My theory is that the touch event for scrolling is not captured? I've confirmed this in tests on Android, and my client reported it from an iPhone.

atomiks commented 2 years ago

It determines if the tap outside was "intentional" vs. they just tried to scroll away instead of intentionally dismissing it. For a popover, that sounds good, but maybe not for a tooltip? It sounds like you want the opposite behavior