Skip to content

Commit f5dc562

Browse files
authored
fix: ensure nested blocks are inert during outro transitions (#10126)
* fix: ensure nested blocks are inert during outro transitions * lint
1 parent 3624a4c commit f5dc562

File tree

4 files changed

+61
-0
lines changed

4 files changed

+61
-0
lines changed

.changeset/spotty-pens-agree.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: ensure nested blocks are inert during outro transitions

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
} from '../../constants.js';
1111
import { readonly } from './proxy/readonly.js';
1212
import { READONLY_SYMBOL, STATE_SYMBOL, proxy, unstate } from './proxy/proxy.js';
13+
import { EACH_BLOCK, IF_BLOCK } from './block.js';
1314

1415
export const SOURCE = 1;
1516
export const DERIVED = 1 << 1;
@@ -1019,6 +1020,28 @@ export function mark_subtree_inert(signal, inert) {
10191020
if (!inert && (flags & IS_EFFECT) !== 0 && (flags & CLEAN) === 0) {
10201021
schedule_effect(/** @type {import('./types.js').EffectSignal} */ (signal), false);
10211022
}
1023+
// Nested if block effects
1024+
const block = signal.b;
1025+
if (block !== null) {
1026+
const type = block.t;
1027+
if (type === IF_BLOCK) {
1028+
const consequent_effect = block.ce;
1029+
if (consequent_effect !== null) {
1030+
mark_subtree_inert(consequent_effect, inert);
1031+
}
1032+
const alternate_effect = block.ae;
1033+
if (alternate_effect !== null) {
1034+
mark_subtree_inert(alternate_effect, inert);
1035+
}
1036+
} else if (type === EACH_BLOCK) {
1037+
const items = block.v;
1038+
for (let { e: each_item_effect } of items) {
1039+
if (each_item_effect !== null) {
1040+
mark_subtree_inert(each_item_effect, inert);
1041+
}
1042+
}
1043+
}
1044+
}
10221045
}
10231046
const references = signal.r;
10241047
if (references !== null) {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { flushSync } from 'svelte';
2+
import { test } from '../../test';
3+
4+
export default test({
5+
html: `<button>hide</button><div>hello</div>`,
6+
7+
async test({ assert, target }) {
8+
const [btn1, btn2] = target.querySelectorAll('button');
9+
10+
flushSync(() => {
11+
btn1.click();
12+
});
13+
14+
assert.htmlEqual(target.innerHTML, `<button>hide</button><div style="opacity: 0;">hello</div>`);
15+
}
16+
});
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<script>
2+
import { fade } from "svelte/transition";
3+
4+
let state = $state("hello");
5+
</script>
6+
7+
<button onclick={() => state = ''}>hide</button>
8+
9+
{#if state}
10+
<div in:fade={{ duration: 2000 }} out:fade={{ duration: 2000 }}>
11+
{#if true}
12+
{state}
13+
{/if}
14+
</div>
15+
{/if}
16+
17+

0 commit comments

Comments
 (0)