From 6d2b648cecc8949c3bfc6a43a91ac84cb3a28382 Mon Sep 17 00:00:00 2001 From: Zeya Peng Date: Thu, 5 Mar 2026 14:13:56 -0500 Subject: [PATCH 01/14] create supportsViewTransition and ReactFiberConfigWithNoViewTransition out of ReactFiberConfigWithNoMutation --- packages/react-art/src/ReactFiberConfigART.js | 87 +--------- .../src/client/ReactFiberConfigDOM.js | 1 + .../src/ReactFiberConfigNative.js | 150 +----------------- .../src/ReactFiberCommitViewTransitions.js | 8 +- .../src/ReactFiberCommitWork.js | 6 +- .../src/ReactFiberConfigWithNoMutation.js | 20 --- .../ReactFiberConfigWithNoViewTransition.js | 42 +++++ .../src/forks/ReactFiberConfig.custom.js | 1 + .../src/ReactFiberConfigTestHost.js | 146 +---------------- scripts/error-codes/codes.json | 3 +- 10 files changed, 58 insertions(+), 406 deletions(-) create mode 100644 packages/react-reconciler/src/ReactFiberConfigWithNoViewTransition.js diff --git a/packages/react-art/src/ReactFiberConfigART.js b/packages/react-art/src/ReactFiberConfigART.js index 50873af6da04..1ed9b04fa855 100644 --- a/packages/react-art/src/ReactFiberConfigART.js +++ b/packages/react-art/src/ReactFiberConfigART.js @@ -249,6 +249,7 @@ function applyTextProps(instance, props, prevProps = {}) { } } +export * from 'react-reconciler/src/ReactFiberConfigWithNoViewTransition'; export * from 'react-reconciler/src/ReactFiberConfigWithNoPersistence'; export * from 'react-reconciler/src/ReactFiberConfigWithNoHydration'; export * from 'react-reconciler/src/ReactFiberConfigWithNoScopes'; @@ -484,92 +485,6 @@ export function unhideTextInstance(textInstance, text): void { // Noop } -export function applyViewTransitionName(instance, name, className) { - // Noop -} - -export function restoreViewTransitionName(instance, props) { - // Noop -} - -export function cancelViewTransitionName(instance, name, props) { - // Noop -} - -export function cancelRootViewTransitionName(rootContainer) { - // Noop -} - -export function restoreRootViewTransitionName(rootContainer) { - // Noop -} - -export function cloneRootViewTransitionContainer(rootContainer) { - throw new Error('Not implemented.'); -} - -export function removeRootViewTransitionClone(rootContainer, clone) { - throw new Error('Not implemented.'); -} - -export type InstanceMeasurement = null; - -export function measureInstance(instance) { - return null; -} - -export function measureClonedInstance(instance) { - return null; -} - -export function wasInstanceInViewport(measurement): boolean { - return true; -} - -export function hasInstanceChanged(oldMeasurement, newMeasurement): boolean { - return false; -} - -export function hasInstanceAffectedParent( - oldMeasurement, - newMeasurement, -): boolean { - return false; -} - -export function startViewTransition() { - return null; -} - -export type RunningViewTransition = null; - -export function startGestureTransition() { - return null; -} - -export function stopViewTransition(transition: RunningViewTransition) {} - -export function addViewTransitionFinishedListener( - transition: RunningViewTransition, - callback: () => void, -) { - callback(); -} - -export type ViewTransitionInstance = null | {name: string, ...}; - -export function createViewTransitionInstance( - name: string, -): ViewTransitionInstance { - return null; -} - -export type GestureTimeline = null; - -export function getCurrentGestureOffset(provider: GestureTimeline): number { - throw new Error('startGestureTransition is not yet supported in react-art.'); -} - export function clearContainer(container) { // TODO Implement this } diff --git a/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js b/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js index a03ccc161ad1..51a091fa707a 100644 --- a/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js +++ b/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js @@ -832,6 +832,7 @@ function handleErrorInNextTick(error: any) { // ------------------- export const supportsMutation = true; +export const supportsViewTransition = true; export function commitMount( domElement: Instance, diff --git a/packages/react-native-renderer/src/ReactFiberConfigNative.js b/packages/react-native-renderer/src/ReactFiberConfigNative.js index fcf356776c2e..87d85b97e716 100644 --- a/packages/react-native-renderer/src/ReactFiberConfigNative.js +++ b/packages/react-native-renderer/src/ReactFiberConfigNative.js @@ -8,7 +8,6 @@ */ import type {InspectorData, TouchedViewDataAtPoint} from './ReactNativeTypes'; -import type {TransitionTypes} from 'react/src/ReactTransitionType'; // Modules provided by RN: import { @@ -35,8 +34,6 @@ import { } from 'react-reconciler/src/ReactEventPriorities'; import type {Fiber} from 'react-reconciler/src/ReactInternalTypes'; -import {enableProfilerTimer} from 'shared/ReactFeatureFlags'; - import {REACT_CONTEXT_TYPE} from 'shared/ReactSymbols'; import type {ReactContext} from 'shared/ReactTypes'; @@ -112,6 +109,7 @@ function recursivelyUncacheFiberNode(node: Instance | TextInstance) { } } +export * from 'react-reconciler/src/ReactFiberConfigWithNoViewTransition'; export * from 'react-reconciler/src/ReactFiberConfigWithNoPersistence'; export * from 'react-reconciler/src/ReactFiberConfigWithNoHydration'; export * from 'react-reconciler/src/ReactFiberConfigWithNoScopes'; @@ -590,152 +588,6 @@ export function unhideInstance(instance: Instance, props: Props): void { ); } -export function applyViewTransitionName( - instance: Instance, - name: string, - className: ?string, -): void { - // Not yet implemented -} - -export function restoreViewTransitionName( - instance: Instance, - props: Props, -): void { - // Not yet implemented -} - -export function cancelViewTransitionName( - instance: Instance, - name: string, - props: Props, -): void { - // Not yet implemented -} - -export function cancelRootViewTransitionName(rootContainer: Container): void { - // Not yet implemented -} - -export function restoreRootViewTransitionName(rootContainer: Container): void { - // Not yet implemented -} - -export function cloneRootViewTransitionContainer( - rootContainer: Container, -): Instance { - throw new Error('Not implemented.'); -} - -export function removeRootViewTransitionClone( - rootContainer: Container, - clone: Instance, -): void { - throw new Error('Not implemented.'); -} - -export type InstanceMeasurement = null; - -export function measureInstance(instance: Instance): InstanceMeasurement { - // This heuristic is better implemented at the native layer. - return null; -} - -export function measureClonedInstance(instance: Instance): InstanceMeasurement { - return null; -} - -export function wasInstanceInViewport( - measurement: InstanceMeasurement, -): boolean { - return true; -} - -export function hasInstanceChanged( - oldMeasurement: InstanceMeasurement, - newMeasurement: InstanceMeasurement, -): boolean { - return false; -} - -export function hasInstanceAffectedParent( - oldMeasurement: InstanceMeasurement, - newMeasurement: InstanceMeasurement, -): boolean { - return false; -} - -export function startViewTransition( - suspendedState: null | SuspendedState, - rootContainer: Container, - transitionTypes: null | TransitionTypes, - mutationCallback: () => void, - layoutCallback: () => void, - afterMutationCallback: () => void, - spawnedWorkCallback: () => void, - passiveCallback: () => mixed, - errorCallback: mixed => void, - blockedCallback: string => void, // Profiling-only - finishedAnimation: () => void, // Profiling-only -): null | RunningViewTransition { - mutationCallback(); - layoutCallback(); - // Skip afterMutationCallback(). We don't need it since we're not animating. - spawnedWorkCallback(); - if (enableProfilerTimer) { - finishedAnimation(); - } - // Skip passiveCallback(). Spawned work will schedule a task. - return null; -} - -export type RunningViewTransition = null; - -export function startGestureTransition( - suspendedState: null | SuspendedState, - rootContainer: Container, - timeline: GestureTimeline, - rangeStart: number, - rangeEnd: number, - transitionTypes: null | TransitionTypes, - mutationCallback: () => void, - animateCallback: () => void, - errorCallback: mixed => void, - finishedAnimation: () => void, // Profiling-only -): null | RunningViewTransition { - mutationCallback(); - animateCallback(); - if (enableProfilerTimer) { - finishedAnimation(); - } - return null; -} - -export function stopViewTransition(transition: RunningViewTransition) {} - -export function addViewTransitionFinishedListener( - transition: RunningViewTransition, - callback: () => void, -) { - callback(); -} - -export type ViewTransitionInstance = null | {name: string, ...}; - -export function createViewTransitionInstance( - name: string, -): ViewTransitionInstance { - return null; -} - -export type GestureTimeline = null; - -export function getCurrentGestureOffset(provider: GestureTimeline): number { - throw new Error( - 'startGestureTransition is not yet supported in React Native.', - ); -} - export function clearContainer(container: Container): void { // TODO Implement this for React Native // UIManager does not expose a "remove all" type method. diff --git a/packages/react-reconciler/src/ReactFiberCommitViewTransitions.js b/packages/react-reconciler/src/ReactFiberCommitViewTransitions.js index a9edc0c84d23..0e35cb2f33d8 100644 --- a/packages/react-reconciler/src/ReactFiberCommitViewTransitions.js +++ b/packages/react-reconciler/src/ReactFiberCommitViewTransitions.js @@ -25,7 +25,7 @@ import { ViewTransitionNamedStatic, } from './ReactFiberFlags'; import { - supportsMutation, + supportsViewTransition, applyViewTransitionName, restoreViewTransitionName, measureInstance, @@ -139,7 +139,7 @@ function applyViewTransitionToHostInstancesRecursive( collectMeasurements: null | Array, stopAtNestedViewTransitions: boolean, ): boolean { - if (!supportsMutation) { + if (!supportsViewTransition) { return false; } let inViewport = false; @@ -201,7 +201,7 @@ function restoreViewTransitionOnHostInstances( child: null | Fiber, stopAtNestedViewTransitions: boolean, ): void { - if (!supportsMutation) { + if (!supportsViewTransition) { return; } while (child !== null) { @@ -648,7 +648,7 @@ function measureViewTransitionHostInstancesRecursive( previousMeasurements: null | Array, stopAtNestedViewTransitions: boolean, ): boolean { - if (!supportsMutation) { + if (!supportsViewTransition) { return true; } let inViewport = false; diff --git a/packages/react-reconciler/src/ReactFiberCommitWork.js b/packages/react-reconciler/src/ReactFiberCommitWork.js index 08882a04766c..735c15724af4 100644 --- a/packages/react-reconciler/src/ReactFiberCommitWork.js +++ b/packages/react-reconciler/src/ReactFiberCommitWork.js @@ -158,6 +158,7 @@ import { supportsHydration, supportsResources, supportsSingletons, + supportsViewTransition, clearSuspenseBoundary, clearSuspenseBoundaryFromContainer, createContainerChildSet, @@ -3709,7 +3710,10 @@ function commitPassiveMountOnFiber( } if (isViewTransitionEligible) { - if (supportsMutation && rootViewTransitionNameCanceled) { + if ( + supportsViewTransition && + rootViewTransitionNameCanceled + ) { restoreRootViewTransitionName(finishedRoot.containerInfo); } } diff --git a/packages/react-reconciler/src/ReactFiberConfigWithNoMutation.js b/packages/react-reconciler/src/ReactFiberConfigWithNoMutation.js index 79cf3990a728..f243805214d7 100644 --- a/packages/react-reconciler/src/ReactFiberConfigWithNoMutation.js +++ b/packages/react-reconciler/src/ReactFiberConfigWithNoMutation.js @@ -37,25 +37,5 @@ export const hideTextInstance = shim; export const unhideInstance = shim; export const unhideTextInstance = shim; export const clearContainer = shim; -export const applyViewTransitionName = shim; -export const restoreViewTransitionName = shim; -export const cancelViewTransitionName = shim; -export const cancelRootViewTransitionName = shim; -export const restoreRootViewTransitionName = shim; -export const cloneRootViewTransitionContainer = shim; -export const removeRootViewTransitionClone = shim; -export type InstanceMeasurement = null; -export const measureInstance = shim; -export const measureClonedInstance = shim; -export const wasInstanceInViewport = shim; -export const hasInstanceChanged = shim; -export const hasInstanceAffectedParent = shim; -export const startViewTransition = shim; -export type RunningViewTransition = null; -export const startGestureTransition = shim; -export const stopViewTransition = shim; -export const addViewTransitionFinishedListener = shim; -export type ViewTransitionInstance = null | {name: string, ...}; -export const createViewTransitionInstance = shim; export type GestureTimeline = any; export const getCurrentGestureOffset = shim; diff --git a/packages/react-reconciler/src/ReactFiberConfigWithNoViewTransition.js b/packages/react-reconciler/src/ReactFiberConfigWithNoViewTransition.js new file mode 100644 index 000000000000..471d969a5d8a --- /dev/null +++ b/packages/react-reconciler/src/ReactFiberConfigWithNoViewTransition.js @@ -0,0 +1,42 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +// Renderers that don't support view transitions +// can re-export everything from this module. + +function shim(...args: any): empty { + throw new Error( + 'The current renderer does not support view transitions. ' + + 'This error is likely caused by a bug in React. ' + + 'Please file an issue.', + ); +} + +// View Transitions (when unsupported) +export const supportsViewTransition = false; +export const applyViewTransitionName = shim; +export const restoreViewTransitionName = shim; +export const cancelViewTransitionName = shim; +export const cancelRootViewTransitionName = shim; +export const restoreRootViewTransitionName = shim; +export const cloneRootViewTransitionContainer = shim; +export const removeRootViewTransitionClone = shim; +export type InstanceMeasurement = null; +export const measureInstance = shim; +export const measureClonedInstance = shim; +export const wasInstanceInViewport = shim; +export const hasInstanceChanged = shim; +export const hasInstanceAffectedParent = shim; +export const startViewTransition = shim; +export type RunningViewTransition = null; +export const startGestureTransition = shim; +export const stopViewTransition = shim; +export const addViewTransitionFinishedListener = shim; +export type ViewTransitionInstance = null | {name: string, ...}; +export const createViewTransitionInstance = shim; diff --git a/packages/react-reconciler/src/forks/ReactFiberConfig.custom.js b/packages/react-reconciler/src/forks/ReactFiberConfig.custom.js index 1785fa9aaec9..4a2d87e8c40c 100644 --- a/packages/react-reconciler/src/forks/ReactFiberConfig.custom.js +++ b/packages/react-reconciler/src/forks/ReactFiberConfig.custom.js @@ -73,6 +73,7 @@ export const warnsIfNotActing = $$$config.warnsIfNotActing; export const supportsMutation = $$$config.supportsMutation; export const supportsPersistence = $$$config.supportsPersistence; export const supportsHydration = $$$config.supportsHydration; +export const supportsViewTransition = $$$config.supportsViewTransition; export const getInstanceFromNode = $$$config.getInstanceFromNode; export const beforeActiveInstanceBlur = $$$config.beforeActiveInstanceBlur; export const afterActiveInstanceBlur = $$$config.afterActiveInstanceBlur; diff --git a/packages/react-test-renderer/src/ReactFiberConfigTestHost.js b/packages/react-test-renderer/src/ReactFiberConfigTestHost.js index 6b04a36d297a..417745828d60 100644 --- a/packages/react-test-renderer/src/ReactFiberConfigTestHost.js +++ b/packages/react-test-renderer/src/ReactFiberConfigTestHost.js @@ -8,8 +8,6 @@ */ import type {ReactContext} from 'shared/ReactTypes'; -import type {TransitionTypes} from 'react/src/ReactTransitionType'; - import isArray from 'shared/isArray'; import {REACT_CONTEXT_TYPE} from 'shared/ReactSymbols'; import { @@ -17,7 +15,6 @@ import { NoEventPriority, type EventPriority, } from 'react-reconciler/src/ReactEventPriorities'; -import {enableProfilerTimer} from 'shared/ReactFeatureFlags'; export {default as rendererVersion} from 'shared/ReactVersion'; // TODO: Consider exporting the react-native version. export const rendererPackageName = 'react-test-renderer'; @@ -56,6 +53,7 @@ export type EventResponder = any; export type RendererInspectionConfig = $ReadOnly<{}>; export type TransitionStatus = mixed; +export * from 'react-reconciler/src/ReactFiberConfigWithNoViewTransition'; export * from 'react-reconciler/src/ReactFiberConfigWithNoPersistence'; export * from 'react-reconciler/src/ReactFiberConfigWithNoHydration'; export * from 'react-reconciler/src/ReactFiberConfigWithNoTestSelectors'; @@ -332,148 +330,6 @@ export function unhideTextInstance( textInstance.isHidden = false; } -export function applyViewTransitionName( - instance: Instance, - name: string, - className: ?string, -): void { - // Noop -} - -export function restoreViewTransitionName( - instance: Instance, - props: Props, -): void { - // Noop -} - -export function cancelViewTransitionName( - instance: Instance, - name: string, - props: Props, -): void { - // Noop -} - -export function cancelRootViewTransitionName(rootContainer: Container): void { - // Noop -} - -export function restoreRootViewTransitionName(rootContainer: Container): void { - // Noop -} - -export function cloneRootViewTransitionContainer( - rootContainer: Container, -): Instance { - return { - type: 'ROOT', - props: {}, - isHidden: false, - children: [], - internalInstanceHandle: null, - rootContainerInstance: rootContainer, - tag: 'INSTANCE', - }; -} - -export function removeRootViewTransitionClone( - rootContainer: Container, - clone: Instance, -): void { - // Noop since it was never inserted anywhere. -} - -export type InstanceMeasurement = null; - -export function measureInstance(instance: Instance): InstanceMeasurement { - return null; -} - -export function measureClonedInstance(instance: Instance): InstanceMeasurement { - return null; -} - -export function wasInstanceInViewport( - measurement: InstanceMeasurement, -): boolean { - return true; -} - -export function hasInstanceChanged( - oldMeasurement: InstanceMeasurement, - newMeasurement: InstanceMeasurement, -): boolean { - return false; -} - -export function hasInstanceAffectedParent( - oldMeasurement: InstanceMeasurement, - newMeasurement: InstanceMeasurement, -): boolean { - return false; -} - -export function startViewTransition( - suspendedState: null | SuspendedState, - rootContainer: Container, - transitionTypes: null | TransitionTypes, - mutationCallback: () => void, - layoutCallback: () => void, - afterMutationCallback: () => void, - spawnedWorkCallback: () => void, - passiveCallback: () => mixed, - errorCallback: mixed => void, - blockedCallback: string => void, // Profiling-only - finishedAnimation: () => void, // Profiling-only -): null | RunningViewTransition { - mutationCallback(); - layoutCallback(); - // Skip afterMutationCallback(). We don't need it since we're not animating. - spawnedWorkCallback(); - // Skip passiveCallback(). Spawned work will schedule a task. - return null; -} - -export type RunningViewTransition = null; - -export function startGestureTransition( - suspendedState: null | SuspendedState, - rootContainer: Container, - timeline: GestureTimeline, - rangeStart: number, - rangeEnd: number, - transitionTypes: null | TransitionTypes, - mutationCallback: () => void, - animateCallback: () => void, - errorCallback: mixed => void, - finishedAnimation: () => void, // Profiling-only -): null | RunningViewTransition { - mutationCallback(); - animateCallback(); - if (enableProfilerTimer) { - finishedAnimation(); - } - return null; -} - -export function stopViewTransition(transition: RunningViewTransition) {} - -export function addViewTransitionFinishedListener( - transition: RunningViewTransition, - callback: () => void, -) { - callback(); -} - -export type ViewTransitionInstance = null | {name: string, ...}; - -export function createViewTransitionInstance( - name: string, -): ViewTransitionInstance { - return null; -} - export type FragmentInstanceType = null; export function createFragmentInstance( diff --git a/scripts/error-codes/codes.json b/scripts/error-codes/codes.json index 46bb2e6bccf0..5ed9fb77ac50 100644 --- a/scripts/error-codes/codes.json +++ b/scripts/error-codes/codes.json @@ -566,5 +566,6 @@ "578": "Already initialized Iterator.", "579": "Invalid data for bytes stream.", "580": "Server Function has too many bound arguments. Received %s but the limit is %s.", - "581": "BigInt is too large. Received %s digits but the limit is %s." + "581": "BigInt is too large. Received %s digits but the limit is %s.", + "582": "The current renderer does not support view transitions. This error is likely caused by a bug in React. Please file an issue." } From 48e398f841729a9c16c64d546a978782958844a3 Mon Sep 17 00:00:00 2001 From: Zeya Peng Date: Thu, 5 Mar 2026 14:13:56 -0500 Subject: [PATCH 02/14] create supportsViewTransition and ReactFiberConfigWithNoViewTransition out of ReactFiberConfigWithNoMutation --- packages/react-art/src/ReactFiberConfigART.js | 1 + packages/react-native-renderer/src/ReactFiberConfigNative.js | 1 + packages/react-test-renderer/src/ReactFiberConfigTestHost.js | 1 + 3 files changed, 3 insertions(+) diff --git a/packages/react-art/src/ReactFiberConfigART.js b/packages/react-art/src/ReactFiberConfigART.js index 1ed9b04fa855..38628113b525 100644 --- a/packages/react-art/src/ReactFiberConfigART.js +++ b/packages/react-art/src/ReactFiberConfigART.js @@ -414,6 +414,7 @@ export const isPrimaryRenderer = false; export const warnsIfNotActing = false; export const supportsMutation = true; +export const supportsViewTransition = false; export function appendChild(parentInstance, child) { if (child.parentNode === parentInstance) { diff --git a/packages/react-native-renderer/src/ReactFiberConfigNative.js b/packages/react-native-renderer/src/ReactFiberConfigNative.js index 87d85b97e716..447de7f084ad 100644 --- a/packages/react-native-renderer/src/ReactFiberConfigNative.js +++ b/packages/react-native-renderer/src/ReactFiberConfigNative.js @@ -373,6 +373,7 @@ export function shouldAttemptEagerTransition(): boolean { // ------------------- export const supportsMutation = true; +export const supportsViewTransition = false; export function appendChild( parentInstance: Instance, diff --git a/packages/react-test-renderer/src/ReactFiberConfigTestHost.js b/packages/react-test-renderer/src/ReactFiberConfigTestHost.js index 417745828d60..e750f7a2b0a7 100644 --- a/packages/react-test-renderer/src/ReactFiberConfigTestHost.js +++ b/packages/react-test-renderer/src/ReactFiberConfigTestHost.js @@ -274,6 +274,7 @@ export const noTimeout: -1 = -1; // ------------------- export const supportsMutation = true; +export const supportsViewTransition = false; export function commitUpdate( instance: Instance, From 9716ea6417f99add92e948addd0ccb46cd7916e2 Mon Sep 17 00:00:00 2001 From: Zeya Peng Date: Thu, 5 Feb 2026 18:13:14 -0500 Subject: [PATCH 03/14] enableViewTransition for RN Summary: - turn on enableViewTransition feature - stub shim - run some mutation config fn at persistence mode too --- .../src/ReactFiberConfigFabric.js | 226 +++++++++++++++++- .../forks/ReactFeatureFlags.native-fb.js | 2 +- ...actFeatureFlags.test-renderer.native-fb.js | 2 +- 3 files changed, 222 insertions(+), 8 deletions(-) diff --git a/packages/react-native-renderer/src/ReactFiberConfigFabric.js b/packages/react-native-renderer/src/ReactFiberConfigFabric.js index f5a4361fd41d..3c293aca3738 100644 --- a/packages/react-native-renderer/src/ReactFiberConfigFabric.js +++ b/packages/react-native-renderer/src/ReactFiberConfigFabric.js @@ -12,6 +12,7 @@ import type { TouchedViewDataAtPoint, ViewConfig, } from './ReactNativeTypes'; +import type {TransitionTypes} from 'react/src/ReactTransitionType'; import {dispatchEvent} from './ReactFabricEventEmitter'; import { NoEventPriority, @@ -72,6 +73,12 @@ import {passChildrenWhenCloningPersistedNodes} from 'shared/ReactFeatureFlags'; import {REACT_CONTEXT_TYPE} from 'shared/ReactSymbols'; import type {ReactContext} from 'shared/ReactTypes'; +export * from 'react-reconciler/src/ReactFiberConfigWithNoHydration'; +export * from 'react-reconciler/src/ReactFiberConfigWithNoScopes'; +export * from 'react-reconciler/src/ReactFiberConfigWithNoTestSelectors'; +export * from 'react-reconciler/src/ReactFiberConfigWithNoResources'; +export * from 'react-reconciler/src/ReactFiberConfigWithNoSingletons'; + export {default as rendererVersion} from 'shared/ReactVersion'; // TODO: Consider exporting the react-native version. export const rendererPackageName = 'react-native-renderer'; export const extraDevToolsConfig = { @@ -157,12 +164,219 @@ if (registerEventHandler) { registerEventHandler(dispatchEvent); } -export * from 'react-reconciler/src/ReactFiberConfigWithNoMutation'; -export * from 'react-reconciler/src/ReactFiberConfigWithNoHydration'; -export * from 'react-reconciler/src/ReactFiberConfigWithNoScopes'; -export * from 'react-reconciler/src/ReactFiberConfigWithNoTestSelectors'; -export * from 'react-reconciler/src/ReactFiberConfigWithNoResources'; -export * from 'react-reconciler/src/ReactFiberConfigWithNoSingletons'; +// ------------------- +// Mutation +// ------------------- + +function shim(...args: any): empty { + throw new Error( + 'The current renderer does not support mutation. ' + + 'This error is likely caused by a bug in React. ' + + 'Please file an issue.', + ); +} + +export const supportsMutation = false; + +export const cloneMutableInstance = shim; +export const cloneMutableTextInstance = shim; +export const appendChild = shim; +export const appendChildToContainer = shim; +export const commitTextUpdate = shim; + +export function commitMount( + instance: Instance, + type: string, + newProps: Props, + internalInstanceHandle: Object, +): void { + console.log('[shim] commitMount'); +} + +export const commitUpdate = shim; +export const insertBefore = shim; +export const insertInContainerBefore = shim; +export const removeChild = shim; +export const removeChildFromContainer = shim; +export const resetTextContent = shim; +export const hideInstance = shim; +export const hideTextInstance = shim; +export const unhideInstance = shim; +export const unhideTextInstance = shim; +export const clearContainer = shim; + +export type InstanceMeasurement = { + rect: {x: number, y: number, width: number, height: number}, + abs: boolean, + clip: boolean, + view: boolean, +}; + +export type RunningViewTransition = null; + +export type ViewTransitionInstance = null | { + name: string, + ... +}; + +export type GestureTimeline = any; + +export function restoreViewTransitionName( + instance: Instance, + props: Props, +): void { + console.log('[shim] restoreViewTransitionName ', instance.canonical.nativeTag); +} + +export function cancelViewTransitionName( + instance: Instance, + oldName: string, + props: Props, +): void { + console.log('[shim] cancelViewTransitionName ', oldName, instance.canonical.nativeTag); +} + +export function cancelRootViewTransitionName(rootContainer: Container): void { + console.log('[shim] cancelRootViewTransitionName'); +} + +export function restoreRootViewTransitionName(rootContainer: Container): void { + console.log('[shim] restoreRootViewTransitionName'); +} + +export function cloneRootViewTransitionContainer( + rootContainer: Container, +): Instance { + console.log('[shim] cloneRootViewTransitionContainer'); +} + +export function removeRootViewTransitionClone( + rootContainer: Container, + clone: Instance, +): void { + console.log('[shim] removeRootViewTransitionClone'); +} + +export function measureInstance(instance: Instance): InstanceMeasurement { + console.log('[shim] measureInstance ', instance.canonical.nativeTag); + return {rect: {x: 0, y: 0, width: 0, height: 0}, abs: false, clip: false, view: true}; +} + +export function measureClonedInstance(instance: Instance): InstanceMeasurement { + console.log('[shim] measureClonedInstance ', instance.canonical.nativeTag); + return {rect: {x: 0, y: 0, width: 0, height: 0}, abs: false, clip: false, view: true}; +} + +export function wasInstanceInViewport( + measurement: InstanceMeasurement, +): boolean { + console.log('[shim] wasInstanceInViewport'); + return measurement.view; +} + +export function hasInstanceChanged( + oldMeasurement: InstanceMeasurement, + newMeasurement: InstanceMeasurement, +): boolean { + console.log('[shim] hasInstanceChanged'); + return false; +} + +export function hasInstanceAffectedParent( + oldMeasurement: InstanceMeasurement, + newMeasurement: InstanceMeasurement, +): boolean { + console.log('[shim] hasInstanceAffectedParent'); + return false; +} + +export function startGestureTransition( + suspendedState: null | SuspendedState, + rootContainer: Container, + timeline: GestureTimeline, + rangeStart: number, + rangeEnd: number, + transitionTypes: null | TransitionTypes, + mutationCallback: () => void, + animateCallback: () => void, + errorCallback: (error: mixed) => void, + finishedAnimation: () => void, +): RunningViewTransition { + console.log('[shim] startGestureTransition'); + return null; +} + +export function stopViewTransition(transition: RunningViewTransition): void { + console.log('[shim] stopViewTransition'); +} + +export function addViewTransitionFinishedListener( + transition: RunningViewTransition, + callback: () => void, +): void { + console.log('[shim] addViewTransitionFinishedListener'); + callback(); +} + +export function createViewTransitionInstance( + name: string, +): ViewTransitionInstance { + console.log('[shim] createViewTransitionInstance', name); + return {name}; +} + +export function getCurrentGestureOffset(timeline: GestureTimeline): number { + console.log('[shim] getCurrentGestureOffset'); + return 0; +} + +export function applyViewTransitionName( + instance: Instance, + name: string, + className: ?string, +): void { + // add view-transition-name to things that might animate for browser + console.log('[shim] applyViewTransitionName', name, className, instance.canonical.nativeTag); +} + +export function startViewTransition( + suspendedState: null | SuspendedState, + rootContainer: Container, + transitionTypes: null | TransitionTypes, + mutationCallback: () => void, + layoutCallback: () => void, + afterMutationCallback: () => void, + spawnedWorkCallback: () => void, + passiveCallback: () => mixed, + errorCallback: (error: mixed) => void, + blockedCallback: (name: string) => void, + finishedAnimation: () => void, +): RunningViewTransition { + console.log('[shim] startViewTransition transitionTypes', JSON.stringify(transitionTypes ?? [])); + + // mutation phase + console.log('[shim] startViewTransition mutations start'); + mutationCallback(); + layoutCallback(); // run layout effects + afterMutationCallback(); + console.log('[shim] startViewTransition mutations finish'); + + // browser creates pseudo elements + console.log('[shim] startViewTransition pseudo element captured'); + + // transition ready + console.log('[shim] startViewTransition transition ready'); + spawnedWorkCallback(); + + console.log('[shim] startViewTransition finishedAnimation'); + // finishedAnimation(); + + // transition ends + console.log('[shim] startViewTransition transition ends'); + passiveCallback(); + + return null; +} export function appendInitialChild( parentInstance: Instance, diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js index eeabe40d33bb..6e57ad63b801 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js @@ -70,7 +70,7 @@ export const syncLaneExpirationMs = 250; export const transitionLaneExpirationMs = 5000; export const enableYieldingBeforePassive: boolean = false; export const enableThrottledScheduling: boolean = false; -export const enableViewTransition: boolean = false; +export const enableViewTransition: boolean = true; export const enableGestureTransition: boolean = false; export const enableScrollEndPolyfill: boolean = true; export const enableSuspenseyImages: boolean = false; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js index a2e623ff5201..268b53cf90bd 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js @@ -56,7 +56,7 @@ export const syncLaneExpirationMs = 250; export const transitionLaneExpirationMs = 5000; export const enableYieldingBeforePassive = false; export const enableThrottledScheduling = false; -export const enableViewTransition = false; +export const enableViewTransition = true; export const enableGestureTransition = false; export const enableScrollEndPolyfill = true; export const enableSuspenseyImages = false; From d18c7b98d517856cae66016e23bc3c9390951bec Mon Sep 17 00:00:00 2001 From: Zeya Peng Date: Fri, 6 Feb 2026 16:07:31 -0500 Subject: [PATCH 04/14] invoke FabricUIManager methods --- .../src/ReactFiberConfigFabric.js | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/react-native-renderer/src/ReactFiberConfigFabric.js b/packages/react-native-renderer/src/ReactFiberConfigFabric.js index 3c293aca3738..c44984248452 100644 --- a/packages/react-native-renderer/src/ReactFiberConfigFabric.js +++ b/packages/react-native-renderer/src/ReactFiberConfigFabric.js @@ -58,6 +58,10 @@ const { unstable_ContinuousEventPriority: FabricContinuousPriority, unstable_IdleEventPriority: FabricIdlePriority, unstable_getCurrentEventPriority: fabricGetCurrentEventPriority, + measureInstance: fabricMeasureInstance, + applyViewTransitionName: fabricApplyViewTransitionName, + executeViewTransition: fabricExecuteViewTransition, + startViewTransition: fabricStartViewTransition, } = nativeFabricUIManager; import {getClosestInstanceFromNode} from './ReactFabricComponentTree'; @@ -259,7 +263,18 @@ export function removeRootViewTransitionClone( export function measureInstance(instance: Instance): InstanceMeasurement { console.log('[shim] measureInstance ', instance.canonical.nativeTag); - return {rect: {x: 0, y: 0, width: 0, height: 0}, abs: false, clip: false, view: true}; + var measurement = fabricMeasureInstance(instance.node); + return { + rect: { + x: measurement.x, + y: measurement.y, + width: measurement.width, + height: measurement.height + }, + abs: false, + clip: false, + view: true + }; } export function measureClonedInstance(instance: Instance): InstanceMeasurement { @@ -337,6 +352,7 @@ export function applyViewTransitionName( ): void { // add view-transition-name to things that might animate for browser console.log('[shim] applyViewTransitionName', name, className, instance.canonical.nativeTag); + fabricApplyViewTransitionName(instance.node, name, className); } export function startViewTransition( @@ -353,6 +369,7 @@ export function startViewTransition( finishedAnimation: () => void, ): RunningViewTransition { console.log('[shim] startViewTransition transitionTypes', JSON.stringify(transitionTypes ?? [])); + fabricStartViewTransition(); // mutation phase console.log('[shim] startViewTransition mutations start'); @@ -367,6 +384,7 @@ export function startViewTransition( // transition ready console.log('[shim] startViewTransition transition ready'); spawnedWorkCallback(); + fabricExecuteViewTransition(); console.log('[shim] startViewTransition finishedAnimation'); // finishedAnimation(); From 98dfcbc07aa6b95c42f83022238b18b0afd68bad Mon Sep 17 00:00:00 2001 From: Zeya Peng Date: Fri, 6 Feb 2026 17:42:16 -0500 Subject: [PATCH 05/14] Rename fabricStartViewTransition to fabricViewTransitionStarted Better reflects that this signals the transition has started rather than initiating it. --- .../src/ReactFiberConfigFabric.js | 51 ++++++++++--------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/packages/react-native-renderer/src/ReactFiberConfigFabric.js b/packages/react-native-renderer/src/ReactFiberConfigFabric.js index c44984248452..52b4f1216554 100644 --- a/packages/react-native-renderer/src/ReactFiberConfigFabric.js +++ b/packages/react-native-renderer/src/ReactFiberConfigFabric.js @@ -60,7 +60,6 @@ const { unstable_getCurrentEventPriority: fabricGetCurrentEventPriority, measureInstance: fabricMeasureInstance, applyViewTransitionName: fabricApplyViewTransitionName, - executeViewTransition: fabricExecuteViewTransition, startViewTransition: fabricStartViewTransition, } = nativeFabricUIManager; @@ -368,30 +367,33 @@ export function startViewTransition( blockedCallback: (name: string) => void, finishedAnimation: () => void, ): RunningViewTransition { - console.log('[shim] startViewTransition transitionTypes', JSON.stringify(transitionTypes ?? [])); - fabricStartViewTransition(); - - // mutation phase - console.log('[shim] startViewTransition mutations start'); - mutationCallback(); - layoutCallback(); // run layout effects - afterMutationCallback(); - console.log('[shim] startViewTransition mutations finish'); - - // browser creates pseudo elements - console.log('[shim] startViewTransition pseudo element captured'); - - // transition ready - console.log('[shim] startViewTransition transition ready'); - spawnedWorkCallback(); - fabricExecuteViewTransition(); - - console.log('[shim] startViewTransition finishedAnimation'); - // finishedAnimation(); + console.log( + "[shim] startViewTransition transitionTypes", + JSON.stringify(null != transitionTypes ? transitionTypes : []) + ); - // transition ends - console.log('[shim] startViewTransition transition ends'); - passiveCallback(); + fabricStartViewTransition( + // mutation + ()=>{ + console.log("[shim] startViewTransition mutations start"); + // completeRoot should run here + mutationCallback(); + layoutCallback(); + afterMutationCallback(); + console.log("[shim] startViewTransition mutations finish"); + }, + // onReady + ()=>{ + console.log("[shim] startViewTransition pseudo element captured"); + console.log("[shim] startViewTransition transition ready"); + spawnedWorkCallback(); + }, + // onComplete + ()=>{ + console.log("[shim] startViewTransition finishedAnimation"); + console.log("[shim] startViewTransition transition ends"); + passiveCallback(); + }); return null; } @@ -789,6 +791,7 @@ export function replaceContainerChildren( container: Container, newChildren: ChildSet, ): void { + console.log('completeRoot'); completeRoot(container.containerTag, newChildren); } From 968234ef35035efcd3562c6eddd7f2aa084335a1 Mon Sep 17 00:00:00 2001 From: Zeya Peng Date: Wed, 11 Feb 2026 11:59:03 -0500 Subject: [PATCH 06/14] restore/cancelViewTransitionName; fallback behavior if fabric doesnt enable startViewTransition --- .../src/ReactFiberConfigFabric.js | 77 +++++++++---------- 1 file changed, 35 insertions(+), 42 deletions(-) diff --git a/packages/react-native-renderer/src/ReactFiberConfigFabric.js b/packages/react-native-renderer/src/ReactFiberConfigFabric.js index 52b4f1216554..b1e35698cb5c 100644 --- a/packages/react-native-renderer/src/ReactFiberConfigFabric.js +++ b/packages/react-native-renderer/src/ReactFiberConfigFabric.js @@ -61,6 +61,8 @@ const { measureInstance: fabricMeasureInstance, applyViewTransitionName: fabricApplyViewTransitionName, startViewTransition: fabricStartViewTransition, + restoreViewTransitionName: fabricRestoreViewTransitionName, + cancelViewTransitionName: fabricCancelViewTransitionName, } = nativeFabricUIManager; import {getClosestInstanceFromNode} from './ReactFabricComponentTree'; @@ -76,12 +78,6 @@ import {passChildrenWhenCloningPersistedNodes} from 'shared/ReactFeatureFlags'; import {REACT_CONTEXT_TYPE} from 'shared/ReactSymbols'; import type {ReactContext} from 'shared/ReactTypes'; -export * from 'react-reconciler/src/ReactFiberConfigWithNoHydration'; -export * from 'react-reconciler/src/ReactFiberConfigWithNoScopes'; -export * from 'react-reconciler/src/ReactFiberConfigWithNoTestSelectors'; -export * from 'react-reconciler/src/ReactFiberConfigWithNoResources'; -export * from 'react-reconciler/src/ReactFiberConfigWithNoSingletons'; - export {default as rendererVersion} from 'shared/ReactVersion'; // TODO: Consider exporting the react-native version. export const rendererPackageName = 'react-native-renderer'; export const extraDevToolsConfig = { @@ -167,8 +163,14 @@ if (registerEventHandler) { registerEventHandler(dispatchEvent); } +export * from 'react-reconciler/src/ReactFiberConfigWithNoHydration'; +export * from 'react-reconciler/src/ReactFiberConfigWithNoScopes'; +export * from 'react-reconciler/src/ReactFiberConfigWithNoTestSelectors'; +export * from 'react-reconciler/src/ReactFiberConfigWithNoResources'; +export * from 'react-reconciler/src/ReactFiberConfigWithNoSingletons'; + // ------------------- -// Mutation +// ViewTransition // ------------------- function shim(...args: any): empty { @@ -192,9 +194,7 @@ export function commitMount( type: string, newProps: Props, internalInstanceHandle: Object, -): void { - console.log('[shim] commitMount'); -} +): void {} export const commitUpdate = shim; export const insertBefore = shim; @@ -228,41 +228,41 @@ export function restoreViewTransitionName( instance: Instance, props: Props, ): void { - console.log('[shim] restoreViewTransitionName ', instance.canonical.nativeTag); + fabricRestoreViewTransitionName(instance.node); } +// Cancel the old and new snapshots of viewTransitionName export function cancelViewTransitionName( instance: Instance, oldName: string, props: Props, ): void { - console.log('[shim] cancelViewTransitionName ', oldName, instance.canonical.nativeTag); + fabricCancelViewTransitionName(instance.node, oldName); } export function cancelRootViewTransitionName(rootContainer: Container): void { - console.log('[shim] cancelRootViewTransitionName'); + } export function restoreRootViewTransitionName(rootContainer: Container): void { - console.log('[shim] restoreRootViewTransitionName'); + } export function cloneRootViewTransitionContainer( rootContainer: Container, ): Instance { - console.log('[shim] cloneRootViewTransitionContainer'); } export function removeRootViewTransitionClone( rootContainer: Container, clone: Instance, ): void { - console.log('[shim] removeRootViewTransitionClone'); + } export function measureInstance(instance: Instance): InstanceMeasurement { - console.log('[shim] measureInstance ', instance.canonical.nativeTag); - var measurement = fabricMeasureInstance(instance.node); + + const measurement = fabricMeasureInstance(instance.node); return { rect: { x: measurement.x, @@ -277,14 +277,12 @@ export function measureInstance(instance: Instance): InstanceMeasurement { } export function measureClonedInstance(instance: Instance): InstanceMeasurement { - console.log('[shim] measureClonedInstance ', instance.canonical.nativeTag); return {rect: {x: 0, y: 0, width: 0, height: 0}, abs: false, clip: false, view: true}; } export function wasInstanceInViewport( measurement: InstanceMeasurement, ): boolean { - console.log('[shim] wasInstanceInViewport'); return measurement.view; } @@ -292,7 +290,6 @@ export function hasInstanceChanged( oldMeasurement: InstanceMeasurement, newMeasurement: InstanceMeasurement, ): boolean { - console.log('[shim] hasInstanceChanged'); return false; } @@ -300,7 +297,6 @@ export function hasInstanceAffectedParent( oldMeasurement: InstanceMeasurement, newMeasurement: InstanceMeasurement, ): boolean { - console.log('[shim] hasInstanceAffectedParent'); return false; } @@ -316,31 +312,26 @@ export function startGestureTransition( errorCallback: (error: mixed) => void, finishedAnimation: () => void, ): RunningViewTransition { - console.log('[shim] startGestureTransition'); return null; } export function stopViewTransition(transition: RunningViewTransition): void { - console.log('[shim] stopViewTransition'); } export function addViewTransitionFinishedListener( transition: RunningViewTransition, callback: () => void, ): void { - console.log('[shim] addViewTransitionFinishedListener'); callback(); } export function createViewTransitionInstance( name: string, ): ViewTransitionInstance { - console.log('[shim] createViewTransitionInstance', name); return {name}; } export function getCurrentGestureOffset(timeline: GestureTimeline): number { - console.log('[shim] getCurrentGestureOffset'); return 0; } @@ -350,7 +341,6 @@ export function applyViewTransitionName( className: ?string, ): void { // add view-transition-name to things that might animate for browser - console.log('[shim] applyViewTransitionName', name, className, instance.canonical.nativeTag); fabricApplyViewTransitionName(instance.node, name, className); } @@ -367,34 +357,38 @@ export function startViewTransition( blockedCallback: (name: string) => void, finishedAnimation: () => void, ): RunningViewTransition { - console.log( - "[shim] startViewTransition transitionTypes", - JSON.stringify(null != transitionTypes ? transitionTypes : []) - ); - fabricStartViewTransition( + const startedTransition = fabricStartViewTransition( // mutation ()=>{ - console.log("[shim] startViewTransition mutations start"); - // completeRoot should run here - mutationCallback(); + mutationCallback(); // completeRoot should run here layoutCallback(); afterMutationCallback(); - console.log("[shim] startViewTransition mutations finish"); }, // onReady ()=>{ - console.log("[shim] startViewTransition pseudo element captured"); - console.log("[shim] startViewTransition transition ready"); spawnedWorkCallback(); }, // onComplete ()=>{ - console.log("[shim] startViewTransition finishedAnimation"); - console.log("[shim] startViewTransition transition ends"); passiveCallback(); }); + if (!startedTransition) { + if (__DEV__) { + console.warn( + "startViewTransition didn't kick off transition in Fabric, the ViewTransition ReactNativeFeatureFlag might not be enabled.", + ); + } + // Flush remaining work synchronously. + mutationCallback(); + layoutCallback(); + // Skip afterMutationCallback(). We don't need it since we're not animating. + spawnedWorkCallback(); + // Skip passiveCallback(). Spawned work will schedule a task. + return null; + } + return null; } @@ -791,7 +785,6 @@ export function replaceContainerChildren( container: Container, newChildren: ChildSet, ): void { - console.log('completeRoot'); completeRoot(container.containerTag, newChildren); } From 3b47f597660a26d4291059248a35f51e22c4d56c Mon Sep 17 00:00:00 2001 From: Zeya Peng Date: Wed, 11 Feb 2026 12:06:37 -0500 Subject: [PATCH 07/14] fix flow --- .../src/ReactFiberConfigFabric.js | 35 +++++++++++++++++-- scripts/flow/react-native-host-hooks.js | 18 ++++++++++ 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/packages/react-native-renderer/src/ReactFiberConfigFabric.js b/packages/react-native-renderer/src/ReactFiberConfigFabric.js index b1e35698cb5c..8162ed80fa7c 100644 --- a/packages/react-native-renderer/src/ReactFiberConfigFabric.js +++ b/packages/react-native-renderer/src/ReactFiberConfigFabric.js @@ -241,23 +241,34 @@ export function cancelViewTransitionName( } export function cancelRootViewTransitionName(rootContainer: Container): void { - + if (__DEV__) { + console.warn('cancelRootViewTransitionName is not implemented'); + } } export function restoreRootViewTransitionName(rootContainer: Container): void { - + if (__DEV__) { + console.warn('restoreRootViewTransitionName is not implemented'); + } } export function cloneRootViewTransitionContainer( rootContainer: Container, ): Instance { + if (__DEV__) { + console.warn('cloneRootViewTransitionContainer is not implemented'); + } + // $FlowFixMe[incompatible-return] Return empty stub + return null; } export function removeRootViewTransitionClone( rootContainer: Container, clone: Instance, ): void { - + if (__DEV__) { + console.warn('removeRootViewTransitionClone is not implemented'); + } } export function measureInstance(instance: Instance): InstanceMeasurement { @@ -277,6 +288,9 @@ export function measureInstance(instance: Instance): InstanceMeasurement { } export function measureClonedInstance(instance: Instance): InstanceMeasurement { + if (__DEV__) { + console.warn('measureClonedInstance is not implemented'); + } return {rect: {x: 0, y: 0, width: 0, height: 0}, abs: false, clip: false, view: true}; } @@ -290,6 +304,9 @@ export function hasInstanceChanged( oldMeasurement: InstanceMeasurement, newMeasurement: InstanceMeasurement, ): boolean { + if (__DEV__) { + console.warn('hasInstanceChanged is not implemented'); + } return false; } @@ -297,6 +314,9 @@ export function hasInstanceAffectedParent( oldMeasurement: InstanceMeasurement, newMeasurement: InstanceMeasurement, ): boolean { + if (__DEV__) { + console.warn('hasInstanceAffectedParent is not implemented'); + } return false; } @@ -312,10 +332,16 @@ export function startGestureTransition( errorCallback: (error: mixed) => void, finishedAnimation: () => void, ): RunningViewTransition { + if (__DEV__) { + console.warn('startGestureTransition is not implemented'); + } return null; } export function stopViewTransition(transition: RunningViewTransition): void { + if (__DEV__) { + console.warn('stopViewTransition is not implemented'); + } } export function addViewTransitionFinishedListener( @@ -332,6 +358,9 @@ export function createViewTransitionInstance( } export function getCurrentGestureOffset(timeline: GestureTimeline): number { + if (__DEV__) { + console.warn('getCurrentGestureOffset is not implemented'); + } return 0; } diff --git a/scripts/flow/react-native-host-hooks.js b/scripts/flow/react-native-host-hooks.js index 227c78bca24a..db8bbd9efaee 100644 --- a/scripts/flow/react-native-host-hooks.js +++ b/scripts/flow/react-native-host-hooks.js @@ -301,5 +301,23 @@ declare const nativeFabricUIManager: { unstable_ContinuousEventPriority: number, unstable_IdleEventPriority: number, unstable_getCurrentEventPriority: () => number, + measureInstance: (node: Object) => { + x: number, + y: number, + width: number, + height: number, + }, + applyViewTransitionName: ( + node: Object, + name: string, + className: ?string, + ) => void, + startViewTransition: ( + mutationCallback: () => void, + onReady: () => void, + onComplete: () => void, + ) => boolean, + restoreViewTransitionName: (node: Object) => void, + cancelViewTransitionName: (node: Object, oldName: string) => void, ... }; From 57395c1bdf5467f4190cc11fa5457dc0c9d15ae8 Mon Sep 17 00:00:00 2001 From: Zeya Peng Date: Wed, 11 Feb 2026 12:14:35 -0500 Subject: [PATCH 08/14] turn off enableViewTransition for fb rn renderer by default --- packages/shared/forks/ReactFeatureFlags.native-fb.js | 2 +- .../shared/forks/ReactFeatureFlags.test-renderer.native-fb.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js index 6e57ad63b801..eeabe40d33bb 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js @@ -70,7 +70,7 @@ export const syncLaneExpirationMs = 250; export const transitionLaneExpirationMs = 5000; export const enableYieldingBeforePassive: boolean = false; export const enableThrottledScheduling: boolean = false; -export const enableViewTransition: boolean = true; +export const enableViewTransition: boolean = false; export const enableGestureTransition: boolean = false; export const enableScrollEndPolyfill: boolean = true; export const enableSuspenseyImages: boolean = false; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js index 268b53cf90bd..a2e623ff5201 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js @@ -56,7 +56,7 @@ export const syncLaneExpirationMs = 250; export const transitionLaneExpirationMs = 5000; export const enableYieldingBeforePassive = false; export const enableThrottledScheduling = false; -export const enableViewTransition = true; +export const enableViewTransition = false; export const enableGestureTransition = false; export const enableScrollEndPolyfill = true; export const enableSuspenseyImages = false; From 1cfc3553641311ca7786f33298421c56973afc62 Mon Sep 17 00:00:00 2001 From: Zeya Peng Date: Wed, 11 Feb 2026 12:21:29 -0500 Subject: [PATCH 09/14] prettier --- .../src/ReactFiberConfigFabric.js | 42 ++++++++++--------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/packages/react-native-renderer/src/ReactFiberConfigFabric.js b/packages/react-native-renderer/src/ReactFiberConfigFabric.js index 8162ed80fa7c..e9ecb5bf3321 100644 --- a/packages/react-native-renderer/src/ReactFiberConfigFabric.js +++ b/packages/react-native-renderer/src/ReactFiberConfigFabric.js @@ -272,18 +272,17 @@ export function removeRootViewTransitionClone( } export function measureInstance(instance: Instance): InstanceMeasurement { - const measurement = fabricMeasureInstance(instance.node); return { rect: { x: measurement.x, y: measurement.y, width: measurement.width, - height: measurement.height + height: measurement.height, }, abs: false, clip: false, - view: true + view: true, }; } @@ -291,7 +290,12 @@ export function measureClonedInstance(instance: Instance): InstanceMeasurement { if (__DEV__) { console.warn('measureClonedInstance is not implemented'); } - return {rect: {x: 0, y: 0, width: 0, height: 0}, abs: false, clip: false, view: true}; + return { + rect: {x: 0, y: 0, width: 0, height: 0}, + abs: false, + clip: false, + view: true, + }; } export function wasInstanceInViewport( @@ -386,22 +390,22 @@ export function startViewTransition( blockedCallback: (name: string) => void, finishedAnimation: () => void, ): RunningViewTransition { - const startedTransition = fabricStartViewTransition( // mutation - ()=>{ - mutationCallback(); // completeRoot should run here - layoutCallback(); - afterMutationCallback(); - }, - // onReady - ()=>{ - spawnedWorkCallback(); - }, - // onComplete - ()=>{ - passiveCallback(); - }); + () => { + mutationCallback(); // completeRoot should run here + layoutCallback(); + afterMutationCallback(); + }, + // onReady + () => { + spawnedWorkCallback(); + }, + // onComplete + () => { + passiveCallback(); + }, + ); if (!startedTransition) { if (__DEV__) { @@ -409,7 +413,7 @@ export function startViewTransition( "startViewTransition didn't kick off transition in Fabric, the ViewTransition ReactNativeFeatureFlag might not be enabled.", ); } - // Flush remaining work synchronously. + // Flush remaining work synchronously. mutationCallback(); layoutCallback(); // Skip afterMutationCallback(). We don't need it since we're not animating. From f2f894f2265129d41fb272fafef01280b0f12d47 Mon Sep 17 00:00:00 2001 From: Zeya Peng Date: Fri, 13 Feb 2026 12:32:19 -0500 Subject: [PATCH 10/14] make startViewTransition async and return ready & finished promises --- .../src/ReactFiberConfigFabric.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/react-native-renderer/src/ReactFiberConfigFabric.js b/packages/react-native-renderer/src/ReactFiberConfigFabric.js index e9ecb5bf3321..c503d8820bcb 100644 --- a/packages/react-native-renderer/src/ReactFiberConfigFabric.js +++ b/packages/react-native-renderer/src/ReactFiberConfigFabric.js @@ -215,7 +215,12 @@ export type InstanceMeasurement = { view: boolean, }; -export type RunningViewTransition = null; +export type RunningViewTransition = { + skipTransition(): void, + finished: Promise, + ready: Promise, + ... +}; export type ViewTransitionInstance = null | { name: string, @@ -389,8 +394,8 @@ export function startViewTransition( errorCallback: (error: mixed) => void, blockedCallback: (name: string) => void, finishedAnimation: () => void, -): RunningViewTransition { - const startedTransition = fabricStartViewTransition( +): null | RunningViewTransition { + const transition = fabricStartViewTransition( // mutation () => { mutationCallback(); // completeRoot should run here @@ -407,7 +412,7 @@ export function startViewTransition( }, ); - if (!startedTransition) { + if (transition == null) { if (__DEV__) { console.warn( "startViewTransition didn't kick off transition in Fabric, the ViewTransition ReactNativeFeatureFlag might not be enabled.", @@ -422,7 +427,7 @@ export function startViewTransition( return null; } - return null; + return transition; } export function appendInitialChild( From 114eb372ea23931a8abc57317035b77d516be010 Mon Sep 17 00:00:00 2001 From: Zeya Peng Date: Wed, 25 Feb 2026 14:24:19 -0500 Subject: [PATCH 11/14] update startViewTransition to use ready/finished promise returned from fabric --- .../src/ReactFiberConfigFabric.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/react-native-renderer/src/ReactFiberConfigFabric.js b/packages/react-native-renderer/src/ReactFiberConfigFabric.js index c503d8820bcb..5a7d076b6e8d 100644 --- a/packages/react-native-renderer/src/ReactFiberConfigFabric.js +++ b/packages/react-native-renderer/src/ReactFiberConfigFabric.js @@ -402,14 +402,6 @@ export function startViewTransition( layoutCallback(); afterMutationCallback(); }, - // onReady - () => { - spawnedWorkCallback(); - }, - // onComplete - () => { - passiveCallback(); - }, ); if (transition == null) { @@ -427,6 +419,14 @@ export function startViewTransition( return null; } + transition.ready.then(() => { + spawnedWorkCallback(); + }); + + transition.finished.finally(() => { + passiveCallback(); + }); + return transition; } From 655affb04b217e10d055979218429f1b8db215aa Mon Sep 17 00:00:00 2001 From: Zeya Peng Date: Thu, 5 Mar 2026 14:13:21 -0500 Subject: [PATCH 12/14] move vt specific config functions to ReactFiberConfigFabricWithViewTransition.js --- .../src/ReactFiberConfigFabric.js | 233 +---------------- ...eactFiberConfigFabricWithViewTransition.js | 240 ++++++++++++++++++ 2 files changed, 244 insertions(+), 229 deletions(-) create mode 100644 packages/react-native-renderer/src/ReactFiberConfigFabricWithViewTransition.js diff --git a/packages/react-native-renderer/src/ReactFiberConfigFabric.js b/packages/react-native-renderer/src/ReactFiberConfigFabric.js index 5a7d076b6e8d..69f43c0256a4 100644 --- a/packages/react-native-renderer/src/ReactFiberConfigFabric.js +++ b/packages/react-native-renderer/src/ReactFiberConfigFabric.js @@ -12,7 +12,6 @@ import type { TouchedViewDataAtPoint, ViewConfig, } from './ReactNativeTypes'; -import type {TransitionTypes} from 'react/src/ReactTransitionType'; import {dispatchEvent} from './ReactFabricEventEmitter'; import { NoEventPriority, @@ -58,11 +57,6 @@ const { unstable_ContinuousEventPriority: FabricContinuousPriority, unstable_IdleEventPriority: FabricIdlePriority, unstable_getCurrentEventPriority: fabricGetCurrentEventPriority, - measureInstance: fabricMeasureInstance, - applyViewTransitionName: fabricApplyViewTransitionName, - startViewTransition: fabricStartViewTransition, - restoreViewTransitionName: fabricRestoreViewTransitionName, - cancelViewTransitionName: fabricCancelViewTransitionName, } = nativeFabricUIManager; import {getClosestInstanceFromNode} from './ReactFabricComponentTree'; @@ -163,14 +157,17 @@ if (registerEventHandler) { registerEventHandler(dispatchEvent); } +export * from 'react-reconciler/src/ReactFiberConfigWithNoMutation'; export * from 'react-reconciler/src/ReactFiberConfigWithNoHydration'; export * from 'react-reconciler/src/ReactFiberConfigWithNoScopes'; export * from 'react-reconciler/src/ReactFiberConfigWithNoTestSelectors'; export * from 'react-reconciler/src/ReactFiberConfigWithNoResources'; export * from 'react-reconciler/src/ReactFiberConfigWithNoSingletons'; +export * from './ReactFiberConfigFabricWithViewTransition'; // ------------------- -// ViewTransition +// Mutation +// (not supported) // ------------------- function shim(...args: any): empty { @@ -208,228 +205,6 @@ export const unhideInstance = shim; export const unhideTextInstance = shim; export const clearContainer = shim; -export type InstanceMeasurement = { - rect: {x: number, y: number, width: number, height: number}, - abs: boolean, - clip: boolean, - view: boolean, -}; - -export type RunningViewTransition = { - skipTransition(): void, - finished: Promise, - ready: Promise, - ... -}; - -export type ViewTransitionInstance = null | { - name: string, - ... -}; - -export type GestureTimeline = any; - -export function restoreViewTransitionName( - instance: Instance, - props: Props, -): void { - fabricRestoreViewTransitionName(instance.node); -} - -// Cancel the old and new snapshots of viewTransitionName -export function cancelViewTransitionName( - instance: Instance, - oldName: string, - props: Props, -): void { - fabricCancelViewTransitionName(instance.node, oldName); -} - -export function cancelRootViewTransitionName(rootContainer: Container): void { - if (__DEV__) { - console.warn('cancelRootViewTransitionName is not implemented'); - } -} - -export function restoreRootViewTransitionName(rootContainer: Container): void { - if (__DEV__) { - console.warn('restoreRootViewTransitionName is not implemented'); - } -} - -export function cloneRootViewTransitionContainer( - rootContainer: Container, -): Instance { - if (__DEV__) { - console.warn('cloneRootViewTransitionContainer is not implemented'); - } - // $FlowFixMe[incompatible-return] Return empty stub - return null; -} - -export function removeRootViewTransitionClone( - rootContainer: Container, - clone: Instance, -): void { - if (__DEV__) { - console.warn('removeRootViewTransitionClone is not implemented'); - } -} - -export function measureInstance(instance: Instance): InstanceMeasurement { - const measurement = fabricMeasureInstance(instance.node); - return { - rect: { - x: measurement.x, - y: measurement.y, - width: measurement.width, - height: measurement.height, - }, - abs: false, - clip: false, - view: true, - }; -} - -export function measureClonedInstance(instance: Instance): InstanceMeasurement { - if (__DEV__) { - console.warn('measureClonedInstance is not implemented'); - } - return { - rect: {x: 0, y: 0, width: 0, height: 0}, - abs: false, - clip: false, - view: true, - }; -} - -export function wasInstanceInViewport( - measurement: InstanceMeasurement, -): boolean { - return measurement.view; -} - -export function hasInstanceChanged( - oldMeasurement: InstanceMeasurement, - newMeasurement: InstanceMeasurement, -): boolean { - if (__DEV__) { - console.warn('hasInstanceChanged is not implemented'); - } - return false; -} - -export function hasInstanceAffectedParent( - oldMeasurement: InstanceMeasurement, - newMeasurement: InstanceMeasurement, -): boolean { - if (__DEV__) { - console.warn('hasInstanceAffectedParent is not implemented'); - } - return false; -} - -export function startGestureTransition( - suspendedState: null | SuspendedState, - rootContainer: Container, - timeline: GestureTimeline, - rangeStart: number, - rangeEnd: number, - transitionTypes: null | TransitionTypes, - mutationCallback: () => void, - animateCallback: () => void, - errorCallback: (error: mixed) => void, - finishedAnimation: () => void, -): RunningViewTransition { - if (__DEV__) { - console.warn('startGestureTransition is not implemented'); - } - return null; -} - -export function stopViewTransition(transition: RunningViewTransition): void { - if (__DEV__) { - console.warn('stopViewTransition is not implemented'); - } -} - -export function addViewTransitionFinishedListener( - transition: RunningViewTransition, - callback: () => void, -): void { - callback(); -} - -export function createViewTransitionInstance( - name: string, -): ViewTransitionInstance { - return {name}; -} - -export function getCurrentGestureOffset(timeline: GestureTimeline): number { - if (__DEV__) { - console.warn('getCurrentGestureOffset is not implemented'); - } - return 0; -} - -export function applyViewTransitionName( - instance: Instance, - name: string, - className: ?string, -): void { - // add view-transition-name to things that might animate for browser - fabricApplyViewTransitionName(instance.node, name, className); -} - -export function startViewTransition( - suspendedState: null | SuspendedState, - rootContainer: Container, - transitionTypes: null | TransitionTypes, - mutationCallback: () => void, - layoutCallback: () => void, - afterMutationCallback: () => void, - spawnedWorkCallback: () => void, - passiveCallback: () => mixed, - errorCallback: (error: mixed) => void, - blockedCallback: (name: string) => void, - finishedAnimation: () => void, -): null | RunningViewTransition { - const transition = fabricStartViewTransition( - // mutation - () => { - mutationCallback(); // completeRoot should run here - layoutCallback(); - afterMutationCallback(); - }, - ); - - if (transition == null) { - if (__DEV__) { - console.warn( - "startViewTransition didn't kick off transition in Fabric, the ViewTransition ReactNativeFeatureFlag might not be enabled.", - ); - } - // Flush remaining work synchronously. - mutationCallback(); - layoutCallback(); - // Skip afterMutationCallback(). We don't need it since we're not animating. - spawnedWorkCallback(); - // Skip passiveCallback(). Spawned work will schedule a task. - return null; - } - - transition.ready.then(() => { - spawnedWorkCallback(); - }); - - transition.finished.finally(() => { - passiveCallback(); - }); - - return transition; -} - export function appendInitialChild( parentInstance: Instance, child: Instance | TextInstance, diff --git a/packages/react-native-renderer/src/ReactFiberConfigFabricWithViewTransition.js b/packages/react-native-renderer/src/ReactFiberConfigFabricWithViewTransition.js new file mode 100644 index 000000000000..0d8796927f2c --- /dev/null +++ b/packages/react-native-renderer/src/ReactFiberConfigFabricWithViewTransition.js @@ -0,0 +1,240 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +import type {TransitionTypes} from 'react/src/ReactTransitionType'; +import type { + Instance, + Props, + Container, + SuspendedState, + GestureTimeline, +} from './ReactFiberConfigFabric'; + +const { + measureInstance: fabricMeasureInstance, + applyViewTransitionName: fabricApplyViewTransitionName, + startViewTransition: fabricStartViewTransition, + restoreViewTransitionName: fabricRestoreViewTransitionName, + cancelViewTransitionName: fabricCancelViewTransitionName, +} = nativeFabricUIManager; + +export const supportsViewTransition = true; + +export type InstanceMeasurement = { + rect: {x: number, y: number, width: number, height: number}, + abs: boolean, + clip: boolean, + view: boolean, +}; + +export type RunningViewTransition = { + skipTransition(): void, + finished: Promise, + ready: Promise, + ... +}; + +export type ViewTransitionInstance = null | { + name: string, + ... +}; + +export function restoreViewTransitionName( + instance: Instance, + props: Props, +): void { + fabricRestoreViewTransitionName(instance.node); +} + +// Cancel the old and new snapshots of viewTransitionName +export function cancelViewTransitionName( + instance: Instance, + oldName: string, + props: Props, +): void { + fabricCancelViewTransitionName(instance.node, oldName); +} + +export function cancelRootViewTransitionName(rootContainer: Container): void { + if (__DEV__) { + console.warn('cancelRootViewTransitionName is not implemented'); + } +} + +export function restoreRootViewTransitionName(rootContainer: Container): void { + if (__DEV__) { + console.warn('restoreRootViewTransitionName is not implemented'); + } +} + +export function cloneRootViewTransitionContainer( + rootContainer: Container, +): Instance { + if (__DEV__) { + console.warn('cloneRootViewTransitionContainer is not implemented'); + } + // $FlowFixMe[incompatible-return] Return empty stub + return null; +} + +export function removeRootViewTransitionClone( + rootContainer: Container, + clone: Instance, +): void { + if (__DEV__) { + console.warn('removeRootViewTransitionClone is not implemented'); + } +} + +export function measureInstance(instance: Instance): InstanceMeasurement { + const measurement = fabricMeasureInstance(instance.node); + return { + rect: { + x: measurement.x, + y: measurement.y, + width: measurement.width, + height: measurement.height, + }, + abs: false, + clip: false, + view: true, + }; +} + +export function measureClonedInstance(instance: Instance): InstanceMeasurement { + if (__DEV__) { + console.warn('measureClonedInstance is not implemented'); + } + return { + rect: {x: 0, y: 0, width: 0, height: 0}, + abs: false, + clip: false, + view: true, + }; +} + +export function wasInstanceInViewport( + measurement: InstanceMeasurement, +): boolean { + return measurement.view; +} + +export function hasInstanceChanged( + oldMeasurement: InstanceMeasurement, + newMeasurement: InstanceMeasurement, +): boolean { + if (__DEV__) { + console.warn('hasInstanceChanged is not implemented'); + } + return false; +} + +export function hasInstanceAffectedParent( + oldMeasurement: InstanceMeasurement, + newMeasurement: InstanceMeasurement, +): boolean { + if (__DEV__) { + console.warn('hasInstanceAffectedParent is not implemented'); + } + return false; +} + +export function startGestureTransition( + suspendedState: null | SuspendedState, + rootContainer: Container, + timeline: GestureTimeline, + rangeStart: number, + rangeEnd: number, + transitionTypes: null | TransitionTypes, + mutationCallback: () => void, + animateCallback: () => void, + errorCallback: (error: mixed) => void, + finishedAnimation: () => void, +): RunningViewTransition { + if (__DEV__) { + console.warn('startGestureTransition is not implemented'); + } + return null; +} + +export function stopViewTransition(transition: RunningViewTransition): void { + if (__DEV__) { + console.warn('stopViewTransition is not implemented'); + } +} + +export function addViewTransitionFinishedListener( + transition: RunningViewTransition, + callback: () => void, +): void { + callback(); +} + +export function createViewTransitionInstance( + name: string, +): ViewTransitionInstance { + return {name}; +} + +export function applyViewTransitionName( + instance: Instance, + name: string, + className: ?string, +): void { + // add view-transition-name to things that might animate for browser + fabricApplyViewTransitionName(instance.node, name, className); +} + +export function startViewTransition( + suspendedState: null | SuspendedState, + rootContainer: Container, + transitionTypes: null | TransitionTypes, + mutationCallback: () => void, + layoutCallback: () => void, + afterMutationCallback: () => void, + spawnedWorkCallback: () => void, + passiveCallback: () => mixed, + errorCallback: (error: mixed) => void, + blockedCallback: (name: string) => void, + finishedAnimation: () => void, +): null | RunningViewTransition { + const transition = fabricStartViewTransition( + // mutation + () => { + mutationCallback(); // completeRoot should run here + layoutCallback(); + afterMutationCallback(); + }, + ); + + if (transition == null) { + if (__DEV__) { + console.warn( + "startViewTransition didn't kick off transition in Fabric, the ViewTransition ReactNativeFeatureFlag might not be enabled.", + ); + } + // Flush remaining work synchronously. + mutationCallback(); + layoutCallback(); + // Skip afterMutationCallback(). We don't need it since we're not animating. + spawnedWorkCallback(); + // Skip passiveCallback(). Spawned work will schedule a task. + return null; + } + + transition.ready.then(() => { + spawnedWorkCallback(); + }); + + transition.finished.finally(() => { + passiveCallback(); + }); + + return transition; +} From efe355f92de7cc4cd4bfcecb3cdc5c57bee894d6 Mon Sep 17 00:00:00 2001 From: Zeya Peng Date: Thu, 5 Mar 2026 16:04:33 -0500 Subject: [PATCH 13/14] implement function createViewTransitionInstance --- ...eactFiberConfigFabricWithViewTransition.js | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/packages/react-native-renderer/src/ReactFiberConfigFabricWithViewTransition.js b/packages/react-native-renderer/src/ReactFiberConfigFabricWithViewTransition.js index 0d8796927f2c..870310a2a5b7 100644 --- a/packages/react-native-renderer/src/ReactFiberConfigFabricWithViewTransition.js +++ b/packages/react-native-renderer/src/ReactFiberConfigFabricWithViewTransition.js @@ -40,8 +40,26 @@ export type RunningViewTransition = { ... }; +interface ViewTransitionPseudoElementType extends mixin$Animatable { + _scope: HTMLElement; + _selector: string; + getComputedStyle(): CSSStyleDeclaration; +} + +function ViewTransitionPseudoElement( + this: ViewTransitionPseudoElementType, + pseudo: string, + name: string, +) { + // TODO: Get the owner document from the root container. + this._pseudo = pseudo; + this._name = name; +} + export type ViewTransitionInstance = null | { name: string, + old: mixin$Animatable, + new: mixin$Animatable, ... }; @@ -179,7 +197,11 @@ export function addViewTransitionFinishedListener( export function createViewTransitionInstance( name: string, ): ViewTransitionInstance { - return {name}; + return { + name, + old: new (ViewTransitionPseudoElement: any)('old', name), + new: new (ViewTransitionPseudoElement: any)('new', name), + }; } export function applyViewTransitionName( From e5a769324d6480b63d1419cadf238da20e8f1a22 Mon Sep 17 00:00:00 2001 From: Zeya Peng Date: Fri, 6 Mar 2026 09:23:03 -0500 Subject: [PATCH 14/14] cleanup --- packages/react-art/src/ReactFiberConfigART.js | 1 - .../src/ReactFiberConfigFabric.js | 40 ------------------- .../src/ReactFiberConfigNative.js | 1 - .../src/ReactFiberConfigTestHost.js | 1 - 4 files changed, 43 deletions(-) diff --git a/packages/react-art/src/ReactFiberConfigART.js b/packages/react-art/src/ReactFiberConfigART.js index 38628113b525..1ed9b04fa855 100644 --- a/packages/react-art/src/ReactFiberConfigART.js +++ b/packages/react-art/src/ReactFiberConfigART.js @@ -414,7 +414,6 @@ export const isPrimaryRenderer = false; export const warnsIfNotActing = false; export const supportsMutation = true; -export const supportsViewTransition = false; export function appendChild(parentInstance, child) { if (child.parentNode === parentInstance) { diff --git a/packages/react-native-renderer/src/ReactFiberConfigFabric.js b/packages/react-native-renderer/src/ReactFiberConfigFabric.js index 69f43c0256a4..3909741ef2ff 100644 --- a/packages/react-native-renderer/src/ReactFiberConfigFabric.js +++ b/packages/react-native-renderer/src/ReactFiberConfigFabric.js @@ -165,46 +165,6 @@ export * from 'react-reconciler/src/ReactFiberConfigWithNoResources'; export * from 'react-reconciler/src/ReactFiberConfigWithNoSingletons'; export * from './ReactFiberConfigFabricWithViewTransition'; -// ------------------- -// Mutation -// (not supported) -// ------------------- - -function shim(...args: any): empty { - throw new Error( - 'The current renderer does not support mutation. ' + - 'This error is likely caused by a bug in React. ' + - 'Please file an issue.', - ); -} - -export const supportsMutation = false; - -export const cloneMutableInstance = shim; -export const cloneMutableTextInstance = shim; -export const appendChild = shim; -export const appendChildToContainer = shim; -export const commitTextUpdate = shim; - -export function commitMount( - instance: Instance, - type: string, - newProps: Props, - internalInstanceHandle: Object, -): void {} - -export const commitUpdate = shim; -export const insertBefore = shim; -export const insertInContainerBefore = shim; -export const removeChild = shim; -export const removeChildFromContainer = shim; -export const resetTextContent = shim; -export const hideInstance = shim; -export const hideTextInstance = shim; -export const unhideInstance = shim; -export const unhideTextInstance = shim; -export const clearContainer = shim; - export function appendInitialChild( parentInstance: Instance, child: Instance | TextInstance, diff --git a/packages/react-native-renderer/src/ReactFiberConfigNative.js b/packages/react-native-renderer/src/ReactFiberConfigNative.js index 447de7f084ad..87d85b97e716 100644 --- a/packages/react-native-renderer/src/ReactFiberConfigNative.js +++ b/packages/react-native-renderer/src/ReactFiberConfigNative.js @@ -373,7 +373,6 @@ export function shouldAttemptEagerTransition(): boolean { // ------------------- export const supportsMutation = true; -export const supportsViewTransition = false; export function appendChild( parentInstance: Instance, diff --git a/packages/react-test-renderer/src/ReactFiberConfigTestHost.js b/packages/react-test-renderer/src/ReactFiberConfigTestHost.js index e750f7a2b0a7..417745828d60 100644 --- a/packages/react-test-renderer/src/ReactFiberConfigTestHost.js +++ b/packages/react-test-renderer/src/ReactFiberConfigTestHost.js @@ -274,7 +274,6 @@ export const noTimeout: -1 = -1; // ------------------- export const supportsMutation = true; -export const supportsViewTransition = false; export function commitUpdate( instance: Instance,