diff --git a/src/runtime/internal/dom.ts b/src/runtime/internal/dom.ts
index bf8fc1f5a036..bc614a7c16ab 100644
--- a/src/runtime/internal/dom.ts
+++ b/src/runtime/internal/dom.ts
@@ -98,7 +98,11 @@ export function set_attributes(node: Element & ElementCSSInlineStyle, attributes
node.removeAttribute(key);
} else if (key === 'style') {
node.style.cssText = attributes[key];
- } else if (key === '__value' || descriptors[key] && descriptors[key].set) {
+ } else if (key === '__value') {
+ const value = attributes[key];
+ (node as any).__value = value;
+ (node as any).value = value;
+ } else if (descriptors[key] && descriptors[key].set) {
node[key] = attributes[key];
} else {
attr(node, key, attributes[key]);
diff --git a/test/runtime/samples/spread-element-input-bind-group-with-value-attr/_config.js b/test/runtime/samples/spread-element-input-bind-group-with-value-attr/_config.js
new file mode 100644
index 000000000000..6e1b89035132
--- /dev/null
+++ b/test/runtime/samples/spread-element-input-bind-group-with-value-attr/_config.js
@@ -0,0 +1,15 @@
+export default {
+ props: {
+ props: {
+ 'data-foo': 'bar'
+ }
+ },
+
+ html: ``,
+
+ async test({ assert, component, target, window }) {
+ const input = target.querySelector('input');
+ assert.equal(input.value, 'abc');
+ assert.equal(input.__value, 'abc');
+ }
+};
diff --git a/test/runtime/samples/spread-element-input-bind-group-with-value-attr/main.svelte b/test/runtime/samples/spread-element-input-bind-group-with-value-attr/main.svelte
new file mode 100644
index 000000000000..ce6b76f0932f
--- /dev/null
+++ b/test/runtime/samples/spread-element-input-bind-group-with-value-attr/main.svelte
@@ -0,0 +1,6 @@
+
+
+
diff --git a/test/runtime/samples/spread-element-input-bind-group-with-value-in-spread/_config.js b/test/runtime/samples/spread-element-input-bind-group-with-value-in-spread/_config.js
new file mode 100644
index 000000000000..baaea373a042
--- /dev/null
+++ b/test/runtime/samples/spread-element-input-bind-group-with-value-in-spread/_config.js
@@ -0,0 +1,22 @@
+export default {
+ // This fails because the test checks for __value being set on the node, which
+ // bind:group requires to work, but when a spread is used to set `value` on the
+ // element, the code that also sets `__value` on the node is not triggered.
+ // This is issue #4808.
+ skip: true,
+
+ props: {
+ props: {
+ 'data-foo': 'bar',
+ value: 'abc'
+ }
+ },
+
+ html: ``,
+
+ async test({ assert, component, target, window }) {
+ const input = target.querySelector('input');
+ assert.equal(input.value, 'abc');
+ assert.equal(input.__value, 'abc');
+ }
+};
diff --git a/test/runtime/samples/spread-element-input-bind-group-with-value-in-spread/main.svelte b/test/runtime/samples/spread-element-input-bind-group-with-value-in-spread/main.svelte
new file mode 100644
index 000000000000..d4aa0d1897af
--- /dev/null
+++ b/test/runtime/samples/spread-element-input-bind-group-with-value-in-spread/main.svelte
@@ -0,0 +1,6 @@
+
+
+