I'm writing a small app using Svelte that presents a list of collapsible panels with text to the user, has them select a set of those panels, and, when the user clicks a button, groups these panels into another collapsible panel in a different list. Conceptually, it's the deferred transitions tutorial with an extra layer on one end.
I have prepared a REPL so you can follow along. Replace the component in App.svelte to switch the implementations.
The Original.svelte component illustrates the problem:
I'm using Svelte's crossfade transition to send and receive, and everything looks great when the grouped panels are collapsed. Any open panel, however, will warp awkwardly to its closed state when sent between the lists, which I understand is an effect of crossfade. The solution is obvious: close the panels first, then send them over to their target.
My question is, now, what is the idiomatic/optimal way to do that in Svelte?
The WithDelay.svelte component shows my attempt using delay on the individual panel transitions based on whether a panel was open. As is evident, this delays the send/receive transitions but still warps the panels, no matter how long the delay is (try a second or longer).
My second intuition was to collect the panels to be moved in an intermediate list, close them, and finally use the transition events on:outrostart/on:outroend to finalize the move. However, the logic was too lengthy to be correct, requiring multiple helper functions and extra arrays to track the elements. Once multiple panels had their events fire simultaneously, everything just went haywire. Preventing race conditions turned out so complicated that I scrapped that attempt entirely.
My third attempt can be seen in WithTimeout.svelte, where I resorted to using setTimeout to delay the actual moving of elements after the panels have been closed. As expected, that works exactly how it should and should be used as a reference for what I want to achieve, but using setTimeout just feels wrong. Still, I feel like I should not need to implement my own wait function using requestAnimationFrame since Svelte itself seems to have no built-in function for that. Internally, it runs the transition in a loop construct that uses requestAnimationFrame.
I'd go on with the timeout, but I would like to hear more experienced opinions before proceeding. I'm not even sure if my concerns are even justified. Maybe requestAnimationFrame only matters when doing actual transition stuff, and setTimeout is fine for assigning variables? Thanks a lot for your help!