From 22c07e69bcc5eb5acd03c8a7ae66be4d143671d1 Mon Sep 17 00:00:00 2001 From: Socialpranker <273312799+Socialpranker@users.noreply.github.com> Date: Tue, 28 Jul 2026 13:09:44 +0200 Subject: [PATCH] fix: apply `` compiled to `attribute_effect` and never reached `set_default_select_value`. `set_attributes` can't apply it either, since assigning the property does nothing on a select. It now marks the default option from the same effect that handles `value`, after the options exist. Server-side the key was only read as `defaultvalue`. That is what the compiler emits for an attribute written in the template, but a spread passes keys through as the user wrote them, so `defaultValue` was ignored and SSR disagreed with the client. Both spellings are accepted now. This is the case #18447 was filed for: `` has no defaultValue attribute — it only says which option is // selected by default, so it applies when there is no `value` to override it - renderer.local.select_value = value === undefined ? defaultvalue : value; + renderer.local.select_value = value === undefined ? default_value : value; fn(renderer); }); this.push(`${is_rich ? '' : ''}`); diff --git a/packages/svelte/tests/runtime-runes/samples/form-default-value-select-spread/_config.js b/packages/svelte/tests/runtime-runes/samples/form-default-value-select-spread/_config.js new file mode 100644 index 0000000000..a0d8ba5b46 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/form-default-value-select-spread/_config.js @@ -0,0 +1,56 @@ +import { test } from '../../test'; +import { flushSync } from 'svelte'; + +export default test({ + async test({ assert, target }) { + /** + * @param {NodeListOf} options + * @param {any[]} selected + */ + function check_options(options, selected) { + for (let i = 0; i < options.length; i++) { + assert.equal(options[i].selected, selected[i], `option ${i}`); + } + } + + /** + * @param {HTMLOptionElement} option + */ + function select_option(option) { + option.selected = true; + option.dispatchEvent(new Event('change', { bubbles: true })); + } + + const reset = /** @type {HTMLInputElement} */ (target.querySelector('input[type=reset]')); + const [test1, test2] = target.querySelectorAll('select'); + const [test1_span] = target.querySelectorAll('span'); + + // a spread carrying defaultValue selects the matching option + { + const options = test1.querySelectorAll('option'); + check_options(options, [false, true, false]); + assert.htmlEqual(test1_span.innerHTML, 'b'); + } + + // value in the same spread still wins over defaultValue + { + const options = test2.querySelectorAll('option'); + check_options(options, [false, false, true]); + } + + // changing the selection and resetting goes back to defaultValue + select_option(test1.querySelectorAll('option')[2]); + select_option(test2.querySelectorAll('option')[0]); + flushSync(); + + assert.htmlEqual(test1_span.innerHTML, 'c'); + + reset.click(); + await Promise.resolve(); + flushSync(); + + check_options(test1.querySelectorAll('option'), [false, true, false]); + check_options(test2.querySelectorAll('option'), [false, true, false]); + assert.htmlEqual(test1_span.innerHTML, 'b'); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/form-default-value-select-spread/main.svelte b/packages/svelte/tests/runtime-runes/samples/form-default-value-select-spread/main.svelte new file mode 100644 index 0000000000..287db5e9a3 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/form-default-value-select-spread/main.svelte @@ -0,0 +1,26 @@ + + +
+ + + + + + + +
+ +

{selected}

diff --git a/packages/svelte/tests/server-side-rendering/samples/select-default-value/_expected.html b/packages/svelte/tests/server-side-rendering/samples/select-default-value/_expected.html new file mode 100644 index 0000000000..c2ccbafd2a --- /dev/null +++ b/packages/svelte/tests/server-side-rendering/samples/select-default-value/_expected.html @@ -0,0 +1,12 @@ + + + diff --git a/packages/svelte/tests/server-side-rendering/samples/select-default-value/main.svelte b/packages/svelte/tests/server-side-rendering/samples/select-default-value/main.svelte new file mode 100644 index 0000000000..ca3fc36a35 --- /dev/null +++ b/packages/svelte/tests/server-side-rendering/samples/select-default-value/main.svelte @@ -0,0 +1,18 @@ + + + + + + +