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

Shift middleware with a boundary doesn't respect bondary bottom edge #2784

Open
VojtechVidra opened this issue Feb 9, 2024 · 10 comments
Open

Comments

@VojtechVidra
Copy link

Describe the bug

Shift middleware with a boundary and rootBoundary: "viewport" doesn't respect bottom edge of boundary when scrolling down. I've read through the shift middleware docs couple of times and haven't found a way to solve this issue.

To Reproduce

https://codesandbox.io/p/sandbox/tender-fermat-ygc24n

Steps to reproduce the behavior:

  1. Start scrolling the whole page of the CodeSandbox Preview.
  2. You will see the tooltip start to shift thanks to top edge of the viewport.
  3. I would expect bottom of the tooltip to stop at the edge of the boundary.
  4. The tooltip doesn't stop and is shifting outside the boundary.

Expected behavior

The tooltip always stays inside of the boundary. This works correctly when scrolling up/resizing the window height until the tooltip is shifted due to the bottom viewport edge but then top of the tooltip stops on the top edge of the boundary.

Screenshots

Correct behavior when scrolling up/resizing the window height.
image

Incrorrect behavior when scrolling down.
image

Context:

  • OS: MacOS
  • Browser: Chrome
  • Version: 120

Additional context

I tried this and it works correctly for all sides except bottom (scrolling down). It can kindof be fixed by limiter but not quite, because the tooltip still escapes the boundary, but then stops when it meets the opposite edge of the reference element.

@atomiks
Copy link
Collaborator

atomiks commented Feb 9, 2024

The key issue is the clipping algorithm has a bias toward top/left over bottom/right when both sides are clipped (in this case, the root boundary/viewport and element boundary).

  • Top screenshot: bottom gets clipped by the root viewport in order to respect the element boundary (biased to top)
  • Bottom screenshot: bottom overflows boundary in order to respect the root boundary (again, biased to top)

So in this case, you want the bias not to be toward a side but rather the element boundary, right?

@VojtechVidra
Copy link
Author

I think you got it right. I would expect that boundary would take precedence over rootBoundary. Yes the rootBoundary should shift the tooltip but only to the edge of the boundary.

@VojtechVidra
Copy link
Author

Do you think this behavior can be achieved with current version of Floating UI?

@atomiks
Copy link
Collaborator

atomiks commented Feb 13, 2024

Not straightforwardly, it would require custom middleware instead of shift, and using detectOverflow most likely.

@VojtechVidra
Copy link
Author

It would be great to have this feature, however it's not super ciritcal for me. So feel free to close this issue 🙂

Thanks for the clarification 🙂

@Yegorich555
Copy link

Try to use web-ui-pack/popup instead 🙂

@atomiks
Copy link
Collaborator

atomiks commented Apr 9, 2024

@Yegorich555 it doesn't seem like that handles the "root" viewport in the first place. It overflows the viewport if the bottom of the viewport is above the boundary bottom.

Screenshot 2024-04-09 at 5 17 50 PM

You can already achieve that behavior in Floating UI with rootBoundary: "document":

shift({ boundary: container, rootBoundary: 'document' })

This issue describes a more complicated scenario with multiple boundaries.

@Yegorich555
Copy link

Yegorich555 commented Apr 9, 2024

@atomiks it does whatever you want, In example 3 it fits the specific container to demonstrate position-behavior
By default it fits the body of course + here customized option placement,
image
image

@atomiks
Copy link
Collaborator

atomiks commented Apr 9, 2024

I'm talking specifically about multiple boundaries, or in that API, multiple elements for fitToElement. If you specify a boundary in Floating UI, it doesn't cause the popover to start overflowing the viewport as in the example I screenshotted. The root boundary is considered separate. It can be changed to document to replicate a "single" boundary/fitToElement (aside from still avoiding overflowing the whole document page).

@Yegorich555
Copy link

Yegorich555 commented Apr 9, 2024

@atomiks the suggested solution defines multiple boundaries automatically based on overflow content scenario. So you need to point the single root boundary. Other possible cases automatically resolves so you don't need to think about extra-scenarios and extra boundaries at all.

And thanks for explanation: I've found the similar issue in the example 3 (here popup checks only visible area of target but not itself)

But I don't unsertand, why need to try place popup inside 1st small scrollable area when popup actually should be placed over it to allow the user to use as much viewport as possible - like it works with Chrome popups by default. In you example it's really bad UX and I think floating-ui is correct here.
Popup really should be attached to the target and position itself inside viewport/root boundary in a proper way. But in your case popup should be partially hidden according to requirement - I think it's not ok for end-user

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

No branches or pull requests

3 participants