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