Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/easy-paths-take.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: take into account static blocks when determining transition locality
5 changes: 4 additions & 1 deletion packages/svelte/src/internal/client/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
10 changes: 9 additions & 1 deletion packages/svelte/src/internal/client/reactivity/effects.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
@@ -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,
`
<button>Toggle</button>
<div>Should not transition out</div>
`
);

btn?.click();
flushSync();
assert.htmlEqual(target.innerHTML, '<button>Toggle</button>');
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

<script>
import { slide } from 'svelte/transition';
let showText = $state(false);
let show = $state(true);
</script>

<button onclick={() => showText = !showText}>
Toggle
</button>

{#if showText}
{#if show}
<div transition:slide>
Should not transition out
</div>
{/if}
{/if}
Loading