ycs77 / headlessui-float

Easily use Headless UI with Floating UI to position floating elements.
https://headlessui-float.vercel.app
MIT License
342 stars 11 forks source link

Vue: Nested floating elements breaks when using static and show props #109

Closed FredrikAnkarang closed 3 months ago

FredrikAnkarang commented 3 months ago

Use Version Use version when bugs appear:

Describe the bug Nesting floating components seems to work well when using Headless UI's own control of display. But when using a static outer floating element and the show prop on the Float component, the nested float's positioning is wrong. It is positioned in the top left corner. See videos below.

To Reproduce https://stackblitz.com/edit/github-bwkajw?file=src%2Fpages%2Fpopover.vue

  1. Choose Popover Component in the menu.
  2. Try opening the nested popover.
  3. If we remove the "show" prop from the Float component and the "static" prop from PopoverPanel it works as expected.

Screenshots

https://github.com/ycs77/headlessui-float/assets/17514769/62e0eede-6189-461b-8106-71065e64bfda

Expected behavior

https://github.com/ycs77/headlessui-float/assets/17514769/b77b680a-bac6-4071-b4f1-dcd9105b16d2

FredrikAnkarang commented 3 months ago

It works as expected if I remove the PopoverButton from the example and just use a regular button instead. I guess there is no need for using a PopoverButton if you are controlling the show/hide yourself for the nested floating element. But the problem would persist if one wanted to have a static outer floating element containing a "normal" nested one (show/hide controlled by Headless UI).

After looking at the source code it seems like the problem is in the renderReferenceElement function. This function calls cloneVNode on the reference element and adds a ref to it. This ref is later used to get the dom-element for the reference so that floating UI can position the floating element correctly in the useFloat() composable.

When using the PopoverButton this ref won't point to the reference element (instead its value is null) as opposed to when using a regular button it points to it as it should. Not sure why this is though... I'm no expert with render functions.

ycs77 commented 3 months ago

Hi @FredrikAnkarang, because the problem I think is affected by Headless UI, so I can't to fixed.

I created this package to float the Headless UI component quickly, and non-invasive to the Headless UI, just supported floating the basic usage for the Headless UI example.

If you want to fix this problem I suggest you create a new custom popover component of the static popover and match the Floating UI Vue to position the custom popover component and add the arrow, this will solve your problem.