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

Floating UI Position Incorrect When Modal is Nested Inside Drawer Component #2858

Closed
ChellappanRajan opened this issue Apr 12, 2024 · 5 comments · Fixed by #2887
Closed

Floating UI Position Incorrect When Modal is Nested Inside Drawer Component #2858

ChellappanRajan opened this issue Apr 12, 2024 · 5 comments · Fixed by #2887
Labels
bug Something is not working. has workaround

Comments

@ChellappanRajan
Copy link

We have developed custom modal, drawer, and datepicker components as web components using ShadowDOM. These components utilize the 'popover' attribute and 'floating-ui' internally for positioning the datepicker container. However, when we place a modal inside a drawer and then place a datepicker inside the drawer, the floating UI position becomes incorrect.

In the parent modal, I have applied 'transform: translate(-50%,-50%)'. If I remove that, the datepicker and floating UI positions work correctly.

I have created a repository here.

To see the issue, click the 'show drawer' button to open a new drawer on the right side. Then, click the input element; the panel position is incorrect.

Screenshots If applicable, add screenshots to help explain your problem.

Context:

  • OS: [e.g. iOS]
  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]

Additional context Add any other context about the problem here.

@atomiks
Copy link
Collaborator

atomiks commented Apr 15, 2024

Is this not correct?
Screenshot 2024-04-15 at 11 55 25 PM

@ChellappanRajan
Copy link
Author

Is this not correct? Screenshot 2024-04-15 at 11 55 25 PM

It is working fine on a small screen; however, if I go fullscreen on this page (https://vitejsvitejzzg6c-drf5--5173--7dbe22a9.local-credentialless.webcontainer.io/) and open the drawer, then clicking on the input field to open the panel causes the floating panel's position to be incorrect.

Screenshot 2024-04-15 at 10 26 42 PM

@atomiks
Copy link
Collaborator

atomiks commented Apr 16, 2024

Hmm, yeah I see that as well. Not sure what would cause it so will need some investigating.

transform: translate(-50%,-50%)

A new "containing block" gets created in this situation, and most positioning bugs that appear now seem to be related to handling this layout situation

Looks like it's related to collision detection when using shift(). When removing that middleware, it's positioned correctly. One possible workaround is to use an empty boundary shift({ boundary: [] }) instead of the default clippingAncestors. Now it will only detect the root viewport collision instead of the incorrectly-calculated clippingAncestors, which may be fine in many situations with top-layer elements...

@atomiks atomiks added bug Something is not working. has workaround labels Apr 16, 2024
@ChellappanRajan
Copy link
Author

Hmm, yeah I see that as well. Not sure what would cause it so will need some investigating.

transform: translate(-50%,-50%)

A new "containing block" gets created in this situation, and most positioning bugs that appear now seem to be related to handling this layout situation

Looks like it's related to collision detection when using shift(). When removing that middleware, it's positioned correctly. One possible workaround is to use an empty boundary shift({ boundary: [] }) instead of the default clippingAncestors. Now it will only detect the root viewport collision instead of the incorrectly-calculated clippingAncestors, which may be fine in many situations with top-layer elements...

Thank you for sharing the workaround. There is one more issue I found in our application regarding the issue with the hide middleware, it seems that it returns 'hide', which might be causing the panel to not open consistently. Do you think this could be related to the same issue you mentioned earlier


If I set the display property based on the hide flag, the panel always remains closed.

export function useFloatingUI(trigger: any, panel: any) {
  computePosition(trigger, panel, {
    middleware: middleware,
    strategy: 'fixed',
  }).then(({ x, y, middlewareData }) => {
    const { hide } = middlewareData;
    Object.assign(panel.style, {
      left: `0px`,
      top: `0px`,
      transform: `translate(${x}px, ${y}px)`,
      // display:hide ? 'none': 'block'
    });
  });
}

@atomiks
Copy link
Collaborator

atomiks commented Apr 16, 2024

Yeah most likely the same issue, if you add boundary: [] for hide() as well, it should work. This also goes for autoPlacement, and any other visibility-optimizer ones that perform collision detection.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something is not working. has workaround
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants