mirror of https://github.com/sveltejs/svelte
parent
a9f48540e2
commit
63ff1e4181
@ -0,0 +1,5 @@
|
||||
---
|
||||
'svelte': patch
|
||||
---
|
||||
|
||||
fix: preserve nullish option values when using spread attributes on `<option>`
|
||||
@ -0,0 +1,9 @@
|
||||
<script>
|
||||
let { value = $bindable(), options } = $props();
|
||||
</script>
|
||||
|
||||
<select bind:value>
|
||||
{#each options as { value, label, ...restprops }}
|
||||
<option {value} {...restprops}>{label}</option>
|
||||
{/each}
|
||||
</select>
|
||||
@ -0,0 +1,9 @@
|
||||
<script>
|
||||
let { value = $bindable(), options } = $props();
|
||||
</script>
|
||||
|
||||
<select bind:value>
|
||||
{#each options as { value, label }}
|
||||
<option {value}>{label}</option>
|
||||
{/each}
|
||||
</select>
|
||||
@ -0,0 +1,49 @@
|
||||
import { flushSync } from 'svelte';
|
||||
import { ok, test } from '../../test';
|
||||
|
||||
export default test({
|
||||
async test({ assert, target, component }) {
|
||||
const [select0, select1] = target.querySelectorAll('select');
|
||||
ok(select0);
|
||||
ok(select1);
|
||||
|
||||
/**
|
||||
* @param {HTMLOptionElement} option
|
||||
*/
|
||||
function get_option_value(option) {
|
||||
if ('__value' in option) {
|
||||
// @ts-ignore
|
||||
return option.__value;
|
||||
}
|
||||
|
||||
return option.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HTMLSelectElement} select
|
||||
* @param {number} index
|
||||
*/
|
||||
function select_at(select, index) {
|
||||
select.selectedIndex = index;
|
||||
select.dispatchEvent(new Event('change', { bubbles: true }));
|
||||
flushSync();
|
||||
}
|
||||
|
||||
for (let i = 0; i < select0.options.length; i += 1) {
|
||||
assert.deepEqual(
|
||||
get_option_value(select1.options[i]),
|
||||
get_option_value(select0.options[i]),
|
||||
`option __value should match at index ${i}`
|
||||
);
|
||||
}
|
||||
|
||||
// nullish values all serialize to '' in the DOM, so select a distinct option first
|
||||
select_at(select0, 6);
|
||||
select_at(select1, 6);
|
||||
select_at(select0, 0);
|
||||
select_at(select1, 0);
|
||||
|
||||
assert.equal(component.value0, undefined);
|
||||
assert.equal(component.value1, undefined);
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,23 @@
|
||||
<script>
|
||||
import SelectOptionWithoutSpread from './SelectOptionWithoutSpread.svelte';
|
||||
import SelectOptionWithSpread from './SelectOptionWithSpread.svelte';
|
||||
|
||||
let value0 = $state();
|
||||
let value1 = $state();
|
||||
|
||||
const options = [
|
||||
{ value: undefined, label: 'undefined' },
|
||||
{ value: null, label: 'null' },
|
||||
{ value: '', label: '""' },
|
||||
{ value: false, label: 'false' },
|
||||
{ value: true, label: 'true' },
|
||||
{ value: 0, label: '0' },
|
||||
{ value: 1, label: '1' },
|
||||
{ value: '0', label: '"0"' },
|
||||
{ value: '1', label: '"1"' },
|
||||
{ value: { prop: 1 }, label: '{ prop: 1 }' }
|
||||
];
|
||||
</script>
|
||||
|
||||
<SelectOptionWithoutSpread bind:value={value0} {options} />
|
||||
<SelectOptionWithSpread bind:value={value1} {options} />
|
||||
Loading…
Reference in new issue