Skip to content

Commit 667ffb7

Browse files
authored
fix: improve global transition handling of effect cleardown (#10469)
* fix: improve global transition handling of effect cleardown
1 parent 1b56a32 commit 667ffb7

File tree

6 files changed

+57
-4
lines changed

6 files changed

+57
-4
lines changed

.changeset/cyan-spies-grin.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: improve global transition handling of effect cleardown

packages/svelte/src/internal/client/render.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1765,7 +1765,9 @@ export function component(anchor_node, component_fn, render_fn) {
17651765
transition.f(() => {
17661766
transitions.delete(transition);
17671767
if (transitions.size === 0) {
1768-
if (render.e !== null) {
1768+
// If the current render has changed since, then we can remove the old render
1769+
// effect as it's stale.
1770+
if (current_render !== render && render.e !== null) {
17691771
if (render.d !== null) {
17701772
remove(render.d);
17711773
render.d = null;
@@ -1891,7 +1893,9 @@ function await_block(anchor_node, input, pending_fn, then_fn, catch_fn) {
18911893
transition.f(() => {
18921894
transitions.delete(transition);
18931895
if (transitions.size === 0) {
1894-
if (render.e !== null) {
1896+
// If the current render has changed since, then we can remove the old render
1897+
// effect as it's stale.
1898+
if (current_render !== render && render.e !== null) {
18951899
if (render.d !== null) {
18961900
remove(render.d);
18971901
render.d = null;
@@ -2051,7 +2055,9 @@ export function key(anchor_node, key, render_fn) {
20512055
transition.f(() => {
20522056
transitions.delete(transition);
20532057
if (transitions.size === 0) {
2054-
if (render.e !== null) {
2058+
// If the current render has changed since, then we can remove the old render
2059+
// effect as it's stale.
2060+
if (current_render !== render && render.e !== null) {
20552061
if (render.d !== null) {
20562062
remove(render.d);
20572063
render.d = null;

packages/svelte/tests/animation-helpers.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,11 @@ class Animation {
7070

7171
_update() {
7272
if (this.#reversed) {
73-
this.currentTime = this.#timeline_offset + (this.#timeline_offset - raf.time);
73+
if (this.#timeline_offset === 0) {
74+
this.currentTime = this.#duration - raf.time;
75+
} else {
76+
this.currentTime = this.#timeline_offset + (this.#timeline_offset - raf.time);
77+
}
7478
} else {
7579
this.currentTime = raf.time - this.#timeline_offset;
7680
}
@@ -130,6 +134,9 @@ class Animation {
130134
}
131135

132136
reverse() {
137+
if (this.#paused && !raf.animations.has(this)) {
138+
raf.animations.add(this);
139+
}
133140
this.#timeline_offset = this.currentTime;
134141
this.#reversed = !this.#reversed;
135142
this.playState = 'running';
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<script>
2+
import { fade } from 'svelte/transition';
3+
let show = $state(true);
4+
</script>
5+
6+
<h1>Outside</h1>
7+
8+
{#if show}
9+
<button onclick={()=> show = false} transition:fade|global={{ duration: 100 }}>Hide</button>
10+
{/if}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { test } from '../../test';
2+
import { flushSync } from 'svelte';
3+
4+
export default test({
5+
async test({ assert, target, raf }) {
6+
const btn = target.querySelector('button');
7+
8+
raf.tick(0);
9+
10+
flushSync(() => {
11+
btn?.click();
12+
});
13+
14+
assert.htmlEqual(target.innerHTML, `<h1>Outside</h1><button>Hide</button>`);
15+
16+
raf.tick(100);
17+
18+
assert.htmlEqual(target.innerHTML, `<h1>Outside</h1>`);
19+
}
20+
});
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script>
2+
import Component from "./Component.svelte"
3+
</script>
4+
5+
<svelte:component this={Component} />

0 commit comments

Comments
 (0)