fix: handle deferred transitions aborted before initialization (#18776)

- make deferred transition facade methods safe before the inner
animation initializes
- report the transition's initial position from the facade until
initialization
- add a runtime regression test for an out-only `crossfade` branch
restored in the same update

Fixes https://github.com/sveltejs/svelte/issues/18773

---------

Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
pull/18846/merge
svelte-triage-bot[bot] 2 days ago committed by GitHub
parent f908535659
commit 7fb397e78f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: handle deferred transitions aborted before initialization

@ -359,9 +359,9 @@ function animate(element, options, counterpart, t2, on_begin, on_finish) {
aborted = true;
a?.abort();
},
deactivate: () => a.deactivate(),
reset: () => a.reset(),
t: () => a.t()
deactivate: () => a?.deactivate(),
reset: () => a?.reset(),
t: () => a?.t() ?? 1 - t2
};
}

@ -0,0 +1,13 @@
import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
async test({ assert, target }) {
const [button] = target.querySelectorAll('button');
button.click();
flushSync();
assert.htmlEqual(target.innerHTML, '<button>Reproduce</button><p>Deferred outro</p>');
}
});

@ -0,0 +1,24 @@
<script>
import { crossfade } from 'svelte/transition';
let visible = $state(true);
let restore = $state(false);
const [send] = crossfade({});
$effect(() => {
if (restore) visible = true;
});
</script>
<button
onclick={() => {
visible = false;
restore = true;
}}
>
Reproduce
</button>
{#if visible}
<p out:send={{ key: 'item' }}>Deferred outro</p>
{/if}
Loading…
Cancel
Save