@@ -271,6 +271,59 @@ function applyExitViewTransition(placement: Fiber): void {
271
271
}
272
272
}
273
273
274
+ function applyNestedViewTransition ( child : Fiber ) : void {
275
+ const state : ViewTransitionState = child . stateNode ;
276
+ const props : ViewTransitionProps = child . memoizedProps ;
277
+ const name = getViewTransitionName ( props , state ) ;
278
+ const className : ?string = getViewTransitionClassName (
279
+ props . className ,
280
+ props . layout ,
281
+ ) ;
282
+ if ( className !== 'none' ) {
283
+ const clones = state . clones ;
284
+ // If there are no clones at this point, that should mean that there are no
285
+ // HostComponent children in this ViewTransition.
286
+ if ( clones !== null ) {
287
+ applyViewTransitionToClones ( name , className , clones ) ;
288
+ }
289
+ }
290
+ }
291
+
292
+ function applyUpdateViewTransition ( current : Fiber , finishedWork : Fiber ) : void {
293
+ const state : ViewTransitionState = finishedWork . stateNode ;
294
+ // Updates can have conflicting names and classNames.
295
+ // Since we're doing a reverse animation the "new" state is actually the current
296
+ // and the "old" state is the finishedWork.
297
+ const newProps : ViewTransitionProps = current . memoizedProps ;
298
+ const oldProps : ViewTransitionProps = finishedWork . memoizedProps ;
299
+ const oldName = getViewTransitionName ( oldProps , state ) ;
300
+ // This className applies only if there are fewer child DOM nodes than
301
+ // before or if this update should've been cancelled but we ended up with
302
+ // a parent animating so we need to animate the child too. Otherwise
303
+ // the "new" state wins. Since "new" normally wins, that's usually what
304
+ // we would use. However, since this animation is going in reverse we actually
305
+ // want the props from "current" since that's the class that would've won if
306
+ // it was the normal direction. To preserve the same effect in either direction.
307
+ let className : ?string = getViewTransitionClassName (
308
+ newProps . className ,
309
+ newProps . update ,
310
+ ) ;
311
+ if ( className === 'none' ) {
312
+ className = getViewTransitionClassName ( newProps . className , newProps . layout ) ;
313
+ if ( className === 'none' ) {
314
+ // If both update and layout are both "none" then we don't have to
315
+ // apply a name. Since we won't animate this boundary.
316
+ return ;
317
+ }
318
+ }
319
+ const clones = state . clones ;
320
+ // If there are no clones at this point, that should mean that there are no
321
+ // HostComponent children in this ViewTransition.
322
+ if ( clones !== null ) {
323
+ applyViewTransitionToClones ( oldName , className , clones ) ;
324
+ }
325
+ }
326
+
274
327
function recursivelyInsertNew (
275
328
parentFiber : Fiber ,
276
329
hostParentClone : Instance ,
@@ -577,6 +630,8 @@ function recursivelyInsertClonesFromExistingTree(
577
630
visitPhase === CLONE_UNHIDE
578
631
) {
579
632
applyAppearingPairViewTransition ( child ) ;
633
+ } else if ( visitPhase === CLONE_UPDATE ) {
634
+ applyNestedViewTransition ( child ) ;
580
635
}
581
636
popMutationContext ( prevMutationContext ) ;
582
637
break ;
@@ -848,6 +903,8 @@ function insertDestinationClonesOfFiber(
848
903
visitPhase === CLONE_UNHIDE
849
904
) {
850
905
applyAppearingPairViewTransition ( finishedWork ) ;
906
+ } else if ( visitPhase === CLONE_UPDATE ) {
907
+ applyUpdateViewTransition ( current , finishedWork ) ;
851
908
}
852
909
popMutationContext ( prevMutationContext ) ;
853
910
break ;
0 commit comments