Skip to content

Commit f45a7d0

Browse files
committed
Commit the Gesture lane if a gesture ends closer to the target state (#35486)
Stacked on #35485. Before this PR, the `startGestureTransition` API would itself never commit its state. After the gesture releases it stops the animation in the next commit which just leaves the DOM tree in the original state. If there's an actual state change from the Action then that's committed as the new DOM tree. To avoid animating from the original state to the new state again, this is DOM without an animation. However, this means that you can't have the actual action committing be in a slightly different state and animate between the final gesture state and into the new action. Instead, we now actually keep the render tree around and commit it in the end. Basically we assume that if the Timeline was closer to the end then visually you're already there and we can commit into that state. Most of the time this will be at the actual end state when you release but if you have something else cancelling the gesture (e.g. `touchcancel`) it can still commit this state even though your gesture recognizer might not consider this an Action. I think this is ok and keeps it simple. When the gesture lane commits, it'll leave a Transition behind as work from the revert lanes on the Optimistic updates. This means that if you don't do anything in the Action this will cause another commit right after which reverts. This revert can animate the snap back. There's a few fixes needed in follow up PRs: - Fixed in #35487. ~To support unentangled Transitions we need to explicitly entangle the revert lane with the Action to avoid committing a revert followed by a forward instead of committing the forward entangled with the revert. This just works now since everything is entangled but won't work with #35392.~ - Fixed in #35510. ~This currently rerenders the gesture lane once before committing if it was already completed but blocked. We should be able to commit the already completed tree as is.~ DiffTrain build for [4028aaa](4028aaa)
1 parent 68bfac4 commit f45a7d0

File tree

21 files changed

+1634
-1515
lines changed

21 files changed

+1634
-1515
lines changed

compiled-rn/VERSION_NATIVE_FB

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
19.3.0-native-fb-f0fbb0d1-20260115
1+
19.3.0-native-fb-4028aaa5-20260115

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-dom/cjs/ReactDOM-dev.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<adc53ad3318065fe2d45f466bc6fde30>>
10+
* @generated SignedSource<<1ccb123dcfabee5159036eb5edce4c66>>
1111
*/
1212

1313
"use strict";
@@ -410,5 +410,5 @@ __DEV__ &&
410410
exports.useFormStatus = function () {
411411
return resolveDispatcher().useHostTransitionStatus();
412412
};
413-
exports.version = "19.3.0-native-fb-f0fbb0d1-20260115";
413+
exports.version = "19.3.0-native-fb-4028aaa5-20260115";
414414
})();

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-dom/cjs/ReactDOM-prod.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<3a509f8bc4b9b67709b02ff4e7f361ad>>
10+
* @generated SignedSource<<1e67dcc1ecc50e817a630b5b83921372>>
1111
*/
1212

