Skip to content

Commit 8c95777

Browse files
authored
fix: improve how transitions are handled on mount (#10157)
1 parent a1a3e81 commit 8c95777

File tree

3 files changed

+36
-23
lines changed

3 files changed

+36
-23
lines changed

.changeset/slow-wombats-reply.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: improve how transitions are handled on mount

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

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,11 +1012,10 @@ export function mutate_store(store, expression, new_value) {
10121012

10131013
/**
10141014
* @param {import('./types.js').ComputationSignal} signal
1015-
* @param {import('./types.js').ComputationSignal} root
10161015
* @param {boolean} inert
10171016
* @returns {void}
10181017
*/
1019-
export function mark_subtree_inert(signal, root, inert, visited_blocks = new Set()) {
1018+
export function mark_subtree_inert(signal, inert, visited_blocks = new Set()) {
10201019
const flags = signal.f;
10211020
const is_already_inert = (flags & INERT) !== 0;
10221021
if (is_already_inert !== inert) {
@@ -1031,23 +1030,22 @@ export function mark_subtree_inert(signal, root, inert, visited_blocks = new Set
10311030
const type = block.t;
10321031
if (type === IF_BLOCK) {
10331032
const condition_effect = block.e;
1034-
const root_block = root.b?.p;
1035-
if (condition_effect !== null && root_block?.t === IF_BLOCK) {
1036-
mark_subtree_inert(condition_effect, root, inert);
1033+
if (condition_effect !== null && block !== current_block) {
1034+
mark_subtree_inert(condition_effect, inert);
10371035
}
10381036
const consequent_effect = block.ce;
10391037
if (consequent_effect !== null) {
1040-
mark_subtree_inert(consequent_effect, root, inert, visited_blocks);
1038+
mark_subtree_inert(consequent_effect, inert, visited_blocks);
10411039
}
10421040
const alternate_effect = block.ae;
10431041
if (alternate_effect !== null) {
1044-
mark_subtree_inert(alternate_effect, root, inert, visited_blocks);
1042+
mark_subtree_inert(alternate_effect, inert, visited_blocks);
10451043
}
10461044
} else if (type === EACH_BLOCK) {
10471045
const items = block.v;
10481046
for (let { e: each_item_effect } of items) {
10491047
if (each_item_effect !== null) {
1050-
mark_subtree_inert(each_item_effect, root, inert, visited_blocks);
1048+
mark_subtree_inert(each_item_effect, inert, visited_blocks);
10511049
}
10521050
}
10531051
}
@@ -1057,7 +1055,7 @@ export function mark_subtree_inert(signal, root, inert, visited_blocks = new Set
10571055
if (references !== null) {
10581056
let i;
10591057
for (i = 0; i < references.length; i++) {
1060-
mark_subtree_inert(references[i], root, inert, visited_blocks);
1058+
mark_subtree_inert(references[i], inert, visited_blocks);
10611059
}
10621060
}
10631061
}

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

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -482,33 +482,43 @@ export function bind_transition(dom, get_transition_fn, props_fn, direction, glo
482482
// @ts-ignore
483483
dom.__animate = true;
484484
}
485-
485+
let foo = false;
486486
/** @type {import('./types.js').Block | null} */
487487
let transition_block = block;
488-
while (transition_block !== null) {
488+
main: while (transition_block !== null) {
489489
if (is_transition_block(transition_block)) {
490490
if (transition_block.t === EACH_ITEM_BLOCK) {
491491
// Lazily apply the each block transition
492492
transition_block.r = each_item_transition;
493493
transition_block.a = each_item_animate;
494494
transition_block = transition_block.p;
495495
} else if (transition_block.t === AWAIT_BLOCK && transition_block.n /* pending */) {
496-
can_show_intro_on_mount = false;
496+
can_show_intro_on_mount = true;
497497
} else if (transition_block.t === IF_BLOCK) {
498498
transition_block.r = if_block_transition;
499+
if (can_show_intro_on_mount) {
500+
/** @type {import('./types.js').Block | null} */
501+
let if_block = transition_block;
502+
while (if_block.t === IF_BLOCK) {
503+
// If we have an if block parent that is currently falsy then
504+
// we can show the intro on mount as long as that block is mounted
505+
if (if_block.e !== null && !if_block.v) {
506+
can_show_intro_on_mount = true;
507+
break main;
508+
}
509+
if_block = if_block.p;
510+
}
511+
}
499512
}
500513
if (!can_apply_lazy_transitions && can_show_intro_on_mount) {
501-
can_show_intro_on_mount = transition_block.e === null;
514+
can_show_intro_on_mount = transition_block.e !== null;
515+
foo = true;
502516
}
503-
if (!can_show_intro_on_mount || !global) {
517+
if (can_show_intro_on_mount || !global) {
504518
can_apply_lazy_transitions = true;
505519
}
506-
} else if (
507-
!can_apply_lazy_transitions &&
508-
transition_block.t === ROOT_BLOCK &&
509-
(transition_block.e !== null || transition_block.i)
510-
) {
511-
can_show_intro_on_mount = false;
520+
} else if (transition_block.t === ROOT_BLOCK && !can_apply_lazy_transitions) {
521+
can_show_intro_on_mount = transition_block.e !== null || transition_block.i;
512522
}
513523
transition_block = transition_block.p;
514524
}
@@ -540,7 +550,7 @@ export function bind_transition(dom, get_transition_fn, props_fn, direction, glo
540550

541551
transition = create_transition(dom, init, direction, transition_effect);
542552
const is_intro = direction === 'in';
543-
const show_intro = !can_show_intro_on_mount && (is_intro || direction === 'both');
553+
const show_intro = can_show_intro_on_mount && (is_intro || direction === 'both');
544554

545555
if (show_intro) {
546556
transition.p = transition.i();
@@ -602,7 +612,7 @@ export function trigger_transitions(transitions, target_direction, from) {
602612
transition.c();
603613
}
604614
transition.d.inert = false;
605-
mark_subtree_inert(effect, effect, false);
615+
mark_subtree_inert(effect, false);
606616
} else if (target_direction === 'key') {
607617
if (direction === 'key') {
608618
transition.p = transition.i(/** @type {DOMRect} */ (from));
@@ -614,7 +624,7 @@ export function trigger_transitions(transitions, target_direction, from) {
614624
outros.push(transition.o);
615625
}
616626
transition.d.inert = true;
617-
mark_subtree_inert(effect, effect, true);
627+
mark_subtree_inert(effect, true);
618628
}
619629
}
620630
if (outros.length > 0) {

0 commit comments

Comments
 (0)