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 @@ + + + +