@@ -20,6 +20,7 @@ import {
20
20
enableComponentPerformanceTrack ,
21
21
enableYieldingBeforePassive ,
22
22
enableGestureTransition ,
23
+ enableDefaultTransitionIndicator ,
23
24
} from 'shared/ReactFeatureFlags' ;
24
25
import {
25
26
NoLane ,
@@ -79,6 +80,9 @@ import {
79
80
syncNestedUpdateFlag ,
80
81
} from './ReactProfilerTimer' ;
81
82
83
+ import noop from 'shared/noop' ;
84
+ import reportGlobalError from 'shared/reportGlobalError' ;
85
+
82
86
// A linked list of all the roots with pending work. In an idiomatic app,
83
87
// there's only a single root, but we do support multi root apps, hence this
84
88
// extra complexity. But this module is optimized for the single root case.
@@ -315,8 +319,33 @@ function processRootScheduleInMicrotask() {
315
319
flushSyncWorkAcrossRoots_impl ( syncTransitionLanes , false ) ;
316
320
}
317
321
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
+ }
320
349
}
321
350
322
351
function scheduleTaskForRootDuringMicrotask (
@@ -655,3 +684,12 @@ export function requestTransitionLane(
655
684
export function didCurrentEventScheduleTransition ( ) : boolean {
656
685
return currentEventTransitionLane !== NoLane ;
657
686
}
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