diff --git a/.changeset/shiny-keys-dance.md b/.changeset/shiny-keys-dance.md new file mode 100644 index 0000000000..20cf754212 --- /dev/null +++ b/.changeset/shiny-keys-dance.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: transform computed keys in keyed `{#each}` destructuring patterns diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/EachBlock.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/EachBlock.js index a1371b516a..45511714a1 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/EachBlock.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/EachBlock.js @@ -294,7 +294,12 @@ export function EachBlock(node, context) { let key_function = b.id('$.index'); if (node.metadata.keyed) { - const pattern = /** @type {Pattern} */ (node.context); // can only be keyed when a context is provided + // the pattern needs to be visited so that expressions inside it (e.g. computed + // keys or default values referencing component scope) are transformed correctly. + // can only be keyed when a context is provided + const pattern = /** @type {Pattern} */ ( + context.visit(/** @type {Pattern} */ (node.context), key_state) + ); const expression = /** @type {Expression} */ ( context.visit(/** @type {Expression} */ (node.key), key_state) ); diff --git a/packages/svelte/tests/runtime-runes/samples/each-keyed-computed-destructuring-key/Child.svelte b/packages/svelte/tests/runtime-runes/samples/each-keyed-computed-destructuring-key/Child.svelte new file mode 100644 index 0000000000..35544d0a55 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/each-keyed-computed-destructuring-key/Child.svelte @@ -0,0 +1,7 @@ + + +{#each options as { [labelKey]: label, [valueKey]: value } (value)} +

{label}: {value}

+{/each} diff --git a/packages/svelte/tests/runtime-runes/samples/each-keyed-computed-destructuring-key/_config.js b/packages/svelte/tests/runtime-runes/samples/each-keyed-computed-destructuring-key/_config.js new file mode 100644 index 0000000000..8a8789d712 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/each-keyed-computed-destructuring-key/_config.js @@ -0,0 +1,29 @@ +import { flushSync } from 'svelte'; +import { ok, test } from '../../test'; + +// https://github.com/sveltejs/svelte/issues/18519 +export default test({ + html: ` + +

1: a1

+

2: a2

+

3: a3

+ `, + + test({ assert, target }) { + const btn = target.querySelector('button'); + ok(btn); + + flushSync(() => btn.click()); + + assert.htmlEqual( + target.innerHTML, + ` + +

3: a3

+

2: a2

+

1: a1

+ ` + ); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/each-keyed-computed-destructuring-key/main.svelte b/packages/svelte/tests/runtime-runes/samples/each-keyed-computed-destructuring-key/main.svelte new file mode 100644 index 0000000000..6885a6918e --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/each-keyed-computed-destructuring-key/main.svelte @@ -0,0 +1,12 @@ + + + +