Related Topic: Svelte Motion/Transition/Animation
This is a chronology of a Svelte TreeView component. From the baseline rendition of this component I wanted to support two additional requirements:
-
Maintain a "deep" state retention. If you collapse/expand a grandparent node, the children/grandchildren expansion state should be un-altered.
-
Provide a visual animation of the tree nodes when collapsing/expanding.
Here is the initial rendition of TreeView
- WITHOUT "deep" state retention
- WITHOUT animation
From this I wanted to retain the expansion state, so when collapsing a grandparent, you don't loose the expansion state of the grandchildren. I did this by retaining the DOM, and using display block/none semantics.
- WITH "deep" state retention (via persistent DOM display block/none semantics)
- WITHOUT animation
The last thing I wanted to accomplish was to provide a smooth animated transition on expansion contraction. I had read how easy this was to accomplish with Svelte.
-
The first thing I discovered, is that svelte transitions are only applicable when adding/removing DOM.
I guess this may be obvious to some, but I think the svelte docs could be a bit more clear on this topic. To be fair, the svelte transition tutorial does mention: "gracefully transitioning elements into and out of the DOM".
Here is a stackoverflow snippet where Tan Li Hau (svelte contributor) clarifies this point.
-
I decided to play with native "CSS Transitions". I had no experience with this, but had seen it briefly in the the TreeView arrow transition.
Needless to say, I discovered that only certain properties could be "CSS Transitioned", and that "display" was NOT one of them .... dohhhh, thwarted again.
I tried playing with CSS Transitions of opacity and height, but this was extremely hoaky, and unappealing (it required pre-defined knowledge of the height) ... I didn't even retain a snapshot of this attempt :-(
-
Needless to say, this left my rendition of "persistent DOM display block/none semantics" out-in-the-cold.
-
I decided that due to the minimalistic DOM savings I would go back to the prior version where the DOM was dynamically added/removed. This hopefully would support the visual animation I was looking for.
-
Here is a rendition that applied animation to TreeView Ver 1
- WITHOUT "deep" state retention
- WITH animation
-
The only thing left to do was to retain the "deep" state retention, when the DOM is added/removed. I accomplished this through a very simple ModuleScope state, that simply initializes the component state.
- WITH "deep" state retention (via ModuleScope state)
- WITH animation
This technique ALMOST works. The issue is: the animation only occurs at the "top most level". To see this:
-
expand all nodes in the tree (i.e. all grandchildren)
-
collapse the top-most node
-
expand the top-most node
NOTICE the animated transition only occurs at the top level. Once the transition is complete (at the top level), the grandchildren "pop out" instantly :-(
It seems like I can't win for loosing :-(
This seems like a bug to me:
Issue: Svelte transitions NOT honored on recursive <svelte:self>
Am I missing something obvious?
Thoughts?