@@ -20,6 +20,7 @@ import {
2020 enableComponentPerformanceTrack ,
2121 enableYieldingBeforePassive ,
2222 enableGestureTransition ,
23+ enableDefaultTransitionIndicator ,
2324} from 'shared/ReactFeatureFlags' ;
2425import {
2526 NoLane ,
@@ -79,6 +80,9 @@ import {
7980 syncNestedUpdateFlag ,
8081} from './ReactProfilerTimer' ;
8182
83+ import noop from 'shared/noop' ;
84+ import reportGlobalError from 'shared/reportGlobalError' ;
85+
8286// A linked list of all the roots with pending work. In an idiomatic app,
8387// there's only a single root, but we do support multi root apps, hence this
8488// extra complexity. But this module is optimized for the single root case.
@@ -315,8 +319,33 @@ function processRootScheduleInMicrotask() {
315319 flushSyncWorkAcrossRoots_impl ( syncTransitionLanes , false ) ;
316320 }
317321
318- // Reset Event Transition Lane so that we allocate a new one next time.
319- currentEventTransitionLane = NoLane ;
322+ if ( currentEventTransitionLane !== NoLane ) {
323+ // Reset Event Transition Lane so that we allocate a new one next time.
324+ currentEventTransitionLane = NoLane ;
325+ startDefaultTransitionIndicatorIfNeeded ( ) ;
326+ }
327+ }
328+
329+ function startDefaultTransitionIndicatorIfNeeded ( ) {
330+ if ( ! enableDefaultTransitionIndicator ) {
331+ return ;
332+ }
333+ // Check all the roots if there are any new indicators needed.
334+ let root = firstScheduledRoot ;
335+ while ( root !== null ) {
336+ if ( root . indicatorLanes !== NoLanes && root . pendingIndicator === null ) {
337+ // We have new indicator lanes that requires a loading state. Start the
338+ // default transition indicator.
339+ try {
340+ const onDefaultTransitionIndicator = root . onDefaultTransitionIndicator ;
341+ root . pendingIndicator = onDefaultTransitionIndicator ( ) || noop ;
342+ } catch ( x ) {
343+ root . pendingIndicator = noop ;
344+ reportGlobalError ( x ) ;
345+ }
346+ }
347+ root = root . next ;
348+ }
320349}
321350
322351function scheduleTaskForRootDuringMicrotask (
@@ -655,3 +684,12 @@ export function requestTransitionLane(
655684export function didCurrentEventScheduleTransition ( ) : boolean {
656685 return currentEventTransitionLane !== NoLane ;
657686}
687+
688+ export function markIndicatorHandled ( root : FiberRoot ) : void {
689+ if ( enableDefaultTransitionIndicator ) {
690+ // The current transition event rendered a synchronous loading state.
691+ // Clear it from the indicator lanes. We don't need to show a separate
692+ // loading state for this lane.
693+ root . indicatorLanes &= ~ currentEventTransitionLane ;
694+ }
695+ }
0 commit comments