fix: ensure nested blocks are inert during outro transitions (#10126)

* fix: ensure nested blocks are inert during outro transitions

* lint
pull/10128/head
Dominic Gannaway 12 months ago committed by GitHub
parent 3624a4c2a0
commit f5dc562ee7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: ensure nested blocks are inert during outro transitions

@ -10,6 +10,7 @@ import {
} from '../../constants.js';
import { readonly } from './proxy/readonly.js';
import { READONLY_SYMBOL, STATE_SYMBOL, proxy, unstate } from './proxy/proxy.js';
import { EACH_BLOCK, IF_BLOCK } from './block.js';
export const SOURCE = 1;
export const DERIVED = 1 << 1;
@ -1019,6 +1020,28 @@ export function mark_subtree_inert(signal, inert) {
if (!inert && (flags & IS_EFFECT) !== 0 && (flags & CLEAN) === 0) {
schedule_effect(/** @type {import('./types.js').EffectSignal} */ (signal), false);
}
// Nested if block effects
const block = signal.b;
if (block !== null) {
const type = block.t;
if (type === IF_BLOCK) {
const consequent_effect = block.ce;
if (consequent_effect !== null) {
mark_subtree_inert(consequent_effect, inert);
}
const alternate_effect = block.ae;
if (alternate_effect !== null) {
mark_subtree_inert(alternate_effect, inert);
}
} else if (type === EACH_BLOCK) {
const items = block.v;
for (let { e: each_item_effect } of items) {
if (each_item_effect !== null) {
mark_subtree_inert(each_item_effect, inert);
}
}
}
}
}
const references = signal.r;
if (references !== null) {

@ -0,0 +1,16 @@
import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
html: `<button>hide</button><div>hello</div>`,
async test({ assert, target }) {
const [btn1, btn2] = target.querySelectorAll('button');
flushSync(() => {
btn1.click();
});
assert.htmlEqual(target.innerHTML, `<button>hide</button><div style="opacity: 0;">hello</div>`);
}
});

@ -0,0 +1,17 @@
<script>
import { fade } from "svelte/transition";
let state = $state("hello");
</script>
<button onclick={() => state = ''}>hide</button>
{#if state}
<div in:fade={{ duration: 2000 }} out:fade={{ duration: 2000 }}>
{#if true}
{state}
{/if}
</div>
{/if}
Loading…
Cancel
Save