diff --git a/.changeset/silly-readers-double.md b/.changeset/silly-readers-double.md new file mode 100644 index 000000000000..6ed1ec41b658 --- /dev/null +++ b/.changeset/silly-readers-double.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: treat spread elements the same as call expressions diff --git a/packages/svelte/src/compiler/phases/2-analyze/index.js b/packages/svelte/src/compiler/phases/2-analyze/index.js index 67eea43e1e00..f5cd6ff9f757 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/index.js +++ b/packages/svelte/src/compiler/phases/2-analyze/index.js @@ -51,6 +51,7 @@ import { RenderTag } from './visitors/RenderTag.js'; import { SlotElement } from './visitors/SlotElement.js'; import { SnippetBlock } from './visitors/SnippetBlock.js'; import { SpreadAttribute } from './visitors/SpreadAttribute.js'; +import { SpreadElement } from './visitors/SpreadElement.js'; import { StyleDirective } from './visitors/StyleDirective.js'; import { SvelteBody } from './visitors/SvelteBody.js'; import { SvelteComponent } from './visitors/SvelteComponent.js'; @@ -163,6 +164,7 @@ const visitors = { SlotElement, SnippetBlock, SpreadAttribute, + SpreadElement, StyleDirective, SvelteBody, SvelteComponent, diff --git a/packages/svelte/src/compiler/phases/2-analyze/visitors/SpreadElement.js b/packages/svelte/src/compiler/phases/2-analyze/visitors/SpreadElement.js new file mode 100644 index 000000000000..c31f86e1a813 --- /dev/null +++ b/packages/svelte/src/compiler/phases/2-analyze/visitors/SpreadElement.js @@ -0,0 +1,16 @@ +/** @import { SpreadElement } from 'estree' */ +/** @import { Context } from '../types' */ + +/** + * @param {SpreadElement} node + * @param {Context} context + */ +export function SpreadElement(node, context) { + if (context.state.expression) { + // treat e.g. `[...x]` the same as `[...x.values()]` + context.state.expression.has_call = true; + context.state.expression.has_state = true; + } + + context.next(); +} diff --git a/packages/svelte/tests/runtime-runes/samples/props-spread-operator/Child.svelte b/packages/svelte/tests/runtime-runes/samples/props-spread-operator/Child.svelte new file mode 100644 index 000000000000..989700486589 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/props-spread-operator/Child.svelte @@ -0,0 +1,5 @@ + + +{numbers.join(', ')} diff --git a/packages/svelte/tests/runtime-runes/samples/props-spread-operator/_config.js b/packages/svelte/tests/runtime-runes/samples/props-spread-operator/_config.js new file mode 100644 index 000000000000..43fbae84d4f2 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/props-spread-operator/_config.js @@ -0,0 +1,13 @@ +import { flushSync } from 'svelte'; +import { test } from '../../test'; + +export default test({ + html: ' 0, 1, 2', + + test({ target, assert }) { + const btn = target.querySelector('button'); + + flushSync(() => btn?.click()); + assert.htmlEqual(target.innerHTML, ' 0, 1, 2, 3'); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/props-spread-operator/main.svelte b/packages/svelte/tests/runtime-runes/samples/props-spread-operator/main.svelte new file mode 100644 index 000000000000..794cdec8528e --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/props-spread-operator/main.svelte @@ -0,0 +1,10 @@ + + + + +