[BUG] Shared layout animations not working when rendered in React portal
See original GitHub issue1. Read the FAQs š
2. Describe the bug
Shared layout animations donāt animate when:
- rendered inside a React portal, AND
- there is an existing motion node that would be normally the parent node of the shared layout animation, but itās not anymore after the animation component gets āteleportedā through the portal
Basically the combination of these two factors breaks the shared layout animation ā instead, only the āfirstā and ālastā states of the animation are rendered (without interpolation).
Initially reported in https://github.com/WordPress/gutenberg/pull/40276
3. IMPORTANT: Provide a CodeSandbox reproduction of the bug
A CodeSandbox minimal reproduction will allow us to quickly follow the reproduction steps. Without one, this bug report wonāt be accepted.
https://codesandbox.io/s/framer-motion-and-portals-ozvlh3
4. Steps to reproduce
Steps to reproduce the behavior:
- Create a component that internally uses shared layout animations via the
layoutId
prop - Render the component as follows:
// pseudo-code. for a real case example, visit the CodeSandbox link above
<motion.div>
<PortalBoundary>
<ComponentThatUsesSharedLayoutAnymations />
</PortalBoundary>
</motion.div>
- Notice how the shared layout animation doesnāt animated (it goes from initial to final state of the āanimationā without interpolating)
- Swap the
motion.div
wrapper elements with a simplediv
- The animation works as expected
After some time spent investigating, I believe that the ProjectionNode
associated to the element participating in the shared layout animation keeps referencing the wrapper motion.div
as its root node, even after the component gets rendered in another part of the dom (via the portal). This could result in buggy behaviour, especially given how ProjectionNode
s forward updates via their root nodes.
5. Expected behavior
The shared layout animation works as expected, interpolating smoothly between the initial and final state of the animation.
6. Video or screenshots
https://user-images.githubusercontent.com/1083581/165150804-ae28b242-8c78-4ad8-9c33-b1eba296876d.mp4
7. Environment details
I donāt think itās relevant, but I can reproduce the bug on Mac OS Chrome, Mac OS Firefox, Mac OS Safari (all latest versions).
Issue Analytics
- State:
- Created a year ago
- Comments:8
Top GitHub Comments
We are experiencing the same bug when trying to use animations inside a modal rendered via portal.
An easy fix, at least in my case, is to reset the
MotionContext
. As I understand this context is created by any motion node. Among other information, it propagates the animation variants downstream. My menu is mounted in a portal so I donāt need this feature.The
MotionContext
created by themotion.div
gets directly overwritten with an empty one. Now there is no connection betweenmotion.div
andMenu
anymore. The shared element animation works perfectly.This solution may has other implications. I havenāt noticed any side-effects so far. For me it generally sounds logical to disconnect a parent motion node from a portaled motion node because they are not in the same visual tree.