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." }