fix: keep nullish `value` of spread `<option>` for `bind:value`

Closes #17395
pull/18890/head
aeTunga 3 days ago
parent 020242d6be
commit f9d9682939

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: keep nullish `value` of spread `<option>` for `bind:value`

@ -350,7 +350,9 @@ function set_attributes(
// a very rare edge case, and removing the attribute altogether isn't possible either
// for the <option value={undefined}> case, so we're not losing any functionality here.
// @ts-ignore
element.value = element.__value = '';
element.value = '';
// @ts-ignore keep the nullish value so that `bind:value` on the parent <select> gets it back
element.__value = value;
current[key] = value;
continue;
}

@ -0,0 +1,19 @@
import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
test({ assert, target }) {
const select = /** @type {HTMLSelectElement} */ (target.querySelector('select'));
const p = /** @type {HTMLParagraphElement} */ (target.querySelector('p'));
select.selectedIndex = 1;
select.dispatchEvent(new Event('change'));
flushSync();
assert.equal(p.textContent, 'undefined undefined');
select.selectedIndex = 2;
select.dispatchEvent(new Event('change'));
flushSync();
assert.equal(p.textContent, 'object null');
}
});

@ -0,0 +1,16 @@
<script>
let value = $state('a');
const options = [
{ value: 'a', label: 'a' },
{ value: undefined, label: 'undefined' },
{ value: null, label: 'null' }
];
</script>
<select bind:value>
{#each options as { value, label, ...rest }}
<option {value} {...rest}>{label}</option>
{/each}
</select>
<p>{typeof value} {String(value)}</p>
Loading…
Cancel
Save