Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[@mantine/hooks]: fix unstable pinning of item by useHeadroom on mobile devices #5793

Merged
merged 2 commits into from
Mar 12, 2024
Merged

[@mantine/hooks]: fix unstable pinning of item by useHeadroom on mobile devices #5793

merged 2 commits into from
Mar 12, 2024

Conversation

Alimobasheri
Copy link
Contributor

fixes #4563

In order to fix the issue, I actually had to change the code logic for checking pin status. The isPinned function was previously used every time the scrollPosition returned by useWindowScroll changed. This is useless as causes the issue as when an address bar hides on scroll in mobile browser, a resize event is fired by the browser, but the scrollPosition hasn't actually changed.

if (isPinned(scrollPosition, scrollRef.current)) {
    return true;
  }

In the above code, both scrollRef.current and scrollPosition hold the same value and don't offer a clear comparison.
This line of code is useless because the next condition call after it which calls isFixed with scrollPosition and the fixedAt value is the only true logic for this hook's implementation.

if (isFixed(scrollPosition, fixedAt)) {
    return true;
  }

I also changed the logic for calling onPin and onRelease callbacks. The ref which was previously used to hold the scrollPosition was actually used for wrong comparison. The onPin callback in my opinion should get called only when the pinning element has switched state from pinned to unpinned or vice versa, when the scrollPosition changes. In the current code, onPin is getting called so many times as user scrolls, this doesn't make sense. So, I have merged the logic of two past useEffects into a single one. I store the pinning status in a ref to prevent extra re-render.

I have marked this PR as a draft to make sure you inspect those changes and I hope this explanation clarifies them for you.

…bile devices

[@mantine/hooks]: refactor the onPin and onRelease logic to prevent excessive calls of onPin
@rtivital
Copy link
Member

Thanks for sending a PR! Unfortunately, it does not work. The header does not become visible when the page is scrolled up.

2024-02-26.17.26.47.mov

@rtivital rtivital added the Invalid Incorrect issue or PR label Feb 26, 2024
@Alimobasheri
Copy link
Contributor Author

@rtivital you're right. I hadn't paid attention to this part of the doc. But the old solution for this, conflicts with mobile device's resize event when the address bar hides. The user hasn't actually scrolled up in that case. Because this particular resize event doesn't change the scrollPosition or the top position of it.
A solution can be adding another hook which returns the scroll direction based on these conditions: 1. A scrollEvent has happened (not a resize one) 2. And the user is still scrolling up
I mean the current code is tricky to be fixed, since it still has to take resize event into consideration for the fixed position.

And do you agree that the current code calls the onPin event excessively? Or is that part of the PR invalid too?

@rtivital
Copy link
Member

I haven't really explored this issue. The hook was contributed by other community member, so it should either be fixed or rewritten from scratch.

@Alimobasheri
Copy link
Contributor Author

So I will try to update this PR with the fix for the issue you mentioned.

added useScrollDirection to handle if user is scrolling up and make sure the scroll is not caused by a resize event like mobile address bar showing
@Alimobasheri
Copy link
Contributor Author

@rtivital I've pushed a new commit which fixes the issue with scroll up.

I had to add the useScrollDirection hook specifically in the code to make sure the user is scrolling up. And I had to add a debounce for resize events in that hook.
This debounce makes sure the scrollTop isn't changed by a resize event (like the address bar hiding) and so the user is actually scrolling up.

@Alimobasheri Alimobasheri marked this pull request as ready for review March 10, 2024 10:01
@rtivital rtivital removed the Invalid Incorrect issue or PR label Mar 12, 2024
@rtivital rtivital merged commit 25310bd into mantinedev:master Mar 12, 2024
1 check passed
@rtivital
Copy link
Member

Thanks! Works correctly on mobile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BUG] use-headroom behaves weird on mobile devices
2 participants