gmrchk/blobity

BUG: Issue with react-router

PickleyD opened this issue · 5 comments

When content is switched out by react-router the blob gets stuck at (0,0) until the cursor hovers over another focusable element.

Try clicking 'Roster' followed by a name from the list on this react-router demo.
https://codepen.io/floop-the-pig/pen/abyrjvG

Have tried working around this with the focusElement and reset API methods but couldn't find anything that worked.

This is not an issue especific do react-router. It happens every time an focusableElement is removed from the DOM while the cursor is inside it. This way the function focusableElementMouseLeave is never called and consequently blobity still thinks you are inside the focusableElement.

Here is a codepen only with vanilla Blobity in it: https://codepen.io/gabrielkuhn/pen/MWEVeOa

I can't think of anything to workaround this from the user end. It's something that needs to be fixed in the lib.

I've been sponsoring this amazing library for a few months now, and this bug is my only gripe!

For UX, it's hard to rely on Blobity as a hover state when it sometimes disappears when routing lots on a PWA.

Thank you for the patience guys, it's been hard getting to all this fun stuff. And thank you for the nice pen examples of the issue!

What do you think about this solution? It should generally fix the issue reported, but would that help the usage in SPAs in general, or am I missing something?
#13

The demo included.
https://deploy-preview-13--serene-benz-218f72.netlify.app/

Thanks for taking a look at this! Your solution makes sense to me but I wonder is it resilient to the case where a parent or grandparent of the subject element is removed (causing a cascading removal) instead of just the element directly? 🤔 This is usually what would happen when navigating pages in a SPA. Could be worth testing that case too

I'm not too familiar with MutationObserver yet, so good point @PickleyD. Thanks for bringing it up. While I would expect it to cascade down, it looks like you're right, the event is actually not being triggered when one of the parent elements is being removed.
That leaves us with two options:

  1. Watch for element removals in the whole body, and detect when the element, or its parent containing the element, is being removed. While I was avoiding this approach because of fear of performance implications, the functionality can be structured in a way that the observing only happens when some of the focusable elements are being hovered. While there can be some mutations to DOM happening during that period, the observer is disabled for the majority of the time. We're also only watching for element add/remove, so the callback shouldn't be triggered that often. Surely, the changes to DOM should also be minimal since we can expect the interaction by user to be minimal, as they are still only hovering over one element while the observing is happening. This is the solution updated in the PR #13 and can be tested here with the grandparent being removed.
  2. Provide a callback to manually reset the cursor blob when events like navigation happen. This would be more flexible, but since the situation would require checking whether the element at hand is removed, and how the DOM is manipulated, we can expect it to be often quite cumbersome to implement.

I'm quite liking the #13 at the end. Please, let me know what you think.