diff --git a/.changeset/heavy-wasps-give.md b/.changeset/heavy-wasps-give.md new file mode 100644 index 0000000000..495583e86f --- /dev/null +++ b/.changeset/heavy-wasps-give.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: `svelte:component` spread props change not picked up diff --git a/packages/svelte/src/compiler/compile/render_dom/wrappers/InlineComponent/index.js b/packages/svelte/src/compiler/compile/render_dom/wrappers/InlineComponent/index.js index ef7e5432d4..77fb1ac96b 100644 --- a/packages/svelte/src/compiler/compile/render_dom/wrappers/InlineComponent/index.js +++ b/packages/svelte/src/compiler/compile/render_dom/wrappers/InlineComponent/index.js @@ -268,6 +268,21 @@ export default class InlineComponentWrapper extends Wrapper { `); if (all_dependencies.size) { const condition = renderer.dirty(Array.from(all_dependencies)); + if (this.node.name === 'svelte:component') { + // statements will become switch_props function body + // rewrite last statement, add props update logic + statements[statements.length - 1] = b` + if (#dirty !== undefined && ${condition}) { + ${props} = @get_spread_update(${levels}, [ + ${changes} + ]); + } else { + for (let #i = 0; #i < ${levels}.length; #i += 1) { + ${props} = @assign(${props}, ${levels}[#i]); + } + } + `; + } updates.push(b` const ${name_changes} = ${condition} ? @get_spread_update(${levels}, [ ${changes} @@ -396,7 +411,7 @@ export default class InlineComponentWrapper extends Wrapper { block.chunks.init.push(b` var ${switch_value} = ${snippet}; - function ${switch_props}(#ctx) { + function ${switch_props}(#ctx, #dirty) { ${ (this.node.attributes.length > 0 || this.node.bindings.length > 0) && b` @@ -464,7 +479,7 @@ export default class InlineComponentWrapper extends Wrapper { if (${switch_value}) { ${update_insert} - ${name} = @construct_svelte_component(${switch_value}, ${switch_props}(#ctx)); + ${name} = @construct_svelte_component(${switch_value}, ${switch_props}(#ctx, #dirty)); ${munged_bindings} ${munged_handlers} diff --git a/packages/svelte/test/runtime/samples/dynamic-component-spread-props/Comp1.svelte b/packages/svelte/test/runtime/samples/dynamic-component-spread-props/Comp1.svelte new file mode 100644 index 0000000000..d4fe28a8a3 --- /dev/null +++ b/packages/svelte/test/runtime/samples/dynamic-component-spread-props/Comp1.svelte @@ -0,0 +1,5 @@ + + +

value(1) = {value}

diff --git a/packages/svelte/test/runtime/samples/dynamic-component-spread-props/Comp2.svelte b/packages/svelte/test/runtime/samples/dynamic-component-spread-props/Comp2.svelte new file mode 100644 index 0000000000..07d41f3d84 --- /dev/null +++ b/packages/svelte/test/runtime/samples/dynamic-component-spread-props/Comp2.svelte @@ -0,0 +1,5 @@ + + +

value(2) = {value}

diff --git a/packages/svelte/test/runtime/samples/dynamic-component-spread-props/_config.js b/packages/svelte/test/runtime/samples/dynamic-component-spread-props/_config.js new file mode 100644 index 0000000000..d5ba1ef64b --- /dev/null +++ b/packages/svelte/test/runtime/samples/dynamic-component-spread-props/_config.js @@ -0,0 +1,26 @@ +export default { + html: ` +

value(1) = 1

+ + `, + + async test({ assert, window, target }) { + const button = target.querySelector('button'); + await button.dispatchEvent(new window.Event('click')); + assert.htmlEqual( + target.innerHTML, + ` +

value(2) = 2

+ + ` + ); + await button.dispatchEvent(new window.Event('click')); + assert.htmlEqual( + target.innerHTML, + ` +

value(1) = 1

+ + ` + ); + } +}; diff --git a/packages/svelte/test/runtime/samples/dynamic-component-spread-props/main.svelte b/packages/svelte/test/runtime/samples/dynamic-component-spread-props/main.svelte new file mode 100644 index 0000000000..b8c45c83a0 --- /dev/null +++ b/packages/svelte/test/runtime/samples/dynamic-component-spread-props/main.svelte @@ -0,0 +1,12 @@ + + + + +