Search code examples
sveltesvelte-componentsvelte-transition

Local Transition with duration in Svelte not working


I am trying to animate list elements sliding in, one after another using this code:

<li class="list-element" in:slide|local={{duration:1000}}>

but somehow it doesn't seem to transition the list elements. When I remove "local" it works, but not one after another. What am I doing wrong? How can I fix this problem?

Edit: Example You can paste this into the svelte REPL, it will show the problem.

<script>
    import {slide} from "svelte/transition"
let data = [...Array(25).keys()];
    let withLocal = true;
</script>

<button on:click={()=>withLocal = !withLocal}>
    Toggle Working / not working
</button>
{#if withLocal} 
<ul class="list">
    {#each data as i}
    <li in:slide|local={{duration:1000}}>{i}</li>
    {/each}
</ul>
{:else}
<ul class="list">
    {#each data as i}
    <li in:slide={{duration:1000}}>{i}</li>
    {/each}
</ul>
{/if}

<style>
.list
    {
        list-style-type: none;
    }
</style>

Thanks


Solution

  • The meaning of local is:

    Local transitions only play when the block they belong to is created or destroyed, not when parent blocks are created or destroyed.

    So setting this flag in no way makes the items correlate with each other. I do not know if there is a simple approach to sliding in the items individually, but setting a delay based on the index gets you most of the way there for initial rendering. Of course the transition needs to be triggered somehow, e.g. by setting the source data with a delay/in onMount.

    <ul class="list">
        {#each data as i}
            <li in:slide={{ duration: 100, delay: i * 50 }}>{i}</li>
        {/each}
    </ul>
    

    REPL example

    One problem is still that newly added items would have an unnecessary delay on their fade-in. One workaround might be to use a data field or separate lookup table instead of just the array index.