-
-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Description
Describe the problem
I get the usual An element that uses the animate directive must be the immediate child of a keyed each block error when attempting to do this:
<script>
import { scale } from 'svelte/transition';
import { flip } from 'svelte/animate';
let values = [1, 2, 3, 4, 5];
const duration = 300;
</script>
{#each values as value, i (value)}
{#if value > 2}
<span in:scale|local={{ duration, delay: i * 10 }} animate:flip={{ duration }}>
{value}
</span>
{/if}
{/each}REPL: https://svelte.dev/repl/9a63f6ad0066480a93d31729ed959577?version=3.59.1
That doesn't work, but the same logic refactored into a filter of the each'd array does work:
<script>
import { scale } from 'svelte/transition';
import { flip } from 'svelte/animate';
let values = [1, 2, 3, 4, 5];
const duration = 300;
</script>
{#each values.filter(value => value > 2) as value, i (value)}
<span in:scale|local={{ duration, delay: i * 10 }} animate:flip={{ duration }}>
{value}
</span>
{/each}REPL: https://svelte.dev/repl/b9a2dec8a0fc474b819e905a79b08b43?version=3.59.1
Describe the proposed solution
Maybe the second is more straightforward for the compiler, but if this restriction could be loosened, I think it would greatly improve the developer experience of working with the animate directive.
Alternatives considered
The only foreseeable workaround would be to continue using the filtered approach which sometimes requires redundant logic, like this:
<script>
import { scale } from 'svelte/transition';
import { flip } from 'svelte/animate';
let values = ['tom', 'frank', 'george'];
const duration = 300;
</script>
{#each values.filter(name => {
const upperName = name.toUpperCase();
return upperName.startsWith('T');
}) as value, i (value)}
{@const upperName = value.toUpperCase()}
<span in:scale|local="{{ duration, delay: i * 10 }}" animate:flip="{{ duration }}">
{upperName}
</span>
{/each}REPL: https://svelte.dev/repl/9a63f6ad0066480a93d31729ed959577?version=3.59.1
when the desire was just to do this:
<script>
import { scale } from 'svelte/transition';
import { flip } from 'svelte/animate';
let values = ['tom', 'frank', 'george'];
const duration = 300;
</script>
{#each values as value, i (value)}
{@const upperName = value.toUpperCase()}
{#if upperName.startsWith('T')}
<span in:scale|local="{{ duration, delay: i * 10 }}" animate:flip="{{ duration }}">
{upperName}
</span>
{/if}
{/each}Importance
would make my life easier