From 8a7e54065cd343a72c9b5c8a7b7ed9ac6a865266 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Wed, 13 Mar 2024 12:41:29 +0100 Subject: [PATCH] fix: handle component binding mutation https://github.com/sveltejs/svelte/issues/10359#issuecomment-1991885046 --- .changeset/witty-readers-provide.md | 5 +++ .../src/internal/client/reactivity/props.js | 5 ++- .../component-binding-deep2/Widget.svelte | 5 +++ .../component-binding-deep2/_config.js | 32 +++++++++++++++++++ .../component-binding-deep2/main.svelte | 11 +++++++ 5 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 .changeset/witty-readers-provide.md create mode 100644 packages/svelte/tests/runtime-legacy/samples/component-binding-deep2/Widget.svelte create mode 100644 packages/svelte/tests/runtime-legacy/samples/component-binding-deep2/_config.js create mode 100644 packages/svelte/tests/runtime-legacy/samples/component-binding-deep2/main.svelte diff --git a/.changeset/witty-readers-provide.md b/.changeset/witty-readers-provide.md new file mode 100644 index 0000000000..60a6bdf009 --- /dev/null +++ b/.changeset/witty-readers-provide.md @@ -0,0 +1,5 @@ +--- +"svelte": patch +--- + +fix: handle component binding mutation diff --git a/packages/svelte/src/internal/client/reactivity/props.js b/packages/svelte/src/internal/client/reactivity/props.js index b3559ae99f..72123fb521 100644 --- a/packages/svelte/src/internal/client/reactivity/props.js +++ b/packages/svelte/src/internal/client/reactivity/props.js @@ -175,10 +175,13 @@ export function prop(props, key, flags, initial) { // intermediate mode — prop is written to, but the parent component had // `bind:foo` which means we can just call `$$props.foo = value` directly if (setter) { - return function (/** @type {V} */ value) { + return function (/** @type {V} */ value, mutation = false) { if (arguments.length === 1) { /** @type {Function} */ (setter)(value); return value; + } else if (mutation) { + /** @type {Function} */ (setter)(getter()); + return value; } else { return getter(); } diff --git a/packages/svelte/tests/runtime-legacy/samples/component-binding-deep2/Widget.svelte b/packages/svelte/tests/runtime-legacy/samples/component-binding-deep2/Widget.svelte new file mode 100644 index 0000000000..c28dfbda90 --- /dev/null +++ b/packages/svelte/tests/runtime-legacy/samples/component-binding-deep2/Widget.svelte @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/packages/svelte/tests/runtime-legacy/samples/component-binding-deep2/_config.js b/packages/svelte/tests/runtime-legacy/samples/component-binding-deep2/_config.js new file mode 100644 index 0000000000..0479b7c529 --- /dev/null +++ b/packages/svelte/tests/runtime-legacy/samples/component-binding-deep2/_config.js @@ -0,0 +1,32 @@ +import { ok, test } from '../../test'; + +export default test({ + html: ` + +

foo

+ `, + + ssrHtml: ` + +

foo

+ `, + + async test({ assert, component, target, window }) { + const event = new window.MouseEvent('input'); + const input = target.querySelector('input'); + ok(input); + + input.value = 'blah'; + await input.dispatchEvent(event); + await Promise.resolve(); + + assert.deepEqual(component.deep, { name: 'blah' }); + assert.htmlEqual( + target.innerHTML, + ` + +

blah

+ ` + ); + } +}); diff --git a/packages/svelte/tests/runtime-legacy/samples/component-binding-deep2/main.svelte b/packages/svelte/tests/runtime-legacy/samples/component-binding-deep2/main.svelte new file mode 100644 index 0000000000..db8cd83b91 --- /dev/null +++ b/packages/svelte/tests/runtime-legacy/samples/component-binding-deep2/main.svelte @@ -0,0 +1,11 @@ + + + + +

{deep.name}

\ No newline at end of file