Description
Describe the problem
The animate directive is only allowed to an immediate child of a keyed each block.
{#each todos.filter(t => !t.done) as todo (todo.id)}
<label animate:flip>{todo.description}</label>
{/each}
As soon as the child might become more complex, the child element might be wrapped in its own component. That breaks the animate directive with the well known error message.
{#each todos.filter(t => !t.done) as todo (todo.id)}
<Todo {todo} />
{/each}
So from a developer experience perspective, this should be possible as well because inside that component the first element is technically still an immediate child of that each block.
I prepared two REPLs.
- Without child component https://svelte.dev/repl/e1c1f2459ed74d96a9de082c0be01741?version=3.46.3
- With child component, animate directive not working https://svelte.dev/repl/b4a879ed63b64d2baaebd023d2209cc0?version=3.46.3
Describe the proposed solution
I can't fix this myself as the animate directive is resolved within the compiler I'm not so familiar with, yet.
- Proposed solutions is that the element in the component is recognized correctly as immediate child of the each block.
{#each todos.filter(t => !t.done) as todo (todo.id)}
<Todo {todo} />
{/each}
And in Todo.svelte
<script>
export let todo;
</script>
<label animate:flip>{todo.description}</label>
- Or allow the animate directive on Components instead of elements.
{#each todos.filter(t => !t.done) as todo (todo.id)}
<Todo {todo} animate:flip={{element}} bind:element/>
{/each}
And in Todo.svelte
<script>
export let todo;
export let element;
</script>
<label bind:this={element}>{todo.description}</label>
Alternatives considered
Alternatives are quite tough.
As I will also use in:receive
and out:send
crossfade transitions, I could try to identify the remaining items of the each loop by myself and put an animation on them.
Importance
would make my life easier