diff --git a/.changeset/strong-pans-doubt.md b/.changeset/strong-pans-doubt.md new file mode 100644 index 0000000000..484fbbee52 --- /dev/null +++ b/.changeset/strong-pans-doubt.md @@ -0,0 +1,5 @@ +--- +"svelte": patch +--- + +fix: correctly reference destructured derived binding in event handler diff --git a/packages/svelte/src/compiler/phases/3-transform/client/utils.js b/packages/svelte/src/compiler/phases/3-transform/client/utils.js index 3b4d5a6f85..bd3a3fd441 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/utils.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/utils.js @@ -523,6 +523,16 @@ function get_hoistable_params(node, context) { // We need both the subscription for getting the value and the store for updating params.push(b.id(binding.node.name.slice(1))); params.push(b.id(binding.node.name)); + } else if ( + // If it's a destructured derived binding, then we can extract the derived signal reference and use that. + binding.expression !== null && + binding.expression.type === 'MemberExpression' && + binding.expression.object.type === 'CallExpression' && + binding.expression.object.callee.type === 'Identifier' && + binding.expression.object.callee.name === '$.get' && + binding.expression.object.arguments[0].type === 'Identifier' + ) { + params.push(b.id(binding.expression.object.arguments[0].name)); } else if ( // If we are referencing a simple $$props value, then we need to reference the object property instead binding.kind === 'prop' && diff --git a/packages/svelte/tests/runtime-runes/samples/destructure-derived-event/_config.js b/packages/svelte/tests/runtime-runes/samples/destructure-derived-event/_config.js new file mode 100644 index 0000000000..0645ff4a16 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/destructure-derived-event/_config.js @@ -0,0 +1,15 @@ +import { test } from '../../test'; +import { log } from './log.js'; + +export default test({ + before_test() { + log.length = 0; + }, + + async test({ assert, target, window }) { + const btn = target.querySelector('button'); + await btn?.click(); + + assert.deepEqual(log, ['works!']); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/destructure-derived-event/log.js b/packages/svelte/tests/runtime-runes/samples/destructure-derived-event/log.js new file mode 100644 index 0000000000..d3df521f4d --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/destructure-derived-event/log.js @@ -0,0 +1,2 @@ +/** @type {any[]} */ +export const log = []; diff --git a/packages/svelte/tests/runtime-runes/samples/destructure-derived-event/main.svelte b/packages/svelte/tests/runtime-runes/samples/destructure-derived-event/main.svelte new file mode 100644 index 0000000000..d4f149eb81 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/destructure-derived-event/main.svelte @@ -0,0 +1,15 @@ + + +{#if structured} + {@const { handler } = structured} + + +{/if}