Skip to content

Commit fd7b950

Browse files
Fruupdummdidumm
andauthored
fix: Abort outro when intro starts (#12321)
Fixes #12319 --------- Co-authored-by: Leon Scherer <[email protected]> Co-authored-by: Simon Holthausen <[email protected]>
1 parent 95422e2 commit fd7b950

File tree

4 files changed

+49
-16
lines changed

4 files changed

+49
-16
lines changed

.changeset/bright-needles-pretend.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: abort outro when intro starts

packages/svelte/src/internal/client/dom/elements/transitions.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,14 +190,16 @@ export function transition(flags, element, get_fn, get_params) {
190190
in() {
191191
element.inert = inert;
192192

193+
// abort the outro to prevent overlap with the intro
194+
outro?.abort();
195+
193196
if (is_intro) {
194197
dispatch_event(element, 'introstart');
195198
intro = animate(element, get_options(), outro, 1, () => {
196199
dispatch_event(element, 'introend');
197200
intro = current_options = undefined;
198201
});
199202
} else {
200-
outro?.abort();
201203
reset?.();
202204
}
203205
},

packages/svelte/tests/runtime-legacy/samples/transition-abort/_config.js

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,48 @@ export default test({
1212
async test({ assert, component, target, raf }) {
1313
component.visible = false;
1414

15-
// abort halfway through the outro transition
16-
raf.tick(50);
15+
raf.tick(25);
16+
assert.htmlEqual(
17+
target.innerHTML,
18+
`
19+
<div style="opacity: 0.75;">a</div>
20+
<div style="opacity: 0.75;">a</div>
21+
`
22+
);
1723

24+
// abort 1/4 through the outro transition
1825
await component.$set({
1926
visible: true,
2027
array: ['a', 'b', 'c']
2128
});
2229

30+
raf.tick(50);
31+
assert.htmlEqual(
32+
target.innerHTML,
33+
// because outro is aborted it will be finished earlier with the intro than the new items
34+
`
35+
<div style="">a</div>
36+
<div style="opacity: 0.25;">b</div>
37+
<div style="opacity: 0.25;">c</div>
38+
39+
<div style="">a</div>
40+
<div style="opacity: 0.25;">b</div>
41+
<div style="opacity: 0.25;">c</div>
42+
`
43+
);
44+
45+
// intros of new items almost finished, aborted outro shouldn't overlap re-intro
46+
raf.tick(75);
2347
assert.htmlEqual(
2448
target.innerHTML,
2549
`
26-
<div>a</div>
27-
<div>b</div>
28-
<div>c</div>
50+
<div style="">a</div>
51+
<div style="opacity: 0.5;">b</div>
52+
<div style="opacity: 0.5;">c</div>
2953
30-
<div>a</div>
31-
<div>b</div>
32-
<div>c</div>
54+
<div style="">a</div>
55+
<div style="opacity: 0.5;">b</div>
56+
<div style="opacity: 0.5;">c</div>
3357
`
3458
);
3559
}

packages/svelte/tests/runtime-legacy/samples/transition-abort/main.svelte

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,22 @@
22
export let array = ['a'];
33
export let visible = true;
44
5-
function slide(_, params) {
6-
return params;
5+
function slide(_) {
6+
return {
7+
duration: 100,
8+
css: (t) => `opacity: ${t}`
9+
};
710
}
811
</script>
912

1013
{#if visible}
1114
{#each array as item}
12-
<div transition:slide={{duration:100}}>{item}</div>
15+
<div transition:slide|global>{item}</div>
1316
{/each}
1417
{/if}
1518

16-
{#if !visible}
17-
{:else}
19+
{#if !visible}{:else}
1820
{#each array as item}
19-
<div transition:slide={{duration:100}}>{item}</div>
21+
<div transition:slide|global>{item}</div>
2022
{/each}
21-
{/if}
23+
{/if}

0 commit comments

Comments
 (0)