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

Example with popper + portal + transition #154

Closed
vincaslt opened this issue Nov 23, 2020 · 6 comments
Closed

Example with popper + portal + transition #154

vincaslt opened this issue Nov 23, 2020 · 6 comments

Comments

@vincaslt
Copy link

Could we get an example of usage with popper and transition in portal?

This example is helpful: https://github.com/tailwindlabs/headlessui/blob/develop/packages/%40headlessui-react/pages/menu/menu-with-transition-and-popper.tsx

However, it doesn't work when we put Portal into play. Just wrapping with Portal will either remove transitions or the dropdown will disappear after the transition depending on what you wrap inside of your Portal.

I kinda made it work (using their own hook) with code like this:

<Portal>
  <Transition
    show={isOpen}
    enter="transition ease-out duration-100"
    enterFrom="transform opacity-0 scale-95"
    enterTo="transform opacity-100 scale-100"
    leave="transition ease-in duration-750"
    leaveFrom="transform opacity-100 scale-100"
    leaveTo="transform opacity-0 scale-95"
  >
    {(ref) => (
      <div
        ref={setPopperElement}
        {...popperProps}
      >
        <div
          ref={ref}
        >
          {children}
        </div>
      </div>
    )}
  </Transition>
</Portal>

It animates enter, but it fails to animate leave though. Also, this is only a custom dropdown element, it becomes even more complicated and fragile with Listbox or Menu. Similar approach worked for Menu, but for Listbox, even enter animations did not work until I added transform opacity-0 scale-95 to className for Listbox.Options in addition to Transition, which is super unintuitive.

Can we get a proper example? Maybe some errors will get fixed in the process too

@vincaslt
Copy link
Author

vincaslt commented Dec 9, 2020

Ok, I figured it out. Here is a working example adapted from Transition+Menu example here:

https://codesandbox.io/s/headlessuireact-transitionmenupopper-example-forked-zl7zg

It is using the dev version of headlessui, because I needed callbacks for beforeEnter and afterLeave. I also used the official react-popper hook, as opposed to what other examples in headlessui use - you'd probably want to use an offical hook anyway.

Main changes are:

  • Wrap transition inside a portal and add a div wrapper with ref (because it must be in dom before transition)
  • In Transition callbacks set the popper element refs in state to the wrapper ref (avoids animation jankiness)
  • Use static prop on listbox and menu items!
  • Position is calculated automatically now by react-popper, so just pass style props to respective elements, do not use relative or absolute positioning on dropdown elements anymore.

The example might be simplified, but it's a good working base for implementation.
@RobinMalfait could be a good thing to add to docs

@vincaslt vincaslt closed this as completed Dec 9, 2020
@mryechkin
Copy link

@vincaslt thanks for the example! This is really cool. +1 to adding more samples like this to the main docs 👍🏻

@paulodeon
Copy link

Great example, saved me hours of coding! thank you!

@ycs77
Copy link

ycs77 commented Mar 15, 2022

@vincaslt Thanks for the example.

Your example inspired me to create a package Headless UI Float, that can be easy to position floating Headless UI elements using Floating UI, support Transition & Portal.

The example below is a fork from your example, but replace Popper.js with my created package:
https://codesandbox.io/s/headlessui-react-transition-menu-floating-ui-example-forked-sv28um?file=/src/App.js

@jithureddy
Copy link

jithureddy commented Jun 29, 2022

Hi All,

I faced similar issue when I use portal + transition+menu, when I remove transition everything was good.

So based on this I have fixed issue with popper adding dynamic styles to menu items container is fixed
https://codesandbox.io/s/headlessuireact-transitionmenupopper-example-forked-zl7zg?file=/src/App.js:429-442

Thanks @vincaslt

@thien-do
Copy link

Small update regarding floating-ui that this excellent technique of @vincaslt still work:

Example commit

The key elements are the same:

  • Have a wrapper outside of the Transition
  • Use the lifecycle props (beforeEnter and afterLeave) to set Floating UI's floating ref

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

6 participants