Skip to content

Commit 765ca03

Browse files
authored
fix: further improve reconciliation of inert each block rows (#13527)
Inert effects are currently outroing and will be removed once the transition is finished Fixes #13302
1 parent db305a0 commit 765ca03

File tree

5 files changed

+75
-3
lines changed

5 files changed

+75
-3
lines changed

.changeset/friendly-dryers-jog.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: further improve reconciliation of inert each block rows

packages/svelte/src/internal/client/dom/blocks/each.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,10 @@ function reconcile(array, state, anchor, render_fn, flags, get_key) {
398398
var to_destroy = seen === undefined ? [] : array_from(seen);
399399

400400
while (current !== null) {
401-
to_destroy.push(current);
401+
// Inert effects are currently outroing and will be removed once the transition is finished
402+
if ((current.e.f & INERT) === 0) {
403+
to_destroy.push(current);
404+
}
402405
current = current.next;
403406
}
404407

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { flushSync } from '../../../../src/index-client.js';
2+
import { test } from '../../test';
3+
4+
export default test({
5+
test({ assert, raf, target }) {
6+
const [btn1, btn2] = target.querySelectorAll('button');
7+
8+
btn1?.click();
9+
btn1?.click();
10+
btn1?.click();
11+
flushSync();
12+
assert.htmlEqual(
13+
target.innerHTML,
14+
'<button>Push</button><button>Remove</button><ul><li>0</li><li>1</li><li>2</li></ul>'
15+
);
16+
17+
btn2?.click();
18+
flushSync();
19+
raf.tick(50);
20+
21+
const li = /** @type {HTMLElement & { foo: number }} */ (target.querySelector('ul > li'));
22+
23+
assert.equal(li.foo, 0.5);
24+
25+
btn1?.click();
26+
flushSync();
27+
28+
assert.equal(li.foo, 0.5);
29+
assert.htmlEqual(
30+
target.innerHTML,
31+
'<button>Push</button><button>Remove</button><ul><li>3</li><li>0</li><li>1</li><li>2</li></ul>'
32+
);
33+
}
34+
});
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<script>
2+
function foo(node, params) {
3+
return {
4+
duration: 100,
5+
tick: (t, u) => {
6+
node.foo = t;
7+
}
8+
};
9+
}
10+
11+
let list = $state([]);
12+
let id = 0;
13+
14+
function push() {
15+
list.push({ id: id++ })
16+
}
17+
18+
function remove() {
19+
list = [];
20+
}
21+
</script>
22+
23+
<button onclick={push}>Push</button>
24+
<button onclick={remove}>Remove</button>
25+
26+
<ul>
27+
{#each list as item (item.id)}
28+
<li out:foo>{item.id}</li>
29+
{/each}
30+
</ul>

packages/svelte/tests/runtime-runes/samples/transition-each/_config.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export default test({
1111
flushSync();
1212
assert.htmlEqual(
1313
target.innerHTML,
14-
'<button>Push</button><button>Remove</button><ul><li>0</li><li>1</li><li>2</li></ul'
14+
'<button>Push</button><button>Remove</button><ul><li>0</li><li>1</li><li>2</li></ul>'
1515
);
1616

1717
btn2?.click();
@@ -28,7 +28,7 @@ export default test({
2828
assert.equal(li.foo, 0.5);
2929
assert.htmlEqual(
3030
target.innerHTML,
31-
'<button>Push</button><button>Remove</button><ul><li>0</li><li>1</li><li>2</li><li>3</li></ul'
31+
'<button>Push</button><button>Remove</button><ul><li>0</li><li>1</li><li>2</li><li>3</li></ul>'
3232
);
3333
}
3434
});

0 commit comments

Comments
 (0)