diff --git a/.changeset/easy-paths-take.md b/.changeset/easy-paths-take.md new file mode 100644 index 0000000000..1378322abe --- /dev/null +++ b/.changeset/easy-paths-take.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: take into account static blocks when determining transition locality diff --git a/packages/svelte/src/internal/client/constants.js b/packages/svelte/src/internal/client/constants.js index 1f35add2a8..6818fd9d30 100644 --- a/packages/svelte/src/internal/client/constants.js +++ b/packages/svelte/src/internal/client/constants.js @@ -14,7 +14,10 @@ export const DESTROYED = 1 << 14; // Flags exclusive to effects export const EFFECT_RAN = 1 << 15; -/** 'Transparent' effects do not create a transition boundary */ +/** + * 'Transparent' effects do not create a transition boundary. + * This is on a block effect 99% of the time but may also be on a branch effect if its parent block effect was pruned + */ export const EFFECT_TRANSPARENT = 1 << 16; export const INSPECT_EFFECT = 1 << 17; export const HEAD_EFFECT = 1 << 18; diff --git a/packages/svelte/src/internal/client/reactivity/effects.js b/packages/svelte/src/internal/client/reactivity/effects.js index bfbb95a8db..9b54598f9e 100644 --- a/packages/svelte/src/internal/client/reactivity/effects.js +++ b/packages/svelte/src/internal/client/reactivity/effects.js @@ -149,6 +149,9 @@ function create_effect(type, fn, sync, push = true) { (e.f & EFFECT_PRESERVED) === 0 ) { e = e.first; + if ((type & BLOCK_EFFECT) !== 0 && (type & EFFECT_TRANSPARENT) !== 0 && e !== null) { + e.f |= EFFECT_TRANSPARENT; + } } if (e !== null) { @@ -604,7 +607,12 @@ export function pause_children(effect, transitions, local) { while (child !== null) { var sibling = child.next; - var transparent = (child.f & EFFECT_TRANSPARENT) !== 0 || (child.f & BRANCH_EFFECT) !== 0; + var transparent = + (child.f & EFFECT_TRANSPARENT) !== 0 || + // If this is a branch effect without a block effect parent, + // it means the parent block effect was pruned. In that case, + // transparency information was transferred to the branch effect. + ((child.f & BRANCH_EFFECT) !== 0 && (effect.f & BLOCK_EFFECT) !== 0); // TODO we don't need to call pause_children recursively with a linked list in place // it's slightly more involved though as we have to account for `transparent` changing // through the tree. diff --git a/packages/svelte/tests/runtime-runes/samples/transition-if-nested-static/_config.js b/packages/svelte/tests/runtime-runes/samples/transition-if-nested-static/_config.js new file mode 100644 index 0000000000..900d6daff8 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/transition-if-nested-static/_config.js @@ -0,0 +1,22 @@ +import { flushSync } from 'svelte'; +import { test } from '../../test'; + +export default test({ + async test({ assert, target }) { + const btn = target.querySelector('button'); + + btn?.click(); + flushSync(); + assert.htmlEqual( + target.innerHTML, + ` + +