fix: ensure correct each block anchoring is applied to new entries

fix-each-anchor
Dominic Gannaway 4 days ago
parent 23484d6875
commit 2aae8c4b83

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: ensure correct each block anchoring is applied to new entries

@ -291,7 +291,10 @@ function reconcile(array, state, anchor, render_fn, flags, get_key) {
item = items.get(key);
if (item === undefined) {
var child_anchor = current ? get_first_node(current.e) : anchor;
var effect_dom = current?.e.dom;
var child_anchor = /** @type {Node} */ (
effect_dom ? (is_array(effect_dom) ? effect_dom[0] : effect_dom) : anchor
);
prev = create_item(child_anchor, prev, prev.next, value, key, i, render_fn, flags);

@ -0,0 +1,33 @@
import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
html: `<button>Add new message</button><p>first</p><p>message 1</p>`,
async test({ assert, target }) {
/**
* @type {{ click: () => void; }}
*/
let btn1;
[btn1] = target.querySelectorAll('button');
flushSync(() => {
btn1.click();
});
assert.htmlEqual(target.innerHTML, `<button>Add new message</button><p>first</p><p>message 1</p><p>message 2</p>`);
await Promise.resolve();
assert.htmlEqual(target.innerHTML, `<button>Add new message</button><p>first</p><p>message 1</p><p>message 2</p>`);
flushSync(() => {
btn1.click();
});
await Promise.resolve();
assert.htmlEqual(target.innerHTML, `<button>Add new message</button><p>first</p><p>message 1</p><p>message 2</p><p>message 3</p>`);
}
});

@ -0,0 +1,23 @@
<script>
let messages = $state([{id: 1, content: "message 1"}]);
function add() {
const newId = messages.length + 1
messages.push({id: 0, tmpId: newId, content: `message ${newId}`})
queueMicrotask(() => {
const msg = messages.find((m) => m.tmpId === newId && m.id === 0)
msg.tmpId = ""
msg.id = newId
})
}
</script>
<button onclick={add}>Add new message</button>
{#each messages as msg, i (`${msg.id}_${msg.tmpId ?? ""}`)}
{#if i === 0}
<p>first</p>
{/if}
<p>{msg.content}</p>
{/each}
Loading…
Cancel
Save