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

Dialog panel enter transition broken when v-auto-animate directive is present #3146

Closed
DamianGlowala opened this issue Apr 26, 2024 · 2 comments
Assignees

Comments

@DamianGlowala
Copy link

DamianGlowala commented Apr 26, 2024

What package within Headless UI are you using?

@headlessui/vue

What version of that package are you using?

For example: v1.7.21

What browser are you using?

n/a

Reproduction URL

https://codesandbox.io/p/devbox/immutable-tdd-6qrmks?embed=1&file=%2Fsrc%2FApp.vue

Describe your issue

Observe how the v-auto-animate directive breaks the dialog panel's enter transition.

@thecrypticace thecrypticace self-assigned this Apr 29, 2024
@thecrypticace
Copy link
Contributor

Hey! So this falls out of a weird but consistent browser behavior from code that calls window.getComputedStyle() before the transition starts for any newly mounted elements. This includes for any element in the tree of the one that is transitioned. I explained a bit about this here: #2557 (comment). We did discover somewhat of a workaround for this that we implemented for v2 of @headlessui/react which I'm going to look into implementing / back porting for both React and Vue in v1.7.x if possible.

In the meantime, there is a workaround you can implement in your own projects to get around this. It requires storing some state to delay the mounting of the button by one frame. The reason is that the button has the v-auto-animate directive which is the thing that calls window.getComputedStyle(…).

I've forked your Code Sandbox with these changes here: https://codesandbox.io/p/devbox/silly-haze-py8cnj?file=%2Fsrc%2FApp.vue%3A52%2C17-60%2C26

To do this you can:

  1. Add a showButton ref set to the value false
const showButton = ref(false)
  1. Add beforeEnter that, after one frame, sets showButton to true
  2. Add afterLeave that resets showButton back to false
function queueButtonShow() {
  requestAnimationFrame(() => {
    requestAnimationFrame(() => {
      showButton.value = true
    })
  })
}
<TransitionChild
  
  @beforeEnter="queueButtonShow"
  @afterLeave="showButton = false"
></TransitionChild>
  1. Conditionally show the button based on the value of showButton
<button
  v-if="showButton"
  v-auto-animate
  
>
  Got it, thanks!
</button>

Once you've done this the transition will start working again. Hope that helps!

@DamianGlowala
Copy link
Author

Appreciate your thorough explanation! I picked v1.7.21 purely for the purporse of the reproduction. However, I am actually using the insiders version :)

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

2 participants