Skip to content

Instantly share code, notes, and snippets.

@KevinAst
Last active August 1, 2021 20:12
Show Gist options
  • Save KevinAst/ba103743c66c750f81f901219443d0fa to your computer and use it in GitHub Desktop.
Save KevinAst/ba103743c66c750f81f901219443d0fa to your computer and use it in GitHub Desktop.
Svelte Issue: Transitions NOT honored on recursive <svelte:self>

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:

  1. Maintain a "deep" state retention. If you collapse/expand a grandparent node, the children/grandchildren expansion state should be un-altered.

  2. Provide a visual animation of the tree nodes when collapsing/expanding.

Baseline TreeView Version

Here is the initial rendition of TreeView

TreeView Ver 1:

  • WITHOUT "deep" state retention
  • WITHOUT animation

Retaining Expansion State

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.

TreeView Ver 2:

  • WITH "deep" state retention (via persistent DOM display block/none semantics)
  • WITHOUT animation

Adding 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

    TreeView Ver 3:

    • 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.

    TreeView Ver 4:

    • 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:

    1. expand all nodes in the tree (i.e. all grandchildren)

    2. collapse the top-most node

    3. 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 :-(

Is this a Svelte Bug?

This seems like a bug to me: Issue: Svelte transitions NOT honored on recursive <svelte:self>

Am I missing something obvious?

Thoughts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment