Skip to content

Commit 2c56037

Browse files
authored
Measure and apply names for the "new" phase (#32612)
Stacked on #32599 and #32611. This is able to reuse the code from CommitViewTransitions for "enter", "shared" and "layout". The difference is that for "enter"/"shared" in the "new" phase we pass in the deletions. For "layout" of nested boundaries we just need to measure the clones at the same time we measure the original nodes since we haven't measured them in a previous phase in the current approach. With these updates, things move around more like expected in the fixture because we're now applying the appropriate pairs to trigger individual animations instead of just the full document cross-fade. The "update" phase is a little more complicated and is coming soon.
1 parent 2e38573 commit 2c56037

File tree

3 files changed

+44
-79
lines changed

3 files changed

+44
-79
lines changed

packages/react-reconciler/src/ReactFiberApplyGesture.js

Lines changed: 5 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ import {
6262
restoreEnterOrExitViewTransitions,
6363
restoreNestedViewTransitions,
6464
appearingViewTransitions,
65+
commitEnterViewTransitions,
66+
measureNestedViewTransitions,
6567
} from './ReactFiberCommitViewTransitions';
6668
import {
6769
getViewTransitionName,
@@ -968,53 +970,6 @@ export function insertDestinationClones(
968970
}
969971
}
970972

971-
function applyDeletedPairViewTransitions(deletion: Fiber): void {
972-
if ((deletion.subtreeFlags & ViewTransitionNamedStatic) === NoFlags) {
973-
// This has no named view transitions in its subtree.
974-
return;
975-
}
976-
let child = deletion.child;
977-
while (child !== null) {
978-
if (child.tag === OffscreenComponent && child.memoizedState === null) {
979-
// This tree was already hidden so we skip it.
980-
} else {
981-
if (
982-
child.tag === ViewTransitionComponent &&
983-
(child.flags & ViewTransitionNamedStatic) !== NoFlags
984-
) {
985-
const props: ViewTransitionProps = child.memoizedProps;
986-
const name = props.name;
987-
if (name != null && name !== 'auto') {
988-
// TODO: Find a pair
989-
}
990-
}
991-
applyDeletedPairViewTransitions(child);
992-
}
993-
child = child.sibling;
994-
}
995-
}
996-
997-
function applyEnterViewTransitions(deletion: Fiber): void {
998-
if (deletion.tag === ViewTransitionComponent) {
999-
const props: ViewTransitionProps = deletion.memoizedProps;
1000-
const name = props.name;
1001-
if (name != null && name !== 'auto') {
1002-
// TODO: Find a pair
1003-
}
1004-
// Look for more pairs deeper in the tree.
1005-
applyDeletedPairViewTransitions(deletion);
1006-
} else if ((deletion.subtreeFlags & ViewTransitionStatic) !== NoFlags) {
1007-
// TODO: Check if this is a hidden Offscreen or a Portal.
1008-
let child = deletion.child;
1009-
while (child !== null) {
1010-
applyEnterViewTransitions(child);
1011-
child = child.sibling;
1012-
}
1013-
} else {
1014-
applyDeletedPairViewTransitions(deletion);
1015-
}
1016-
}
1017-
1018973
function measureExitViewTransitions(placement: Fiber): void {
1019974
if (placement.tag === ViewTransitionComponent) {
1020975
// const state: ViewTransitionState = placement.stateNode;
@@ -1036,24 +991,6 @@ function measureExitViewTransitions(placement: Fiber): void {
1036991
}
1037992
}
1038993

1039-
function measureNestedViewTransitions(changedParent: Fiber): void {
1040-
let child = changedParent.child;
1041-
while (child !== null) {
1042-
if (child.tag === ViewTransitionComponent) {
1043-
const current = child.alternate;
1044-
if (current !== null) {
1045-
// const props: ViewTransitionProps = child.memoizedProps;
1046-
// const name = getViewTransitionName(props, child.stateNode);
1047-
// TODO: Measure both the old and new state and see if they're different.
1048-
}
1049-
} else if ((child.subtreeFlags & ViewTransitionStatic) !== NoFlags) {
1050-
// TODO: Check if this is a hidden Offscreen or a Portal.
1051-
measureNestedViewTransitions(child);
1052-
}
1053-
child = child.sibling;
1054-
}
1055-
}
1056-
1057994
function measureUpdateViewTransition(
1058995
current: Fiber,
1059996
finishedWork: Fiber,
@@ -1066,7 +1003,7 @@ function recursivelyApplyViewTransitions(parentFiber: Fiber) {
10661003
if (deletions !== null) {
10671004
for (let i = 0; i < deletions.length; i++) {
10681005
const childToDelete = deletions[i];
1069-
applyEnterViewTransitions(childToDelete);
1006+
commitEnterViewTransitions(childToDelete, true);
10701007
}
10711008
}
10721009

@@ -1084,7 +1021,7 @@ function recursivelyApplyViewTransitions(parentFiber: Fiber) {
10841021
// Nothing has changed in this subtree, but the parent may have still affected
10851022
// its size and position. We need to measure the old and new state to see if
10861023
// we should animate its size and position.
1087-
measureNestedViewTransitions(parentFiber);
1024+
measureNestedViewTransitions(parentFiber, true);
10881025
}
10891026
}
10901027

@@ -1121,7 +1058,7 @@ function applyViewTransitionsOnFiber(finishedWork: Fiber) {
11211058
measureExitViewTransitions(finishedWork);
11221059
} else if (current !== null && current.memoizedState === null) {
11231060
// Was previously mounted as visible but is now hidden.
1124-
applyEnterViewTransitions(current);
1061+
commitEnterViewTransitions(current, true);
11251062
}
11261063
}
11271064
break;

packages/react-reconciler/src/ReactFiberCommitViewTransitions.js

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,10 @@ function commitAppearingPairViewTransitions(placement: Fiber): void {
257257
}
258258
}
259259

260-
export function commitEnterViewTransitions(placement: Fiber): void {
260+
export function commitEnterViewTransitions(
261+
placement: Fiber,
262+
gesture: boolean,
263+
): void {
261264
if (placement.tag === ViewTransitionComponent) {
262265
const state: ViewTransitionState = placement.stateNode;
263266
const props: ViewTransitionProps = placement.memoizedProps;
@@ -284,7 +287,11 @@ export function commitEnterViewTransitions(placement: Fiber): void {
284287
commitAppearingPairViewTransitions(placement);
285288

286289
if (!state.paired) {
287-
scheduleViewTransitionEvent(placement, props.onEnter);
290+
if (gesture) {
291+
// TODO: Schedule gesture events.
292+
} else {
293+
scheduleViewTransitionEvent(placement, props.onEnter);
294+
}
288295
}
289296
}
290297
} else {
@@ -293,7 +300,7 @@ export function commitEnterViewTransitions(placement: Fiber): void {
293300
} else if ((placement.subtreeFlags & ViewTransitionStatic) !== NoFlags) {
294301
let child = placement.child;
295302
while (child !== null) {
296-
commitEnterViewTransitions(child);
303+
commitEnterViewTransitions(child, gesture);
297304
child = child.sibling;
298305
}
299306
} else {
@@ -703,6 +710,8 @@ function measureViewTransitionHostInstancesRecursive(
703710
}
704711
if ((parentViewTransition.flags & Update) !== NoFlags) {
705712
// We might update this node so we need to apply its new name for the new state.
713+
// Additionally in the ApplyGesture case we also need to do this because the clone
714+
// will have the name but this one won't.
706715
applyViewTransitionName(
707716
instance,
708717
viewTransitionHostInstanceIdx === 0
@@ -828,32 +837,51 @@ export function measureUpdateViewTransition(
828837
return inViewport;
829838
}
830839

831-
export function measureNestedViewTransitions(changedParent: Fiber): void {
840+
export function measureNestedViewTransitions(
841+
changedParent: Fiber,
842+
gesture: boolean,
843+
): void {
832844
let child = changedParent.child;
833845
while (child !== null) {
834846
if (child.tag === ViewTransitionComponent) {
835847
const props: ViewTransitionProps = child.memoizedProps;
836-
const name = getViewTransitionName(props, child.stateNode);
848+
const state: ViewTransitionState = child.stateNode;
849+
const name = getViewTransitionName(props, state);
837850
const className: ?string = getViewTransitionClassName(
838851
props.className,
839852
props.layout,
840853
);
854+
let previousMeasurements: null | Array<InstanceMeasurement>;
855+
if (gesture) {
856+
const clones = state.clones;
857+
if (clones === null) {
858+
previousMeasurements = null;
859+
} else {
860+
previousMeasurements = clones.map(measureInstance);
861+
}
862+
} else {
863+
previousMeasurements = child.memoizedState;
864+
}
841865
const inViewport = measureViewTransitionHostInstances(
842866
child,
843867
child.child,
844868
name,
845869
name, // Since this is unchanged, new and old name is the same.
846870
className,
847-
child.memoizedState,
871+
previousMeasurements,
848872
false,
849873
);
850874
if ((child.flags & Update) === NoFlags || !inViewport) {
851875
// Nothing changed.
852876
} else {
853-
scheduleViewTransitionEvent(child, props.onLayout);
877+
if (gesture) {
878+
// TODO: Schedule gesture events.
879+
} else {
880+
scheduleViewTransitionEvent(child, props.onLayout);
881+
}
854882
}
855883
} else if ((child.subtreeFlags & ViewTransitionStatic) !== NoFlags) {
856-
measureNestedViewTransitions(child);
884+
measureNestedViewTransitions(child, gesture);
857885
}
858886
child = child.sibling;
859887
}

packages/react-reconciler/src/ReactFiberCommitWork.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2450,7 +2450,7 @@ function recursivelyTraverseAfterMutationEffects(
24502450
// Nothing has changed in this subtree, but the parent may have still affected
24512451
// its size and position. We need to measure this and if not, restore it to
24522452
// not animate.
2453-
measureNestedViewTransitions(parentFiber);
2453+
measureNestedViewTransitions(parentFiber, false);
24542454
}
24552455
}
24562456

@@ -2468,7 +2468,7 @@ function commitAfterMutationEffectsOnFiber(
24682468
// we can just bail after we're done with the first one.
24692469
// The first ViewTransition inside a newly mounted tree runs an enter transition
24702470
// but other nested ones don't unless they have a named pair.
2471-
commitEnterViewTransitions(finishedWork);
2471+
commitEnterViewTransitions(finishedWork, false);
24722472
return;
24732473
}
24742474

@@ -2512,7 +2512,7 @@ function commitAfterMutationEffectsOnFiber(
25122512
// The Offscreen tree is visible.
25132513
const wasHidden = current.memoizedState !== null;
25142514
if (wasHidden) {
2515-
commitEnterViewTransitions(finishedWork);
2515+
commitEnterViewTransitions(finishedWork, false);
25162516
// If it was previous hidden then the children are treated as enter
25172517
// not updates so we don't need to visit these children.
25182518
} else {

0 commit comments

Comments
 (0)