From a2b6401c43c44454bb30bc785a5b358fe2bdb6e0 Mon Sep 17 00:00:00 2001 From: hackape Date: Thu, 20 Jul 2023 21:55:22 +0800 Subject: [PATCH] fix: `svelte:component` spread props change not picked up (#9006) fix #9003, amend #8946 (comment) --- .changeset/heavy-wasps-give.md | 5 ++++ .../wrappers/InlineComponent/index.js | 19 ++++++++++++-- .../Comp1.svelte | 5 ++++ .../Comp2.svelte | 5 ++++ .../dynamic-component-spread-props/_config.js | 26 +++++++++++++++++++ .../main.svelte | 12 +++++++++ 6 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 .changeset/heavy-wasps-give.md create mode 100644 packages/svelte/test/runtime/samples/dynamic-component-spread-props/Comp1.svelte create mode 100644 packages/svelte/test/runtime/samples/dynamic-component-spread-props/Comp2.svelte create mode 100644 packages/svelte/test/runtime/samples/dynamic-component-spread-props/_config.js create mode 100644 packages/svelte/test/runtime/samples/dynamic-component-spread-props/main.svelte diff --git a/.changeset/heavy-wasps-give.md b/.changeset/heavy-wasps-give.md new file mode 100644 index 000000000000..495583e86fc4 --- /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 ef7e5432d47e..77fb1ac96b55 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 000000000000..d4fe28a8a370 --- /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 000000000000..07d41f3d8464 --- /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 000000000000..d5ba1ef64b58 --- /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 000000000000..b8c45c83a084 --- /dev/null +++ b/packages/svelte/test/runtime/samples/dynamic-component-spread-props/main.svelte @@ -0,0 +1,12 @@ + + + + +