@@ -271,6 +271,59 @@ function applyExitViewTransition(placement: Fiber): void {
271271 }
272272}
273273
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+
274327function recursivelyInsertNew (
275328 parentFiber : Fiber ,
276329 hostParentClone : Instance ,
@@ -577,6 +630,8 @@ function recursivelyInsertClonesFromExistingTree(
577630 visitPhase === CLONE_UNHIDE
578631 ) {
579632 applyAppearingPairViewTransition ( child ) ;
633+ } else if ( visitPhase === CLONE_UPDATE ) {
634+ applyNestedViewTransition ( child ) ;
580635 }
581636 popMutationContext ( prevMutationContext ) ;
582637 break ;
@@ -848,6 +903,8 @@ function insertDestinationClonesOfFiber(
848903 visitPhase === CLONE_UNHIDE
849904 ) {
850905 applyAppearingPairViewTransition ( finishedWork ) ;
906+ } else if ( visitPhase === CLONE_UPDATE ) {
907+ applyUpdateViewTransition ( current , finishedWork ) ;
851908 }
852909 popMutationContext ( prevMutationContext ) ;
853910 break ;
0 commit comments