fix: keep defaultChecked on hydrated radio inputs with spread attributes (#18701)

radio buttons were missing in the type check - remove the check instead (aligns with how we do it in the compiler, see `has_default_value_attribute`). Strictly speaking not fully correct but pragmatic solution that doesn't have any impact in practise

Needed by sveltejs/kit#16926.
pull/18710/head
Nic Polumeyv 1 month ago committed by GitHub
parent 1b02aa28c8
commit 6b16b7f73f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: keep `defaultChecked` on hydrated radio inputs with spread attributes

@ -291,11 +291,8 @@ function set_attributes(
skip_warning = false skip_warning = false
) { ) {
if (hydrating && should_remove_defaults && element.nodeName === INPUT_TAG) { if (hydrating && should_remove_defaults && element.nodeName === INPUT_TAG) {
var input = /** @type {HTMLInputElement} */ (element); if (!('defaultValue' in next || 'defaultChecked' in next)) {
var attribute = input.type === 'checkbox' ? 'defaultChecked' : 'defaultValue'; remove_input_defaults(/** @type {HTMLInputElement} */ (element));
if (!(attribute in next)) {
remove_input_defaults(input);
} }
} }

@ -0,0 +1,23 @@
import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
mode: ['hydrate'],
async test({ assert, target }) {
const [a, b, reset] = target.querySelectorAll('input');
// let the deferred hydration cleanup run
await Promise.resolve();
flushSync();
b.checked = true;
reset.click();
await Promise.resolve();
flushSync();
assert.equal(a.defaultChecked, true);
assert.equal(a.checked, true);
assert.equal(b.checked, false);
}
});

@ -0,0 +1,9 @@
<script>
let spread = { defaultChecked: true, checked: true };
</script>
<form>
<input type="radio" name="option" value="a" {...spread} />
<input type="radio" name="option" value="b" />
<input type="reset" value="Reset" />
</form>
Loading…
Cancel
Save