diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 5aa81f6a21ac..ba6ea2a09f63 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -3970,7 +3970,7 @@ PODS: - RNWorklets - SocketRocket - Yoga - - RNScreens (4.15.4): + - RNScreens (4.25.0-beta.1): - boost - DoubleConversion - fast_float @@ -3997,10 +3997,10 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - RNScreens/common (= 4.15.4) + - RNScreens/common (= 4.25.0-beta.1) - SocketRocket - Yoga - - RNScreens/common (4.15.4): + - RNScreens/common (4.25.0-beta.1): - boost - DoubleConversion - fast_float @@ -4807,7 +4807,7 @@ SPEC CHECKSUMS: GTMAppAuth: f69bd07d68cd3b766125f7e072c45d7340dea0de GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6 GzipSwift: 893f3e48e597a1a4f62fafcb6514220fcf8287fa - hermes-engine: b39ec807040f5a775de027a4a9647c0f4222c6ef + hermes-engine: 164a2a741070fc695f1930a2d7a5b885a98c32ce libavif: 84bbb62fb232c3018d6f1bab79beea87e35de7b7 libdav1d: 23581a4d8ec811ff171ed5e2e05cd27bad64c39f libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8 @@ -4934,7 +4934,7 @@ SPEC CHECKSUMS: RNPermissions: 518f0a0c439acc74e2b9937e0e7d29e5031ae949 RNReactNativeHapticFeedback: 5f1542065f0b24c9252bd8cf3e83bc9c548182e4 RNReanimated: fbcb7fd8da5b0b088401542c58fb5d266388f1cf - RNScreens: 4f2aed147a2775017923789d8a0a2d377712ec2e + RNScreens: f157fcda842dd004cbb55e536d592f20e805fb0b RNSentry: f73f4da92e4c20841ab16e1fa22fc289bc2f9f4e RNShare: 1c1fde2c4134b9cf220ffebbd6df9c414036d382 RNSVG: 74eb75bd44d62ba9969941e80d8f9832971c681f diff --git a/package-lock.json b/package-lock.json index 901287bc1b8c..912667e0a364 100644 --- a/package-lock.json +++ b/package-lock.json @@ -125,7 +125,7 @@ "react-native-reanimated": "4.2.1", "react-native-render-html": "6.3.1", "react-native-safe-area-context": "5.6.2", - "react-native-screens": "4.15.4", + "react-native-screens": "4.25.0-beta.1", "react-native-share": "11.0.2", "react-native-svg": "15.12.1", "react-native-tab-view": "^4.3.0", @@ -7562,9 +7562,9 @@ } }, "node_modules/@firebase/app": { - "version": "0.14.10", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.14.10.tgz", - "integrity": "sha512-PlPhdtjgWUra+LImQTnXOUqUa/jcufZhizdR93ZjlQSS3ahCtDTG6pJw7j0OwFal18DQjICXfeVNsUUrcNisfA==", + "version": "0.14.11", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.14.11.tgz", + "integrity": "sha512-yxADFW35LYkP8oSGobGsYIrI42I+GPCvKTNHx4meT9Yq3C950IVz1eANoBk822I9tbKv1wyv9P4Bv1G5TpucFw==", "license": "Apache-2.0", "peer": true, "dependencies": { @@ -34840,18 +34840,17 @@ } }, "node_modules/react-native-screens": { - "version": "4.15.4", - "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-4.15.4.tgz", - "integrity": "sha512-aKHPDScUbpQiZEG9eZssHdG5jEQs4yiJ8eMx6g81Ex/xU7DZkv3911enzdCb+v4eJE79X8waizY0ZhauZJQmrw==", + "version": "4.25.0-beta.1", + "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-4.25.0-beta.1.tgz", + "integrity": "sha512-UBJmva20ew9Z+BC/uZe5eAu8ccmhiRBH/YscWXR1DNSlRS3vxvt3n3UH3zn3t/jL0MW6gVvrIwIxVmjaA+C/lg==", "license": "MIT", "dependencies": { "react-freeze": "^1.0.0", - "react-native-is-edge-to-edge": "^1.2.1", "warn-once": "^0.1.0" }, "peerDependencies": { "react": "*", - "react-native": "*" + "react-native": ">=0.82.0" } }, "node_modules/react-native-share": { diff --git a/package.json b/package.json index 99c55a8fd6b4..3ab63c4bf872 100644 --- a/package.json +++ b/package.json @@ -189,7 +189,7 @@ "react-native-reanimated": "4.2.1", "react-native-render-html": "6.3.1", "react-native-safe-area-context": "5.6.2", - "react-native-screens": "4.15.4", + "react-native-screens": "4.25.0-beta.1", "react-native-share": "11.0.2", "react-native-svg": "15.12.1", "react-native-tab-view": "^4.3.0", @@ -361,6 +361,7 @@ "webpack-merge": "^5.8.0" }, "overrides": { + "react-native-screens": "4.25.0-beta.1", "babel-plugin-react-compiler": "0.0.0-experimental-a1856f3-20260422", "braces": "3.0.3", "yargs": "17.7.2", diff --git a/patches/react-native-screens/details.md b/patches/react-native-screens/details.md index e9986d919fec..f893f7dc1912 100644 --- a/patches/react-native-screens/details.md +++ b/patches/react-native-screens/details.md @@ -1,8 +1,8 @@ # `react-native-screens` patches -### [react-native-screens+4.15.4+001+fix-lifecycle-events-in-fragment-host.patch](react-native-screens+4.15.4+001+fix-lifecycle-events-in-fragment-host.patch) +### [react-native-screens+4.25.0-beta.1.patch](react-native-screens+4.25.0-beta.1.patch) -- Reason: In HybridApp, React Native is hosted inside a `ReactNativeFragment`, which causes `ScreenFragment.dispatchViewAnimationEvent()` to silently dismiss lifecycle events for root screen fragments. This prevents `transitionStart`/`transitionEnd` from being emitted, which breaks `TransitionTracker` (`src/libs/Navigation/TransitionTracker.ts`). The fix allows event dispatch when the parent fragment is not a `ScreenFragment`. -- Upstream PR/issue: https://github.com/software-mansion/react-native-screens/pull/3854 — once merged and released, bump the version and remove this patch. +- Reason: `SafeAreaView.web.tsx` only has a `default` export, but `safe-area/index.ts` re-exports it as a named export (`export { SafeAreaView } from './SafeAreaView'`). Webpack resolves the `.web` variant for web builds, causing a `ModuleDependencyWarning` that fails the Storybook smoke test. The fix adds a named export alongside the existing default export. +- Upstream PR/issue: https://github.com/software-mansion/react-native-screens/pull/3956 — once merged and released, bump the version and remove this patch. - E/App issue: 🛑 -- PR Introducing Patch: https://github.com/Expensify/App/pull/85759 +- PR Introducing Patch: https://github.com/Expensify/App/pull/89199 diff --git a/patches/react-native-screens/react-native-screens+4.15.4+001+fix-lifecycle-events-in-fragment-host.patch b/patches/react-native-screens/react-native-screens+4.15.4+001+fix-lifecycle-events-in-fragment-host.patch deleted file mode 100644 index 7060a0baaa35..000000000000 --- a/patches/react-native-screens/react-native-screens+4.15.4+001+fix-lifecycle-events-in-fragment-host.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/node_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ScreenFragment.kt b/node_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ScreenFragment.kt -index 65c6e30..3b9f2e2 100644 ---- a/node_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ScreenFragment.kt -+++ b/node_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ScreenFragment.kt -@@ -293,7 +293,7 @@ open class ScreenFragment : - // check for `isTransitioning` should be enough since the child's animation should take only - // 20ms due to always being `StackAnimation.NONE` when nested stack being pushed - val parent = parentFragment -- if (parent == null || (parent is ScreenFragment && !parent.isTransitioning)) { -+ if (parent == null || parent !is ScreenFragment || (parent is ScreenFragment && !parent.isTransitioning)) { - // onViewAnimationStart/End is triggered from View#onAnimationStart/End method of the fragment's root - // view. We override an appropriate method of the StackFragment's - // root view in order to achieve this. diff --git a/patches/react-native-screens/react-native-screens+4.25.0-beta.1.patch b/patches/react-native-screens/react-native-screens+4.25.0-beta.1.patch new file mode 100644 index 000000000000..4a2df76295e1 --- /dev/null +++ b/patches/react-native-screens/react-native-screens+4.25.0-beta.1.patch @@ -0,0 +1,23 @@ +diff --git a/node_modules/react-native-screens/lib/module/components/safe-area/SafeAreaView.web.js b/node_modules/react-native-screens/lib/module/components/safe-area/SafeAreaView.web.js +index 398afe2..60f14e2 100644 +--- a/node_modules/react-native-screens/lib/module/components/safe-area/SafeAreaView.web.js ++++ b/node_modules/react-native-screens/lib/module/components/safe-area/SafeAreaView.web.js +@@ -1,4 +1,5 @@ + import { View } from 'react-native'; + const SafeAreaView = View; ++export { SafeAreaView }; + export default SafeAreaView; + //# sourceMappingURL=SafeAreaView.web.js.map +diff --git a/node_modules/react-native-screens/src/components/safe-area/SafeAreaView.web.tsx b/node_modules/react-native-screens/src/components/safe-area/SafeAreaView.web.tsx +index aff03a5..3398bef 100644 +--- a/node_modules/react-native-screens/src/components/safe-area/SafeAreaView.web.tsx ++++ b/node_modules/react-native-screens/src/components/safe-area/SafeAreaView.web.tsx +@@ -1,5 +1,8 @@ ++// Implementation adapted from `react-native-safe-area-context`: ++// https://github.com/AppAndFlow/react-native-safe-area-context/blob/v5.6.1/src/SafeAreaView.tsx + import { View } from 'react-native'; + + const SafeAreaView = View; + ++export { SafeAreaView }; + export default SafeAreaView;