react-native-screens 3.35.0-rc.1 → 3.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/android/CMakeLists.txt +28 -19
- package/android/build.gradle +18 -2
- package/android/src/fabric/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +4 -3
- package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +18 -34
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +9 -3
- package/android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.kt +2 -1
- package/android/src/main/java/com/swmansion/rnscreens/ScreenWindowTraits.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/events/HeaderHeightChangeEvent.kt +3 -3
- package/android/src/main/java/com/swmansion/rnscreens/ext/ViewExt.kt +56 -0
- package/android/src/main/jni/CMakeLists.txt +28 -19
- package/android/src/main/res/base/anim/rns_ios_from_left_background_close.xml +5 -0
- package/android/src/main/res/base/anim/{rns_slide_out_to_left_ios.xml → rns_ios_from_left_background_open.xml} +1 -1
- package/android/src/main/res/base/anim/rns_ios_from_left_foreground_close.xml +6 -0
- package/android/src/main/res/base/anim/rns_ios_from_left_foreground_open.xml +6 -0
- package/android/src/main/res/base/anim/rns_ios_from_right_background_open.xml +5 -0
- package/android/src/paper/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +1 -1
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenComponentDescriptor.h +5 -99
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.cpp +101 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.h +2 -0
- package/ios/RNSConvert.h +13 -4
- package/ios/RNSConvert.mm +54 -29
- package/ios/RNSEnums.h +46 -0
- package/ios/RNSFullWindowOverlay.mm +6 -0
- package/ios/RNSModalScreen.mm +7 -0
- package/ios/RNSScreen.h +14 -0
- package/ios/RNSScreen.mm +22 -4
- package/ios/RNSScreenContainer.mm +6 -0
- package/ios/RNSScreenNavigationContainer.mm +7 -0
- package/ios/RNSScreenStack.mm +53 -7
- package/ios/RNSScreenStackHeaderConfig.h +1 -1
- package/ios/RNSScreenStackHeaderConfig.mm +54 -29
- package/ios/RNSScreenStackHeaderSubview.mm +30 -3
- package/ios/RNSSearchBar.mm +7 -0
- package/lib/commonjs/TransitionProgressContext.js +1 -0
- package/lib/commonjs/TransitionProgressContext.js.map +1 -1
- package/lib/commonjs/components/FullWindowOverlay.js +8 -5
- package/lib/commonjs/components/FullWindowOverlay.js.map +1 -1
- package/lib/commonjs/components/Screen.js +9 -0
- package/lib/commonjs/components/Screen.js.map +1 -1
- package/lib/commonjs/components/Screen.web.js +2 -0
- package/lib/commonjs/components/Screen.web.js.map +1 -1
- package/lib/commonjs/components/ScreenContainer.js +1 -0
- package/lib/commonjs/components/ScreenContainer.js.map +1 -1
- package/lib/commonjs/components/ScreenStack.js +1 -0
- package/lib/commonjs/components/ScreenStack.js.map +1 -1
- package/lib/commonjs/components/ScreenStackHeaderConfig.js +1 -0
- package/lib/commonjs/components/ScreenStackHeaderConfig.js.map +1 -1
- package/lib/commonjs/components/SearchBar.js +1 -0
- package/lib/commonjs/components/SearchBar.js.map +1 -1
- package/lib/commonjs/core.js +1 -0
- package/lib/commonjs/core.js.map +1 -1
- package/lib/commonjs/fabric/FullWindowOverlayNativeComponent.js +1 -0
- package/lib/commonjs/fabric/FullWindowOverlayNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/ModalScreenNativeComponent.js +1 -0
- package/lib/commonjs/fabric/ModalScreenNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/NativeScreensModule.js +2 -1
- package/lib/commonjs/fabric/NativeScreensModule.js.map +1 -1
- package/lib/commonjs/fabric/ScreenContainerNativeComponent.js +1 -0
- package/lib/commonjs/fabric/ScreenContainerNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/ScreenNativeComponent.js +1 -0
- package/lib/commonjs/fabric/ScreenNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/ScreenNavigationContainerNativeComponent.js +1 -0
- package/lib/commonjs/fabric/ScreenNavigationContainerNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js +1 -0
- package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/ScreenStackHeaderSubviewNativeComponent.js +1 -0
- package/lib/commonjs/fabric/ScreenStackHeaderSubviewNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/ScreenStackNativeComponent.js +1 -0
- package/lib/commonjs/fabric/ScreenStackNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/SearchBarNativeComponent.js +2 -2
- package/lib/commonjs/fabric/SearchBarNativeComponent.js.map +1 -1
- package/lib/commonjs/native-stack/contexts/GHContext.js +1 -0
- package/lib/commonjs/native-stack/contexts/GHContext.js.map +1 -1
- package/lib/module/TransitionProgressContext.js +2 -0
- package/lib/module/TransitionProgressContext.js.map +1 -1
- package/lib/module/components/FullWindowOverlay.js +9 -6
- package/lib/module/components/FullWindowOverlay.js.map +1 -1
- package/lib/module/components/Screen.js +10 -0
- package/lib/module/components/Screen.js.map +1 -1
- package/lib/module/components/Screen.web.js +3 -0
- package/lib/module/components/Screen.web.js.map +1 -1
- package/lib/module/components/ScreenContainer.js +2 -0
- package/lib/module/components/ScreenContainer.js.map +1 -1
- package/lib/module/components/ScreenStack.js +2 -0
- package/lib/module/components/ScreenStack.js.map +1 -1
- package/lib/module/components/ScreenStackHeaderConfig.js +2 -0
- package/lib/module/components/ScreenStackHeaderConfig.js.map +1 -1
- package/lib/module/components/SearchBar.js +2 -0
- package/lib/module/components/SearchBar.js.map +1 -1
- package/lib/module/core.js +2 -0
- package/lib/module/core.js.map +1 -1
- package/lib/module/fabric/FullWindowOverlayNativeComponent.js +2 -0
- package/lib/module/fabric/FullWindowOverlayNativeComponent.js.map +1 -1
- package/lib/module/fabric/ModalScreenNativeComponent.js +2 -0
- package/lib/module/fabric/ModalScreenNativeComponent.js.map +1 -1
- package/lib/module/fabric/NativeScreensModule.js +2 -1
- package/lib/module/fabric/NativeScreensModule.js.map +1 -1
- package/lib/module/fabric/ScreenContainerNativeComponent.js +2 -0
- package/lib/module/fabric/ScreenContainerNativeComponent.js.map +1 -1
- package/lib/module/fabric/ScreenNativeComponent.js +2 -0
- package/lib/module/fabric/ScreenNativeComponent.js.map +1 -1
- package/lib/module/fabric/ScreenNavigationContainerNativeComponent.js +2 -0
- package/lib/module/fabric/ScreenNavigationContainerNativeComponent.js.map +1 -1
- package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js +2 -0
- package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -1
- package/lib/module/fabric/ScreenStackHeaderSubviewNativeComponent.js +2 -0
- package/lib/module/fabric/ScreenStackHeaderSubviewNativeComponent.js.map +1 -1
- package/lib/module/fabric/ScreenStackNativeComponent.js +2 -0
- package/lib/module/fabric/ScreenStackNativeComponent.js.map +1 -1
- package/lib/module/fabric/SearchBarNativeComponent.js +2 -0
- package/lib/module/fabric/SearchBarNativeComponent.js.map +1 -1
- package/lib/module/native-stack/contexts/GHContext.js +2 -0
- package/lib/module/native-stack/contexts/GHContext.js.map +1 -1
- package/lib/typescript/TransitionProgressContext.d.ts.map +1 -1
- package/lib/typescript/components/FullWindowOverlay.d.ts.map +1 -1
- package/lib/typescript/components/Screen.d.ts.map +1 -1
- package/lib/typescript/components/Screen.web.d.ts.map +1 -1
- package/lib/typescript/components/ScreenContainer.d.ts.map +1 -1
- package/lib/typescript/components/ScreenStack.d.ts.map +1 -1
- package/lib/typescript/components/ScreenStackHeaderConfig.d.ts.map +1 -1
- package/lib/typescript/components/SearchBar.d.ts.map +1 -1
- package/lib/typescript/core.d.ts.map +1 -1
- package/lib/typescript/fabric/FullWindowOverlayNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/NativeScreensModule.d.ts.map +1 -1
- package/lib/typescript/fabric/ScreenContainerNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/ScreenNativeComponent.d.ts +1 -1
- package/lib/typescript/fabric/ScreenNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/ScreenNavigationContainerNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts +2 -2
- package/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/ScreenStackNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/SearchBarNativeComponent.d.ts.map +1 -1
- package/lib/typescript/native-stack/contexts/GHContext.d.ts.map +1 -1
- package/lib/typescript/native-stack/types.d.ts +3 -1
- package/lib/typescript/native-stack/types.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +5 -3
- package/lib/typescript/types.d.ts.map +1 -1
- package/native-stack/README.md +3 -1
- package/package.json +1 -1
- package/src/TransitionProgressContext.tsx +2 -0
- package/src/components/FullWindowOverlay.tsx +10 -2
- package/src/components/Screen.tsx +8 -0
- package/src/components/Screen.web.tsx +3 -0
- package/src/components/ScreenContainer.tsx +2 -0
- package/src/components/ScreenStack.tsx +2 -0
- package/src/components/ScreenStackHeaderConfig.tsx +2 -0
- package/src/components/SearchBar.tsx +2 -0
- package/src/core.ts +2 -0
- package/src/fabric/FullWindowOverlayNativeComponent.ts +2 -0
- package/src/fabric/ModalScreenNativeComponent.ts +2 -0
- package/src/fabric/NativeScreensModule.ts +2 -0
- package/src/fabric/ScreenContainerNativeComponent.ts +2 -0
- package/src/fabric/ScreenNativeComponent.ts +5 -1
- package/src/fabric/ScreenNavigationContainerNativeComponent.ts +2 -0
- package/src/fabric/ScreenStackHeaderConfigNativeComponent.ts +4 -1
- package/src/fabric/ScreenStackHeaderSubviewNativeComponent.ts +2 -0
- package/src/fabric/ScreenStackNativeComponent.ts +2 -0
- package/src/fabric/SearchBarNativeComponent.ts +2 -0
- package/src/native-stack/contexts/GHContext.tsx +2 -0
- package/src/native-stack/types.tsx +3 -1
- package/src/types.tsx +7 -2
- package/windows/RNScreens/Screen.h +3 -1
- /package/android/src/main/res/base/anim/{rns_slide_in_from_left_ios.xml → rns_ios_from_right_background_close.xml} +0 -0
- /package/android/src/main/res/base/anim/{rns_slide_out_to_right_ios.xml → rns_ios_from_right_foreground_close.xml} +0 -0
- /package/android/src/main/res/base/anim/{rns_slide_in_from_right_ios.xml → rns_ios_from_right_foreground_open.xml} +0 -0
package/README.md
CHANGED
|
@@ -188,7 +188,7 @@ To take advantage of the native stack navigator primitive for React Navigation t
|
|
|
188
188
|
|
|
189
189
|
## `FullWindowOverlay`
|
|
190
190
|
|
|
191
|
-
Native `iOS` component for rendering views straight under the `Window`. Based on `RCTPerfMonitor`. You should treat it as a wrapper, providing full-screen, transparent view which receives no props and should ideally render one child `View`, being the root of its view hierarchy. For the example usage, see https://github.com/software-mansion/react-native-screens/blob/main/
|
|
191
|
+
Native `iOS` component for rendering views straight under the `Window`. Based on `RCTPerfMonitor`. You should treat it as a wrapper, providing full-screen, transparent view which receives no props and should ideally render one child `View`, being the root of its view hierarchy. For the example usage, see https://github.com/software-mansion/react-native-screens/blob/main/apps/src/tests/Test1096.tsx
|
|
192
192
|
|
|
193
193
|
## Interop with [react-native-navigation](https://github.com/wix/react-native-navigation)
|
|
194
194
|
|
package/android/CMakeLists.txt
CHANGED
|
@@ -41,28 +41,37 @@ find_package(ReactAndroid REQUIRED CONFIG)
|
|
|
41
41
|
if(${RNS_NEW_ARCH_ENABLED})
|
|
42
42
|
find_package(fbjni REQUIRED CONFIG)
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
rnscreens
|
|
44
|
+
if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 76)
|
|
45
|
+
target_link_libraries(rnscreens
|
|
46
|
+
ReactAndroid::reactnative
|
|
46
47
|
ReactAndroid::jsi
|
|
47
|
-
ReactAndroid::react_nativemodule_core
|
|
48
|
-
ReactAndroid::react_utils
|
|
49
|
-
ReactAndroid::reactnativejni
|
|
50
|
-
ReactAndroid::fabricjni
|
|
51
|
-
ReactAndroid::react_debug
|
|
52
|
-
ReactAndroid::react_render_core
|
|
53
|
-
ReactAndroid::runtimeexecutor
|
|
54
|
-
ReactAndroid::react_render_graphics
|
|
55
|
-
ReactAndroid::rrc_view
|
|
56
|
-
ReactAndroid::yoga
|
|
57
|
-
ReactAndroid::rrc_text
|
|
58
|
-
ReactAndroid::glog
|
|
59
|
-
ReactAndroid::react_render_componentregistry
|
|
60
|
-
ReactAndroid::react_render_consistency
|
|
61
|
-
ReactAndroid::react_performance_timeline
|
|
62
|
-
ReactAndroid::react_render_observers_events
|
|
63
48
|
fbjni::fbjni
|
|
64
49
|
android
|
|
65
|
-
|
|
50
|
+
)
|
|
51
|
+
else()
|
|
52
|
+
target_link_libraries(
|
|
53
|
+
rnscreens
|
|
54
|
+
ReactAndroid::jsi
|
|
55
|
+
ReactAndroid::react_nativemodule_core
|
|
56
|
+
ReactAndroid::react_utils
|
|
57
|
+
ReactAndroid::reactnativejni
|
|
58
|
+
ReactAndroid::fabricjni
|
|
59
|
+
ReactAndroid::react_debug
|
|
60
|
+
ReactAndroid::react_render_core
|
|
61
|
+
ReactAndroid::runtimeexecutor
|
|
62
|
+
ReactAndroid::react_render_graphics
|
|
63
|
+
ReactAndroid::rrc_view
|
|
64
|
+
ReactAndroid::yoga
|
|
65
|
+
ReactAndroid::rrc_text
|
|
66
|
+
ReactAndroid::glog
|
|
67
|
+
ReactAndroid::react_render_componentregistry
|
|
68
|
+
ReactAndroid::react_render_consistency
|
|
69
|
+
ReactAndroid::react_performance_timeline
|
|
70
|
+
ReactAndroid::react_render_observers_events
|
|
71
|
+
fbjni::fbjni
|
|
72
|
+
android
|
|
73
|
+
)
|
|
74
|
+
endif()
|
|
66
75
|
else()
|
|
67
76
|
target_link_libraries(rnscreens
|
|
68
77
|
ReactAndroid::jsi
|
package/android/build.gradle
CHANGED
|
@@ -148,10 +148,26 @@ android {
|
|
|
148
148
|
repositories {
|
|
149
149
|
maven {
|
|
150
150
|
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
|
|
151
|
-
|
|
151
|
+
|
|
152
|
+
// First look for the standard location of react-native, as in RN Hello World template
|
|
152
153
|
// https://github.com/facebook/react-native/blob/1e8f3b11027fe0a7514b4fc97d0798d3c64bc895/local-cli/templates/HelloWorld/android/build.gradle#L21
|
|
153
|
-
|
|
154
|
+
// TODO(kkafar): Note, that in latest template app https://github.com/react-native-community/template/blob/0f4745b7a9d84232aeedec2def8d75ab9b050d11/template/android/build.gradle
|
|
155
|
+
// this is not specified at all.
|
|
156
|
+
File standardRnAndroidDirLocation = file("$rootDir/../node_modules/react-native/android")
|
|
157
|
+
if (standardRnAndroidDirLocation.exists()) {
|
|
158
|
+
url standardRnAndroidDirLocation
|
|
159
|
+
} else {
|
|
160
|
+
// We're in non standard setup - try to use node resolver to locate the react-native package.
|
|
161
|
+
File reactNativePackage = file(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim())
|
|
162
|
+
def rnAndroidDirLocation = "$reactNativePackage.parentFile/android"
|
|
163
|
+
if (reactNativePackage.exists()) {
|
|
164
|
+
url rnAndroidDirLocation
|
|
165
|
+
} else {
|
|
166
|
+
println "[RNScreens] Failed to resolve react-native directory. Attempted locations: ${standardRnAndroidDirLocation}, ${rnAndroidDirLocation}"
|
|
167
|
+
}
|
|
168
|
+
}
|
|
154
169
|
}
|
|
170
|
+
|
|
155
171
|
mavenCentral()
|
|
156
172
|
mavenLocal()
|
|
157
173
|
google()
|
|
@@ -24,7 +24,7 @@ abstract class FabricEnabledViewGroup(
|
|
|
24
24
|
protected fun updateScreenSizeFabric(
|
|
25
25
|
width: Int,
|
|
26
26
|
height: Int,
|
|
27
|
-
headerHeight:
|
|
27
|
+
headerHeight: Int,
|
|
28
28
|
) {
|
|
29
29
|
updateState(width, height, headerHeight)
|
|
30
30
|
}
|
|
@@ -33,10 +33,11 @@ abstract class FabricEnabledViewGroup(
|
|
|
33
33
|
fun updateState(
|
|
34
34
|
width: Int,
|
|
35
35
|
height: Int,
|
|
36
|
-
headerHeight:
|
|
36
|
+
headerHeight: Int,
|
|
37
37
|
) {
|
|
38
38
|
val realWidth: Float = PixelUtil.toDIPFromPixel(width.toFloat())
|
|
39
39
|
val realHeight: Float = PixelUtil.toDIPFromPixel(height.toFloat())
|
|
40
|
+
val realHeaderHeight: Float = PixelUtil.toDIPFromPixel(headerHeight.toFloat())
|
|
40
41
|
|
|
41
42
|
// Check incoming state values. If they're already the correct value, return early to prevent
|
|
42
43
|
// infinite UpdateState/SetState loop.
|
|
@@ -54,7 +55,7 @@ abstract class FabricEnabledViewGroup(
|
|
|
54
55
|
putDouble("frameWidth", realWidth.toDouble())
|
|
55
56
|
putDouble("frameHeight", realHeight.toDouble())
|
|
56
57
|
putDouble("contentOffsetX", 0.0)
|
|
57
|
-
putDouble("contentOffsetY",
|
|
58
|
+
putDouble("contentOffsetY", realHeaderHeight.toDouble())
|
|
58
59
|
}
|
|
59
60
|
mStateWrapper?.updateState(map)
|
|
60
61
|
}
|
|
@@ -5,19 +5,20 @@ import android.content.pm.ActivityInfo
|
|
|
5
5
|
import android.graphics.Paint
|
|
6
6
|
import android.os.Parcelable
|
|
7
7
|
import android.util.SparseArray
|
|
8
|
-
import android.util.TypedValue
|
|
9
8
|
import android.view.View
|
|
10
9
|
import android.view.ViewGroup
|
|
11
10
|
import android.view.WindowManager
|
|
12
11
|
import android.webkit.WebView
|
|
12
|
+
import android.widget.ImageView
|
|
13
13
|
import androidx.core.view.children
|
|
14
14
|
import androidx.fragment.app.Fragment
|
|
15
|
+
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
|
15
16
|
import com.facebook.react.bridge.GuardedRunnable
|
|
16
17
|
import com.facebook.react.bridge.ReactContext
|
|
17
|
-
import com.facebook.react.uimanager.PixelUtil
|
|
18
18
|
import com.facebook.react.uimanager.UIManagerHelper
|
|
19
19
|
import com.facebook.react.uimanager.UIManagerModule
|
|
20
20
|
import com.swmansion.rnscreens.events.HeaderHeightChangeEvent
|
|
21
|
+
import com.swmansion.rnscreens.ext.isInsideScrollViewWithRemoveClippedSubviews
|
|
21
22
|
|
|
22
23
|
@SuppressLint("ViewConstructor") // Only we construct this view, it is never inflated.
|
|
23
24
|
class Screen(
|
|
@@ -75,16 +76,13 @@ class Screen(
|
|
|
75
76
|
val width = r - l
|
|
76
77
|
val height = b - t
|
|
77
78
|
|
|
78
|
-
val headerHeight = calculateHeaderHeight()
|
|
79
|
-
val totalHeight =
|
|
80
|
-
headerHeight.first + headerHeight.second // action bar height + status bar height
|
|
81
79
|
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
|
82
|
-
updateScreenSizeFabric(width, height,
|
|
80
|
+
updateScreenSizeFabric(width, height, t)
|
|
83
81
|
} else {
|
|
84
82
|
updateScreenSizePaper(width, height)
|
|
85
83
|
}
|
|
86
84
|
|
|
87
|
-
notifyHeaderHeightChange(
|
|
85
|
+
notifyHeaderHeightChange(t)
|
|
88
86
|
}
|
|
89
87
|
}
|
|
90
88
|
|
|
@@ -295,7 +293,7 @@ class Screen(
|
|
|
295
293
|
parent?.let {
|
|
296
294
|
for (i in 0 until it.childCount) {
|
|
297
295
|
val child = it.getChildAt(i)
|
|
298
|
-
if (child
|
|
296
|
+
if (parent is SwipeRefreshLayout && child is ImageView) {
|
|
299
297
|
// SwipeRefreshLayout class which has CircleImageView as a child,
|
|
300
298
|
// does not handle `startViewTransition` properly.
|
|
301
299
|
// It has a custom `getChildDrawingOrder` method which returns
|
|
@@ -312,38 +310,22 @@ class Screen(
|
|
|
312
310
|
startTransitionRecursive(child.toolbar)
|
|
313
311
|
}
|
|
314
312
|
if (child is ViewGroup) {
|
|
313
|
+
// The children are miscounted when there's a FlatList with
|
|
314
|
+
// removeClippedSubviews set to true (default).
|
|
315
|
+
// We add a simple view for each item in the list to make it work as expected.
|
|
316
|
+
// See https://github.com/software-mansion/react-native-screens/pull/2383
|
|
317
|
+
if (child.isInsideScrollViewWithRemoveClippedSubviews()) {
|
|
318
|
+
for (j in 0 until child.childCount) {
|
|
319
|
+
child.addView(View(context))
|
|
320
|
+
}
|
|
321
|
+
}
|
|
315
322
|
startTransitionRecursive(child)
|
|
316
323
|
}
|
|
317
324
|
}
|
|
318
325
|
}
|
|
319
326
|
}
|
|
320
327
|
|
|
321
|
-
private fun
|
|
322
|
-
val actionBarTv = TypedValue()
|
|
323
|
-
val resolvedActionBarSize =
|
|
324
|
-
context.theme.resolveAttribute(android.R.attr.actionBarSize, actionBarTv, true)
|
|
325
|
-
|
|
326
|
-
// Check if it's possible to get an attribute from theme context and assign a value from it.
|
|
327
|
-
// Otherwise, the default value will be returned.
|
|
328
|
-
val actionBarHeight =
|
|
329
|
-
TypedValue
|
|
330
|
-
.complexToDimensionPixelSize(actionBarTv.data, resources.displayMetrics)
|
|
331
|
-
.takeIf { resolvedActionBarSize && headerConfig?.isHeaderHidden != true && headerConfig?.isHeaderTranslucent != true }
|
|
332
|
-
?.let { PixelUtil.toDIPFromPixel(it.toFloat()).toDouble() } ?: 0.0
|
|
333
|
-
|
|
334
|
-
val statusBarHeight =
|
|
335
|
-
context.resources
|
|
336
|
-
.getIdentifier("status_bar_height", "dimen", "android")
|
|
337
|
-
// Count only status bar when action bar is visible and status bar is not hidden
|
|
338
|
-
.takeIf { it > 0 && isStatusBarHidden != true && actionBarHeight > 0 }
|
|
339
|
-
?.let { (context.resources::getDimensionPixelSize)(it) }
|
|
340
|
-
?.let { PixelUtil.toDIPFromPixel(it.toFloat()).toDouble() }
|
|
341
|
-
?: 0.0
|
|
342
|
-
|
|
343
|
-
return actionBarHeight to statusBarHeight
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
private fun notifyHeaderHeightChange(headerHeight: Double) {
|
|
328
|
+
private fun notifyHeaderHeightChange(headerHeight: Int) {
|
|
347
329
|
val screenContext = context as ReactContext
|
|
348
330
|
val surfaceId = UIManagerHelper.getSurfaceId(screenContext)
|
|
349
331
|
UIManagerHelper
|
|
@@ -366,6 +348,8 @@ class Screen(
|
|
|
366
348
|
SLIDE_FROM_LEFT,
|
|
367
349
|
FADE_FROM_BOTTOM,
|
|
368
350
|
IOS,
|
|
351
|
+
IOS_FROM_RIGHT,
|
|
352
|
+
IOS_FROM_LEFT,
|
|
369
353
|
}
|
|
370
354
|
|
|
371
355
|
enum class ReplaceAnimation {
|
|
@@ -160,7 +160,9 @@ class ScreenStack(
|
|
|
160
160
|
R.anim.rns_no_animation_medium,
|
|
161
161
|
)
|
|
162
162
|
StackAnimation.FADE_FROM_BOTTOM -> it.setCustomAnimations(R.anim.rns_fade_from_bottom, R.anim.rns_no_animation_350)
|
|
163
|
-
StackAnimation.IOS -> it.setCustomAnimations(R.anim.
|
|
163
|
+
StackAnimation.IOS -> it.setCustomAnimations(R.anim.rns_ios_from_right_foreground_open, R.anim.rns_ios_from_right_background_open)
|
|
164
|
+
StackAnimation.IOS_FROM_RIGHT -> it.setCustomAnimations(R.anim.rns_ios_from_right_foreground_open, R.anim.rns_ios_from_right_background_open)
|
|
165
|
+
StackAnimation.IOS_FROM_LEFT -> it.setCustomAnimations(R.anim.rns_ios_from_left_foreground_open, R.anim.rns_ios_from_left_background_open)
|
|
164
166
|
}
|
|
165
167
|
} else {
|
|
166
168
|
when (stackAnimation) {
|
|
@@ -183,7 +185,9 @@ class ScreenStack(
|
|
|
183
185
|
R.anim.rns_slide_out_to_bottom,
|
|
184
186
|
)
|
|
185
187
|
StackAnimation.FADE_FROM_BOTTOM -> it.setCustomAnimations(R.anim.rns_no_animation_250, R.anim.rns_fade_to_bottom)
|
|
186
|
-
StackAnimation.IOS -> it.setCustomAnimations(R.anim.
|
|
188
|
+
StackAnimation.IOS -> it.setCustomAnimations(R.anim.rns_ios_from_right_foreground_close, R.anim.rns_ios_from_right_background_close)
|
|
189
|
+
StackAnimation.IOS_FROM_RIGHT -> it.setCustomAnimations(R.anim.rns_ios_from_right_background_close, R.anim.rns_ios_from_right_foreground_close)
|
|
190
|
+
StackAnimation.IOS_FROM_LEFT -> it.setCustomAnimations(R.anim.rns_ios_from_left_background_close, R.anim.rns_ios_from_left_foreground_close)
|
|
187
191
|
}
|
|
188
192
|
}
|
|
189
193
|
}
|
|
@@ -370,6 +374,8 @@ class ScreenStack(
|
|
|
370
374
|
Build.VERSION.SDK_INT >= 33 ||
|
|
371
375
|
fragmentWrapper.screen.stackAnimation === StackAnimation.SLIDE_FROM_BOTTOM ||
|
|
372
376
|
fragmentWrapper.screen.stackAnimation === StackAnimation.FADE_FROM_BOTTOM ||
|
|
373
|
-
fragmentWrapper.screen.stackAnimation === StackAnimation.IOS
|
|
377
|
+
fragmentWrapper.screen.stackAnimation === StackAnimation.IOS ||
|
|
378
|
+
fragmentWrapper.screen.stackAnimation === StackAnimation.IOS_FROM_RIGHT ||
|
|
379
|
+
fragmentWrapper.screen.stackAnimation === StackAnimation.IOS_FROM_LEFT
|
|
374
380
|
}
|
|
375
381
|
}
|
|
@@ -48,7 +48,6 @@ open class ScreenViewManager :
|
|
|
48
48
|
stateWrapper: StateWrapper?,
|
|
49
49
|
): Any? {
|
|
50
50
|
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
|
51
|
-
// fabricViewStateManager should never be null in Fabric. The null check is only for Paper's empty impl.
|
|
52
51
|
view.setStateWrapper(stateWrapper)
|
|
53
52
|
}
|
|
54
53
|
return super.updateState(view, props, stateWrapper)
|
|
@@ -104,6 +103,8 @@ open class ScreenViewManager :
|
|
|
104
103
|
"slide_from_bottom" -> Screen.StackAnimation.SLIDE_FROM_BOTTOM
|
|
105
104
|
"fade_from_bottom" -> Screen.StackAnimation.FADE_FROM_BOTTOM
|
|
106
105
|
"ios" -> Screen.StackAnimation.IOS
|
|
106
|
+
"ios_from_right" -> Screen.StackAnimation.IOS_FROM_RIGHT
|
|
107
|
+
"ios_from_left" -> Screen.StackAnimation.IOS_FROM_LEFT
|
|
107
108
|
else -> throw JSApplicationIllegalArgumentException("Unknown animation type $animation")
|
|
108
109
|
}
|
|
109
110
|
}
|
|
@@ -214,7 +214,7 @@ object ScreenWindowTraits {
|
|
|
214
214
|
val window = activity.window
|
|
215
215
|
|
|
216
216
|
val screenForNavBarTranslucent = findScreenForTrait(screen, WindowTraits.NAVIGATION_BAR_TRANSLUCENT)
|
|
217
|
-
val translucent = screenForNavBarTranslucent?.isNavigationBarTranslucent ?:
|
|
217
|
+
val translucent = screenForNavBarTranslucent?.isNavigationBarTranslucent ?: return
|
|
218
218
|
|
|
219
219
|
// Following method controls whether to display edge-to-edge content that draws behind the navigation bar
|
|
220
220
|
WindowCompat.setDecorFitsSystemWindows(window, !translucent)
|
|
@@ -7,16 +7,16 @@ import com.facebook.react.uimanager.events.Event
|
|
|
7
7
|
class HeaderHeightChangeEvent(
|
|
8
8
|
surfaceId: Int,
|
|
9
9
|
viewId: Int,
|
|
10
|
-
private val headerHeight:
|
|
10
|
+
private val headerHeight: Int,
|
|
11
11
|
) : Event<HeaderHeightChangeEvent>(surfaceId, viewId) {
|
|
12
12
|
override fun getEventName() = EVENT_NAME
|
|
13
13
|
|
|
14
14
|
// As the same header height could appear twice, use header height as a coalescing key.
|
|
15
|
-
override fun getCoalescingKey(): Short = headerHeight.
|
|
15
|
+
override fun getCoalescingKey(): Short = headerHeight.toShort()
|
|
16
16
|
|
|
17
17
|
override fun getEventData(): WritableMap? =
|
|
18
18
|
Arguments.createMap().apply {
|
|
19
|
-
putDouble("headerHeight", headerHeight)
|
|
19
|
+
putDouble("headerHeight", headerHeight.toDouble())
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
companion object {
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
package com.swmansion.rnscreens.ext
|
|
2
|
+
|
|
3
|
+
import android.graphics.drawable.ColorDrawable
|
|
4
|
+
import android.view.View
|
|
5
|
+
import android.view.ViewGroup
|
|
6
|
+
import com.facebook.react.views.scroll.ReactHorizontalScrollView
|
|
7
|
+
import com.facebook.react.views.scroll.ReactScrollView
|
|
8
|
+
import com.swmansion.rnscreens.ScreenStack
|
|
9
|
+
|
|
10
|
+
internal fun View.parentAsView() = this.parent as? View
|
|
11
|
+
|
|
12
|
+
internal fun View.parentAsViewGroup() = this.parent as? ViewGroup
|
|
13
|
+
|
|
14
|
+
internal fun View.recycle(): View {
|
|
15
|
+
// screen fragments reuse view instances instead of creating new ones. In order to reuse a given
|
|
16
|
+
// view it needs to be detached from the view hierarchy to allow the fragment to attach it back.
|
|
17
|
+
this.parentAsViewGroup()?.let { parent ->
|
|
18
|
+
parent.endViewTransition(this)
|
|
19
|
+
parent.removeView(this)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// view detached from fragment manager get their visibility changed to GONE after their state is
|
|
23
|
+
// dumped. Since we don't restore the state but want to reuse the view we need to change
|
|
24
|
+
// visibility back to VISIBLE in order for the fragment manager to animate in the view.
|
|
25
|
+
this.visibility = View.VISIBLE
|
|
26
|
+
return this
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
internal fun View.maybeBgColor(): Int? {
|
|
30
|
+
val bgDrawable = this.background
|
|
31
|
+
if (bgDrawable is ColorDrawable) {
|
|
32
|
+
return bgDrawable.color
|
|
33
|
+
}
|
|
34
|
+
return null
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
internal fun View.isInsideScrollViewWithRemoveClippedSubviews(): Boolean {
|
|
38
|
+
if (this is ReactHorizontalScrollView || this is ReactScrollView) {
|
|
39
|
+
return false
|
|
40
|
+
}
|
|
41
|
+
var parentView = this.parent
|
|
42
|
+
while (parentView is ViewGroup && parentView !is ScreenStack) {
|
|
43
|
+
when (parentView) {
|
|
44
|
+
is ReactHorizontalScrollView -> {
|
|
45
|
+
return parentView.removeClippedSubviews
|
|
46
|
+
}
|
|
47
|
+
is ReactScrollView -> {
|
|
48
|
+
return parentView.removeClippedSubviews
|
|
49
|
+
}
|
|
50
|
+
else -> {
|
|
51
|
+
parentView = parentView.parent
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return false
|
|
56
|
+
}
|
|
@@ -38,25 +38,34 @@ target_include_directories(
|
|
|
38
38
|
${LIB_ANDROID_GENERATED_COMPONENTS_DIR}
|
|
39
39
|
)
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
41
|
+
if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 76)
|
|
42
|
+
target_link_libraries(
|
|
43
|
+
${LIB_TARGET_NAME}
|
|
44
|
+
ReactAndroid::reactnative
|
|
45
|
+
ReactAndroid::jsi
|
|
46
|
+
fbjni::fbjni
|
|
47
|
+
)
|
|
48
|
+
else()
|
|
49
|
+
target_link_libraries(
|
|
50
|
+
${LIB_TARGET_NAME}
|
|
51
|
+
fbjni
|
|
52
|
+
folly_runtime
|
|
53
|
+
glog
|
|
54
|
+
jsi
|
|
55
|
+
react_codegen_rncore
|
|
56
|
+
react_debug
|
|
57
|
+
react_nativemodule_core
|
|
58
|
+
react_render_core
|
|
59
|
+
react_render_debug
|
|
60
|
+
react_render_graphics
|
|
61
|
+
react_render_mapbuffer
|
|
62
|
+
react_render_componentregistry
|
|
63
|
+
react_utils
|
|
64
|
+
rrc_view
|
|
65
|
+
turbomodulejsijni
|
|
66
|
+
yoga
|
|
67
|
+
)
|
|
68
|
+
endif()
|
|
60
69
|
|
|
61
70
|
target_compile_options(
|
|
62
71
|
${LIB_TARGET_NAME}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<translate xmlns:android="http://schemas.android.com/apk/res/android"
|
|
3
|
+
android:duration="@android:integer/config_shortAnimTime"
|
|
4
|
+
android:interpolator="@android:interpolator/accelerate_decelerate"
|
|
5
|
+
android:fromXDelta="0%"
|
|
6
|
+
android:toXDelta="-100%" />
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<translate xmlns:android="http://schemas.android.com/apk/res/android"
|
|
3
|
+
android:duration="@android:integer/config_shortAnimTime"
|
|
4
|
+
android:interpolator="@android:interpolator/accelerate_decelerate"
|
|
5
|
+
android:fromXDelta="-100%"
|
|
6
|
+
android:toXDelta="0%" />
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
#endif
|
|
6
6
|
#include <react/debug/react_native_assert.h>
|
|
7
7
|
#include <react/renderer/components/rnscreens/Props.h>
|
|
8
|
+
#include <react/renderer/components/rnscreens/utils/RectUtil.h>
|
|
8
9
|
#include <react/renderer/core/ConcreteComponentDescriptor.h>
|
|
9
10
|
#include "RNSScreenShadowNode.h"
|
|
10
|
-
#include "utils/RectUtil.h"
|
|
11
11
|
|
|
12
12
|
namespace facebook {
|
|
13
13
|
namespace react {
|
|
@@ -19,9 +19,6 @@ class RNSScreenComponentDescriptor final
|
|
|
19
19
|
public:
|
|
20
20
|
using ConcreteComponentDescriptor::ConcreteComponentDescriptor;
|
|
21
21
|
|
|
22
|
-
static constexpr const char *kScreenDummyLayoutHelperClass =
|
|
23
|
-
"com/swmansion/rnscreens/utils/ScreenDummyLayoutHelper";
|
|
24
|
-
|
|
25
22
|
void adopt(ShadowNode &shadowNode) const override {
|
|
26
23
|
react_native_assert(dynamic_cast<RNSScreenShadowNode *>(&shadowNode));
|
|
27
24
|
auto &screenShadowNode = static_cast<RNSScreenShadowNode &>(shadowNode);
|
|
@@ -39,8 +36,8 @@ class RNSScreenComponentDescriptor final
|
|
|
39
36
|
#ifdef ANDROID
|
|
40
37
|
if (stateData.frameSize.width != 0 && stateData.frameSize.height != 0) {
|
|
41
38
|
// When we receive dimensions from JVM side we can remove padding used for
|
|
42
|
-
// correction, and we can stop applying height
|
|
43
|
-
//
|
|
39
|
+
// correction, and we can stop applying height and offset corrections for
|
|
40
|
+
// the frame.
|
|
44
41
|
// TODO: In future, when we have dynamic header height we might want to
|
|
45
42
|
// update Y offset correction here.
|
|
46
43
|
|
|
@@ -67,36 +64,11 @@ class RNSScreenComponentDescriptor final
|
|
|
67
64
|
screenShadowNode.setPadding({0, 0, 0, 0});
|
|
68
65
|
screenShadowNode.getFrameCorrectionModes().unset(
|
|
69
66
|
FrameCorrectionModes::Mode::FrameHeightCorrection);
|
|
67
|
+
screenShadowNode.getFrameCorrectionModes().unset(
|
|
68
|
+
FrameCorrectionModes::Mode::FrameOriginCorrection);
|
|
70
69
|
|
|
71
70
|
layoutableShadowNode.setSize(
|
|
72
71
|
Size{stateData.frameSize.width, stateData.frameSize.height});
|
|
73
|
-
} else {
|
|
74
|
-
// This code path should be executed only on the very first (few)
|
|
75
|
-
// layout(s), when we haven't received state update from JVM side yet.
|
|
76
|
-
|
|
77
|
-
auto headerConfigChildOpt = findHeaderConfigChild(layoutableShadowNode);
|
|
78
|
-
|
|
79
|
-
// During creation of the shadow node children are not attached yet.
|
|
80
|
-
// We also do not want to set any padding in case.
|
|
81
|
-
if (headerConfigChildOpt) {
|
|
82
|
-
const auto &headerConfigChild = headerConfigChildOpt->get();
|
|
83
|
-
const auto &headerProps =
|
|
84
|
-
*std::static_pointer_cast<const RNSScreenStackHeaderConfigProps>(
|
|
85
|
-
headerConfigChild->getProps());
|
|
86
|
-
|
|
87
|
-
const auto headerHeight = headerProps.hidden
|
|
88
|
-
? 0.f
|
|
89
|
-
: findHeaderHeight(
|
|
90
|
-
headerProps.titleFontSize, headerProps.title.empty())
|
|
91
|
-
.value_or(0.f);
|
|
92
|
-
|
|
93
|
-
screenShadowNode.setPadding({0, 0, 0, headerHeight});
|
|
94
|
-
screenShadowNode.setHeaderHeight(headerHeight);
|
|
95
|
-
screenShadowNode.getFrameCorrectionModes().set(
|
|
96
|
-
FrameCorrectionModes::Mode(
|
|
97
|
-
FrameCorrectionModes::Mode::FrameHeightCorrection |
|
|
98
|
-
FrameCorrectionModes::Mode::FrameOriginCorrection));
|
|
99
|
-
}
|
|
100
72
|
}
|
|
101
73
|
#else
|
|
102
74
|
if (stateData.frameSize.width != 0 && stateData.frameSize.height != 0) {
|
|
@@ -106,72 +78,6 @@ class RNSScreenComponentDescriptor final
|
|
|
106
78
|
#endif // ANDROID
|
|
107
79
|
ConcreteComponentDescriptor::adopt(shadowNode);
|
|
108
80
|
}
|
|
109
|
-
|
|
110
|
-
std::optional<std::reference_wrapper<const ShadowNode::Shared>>
|
|
111
|
-
findHeaderConfigChild(
|
|
112
|
-
const YogaLayoutableShadowNode &screenShadowNode) const {
|
|
113
|
-
for (const ShadowNode::Shared &child : screenShadowNode.getChildren()) {
|
|
114
|
-
if (std::strcmp(
|
|
115
|
-
child->getComponentName(), "RNSScreenStackHeaderConfig") == 0) {
|
|
116
|
-
return {std::cref(child)};
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
return {};
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
#ifdef ANDROID
|
|
123
|
-
std::optional<float> findHeaderHeight(
|
|
124
|
-
const int fontSize,
|
|
125
|
-
const bool isTitleEmpty) const {
|
|
126
|
-
JNIEnv *env = facebook::jni::Environment::current();
|
|
127
|
-
|
|
128
|
-
if (env == nullptr) {
|
|
129
|
-
LOG(ERROR) << "[RNScreens] Failed to retrieve env\n";
|
|
130
|
-
return {};
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
jclass layoutHelperClass = env->FindClass(kScreenDummyLayoutHelperClass);
|
|
134
|
-
|
|
135
|
-
if (layoutHelperClass == nullptr) {
|
|
136
|
-
LOG(ERROR) << "[RNScreens] Failed to find class with id "
|
|
137
|
-
<< kScreenDummyLayoutHelperClass;
|
|
138
|
-
return {};
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
jmethodID computeDummyLayoutID =
|
|
142
|
-
env->GetMethodID(layoutHelperClass, "computeDummyLayout", "(IZ)F");
|
|
143
|
-
|
|
144
|
-
if (computeDummyLayoutID == nullptr) {
|
|
145
|
-
LOG(ERROR)
|
|
146
|
-
<< "[RNScreens] Failed to retrieve computeDummyLayout method ID";
|
|
147
|
-
return {};
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
jmethodID getInstanceMethodID = env->GetStaticMethodID(
|
|
151
|
-
layoutHelperClass,
|
|
152
|
-
"getInstance",
|
|
153
|
-
"()Lcom/swmansion/rnscreens/utils/ScreenDummyLayoutHelper;");
|
|
154
|
-
|
|
155
|
-
if (getInstanceMethodID == nullptr) {
|
|
156
|
-
LOG(ERROR) << "[RNScreens] Failed to retrieve getInstanceMethodID";
|
|
157
|
-
return {};
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
jobject packageInstance =
|
|
161
|
-
env->CallStaticObjectMethod(layoutHelperClass, getInstanceMethodID);
|
|
162
|
-
|
|
163
|
-
if (packageInstance == nullptr) {
|
|
164
|
-
LOG(ERROR)
|
|
165
|
-
<< "[RNScreens] Failed to retrieve packageInstance or the package instance was null on JVM side";
|
|
166
|
-
return {};
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
jfloat headerHeight = env->CallFloatMethod(
|
|
170
|
-
packageInstance, computeDummyLayoutID, fontSize, isTitleEmpty);
|
|
171
|
-
|
|
172
|
-
return {headerHeight};
|
|
173
|
-
}
|
|
174
|
-
#endif // ANDROID
|
|
175
81
|
};
|
|
176
82
|
|
|
177
83
|
} // namespace react
|