[Fizz] Make ViewTransition enter/exit/share null the same as none (#33331)
I believe that these mean the same thing. We don't have to emit the attribute if it's `none` for these cases because if there is no matching scenario we won't apply the animation in this case. The only case where we have to emit `none` in the attribute is for `vt-update` because those can block updates from propagating upwards.
Sebastian Markbåge committed
May 22, 2025 at 10:21 UTC
08064ea6713ff55730c5d4f50b733891ebe0e875
1 file changed
+11
-17
packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js
+11
-17
@@ -759,10 +759,9 @@ const SUBTREE_SCOPE = ~(ENTER_SCOPE | EXIT_SCOPE);
759
760
type ViewTransitionContext = {
761
update: 'none' | 'auto' | string,
762
- // null here means that this case can never trigger. Not "auto" like it does in props.
763
- enter: null | 'none' | 'auto' | string,
764
- exit: null | 'none' | 'auto' | string,
765
- share: null | 'none' | 'auto' | string,
762
+ enter: 'none' | 'auto' | string,
763
+ exit: 'none' | 'auto' | string,
764
+ share: 'none' | 'auto' | string,
765
name: 'auto' | string,
766
autoName: string, // a name that can be used if an explicit one is not defined.
767
nameIdx: number, // keeps track of how many duplicates of this name we've emitted.
@@ -917,8 +916,8 @@ function getSuspenseViewTransition(
916
// we would've used (the parent ViewTransition name or auto-assign one).
917
const viewTransition: ViewTransitionContext = {
918
update: parentViewTransition.update, // For deep updates.
920
- enter: null,
921
- exit: null,
919
+ enter: 'none',
920
+ exit: 'none',
921
share: parentViewTransition.update, // For exit or enter of reveals.
922
name: parentViewTransition.autoName,
923
autoName: parentViewTransition.autoName,
@@ -989,13 +988,8 @@ export function getViewTransitionFormatContext(
988
share = parentViewTransition.share;
989
} else {
990
name = 'auto';
992
- share = null; // share is only relevant if there's an explicit name
991
+ share = 'none'; // share is only relevant if there's an explicit name
992
}
994
- } else if (share === 'none') {
995
- // I believe if share is disabled, it means the same thing as if it doesn't
996
- // exit because enter/exit will take precedence and if it's deeply nested
997
- // it just animates along whatever the parent does when disabled.
998
- share = null;
993
} else {
994
if (share == null) {
995
share = 'auto';
@@ -1008,12 +1002,12 @@ export function getViewTransitionFormatContext(
1002
}
1003
}
1004
if (!(parentContext.tagScope & EXIT_SCOPE)) {
1011
- exit = null; // exit is only relevant for the first ViewTransition inside fallback
1005
+ exit = 'none'; // exit is only relevant for the first ViewTransition inside fallback
1006
} else {
1007
resumableState.instructions |= NeedUpgradeToViewTransitions;
1008
}
1009
if (!(parentContext.tagScope & ENTER_SCOPE)) {
1016
- enter = null; // enter is only relevant for the first ViewTransition inside content
1010
+ enter = 'none'; // enter is only relevant for the first ViewTransition inside content
1011
} else {
1012
resumableState.instructions |= NeedUpgradeToViewTransitions;
1013
}
@@ -1125,13 +1119,13 @@ function pushViewTransitionAttributes(
1119
viewTransition.nameIdx++;
1120
}
1121
pushStringAttribute(target, 'vt-update', viewTransition.update);
1128
- if (viewTransition.enter !== null) {
1122
+ if (viewTransition.enter !== 'none') {
1123
pushStringAttribute(target, 'vt-enter', viewTransition.enter);
1124
}
1131
- if (viewTransition.exit !== null) {
1125
+ if (viewTransition.exit !== 'none') {
1126
pushStringAttribute(target, 'vt-exit', viewTransition.exit);
1127
}
1134
- if (viewTransition.share !== null) {
1128
+ if (viewTransition.share !== 'none') {
1129
pushStringAttribute(target, 'vt-share', viewTransition.share);
1130
}
1131
}