@@ -21,7 +21,11 @@ import type {
2121 TransitionAbort ,
2222} from './ReactFiberTracingMarkerComponent' ;
2323import type { OffscreenInstance } from './ReactFiberActivityComponent' ;
24- import type { Resource , ViewTransitionInstance } from './ReactFiberConfig' ;
24+ import type {
25+ Resource ,
26+ ViewTransitionInstance ,
27+ RunningViewTransition ,
28+ } from './ReactFiberConfig' ;
2529import type { RootState } from './ReactFiberRoot' ;
2630import {
2731 getViewTransitionName ,
@@ -102,6 +106,7 @@ import {
102106 trackSchedulerEvent ,
103107 startViewTransition ,
104108 startGestureTransition ,
109+ stopViewTransition ,
105110 createViewTransitionInstance ,
106111} from './ReactFiberConfig' ;
107112
@@ -665,6 +670,7 @@ let pendingEffectsRemainingLanes: Lanes = NoLanes;
665670let pendingEffectsRenderEndTime : number = - 0 ; // Profiling-only
666671let pendingPassiveTransitions : Array < Transition > | null = null ;
667672let pendingRecoverableErrors : null | Array < CapturedValue < mixed >> = null ;
673+ let pendingViewTransition : null | RunningViewTransition = null ;
668674let pendingViewTransitionEvents : Array < ( types : Array < string > ) => void > | null =
669675 null ;
670676let pendingTransitionTypes : null | TransitionTypes = null ;
@@ -3504,7 +3510,7 @@ function commitRoot(
35043510
35053511 pendingEffectsStatus = PENDING_MUTATION_PHASE ;
35063512 if ( enableViewTransition && willStartViewTransition ) {
3507- startViewTransition (
3513+ pendingViewTransition = startViewTransition (
35083514 root . containerInfo ,
35093515 pendingTransitionTypes ,
35103516 flushMutationEffects ,
@@ -3644,6 +3650,8 @@ function flushSpawnedWork(): void {
36443650 }
36453651 pendingEffectsStatus = NO_PENDING_EFFECTS ;
36463652
3653+ pendingViewTransition = null ; // The view transition has now fully started.
3654+
36473655 // Tell Scheduler to yield at the end of the frame, so the browser has an
36483656 // opportunity to paint.
36493657 requestPaint ( ) ;
@@ -3913,7 +3921,7 @@ function commitGestureOnRoot(
39133921 pendingTransitionTypes = null ;
39143922 pendingEffectsStatus = PENDING_GESTURE_MUTATION_PHASE ;
39153923
3916- finishedGesture . running = startGestureTransition (
3924+ pendingViewTransition = finishedGesture . running = startGestureTransition (
39173925 root . containerInfo ,
39183926 finishedGesture . provider ,
39193927 finishedGesture . rangeCurrent ,
@@ -3973,6 +3981,8 @@ function flushGestureAnimations(): void {
39733981 pendingFinishedWork = ( null : any ) ; // Clear for GC purposes.
39743982 pendingEffectsLanes = NoLanes ;
39753983
3984+ pendingViewTransition = null ; // The view transition has now fully started.
3985+
39763986 const prevTransition = ReactSharedInternals . T ;
39773987 ReactSharedInternals . T = null ;
39783988 const previousPriority = getCurrentUpdatePriority ( ) ;
@@ -4023,8 +4033,27 @@ function releaseRootPooledCache(root: FiberRoot, remainingLanes: Lanes) {
40234033 }
40244034}
40254035
4036+ let didWarnAboutInterruptedViewTransitions = false ;
4037+
40264038export function flushPendingEffects ( wasDelayedCommit ?: boolean ) : boolean {
40274039 // Returns whether passive effects were flushed.
4040+ if ( enableViewTransition && pendingViewTransition !== null ) {
4041+ // If we forced a flush before the View Transition full started then we skip it.
4042+ // This ensures that we're not running a partial animation.
4043+ stopViewTransition ( pendingViewTransition ) ;
4044+ if ( __DEV__ ) {
4045+ if ( ! didWarnAboutInterruptedViewTransitions ) {
4046+ didWarnAboutInterruptedViewTransitions = true ;
4047+ console . warn (
4048+ 'A flushSync update cancelled a View Transition because it was called ' +
4049+ 'while the View Transition was still preparing . To preserve the synchronous ' +
4050+ 'semantics , React had to skip the View Transition . If you can , try to avoid ' +
4051+ "flushSync ( ) in a scenario that 's likely to interfere . ",
4052+ ) ;
4053+ }
4054+ }
4055+ pendingViewTransition = null ;
4056+ }
40284057 flushGestureMutations ( ) ;
40294058 flushGestureAnimations ( ) ;
40304059 flushMutationEffects ( ) ;
0 commit comments