mirror of https://github.com/sveltejs/svelte
feat: support `defaultValue` on `<select>` (#18591)
Closes #18447 --------- Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com> Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>pull/18721/head
parent
b433f3cd87
commit
c575b07bca
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': minor
|
||||||
|
---
|
||||||
|
|
||||||
|
feat: support `defaultValue` on `<select>`
|
||||||
@ -0,0 +1,96 @@
|
|||||||
|
import { test } from '../../test';
|
||||||
|
import { flushSync } from 'svelte';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
async test({ assert, target }) {
|
||||||
|
/** @param {HTMLSelectElement} select @param {boolean[]} expected */
|
||||||
|
function check(select, expected) {
|
||||||
|
assert.deepEqual(
|
||||||
|
[...select.options].map((option) => option.selected),
|
||||||
|
expected
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {HTMLSelectElement} select @param {number[]} indexes */
|
||||||
|
function select(select, indexes) {
|
||||||
|
for (let i = 0; i < select.options.length; i++) {
|
||||||
|
select.options[i].selected = indexes.includes(i);
|
||||||
|
}
|
||||||
|
select.dispatchEvent(new Event('change', { bubbles: true }));
|
||||||
|
}
|
||||||
|
|
||||||
|
const selects = target.querySelectorAll('select');
|
||||||
|
const reset = /** @type {HTMLInputElement} */ (target.querySelector('input[type=reset]'));
|
||||||
|
/** @param {string} name */
|
||||||
|
const button = (name) => /** @type {HTMLButtonElement} */ (target.querySelector(`.${name}`));
|
||||||
|
|
||||||
|
check(selects[0], [false, true, false]);
|
||||||
|
check(selects[1], [false, false, true]);
|
||||||
|
check(selects[2], [false, true, false]);
|
||||||
|
check(selects[3], [true]);
|
||||||
|
check(selects[4], [false, true]);
|
||||||
|
check(selects[5], [false, true, false]);
|
||||||
|
check(selects[6], [true, false]);
|
||||||
|
check(selects[7], [true, false, true]);
|
||||||
|
check(selects[8], [false, false, true]);
|
||||||
|
|
||||||
|
select(selects[0], [2]);
|
||||||
|
select(selects[1], [0]);
|
||||||
|
select(selects[5], [2]);
|
||||||
|
select(selects[7], [1]);
|
||||||
|
flushSync();
|
||||||
|
|
||||||
|
reset.click();
|
||||||
|
await Promise.resolve();
|
||||||
|
flushSync();
|
||||||
|
check(selects[0], [false, true, false]);
|
||||||
|
check(selects[1], [false, true, false]);
|
||||||
|
check(selects[5], [false, true, false]);
|
||||||
|
check(selects[7], [true, false, true]);
|
||||||
|
|
||||||
|
select(selects[2], [2]);
|
||||||
|
select(selects[5], [2]);
|
||||||
|
button('update').click();
|
||||||
|
flushSync();
|
||||||
|
check(selects[2], [false, false, true]);
|
||||||
|
check(selects[5], [false, false, true]);
|
||||||
|
assert.deepEqual(
|
||||||
|
[...selects[5].options].map((option) => option.defaultSelected),
|
||||||
|
[true, false, false]
|
||||||
|
);
|
||||||
|
|
||||||
|
button('add').click();
|
||||||
|
flushSync();
|
||||||
|
await Promise.resolve();
|
||||||
|
check(selects[3], [true, false]);
|
||||||
|
assert.equal(selects[3].options[1].defaultSelected, true);
|
||||||
|
|
||||||
|
reset.click();
|
||||||
|
await Promise.resolve();
|
||||||
|
flushSync();
|
||||||
|
check(selects[0], [true, false, false]);
|
||||||
|
check(selects[2], [true, false, false]);
|
||||||
|
check(selects[3], [false, true]);
|
||||||
|
check(selects[5], [true, false, false]);
|
||||||
|
|
||||||
|
select(selects[5], [2]);
|
||||||
|
select(selects[7], [1]);
|
||||||
|
button('remove').click();
|
||||||
|
button('clear').click();
|
||||||
|
flushSync();
|
||||||
|
assert.equal(
|
||||||
|
[...selects[5].options].some((option) => option.defaultSelected),
|
||||||
|
false
|
||||||
|
);
|
||||||
|
assert.equal(
|
||||||
|
[...selects[7].options].some((option) => option.defaultSelected),
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
reset.click();
|
||||||
|
await Promise.resolve();
|
||||||
|
flushSync();
|
||||||
|
check(selects[5], [true, false, false]);
|
||||||
|
check(selects[7], [false, false, false]);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,79 @@
|
|||||||
|
<script>
|
||||||
|
let selected1 = $state();
|
||||||
|
let selected2 = $state('c');
|
||||||
|
let selected3 = $state();
|
||||||
|
let selected4 = $state(['c']);
|
||||||
|
let defaultValue = $state('b');
|
||||||
|
let multipleDefault = $state(/** @type {string[] | undefined} */ (['a', 'c']));
|
||||||
|
let options = $state(['a']);
|
||||||
|
let props = $state({ defaultValue: 'b' });
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<form>
|
||||||
|
<select {defaultValue} bind:value={selected1}>
|
||||||
|
<option value="a">A</option>
|
||||||
|
<option value="b">B</option>
|
||||||
|
<option value="c">C</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select {defaultValue} bind:value={selected2}>
|
||||||
|
<option value="a">A</option>
|
||||||
|
<option value="b">B</option>
|
||||||
|
<option value="c">C</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select {defaultValue}>
|
||||||
|
<option value="a">A</option>
|
||||||
|
<option value="b">B</option>
|
||||||
|
<option value="c">C</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select defaultValue="b">
|
||||||
|
{#each options as option}
|
||||||
|
<option value={option}>{option}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select defaultvalue="b">
|
||||||
|
<option value="a">A</option>
|
||||||
|
<option value="b">B</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select {...props} bind:value={selected3}>
|
||||||
|
<option value="a">A</option>
|
||||||
|
<option value="b">B</option>
|
||||||
|
<option value="c">C</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select {...{ defaultValue: 'b' }} defaultValue="a">
|
||||||
|
<option value="a">A</option>
|
||||||
|
<option value="b">B</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select multiple defaultValue={multipleDefault}>
|
||||||
|
<option value="a">A</option>
|
||||||
|
<option value="b">B</option>
|
||||||
|
<option value="c">C</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select multiple defaultValue={multipleDefault} bind:value={selected4}>
|
||||||
|
<option value="a">A</option>
|
||||||
|
<option value="b">B</option>
|
||||||
|
<option value="c">C</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<input type="reset" value="Reset" />
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="update"
|
||||||
|
onclick={() => {
|
||||||
|
defaultValue = 'a';
|
||||||
|
props.defaultValue = 'a';
|
||||||
|
}}>Update defaults</button
|
||||||
|
>
|
||||||
|
<button type="button" class="add" onclick={() => options.push('b')}>Add option</button>
|
||||||
|
<button type="button" class="remove" onclick={() => delete props.defaultValue}>Remove default</button>
|
||||||
|
<button type="button" class="clear" onclick={() => (multipleDefault = undefined)}>Clear defaults</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<p>{selected1} {selected2} {selected3} {selected4.join(',')}</p>
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
<select>
|
||||||
|
<option value="a">A</option>
|
||||||
|
<option selected="" value="b">B</option>
|
||||||
|
</select>
|
||||||
|
<select>
|
||||||
|
<option value="a">A</option>
|
||||||
|
<option selected="" value="b">B</option>
|
||||||
|
</select>
|
||||||
|
<select>
|
||||||
|
<option selected="" value="a">A</option>
|
||||||
|
<option value="b">B</option>
|
||||||
|
</select>
|
||||||
|
<select multiple="">
|
||||||
|
<option selected="" value="a">A</option>
|
||||||
|
<option value="b">B</option>
|
||||||
|
<option selected="" value="c">C</option>
|
||||||
|
</select>
|
||||||
|
<select>
|
||||||
|
<option value="a">A</option>
|
||||||
|
<option selected="" value="b">B</option>
|
||||||
|
</select>
|
||||||
|
<select>
|
||||||
|
<option selected="" value="a">A</option>
|
||||||
|
<option value="b">B</option>
|
||||||
|
</select>
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
<script>
|
||||||
|
const props = { defaultValue: 'b' };
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<select defaultValue="b">
|
||||||
|
<option value="a">A</option>
|
||||||
|
<option value="b">B</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select {...props}>
|
||||||
|
<option value="a">A</option>
|
||||||
|
<option value="b">B</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select defaultValue="b" value="a">
|
||||||
|
<option value="a">A</option>
|
||||||
|
<option value="b">B</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select multiple="" defaultValue={['a', 'c']}>
|
||||||
|
<option value="a">A</option>
|
||||||
|
<option value="b">B</option>
|
||||||
|
<option value="c">C</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select defaultvalue="b">
|
||||||
|
<option value="a">A</option>
|
||||||
|
<option value="b">B</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select {...{ defaultValue: 'b' }} defaultValue="a">
|
||||||
|
<option value="a">A</option>
|
||||||
|
<option value="b">B</option>
|
||||||
|
</select>
|
||||||
Loading…
Reference in new issue