1313
"use strict";
@@ -209,4 +209,4 @@ exports.useFormState = function (action, initialState, permalink) {
209209
exports.useFormStatus = function () {
210210
return ReactSharedInternals.H.useHostTransitionStatus();
211211
};
212-
exports.version = "19.3.0-native-fb-f0fbb0d1-20260115";
212+
exports.version = "19.3.0-native-fb-4028aaa5-20260115";

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-dom/cjs/ReactDOM-profiling.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<3a509f8bc4b9b67709b02ff4e7f361ad>>
10+
* @generated SignedSource<<1e67dcc1ecc50e817a630b5b83921372>>
1111
*/
1212

1313
"use strict";
@@ -209,4 +209,4 @@ exports.useFormState = function (action, initialState, permalink) {
209209
exports.useFormStatus = function () {
210210
return ReactSharedInternals.H.useHostTransitionStatus();
211211
};
212-
exports.version = "19.3.0-native-fb-f0fbb0d1-20260115";
212+
exports.version = "19.3.0-native-fb-4028aaa5-20260115";

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-dom/cjs/ReactDOMClient-dev.js

Lines changed: 301 additions & 289 deletions
Large diffs are not rendered by default.

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-dom/cjs/ReactDOMClient-prod.js

Lines changed: 69 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<c057992bc9ab31914f2159c79d03e7c4>>
10+
* @generated SignedSource<<996d403d98a564085eb9487d32c2e9d2>>
1111
*/
1212

1313
/*
@@ -11826,7 +11826,7 @@ function performWorkOnRoot(root$jscomp$0, lanes, forceSync) {
1182611826
if (0 !== getNextLanes(shouldTimeSlice, 0, !0)) break a;
1182711827
pendingEffectsLanes = lanes;
1182811828
shouldTimeSlice.timeoutHandle = scheduleTimeout(
11829-
commitRootWhenReady.bind(
11829+
completeRootWhenReady.bind(
1183011830
null,
1183111831
shouldTimeSlice,
1183211832
forceSync,
@@ -11847,7 +11847,7 @@ function performWorkOnRoot(root$jscomp$0, lanes, forceSync) {
1184711847
);
1184811848
break a;
1184911849
}
11850-
commitRootWhenReady(
11850+
completeRootWhenReady(
1185111851
shouldTimeSlice,
1185211852
forceSync,
1185311853
workInProgressRootRecoverableErrors,
@@ -11869,7 +11869,7 @@ function performWorkOnRoot(root$jscomp$0, lanes, forceSync) {
1186911869
} while (1);
1187011870
ensureRootIsScheduled(root$jscomp$0);
1187111871
}
11872-
function commitRootWhenReady(
11872+
function completeRootWhenReady(
1187311873
root,
1187411874
finishedWork,
1187511875
recoverableErrors,
@@ -11919,7 +11919,7 @@ function commitRootWhenReady(
1191911919
if (null !== timeoutOffset) {
1192011920
pendingEffectsLanes = lanes;
1192111921
root.cancelPendingCommit = timeoutOffset(
11922-
commitRoot.bind(
11922+
completeRoot.bind(
1192311923
null,
1192411924
root,
1192511925
finishedWork,
@@ -11930,6 +11930,7 @@ function commitRootWhenReady(
1193011930
spawnedLane,
1193111931
updatedLanes,
1193211932
suspendedRetryLanes,
11933+
didSkipSuspendedSiblings,
1193311934
exitStatus,
1193411935
suspendedCommitReason,
1193511936
null,
@@ -11941,7 +11942,7 @@ function commitRootWhenReady(
1194111942
return;
1194211943
}
1194311944
}
11944-
commitRoot(
11945+
completeRoot(
1194511946
root,
1194611947
finishedWork,
1194711948
lanes,
@@ -12491,7 +12492,7 @@ function unwindUnitOfWork(unitOfWork, skipSiblings) {
1249112492
workInProgressRootExitStatus = 6;
1249212493
workInProgress = null;
1249312494
}
12494-
function commitRoot(
12495+
function completeRoot(
1249512496
root,
1249612497
finishedWork,
1249712498
lanes,
@@ -12508,55 +12509,72 @@ function commitRoot(
1250812509
if (0 !== (executionContext & 6)) throw Error(formatProdErrorMessage(327));
1250912510
if (null !== finishedWork) {
1251012511
if (finishedWork === root.current) throw Error(formatProdErrorMessage(177));
12511-
didIncludeRenderPhaseUpdate = finishedWork.lanes | finishedWork.childLanes;
12512-
didIncludeRenderPhaseUpdate |= concurrentlyUpdatedLanes;
12513-
markRootFinished(
12514-
root,
12515-
lanes,
12516-
didIncludeRenderPhaseUpdate,
12517-
spawnedLane,
12518-
updatedLanes,
12519-
suspendedRetryLanes
12520-
);
1252112512
root === workInProgressRoot &&
1252212513
((workInProgress = workInProgressRoot = null),
1252312514
(workInProgressRootRenderLanes = 0));
1252412515
pendingFinishedWork = finishedWork;
1252512516
pendingEffectsRoot = root;
1252612517
pendingEffectsLanes = lanes;
12527-
pendingEffectsRemainingLanes = didIncludeRenderPhaseUpdate;
1252812518
pendingPassiveTransitions = transitions;
1252912519
pendingRecoverableErrors = recoverableErrors;
12530-
0 !== (finishedWork.subtreeFlags & 10256) ||
12531-
0 !== (finishedWork.flags & 10256)
12532-
? ((root.callbackNode = null),
12533-
(root.callbackPriority = 0),
12534-
scheduleCallback$1(NormalPriority$1, function () {
12535-
flushPassiveEffects();
12536-
return null;
12537-
}))
12538-
: ((root.callbackNode = null), (root.callbackPriority = 0));
12539-
recoverableErrors = 0 !== (finishedWork.flags & 13878);
12540-
if (0 !== (finishedWork.subtreeFlags & 13878) || recoverableErrors) {
12541-
recoverableErrors = ReactSharedInternals.T;
12542-
ReactSharedInternals.T = null;
12543-
transitions = ReactDOMSharedInternals.p;
12544-
ReactDOMSharedInternals.p = 2;
12545-
spawnedLane = executionContext;
12546-
executionContext |= 4;
12547-
try {
12548-
commitBeforeMutationEffects(root, finishedWork, lanes);
12549-
} finally {
12550-
(executionContext = spawnedLane),
12551-
(ReactDOMSharedInternals.p = transitions),
12552-
(ReactSharedInternals.T = recoverableErrors);
12553-
}
12520+
commitRoot(
12521+
root,
12522+
finishedWork,
12523+
lanes,
12524+
spawnedLane,
12525+
updatedLanes,
12526+
suspendedRetryLanes
12527+
);
12528+
}
12529+
}
12530+
function commitRoot(
12531+
root,
12532+
finishedWork,
12533+
lanes,
12534+
spawnedLane,
12535+
updatedLanes,
12536+
suspendedRetryLanes
12537+
) {
12538+
var remainingLanes = finishedWork.lanes | finishedWork.childLanes;
12539+
pendingEffectsRemainingLanes = remainingLanes;
12540+
remainingLanes |= concurrentlyUpdatedLanes;
12541+
markRootFinished(
12542+
root,
12543+
lanes,
12544+
remainingLanes,
12545+
spawnedLane,
12546+
updatedLanes,
12547+
suspendedRetryLanes
12548+
);
12549+
0 !== (finishedWork.subtreeFlags & 10256) ||
12550+
0 !== (finishedWork.flags & 10256)
12551+
? ((root.callbackNode = null),
12552+
(root.callbackPriority = 0),
12553+
scheduleCallback$1(NormalPriority$1, function () {
12554+
flushPassiveEffects();
12555+
return null;
12556+
}))
12557+
: ((root.callbackNode = null), (root.callbackPriority = 0));
12558+
spawnedLane = 0 !== (finishedWork.flags & 13878);
12559+
if (0 !== (finishedWork.subtreeFlags & 13878) || spawnedLane) {
12560+
spawnedLane = ReactSharedInternals.T;
12561+
ReactSharedInternals.T = null;
12562+
updatedLanes = ReactDOMSharedInternals.p;
12563+
ReactDOMSharedInternals.p = 2;
12564+
suspendedRetryLanes = executionContext;
12565+
executionContext |= 4;
12566+
try {
12567+
commitBeforeMutationEffects(root, finishedWork, lanes);
12568+
} finally {
12569+
(executionContext = suspendedRetryLanes),
12570+
(ReactDOMSharedInternals.p = updatedLanes),
12571+
(ReactSharedInternals.T = spawnedLane);
1255412572
}
12555-
pendingEffectsStatus = 1;
12556-
flushMutationEffects();
12557-
flushLayoutEffects();
12558-
flushSpawnedWork();
1255912573
}
12574+
pendingEffectsStatus = 1;
12575+
flushMutationEffects();
12576+
flushLayoutEffects();
12577+
flushSpawnedWork();
1256012578
}
1256112579
function flushMutationEffects() {
1256212580
if (1 === pendingEffectsStatus) {
@@ -17701,14 +17719,14 @@ ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = function (target) {
1770117719
};
1770217720
var isomorphicReactPackageVersion$jscomp$inline_2054 = React.version;
1770317721
if (
17704-
"19.3.0-native-fb-f0fbb0d1-20260115" !==
17722+
"19.3.0-native-fb-4028aaa5-20260115" !==
1770517723
isomorphicReactPackageVersion$jscomp$inline_2054
1770617724
)
1770717725
throw Error(
1770817726
formatProdErrorMessage(
1770917727
527,
1771017728
isomorphicReactPackageVersion$jscomp$inline_2054,
17711-
"19.3.0-native-fb-f0fbb0d1-20260115"
17729+
"19.3.0-native-fb-4028aaa5-20260115"
1771217730
)
1771317731
);
1771417732
ReactDOMSharedInternals.findDOMNode = function (componentOrElement) {
@@ -17730,10 +17748,10 @@ ReactDOMSharedInternals.findDOMNode = function (componentOrElement) {
1773017748
};
1773117749
var internals$jscomp$inline_2638 = {
1773217750
bundleType: 0,
17733-
version: "19.3.0-native-fb-f0fbb0d1-20260115",
17751+
version: "19.3.0-native-fb-4028aaa5-20260115",
1773417752
rendererPackageName: "react-dom",
1773517753
currentDispatcherRef: ReactSharedInternals,
17736-
reconcilerVersion: "19.3.0-native-fb-f0fbb0d1-20260115"
17754+
reconcilerVersion: "19.3.0-native-fb-4028aaa5-20260115"
1773717755
};
1773817756
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
1773917757
var hook$jscomp$inline_2639 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
@@ -17840,4 +17858,4 @@ exports.hydrateRoot = function (container, initialChildren, options) {
1784017858
listenToAllSupportedEvents(container);
1784117859
return new ReactDOMHydrationRoot(initialChildren);
1784217860
};
17843-
exports.version = "19.3.0-native-fb-f0fbb0d1-20260115";
17861+
exports.version = "19.3.0-native-fb-4028aaa5-20260115";

0 commit comments

Comments
 (0)