diff --git a/.changeset/fix-select-multiple-dynamic.md b/.changeset/fix-select-multiple-dynamic.md
new file mode 100644
index 000000000000..5371de9e33d4
--- /dev/null
+++ b/.changeset/fix-select-multiple-dynamic.md
@@ -0,0 +1,5 @@
+---
+"svelte": patch
+---
+
+fix: handle dynamic multiple attribute on select
diff --git a/packages/svelte/src/compiler/phases/2-analyze/visitors/BindDirective.js b/packages/svelte/src/compiler/phases/2-analyze/visitors/BindDirective.js
index ab541703a0c9..a2ba14be1128 100644
--- a/packages/svelte/src/compiler/phases/2-analyze/visitors/BindDirective.js
+++ b/packages/svelte/src/compiler/phases/2-analyze/visitors/BindDirective.js
@@ -81,17 +81,7 @@ export function BindDirective(node, context) {
}
if (parent.name === 'select' && node.name !== 'this') {
- const multiple = parent.attributes.find(
- (a) =>
- a.type === 'Attribute' &&
- a.name === 'multiple' &&
- !is_text_attribute(a) &&
- a.value !== true
- );
-
- if (multiple) {
- e.attribute_invalid_multiple(multiple);
- }
+ // We used to forbid dynamic multiple, but we now support it
}
if (node.name === 'offsetWidth' && is_svg(parent.name)) {
diff --git a/packages/svelte/src/internal/client/dom/elements/bindings/select.js b/packages/svelte/src/internal/client/dom/elements/bindings/select.js
index 46e8f524f8f3..03a7c021279c 100644
--- a/packages/svelte/src/internal/client/dom/elements/bindings/select.js
+++ b/packages/svelte/src/internal/client/dom/elements/bindings/select.js
@@ -69,7 +69,7 @@ export function init_select(select) {
// (doesn't get notified of select value changes,
// because that property is not reflected as an attribute)
attributes: true,
- attributeFilter: ['value']
+ attributeFilter: ['value', 'multiple']
});
teardown(() => {
diff --git a/packages/svelte/tests/runtime-runes/samples/select-multiple-dynamic-attribute/main.svelte b/packages/svelte/tests/runtime-runes/samples/select-multiple-dynamic-attribute/main.svelte
new file mode 100644
index 000000000000..83870b6ab5fa
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/select-multiple-dynamic-attribute/main.svelte
@@ -0,0 +1,12 @@
+
+
+
+
+
diff --git a/packages/svelte/tests/runtime-runes/samples/select-multiple-dynamic-attribute/test.ts b/packages/svelte/tests/runtime-runes/samples/select-multiple-dynamic-attribute/test.ts
new file mode 100644
index 000000000000..9454e43340da
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/select-multiple-dynamic-attribute/test.ts
@@ -0,0 +1,26 @@
+export async function test({ assert, target, logs }: { assert: any; target: any; logs: any }) {
+ const select = target.querySelector('select');
+ const options = target.querySelectorAll('option');
+ const [btn] = target.querySelectorAll('button');
+
+ assert.equal(select.multiple, false);
+ assert.equal(options[0].selected, false);
+ assert.equal(options[1].selected, true);
+ assert.equal(options[2].selected, false);
+
+ btn.click();
+ await Promise.resolve();
+
+ assert.equal(select.multiple, true);
+ assert.equal(options[0].selected, false);
+ assert.equal(options[1].selected, true);
+ assert.equal(options[2].selected, false);
+
+ btn.click();
+ await Promise.resolve();
+
+ assert.equal(select.multiple, false);
+ assert.equal(options[0].selected, false);
+ assert.equal(options[1].selected, true);
+ assert.equal(options[2].selected, false);
+}
diff --git a/packages/svelte/tests/validator/samples/binding-select-multiple-dynamic/errors.json b/packages/svelte/tests/validator/samples/binding-select-multiple-dynamic/errors.json
deleted file mode 100644
index 8430d40d6199..000000000000
--- a/packages/svelte/tests/validator/samples/binding-select-multiple-dynamic/errors.json
+++ /dev/null
@@ -1,14 +0,0 @@
-[
- {
- "code": "attribute_invalid_multiple",
- "message": "'multiple' attribute must be static if select uses two-way binding",
- "start": {
- "line": 14,
- "column": 19
- },
- "end": {
- "line": 14,
- "column": 29
- }
- }
-]
diff --git a/packages/svelte/tests/validator/samples/binding-select-multiple-dynamic/input.svelte b/packages/svelte/tests/validator/samples/binding-select-multiple-dynamic/input.svelte
deleted file mode 100644
index 4908672985ea..000000000000
--- a/packages/svelte/tests/validator/samples/binding-select-multiple-dynamic/input.svelte
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file