@samitouri / QOS-React-1 / commits / f6fe4275c7

Wire up createViewTransitionInstance and suspendOnActiveViewTransition in Fabric (#36196)

## Summary - Wires up the native `fabricCreateViewTransitionInstance` call in `createViewTransitionInstance` which will create a ShadowNode for old pseudo element - Extracts tag allocation logic into a shared `allocateTag()` function exported from `ReactFiberConfigFabric` - Imports `allocateTag` in `ReactFiberConfigFabricWithViewTransition` - Reuses `allocateTag()` in `createInstance` and `createTextInstance` instead of inline tag incrementing - Wires up native `fabricSuspendOnActiveViewTransition` call in `suspendOnActiveViewTransition` which suspends another view transition when the previous one is not yet finished ## Test plan - Existing Fabric renderer tests should continue to pass - ViewTransition instance creation now properly allocates a tag and calls the native module

Zeya Peng committed Apr 16, 2026 at 16:59 UTC f6fe4275c7ec869e20a4b91f70df88cdc14d5161
3 files changed +18 -5
packages/react-native-renderer/src/ReactFiberConfigFabric.js
+11 -5
@@ -60,6 +60,7 @@ const {
60 unstable_ContinuousEventPriority: FabricContinuousPriority,
61 unstable_IdleEventPriority: FabricIdlePriority,
62 unstable_getCurrentEventPriority: fabricGetCurrentEventPriority,
63 + suspendOnActiveViewTransition: fabricSuspendOnActiveViewTransition,
64 } = nativeFabricUIManager;
65
66 import {getClosestInstanceFromNode} from './ReactFabricComponentTree';
@@ -88,6 +89,11 @@ const {get: getViewConfigForType} = ReactNativeViewConfigRegistry;
89 // % 2 === 0 means it is a Fabric tag.
90 // This means that they never overlap.
91 let nextReactTag = 2;
92 +export function allocateTag(): number {
93 + const tag = nextReactTag;
94 + nextReactTag += 2;
95 + return tag;
96 +}
97
98 type InternalInstanceHandle = Object;
99
@@ -180,8 +186,7 @@ export function createInstance(
186 hostContext: HostContext,
187 internalInstanceHandle: InternalInstanceHandle,
188 ): Instance {
183 - const tag = nextReactTag;
184 - nextReactTag += 2;
189 + const tag = allocateTag();
190
191 const viewConfig = getViewConfigForType(type);
192
@@ -231,8 +236,7 @@ export function createTextInstance(
236 }
237 }
238
234 - const tag = nextReactTag;
235 - nextReactTag += 2;
239 + const tag = allocateTag();
240
241 const node = createNode(
242 tag, // reactTag
@@ -652,7 +656,9 @@ export function suspendInstance(
656 export function suspendOnActiveViewTransition(
657 state: SuspendedState,
658 container: Container,
655 -): void {}
659 +): void {
660 + fabricSuspendOnActiveViewTransition();
661 +}
662
663 export function waitForCommitToBeReady(
664 state: SuspendedState,
packages/react-native-renderer/src/ReactFiberConfigFabricWithViewTransition.js
+5
@@ -16,8 +16,11 @@ import type {
16 GestureTimeline,
17 } from './ReactFiberConfigFabric';
18
19 +import {allocateTag} from './ReactFiberConfigFabric';
20 +
21 const {
22 applyViewTransitionName: fabricApplyViewTransitionName,
23 + createViewTransitionInstance: fabricCreateViewTransitionInstance,
24 startViewTransition: fabricStartViewTransition,
25 startViewTransitionReadyFinished: fabricStartViewTransitionReadyFinished,
26 } = nativeFabricUIManager;
@@ -197,6 +200,8 @@ export function addViewTransitionFinishedListener(
200 export function createViewTransitionInstance(
201 name: string,
202 ): ViewTransitionInstance {
203 + const tag = allocateTag();
204 + fabricCreateViewTransitionInstance(name, tag);
205 return {
206 name,
207 old: new (ViewTransitionPseudoElement: any)('old', name),
scripts/flow/react-native-host-hooks.js
+2
@@ -213,10 +213,12 @@ declare const nativeFabricUIManager: {
213 name: string,
214 className: ?string,
215 ) => void,
216 + createViewTransitionInstance: (name: string, tag: number) => void,
217 startViewTransition: (mutationCallback: () => void) => {
218 finished: Promise<void>,
219 ready: Promise<void>,
220 },
221 startViewTransitionReadyFinished: () => void,
222 + suspendOnActiveViewTransition: () => void,
223 ...
224 };