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] Leave transition not working when using :unmount="false" (vue) #2987

Open
benjamincanac opened this issue Feb 16, 2024 · 4 comments

Comments

@benjamincanac
Copy link

benjamincanac commented Feb 16, 2024

What package within Headless UI are you using?

@headlessui/vue

What version of that package are you using?

v1.7.19

What browser are you using?

Chrome

Reproduction URL

https://stackblitz.com/edit/vitejs-vite-jh8put?file=src/components/Dialog.vue,src/App.vue&terminal=dev

Describe your issue

I've made a minimal reproduction following the example on https://headlessui.com/vue/dialog with :unmount="false" on the Dialog, TransitionRoot and TransitionChild components.

The leave transition is not working unless the ref is true when first loading the page. You can see on reload it will work, but it won't when closing it the second time.

@benjamincanac benjamincanac changed the title [Dialog] Leave transition not working when using :unmount="false" [Dialog] Leave transition not working when using :unmount="false" (vue) Feb 16, 2024
@joshdavies14
Copy link

joshdavies14 commented Aug 26, 2024

Are there any updates on this being fixed?

We have multiple cases where we use Dialog components either with forms inside them or as part of a larger form and need to run validation on the form contents. unmount is required to be false here to ensure that all fields of the form are correctly checked before submitting in the parent component, but applying that fix means we now regress on the leave transitions due to this bug. Essentially we now have to choose between working validation and JS-side manipulation of fields (as refs are null if they aren't mounted), or regressing in transitions.

@joshdavies14
Copy link

I ended up deciding to take a quick look at this...

if (show.value) {
state.value = TreeStates.Visible
} else if (!hasChildren(nestingBag)) {
state.value = TreeStates.Hidden
}

In the linked code above, we see an if statement run on effect on the TransitionRoot component, that changes the visible/hidden state of the tree depending on the show value passed to the component.

From adding some console log statements into the playground locally, I can see that upon setting the open value to false (e.g. after closing a Dialog component), we see that the show value is correctly set to false, but the value of hasChildren(nestingBag) is originally false. We also see that the transitions on the child components don't activate instantly. Because of this, the state of the TransitionRoot is set to hidden before the leave transitions even become visible.

image

I think we don't see this behaviour when not setting unmount to false because, while the same code in TransitionRoot executes fine, the watchEffect in TransitionChild is bypassed with unmount = true, and so the delayed code isn't required to be triggered at all.

let strategy = computed(() => (props.unmount ? RenderStrategy.Unmount : RenderStrategy.Hidden))

if (strategy.value !== RenderStrategy.Hidden) return

I think what is happening is the watchEffect in the TransitionChild is running at the same time as the watchEffect in the TransitionRoot, and the check for children with active transitions in Root completes before the child has time to activate it's transition, so its getting caught out and everything is being set to hidden. I could very well be wrong here so please don't take this as gospel, but it might help with some investigation.

@Archetipo95
Copy link

Any update on this?

@Archetipo95
Copy link

Archetipo95 commented Oct 18, 2024

I think that my issue #3535 is linked to this one

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

3 participants