Skip to content

Commit afae274

Browse files
authored
fix: value/checked not correctly set using spread (#15239)
* set value/checked by JS * test * changeset * fix test form-default-value-spread
1 parent 85f83ec commit afae274

File tree

4 files changed

+68
-5
lines changed

4 files changed

+68
-5
lines changed

.changeset/fuzzy-zoos-repeat.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: value/checked not correctly set using spread

packages/svelte/src/internal/client/dom/elements/attributes.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -399,15 +399,18 @@ export function set_attributes(
399399
if (name === 'value' || name === 'checked') {
400400
// removing value/checked also removes defaultValue/defaultChecked — preserve
401401
let input = /** @type {HTMLInputElement} */ (element);
402-
402+
const use_default = prev === undefined;
403403
if (name === 'value') {
404-
let prev = input.defaultValue;
404+
let previous = input.defaultValue;
405405
input.removeAttribute(name);
406-
input.defaultValue = prev;
406+
input.defaultValue = previous;
407+
// @ts-ignore
408+
input.value = input.__value = use_default ? previous : null;
407409
} else {
408-
let prev = input.defaultChecked;
410+
let previous = input.defaultChecked;
409411
input.removeAttribute(name);
410-
input.defaultChecked = prev;
412+
input.defaultChecked = previous;
413+
input.checked = use_default ? previous : false;
411414
}
412415
} else {
413416
element.removeAttribute(key);
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { flushSync } from 'svelte';
2+
import { test } from '../../test';
3+
4+
export default test({
5+
async test({ target, assert }) {
6+
// Test for https://github.com/sveltejs/svelte/issues/15237
7+
const [setValues, clearValue] = target.querySelectorAll('button');
8+
const [text1, text2, check1, check2] = target.querySelectorAll('input');
9+
10+
assert.equal(text1.value, '');
11+
assert.equal(text2.value, '');
12+
assert.equal(check1.checked, false);
13+
assert.equal(check2.checked, false);
14+
15+
flushSync(() => {
16+
setValues.click();
17+
});
18+
19+
assert.equal(text1.value, 'message');
20+
assert.equal(text2.value, 'message');
21+
assert.equal(check1.checked, true);
22+
assert.equal(check2.checked, true);
23+
24+
flushSync(() => {
25+
clearValue.click();
26+
});
27+
28+
assert.equal(text1.value, '');
29+
assert.equal(text2.value, '');
30+
assert.equal(check1.checked, false);
31+
assert.equal(check2.checked, false);
32+
}
33+
});
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<script>
2+
let value = $state();
3+
let checked = $state(false);
4+
5+
function setValues() {
6+
value = 'message';
7+
checked = true;
8+
}
9+
function clearValues() {
10+
value = null;
11+
checked = null;
12+
}
13+
</script>
14+
15+
<button onclick={setValues}>setValues</button>
16+
<button onclick={clearValues}>clearValues</button>
17+
18+
<input type="text" {value} />
19+
<input type="text" {value} {...{}} />
20+
21+
<input type="checkbox" {checked} />
22+
<input type="checkbox" {checked} {...{}} />

0 commit comments

Comments
 (0)