-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
feat(modifier): detectOverflow implementation #793
Conversation
I have a couple questions:
|
Yes this will just detect it, I haven't yet worked on the actual modifier that will alter the computed offsets. (but it should be trivial once this one works properly) The logic to detect the overflow is not stable, if you open the visual test cases you will notice there are a lot not working. |
Hey @FezVrasta , can you explain a bit how the visual test cases are not working with overflow? I can't seem to find it or don't know where to look. I have cloned, checked out to this branch and opened the visual page. |
@mykas please add a Then open the There are a lot of other cases like this. |
@inomdzhon I can't quite understand where a container ends and the other begins from your screenshots, but from what I can see it seems to work correctly in that case. |
Sorry for bad example 😞 |
Just a heads up, if you don't know how Flow works, feel free to ignore it and send PRs with broken type checking, I will take care of it. |
Actually, I write in TS so there will be no problem, thanks. Nevertheless, maybe I ignore it 🤔 |
The WIP implementation has the overflow detection based on the @FezVrasta have you got any rough ideas about what needs to be taken into account to get this to work? I'm guessing you've experimented with this a lot already. I'm assuming the scroll positions of each of the scroll containers is one aspect. I'm currently lost conceptually in what parts need to fit together to get this to work. A deep explanation of the problem and what needs to be achieved would be really helpful. @inomdzhon what ideas have you experimented with so far? |
Basically, the modifier should calculate all the offsets from the popper up to its scrolling container (common to the reference element), and then from that container, down to the reference element. Once you have these two measures, you should be able to detect if the popper is overflowing the container. It's been a while since the last time I touched this code so I may easily saying bullshit, sorry 😥 |
Is handling nested scroll containers the main difficulty? If so, maybe only handling one is good enough (same as v1), theoretically handling infinitely nested containers is great but it's pretty rare in real UIs, so if it's blocking this it's probably not worth it... assuming that is the reason of course. Or is it the difficulty in converting the "write" modifier to this "read" version with new architecture? 🤔 |
The multi scrolling container is the main issue, but I would love to have that. |
Is it possible to work on in a feat release after v2? I don't see a reason it should block since it doesn't exist in the lib yet anyway. |
AFAIK there's some basic support for that. |
@atomiks sure, it should based on the For example, we have two scroll parents. We should detect the popper is overflowing relative the closest scroll parent, if it is don't, we should go to the upper scroll parent, but now we should consider the previous scroll parent. Until I didn't start implementation 😩 |
I'm experimenting with an alternative approach to the problem, I'm using I use the state.modifiersData.detectOverflow = {
top: boundaryClientRect.top > popperClientRect.top,
bottom: boundaryClientRect.bottom < popperClientRect.bottom,
left: boundaryClientRect.left > popperClientRect.left,
right: boundaryClientRect.right > popperClientRect.right,
}; to detect the overflow state of each side. I'd love to have your feedback about this, do you see any obvious problem with this approach? |
this makes it easier to see if parts of the elements are hidden
This new implementation uses HTMLElement#getBoundingClientRect to obtain the coordinates of the elements relative to the viewport, this allows us to simplify the overflow detection logic, since we can ignore nesting, scrolling and a whole set of cases. The implementation coming with this commit is not yet finished.
Think there's a typo: - right: boundaryClientRect.right > popperClientRect.right,
+ right: boundaryClientRect.right < popperClientRect.right, That said, it seems... like a good solution on first intuition? I think I use the same thing in tippy.js for interactivity to see if the cursor left the popper - you don't need to take into account scrolls/nesting since as just "works" based on client coords. I think this concept is similar. I think I was getting confused with the offsets the popper uses to position itself (which needs to take all of that complexity into account) with detecting "intersection" (which is based on ClientRects), in attempting to solve this problem 😅 |
Thanks, I fixed the typo. I pushed a commit to fix the only remaining issue I was experiencing in the If anyone wants to fix it it'd be great. Also, if someone wants to test this implementation on all the other visual tests and report issues that'd be very helpful. @atomiks, the positioning logic is already working on this branch, and from what I could see it's very solid. |
Not sure what you mean, what remaining issue? The margin calculation seems to work from briefly testing it |
The |
Hmm should it be like bottom: boundaryClientRect.bottom + boundaryMargins.bottom, But why is the boundary margin being taken into account anyway? |
If you'd like to send a PR targeting this branch please do so 🤗 |
I'm not sure I understand the purpose of subtracting the boundary margin in the first place. When I remove the margins, the boolean switches to true correctly (I think, not sure what behavior you're looking for). I added margins to the popper and it switches correctly as well. I think the margins added to
|
I'm not sure, I'm too tired probably 😅 If you can get it to work it's okay to me, I'm not even sure if the margin thing is needed. |
* fix: remove boundary margin calc * refactor: remove redundant object * fix: revert object spread operator
I know one "problem" – |
@inomdzhon that's a good point, I haven't clear in my head the implications of this though. 🤔 |
I changed the default boundaryElement to be |
So the default boundary will no longer be |
🤦♂ yeah right... About At the moment I don't remember what qualifies one, but it should be something like edit: here's a few example of clipping containers, I think this kind of containers are the one that should be used by default. |
I was thinking that rather than reporting |
ok folks, I'm merging this PR. |
Does Hover over "Clear Console" icon down the bottom. Notice that the tippy overlaps due to the fact that it's in a scrolling parent. This is a common bug that people kinda struggle to fix (fixed with Maybe |
Still very work in progress, but since I'm stuck with this I'm sharing my progress hoping someone can help.
The idea is to provide a list of directions (top/right/bottom/left) set to either
true
(the popper is overflowing) orfalse
(it's not).This data is stored into a new
modifiersData
state object, which is going to be readable by other modifiers to leverage the data exposed by it.I think it would make sense to expose a stricter contract to disallow extensions from writing to other modifiers namespaces, but for now this gets the job done.