[Bug]: beforeUnmount destroys too soon during Vue transitions
sambedingfield opened this issue Β· 16 comments
Which variants of Embla Carousel are you using?
- embla-carousel (Core)
- embla-carousel-react
- embla-carousel-vue
- embla-carousel-svelte
- embla-carousel-autoplay
- embla-carousel-auto-scroll
- embla-carousel-solid
- embla-carousel-auto-height
- embla-carousel-class-names
- embla-carousel-docs (Documentation)
- embla-carousel-docs (Generator)
Steps to reproduce
The bug occurs when I transition away a Vue component containing an Embla carousel, causing it to be destroyed too early. This causes a flicker of an unstyled carousel during the transition.
For a common example, imagine a transition on an app route and clicking a link from within a carousel slide.
The user sees the destroyed state of the carousel before the page transitions away.
Expected Behavior
That either the clean up can be prevented or delayed during beforeUnmount
.
Additional Context
To clarify, this is a known Vue thing, and not unique to Embla. It happens with a lot of libraries that clean up using Vue's beforeUnmount
hook.
A solution could be using a mutation observer or providing a timeout prop to delay the destroying.
Here's how it got discussed for Splide.
This could require a similar solution to the React issue here #540, where "freezing" styles could work.
I tried the following workaround, but it doesn't consider slides that are translated during loops :
beforeUnmount(){
const x = this.embla.internalEngine().location.get();
const $cont = this.embla.containerNode();
$cont.style.transform = 'translateX('+x+'px)';
}
What browsers are you seeing the problem on?
All browsers
Version
v8.0.4
CodeSandbox
https://codesandbox.io/p/devbox/reverent-almeida-nh8pkr
Before submitting
- I've made research efforts and searched the documentation
- I've searched for existing issues
- I agree to follow this project's Contributing Guidelines for bug reports
@sambedingfield thanks for your bug report. Is this expected behaviour for onBeforeUnmount
:
Or is it a bug? It seems like some of the comments suggest it's by design? This was the PR where the onUnmounted
was replaced with onBeforeUnmount
:
I'm not a seasoned Vue dev by any means but would re-introducing onUnmounted
fix the problem? @meirroth and/or @sadeghbarati, any thoughts on this?
It doesn't look like it's going to change, so... by design Β―\_(γ)_/Β―
Without any kind of destroy delay or style freeze via Embla there's no other workaround (that I know of) to prevent this.
So feel free to flag this as a feature request instead!
To clarify, both onUnmounted
and onBeforeUnmount
trigger beforehand, irrelevant to parent Vue transitions.
Will create Vue SFC playground to see differences between Vue versions
IIRC they refactored Transition component alot lately
@davidjerleke I'd be concerned about making such a change without extensive testing, especially given any potential errors or performance changes #672 (comment).
@sambedingfield Is it possible for you to share a minimal reproduction of the problem you're experiencing so that we can visualize it, debug it, and possibly find a solution? One option I can think of is to use the embla-carousel core without the wrapper and manually destroy it whenever you want. It's actually quite simple, as demonstrated by the Vue 2 example I provided earlier.
Here the Vue SFC playground
It appears that there are issues with Transition and onBeforeUnmount
@meirroth My CodeSandbox is in the original report, here: https://codesandbox.io/p/devbox/reverent-almeida-nh8pkr
And you're correct, a workaround could be to not use the Vue version.
@sambedingfield Sorry I missed it π€¦ββοΈ Thanks for sharing.
It seems to me that the issue persists after replacing onBeforeUnmount
with onUnmounted
as you can see in this Vue SFC playground using embla-carousel core.
@davidjerleke Just a thought, do you think this can be fixed by leaving translations as is on destroy?
https://github.com/davidjerleke/embla-carousel/blob/61c050c64b8631f68e091d9e6e1ce96ccad568ad/packages/embla-carousel/src/components/EmblaCarousel.ts#L139C12-L139C21
@meirroth it can, but not every user would want that. I'm not sure how to solve this in an optimal way. Maybe we can add a parameter to destroy()
that's a boolean
:
function destroy(keepStyles: boolean): void {
// ...
}
On the other hand, that wouldn't solve this request which is related to this to some extent:
React
is working fine withframer-motion
https://stackblitz.com/edit/basic-embla-carousel-dthb3k
Svelte
is also fine with transition
https://svelte.dev/repl/0e18b50b771c496dbf11a7d330a46164?version=3.31.2
@sadeghbarati @sambedingfield @meirroth I'm closing this issue for now if you don't have any objections? My understanding is that this problem has been raised in the vuejs/core
repository here by @sadeghbarati and it's waiting for a response:
No objections from me. Thanks for raising the problem with Vue!
To conclude from my perspective, I ended up using Embla Core wrapped in a Vue component as suggested.
I have a prop to control the delay before destroying, so that it can be used with different transition lengths. Works great!
Site launched this week actually!
https://wondermake.xyz/services/branding <- I use Embla carousels in the hero of each service page, and you can quickly jump between routes using the fixed nav. Buttery smooth!
@sambedingfield nice work ππ»! Feel free to share it here:
@sambedingfield Stunning website! Bookmarked. Is it plain Vue?
Anyone who hasnβt done so yet, if you donβt mind, please go to the vuejs/core issue that @sadeghbarati created and give it a thumbs up. That would better out chances of getting it fixed: