mirror of https://github.com/sveltejs/svelte
fix: correctly determine `bind:group` members (#10368)
- Previously, any each block parents where used as keys for the sub group. That's wrong, it should only be using each blocks whos declarations contribute to the `bind:group` expression. Fixes #10345 - Only the left-most identifier of the expression was used to determine the binding group. This is wrong, all identifiers within the expression need to be taken into account. Fixes #9947pull/10367/head
parent
3b78c14be8
commit
bd0ebf3b81
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"svelte": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: correctly determine `bind:group` members
|
@ -0,0 +1,39 @@
|
|||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
async test({ assert, target, window }) {
|
||||||
|
const [input1, input2, input3, input4] = target.querySelectorAll('input');
|
||||||
|
const [p] = target.querySelectorAll('p');
|
||||||
|
const event = new window.Event('change');
|
||||||
|
|
||||||
|
input1.checked = true;
|
||||||
|
await input1.dispatchEvent(event);
|
||||||
|
await Promise.resolve();
|
||||||
|
assert.htmlEqual(p.innerHTML, '["1a"]');
|
||||||
|
|
||||||
|
input2.checked = true;
|
||||||
|
await input1.dispatchEvent(event);
|
||||||
|
await Promise.resolve();
|
||||||
|
assert.htmlEqual(p.innerHTML, '["1a","1b"]');
|
||||||
|
|
||||||
|
input3.checked = true;
|
||||||
|
await input1.dispatchEvent(event);
|
||||||
|
await Promise.resolve();
|
||||||
|
assert.htmlEqual(p.innerHTML, '["1a","1b","2a"]');
|
||||||
|
|
||||||
|
input4.checked = true;
|
||||||
|
await input1.dispatchEvent(event);
|
||||||
|
await Promise.resolve();
|
||||||
|
assert.htmlEqual(p.innerHTML, '["1a","1b","2a","2b"]');
|
||||||
|
|
||||||
|
input1.checked = false;
|
||||||
|
await input1.dispatchEvent(event);
|
||||||
|
await Promise.resolve();
|
||||||
|
assert.htmlEqual(p.innerHTML, '["1b","2a","2b"]');
|
||||||
|
|
||||||
|
input3.checked = false;
|
||||||
|
await input1.dispatchEvent(event);
|
||||||
|
await Promise.resolve();
|
||||||
|
assert.htmlEqual(p.innerHTML, '["1b","2b"]');
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,26 @@
|
|||||||
|
<script>
|
||||||
|
let group = [];
|
||||||
|
|
||||||
|
const options = [
|
||||||
|
["1", ["1a", "1b"]],
|
||||||
|
["2", ["2a", "2b"]],
|
||||||
|
];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#each options as [prefix, arr]}
|
||||||
|
{prefix}
|
||||||
|
<div>
|
||||||
|
{#each arr as item}
|
||||||
|
<label>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
bind:group
|
||||||
|
value={item}
|
||||||
|
/>
|
||||||
|
{item}
|
||||||
|
</label>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
|
||||||
|
<p>{JSON.stringify(group)}</p>
|
@ -0,0 +1,23 @@
|
|||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
async test({ assert, target }) {
|
||||||
|
const checkboxes = /** @type {NodeListOf<HTMLInputElement>} */ (
|
||||||
|
target.querySelectorAll('input[type="checkbox"]')
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.isFalse(checkboxes[0].checked);
|
||||||
|
assert.isTrue(checkboxes[1].checked);
|
||||||
|
assert.isFalse(checkboxes[2].checked);
|
||||||
|
|
||||||
|
await checkboxes[1].click();
|
||||||
|
|
||||||
|
const noChecked = target.querySelector('#output')?.innerHTML;
|
||||||
|
assert.equal(noChecked, '');
|
||||||
|
|
||||||
|
await checkboxes[1].click();
|
||||||
|
|
||||||
|
const oneChecked = target.querySelector('#output')?.innerHTML;
|
||||||
|
assert.equal(oneChecked, 'Mint choc chip');
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,18 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { writable } from 'svelte/store';
|
||||||
|
let menu = ['Cookies and cream', 'Mint choc chip', 'Raspberry ripple'];
|
||||||
|
let order = writable({ iceCream: [{flavours: ['Mint choc chip']}], scoops: 1 });
|
||||||
|
let index = 0
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<form method="POST">
|
||||||
|
<input type="radio" bind:group={$order.scoops} name="scoops" value={1} /> One scoop
|
||||||
|
<input type="radio" bind:group={$order.scoops} name="scoops" value={2} /> Two scoops
|
||||||
|
<input type="radio" bind:group={$order.scoops} name="scoops" value={3} /> Three scoops
|
||||||
|
|
||||||
|
{#each menu as flavour}
|
||||||
|
<input type="checkbox" bind:group={$order.iceCream[index].flavours} name="flavours" value={flavour} /> {flavour}
|
||||||
|
{/each}
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div id="output">{$order.iceCream[index].flavours.join('+')}</div>
|
Loading…
Reference in new issue