react-native-screens 3.25.0 → 3.26.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.
Files changed (138) hide show
  1. package/README.md +1 -1
  2. package/RNScreens.podspec +53 -32
  3. package/android/build.gradle +13 -11
  4. package/android/src/main/java/com/swmansion/rnscreens/FragmentHolder.kt +7 -0
  5. package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +41 -10
  6. package/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.kt +35 -36
  7. package/android/src/main/java/com/swmansion/rnscreens/ScreenContainerViewManager.kt +7 -7
  8. package/android/src/main/java/com/swmansion/rnscreens/ScreenEventDispatcher.kt +21 -0
  9. package/android/src/main/java/com/swmansion/rnscreens/ScreenFragment.kt +46 -38
  10. package/android/src/main/java/com/swmansion/rnscreens/ScreenFragmentWrapper.kt +22 -0
  11. package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +40 -39
  12. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt +35 -10
  13. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragmentWrapper.kt +15 -0
  14. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt +6 -4
  15. package/android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.kt +11 -18
  16. package/android/src/main/java/com/swmansion/rnscreens/ScreenWindowTraits.kt +1 -1
  17. package/android/src/main/java/com/swmansion/rnscreens/ScreensShadowNode.kt +1 -1
  18. package/android/src/main/java/com/swmansion/rnscreens/SearchBarView.kt +23 -7
  19. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderAttachedEvent.kt +3 -5
  20. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderBackButtonClickedEvent.kt +3 -5
  21. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderDetachedEvent.kt +3 -5
  22. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderHeightChangeEvent.kt +26 -0
  23. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenAppearEvent.kt +3 -5
  24. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenDisappearEvent.kt +3 -5
  25. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenDismissedEvent.kt +4 -7
  26. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenTransitionProgressEvent.kt +7 -8
  27. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenWillAppearEvent.kt +3 -5
  28. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenWillDisappearEvent.kt +3 -5
  29. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarBlurEvent.kt +3 -5
  30. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarChangeTextEvent.kt +5 -6
  31. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarCloseEvent.kt +3 -5
  32. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarFocusEvent.kt +3 -5
  33. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarOpenEvent.kt +3 -5
  34. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarSearchButtonPressEvent.kt +4 -6
  35. package/android/src/main/java/com/swmansion/rnscreens/events/StackFinishTransitioningEvent.kt +3 -5
  36. package/android/src/main/java/com/swmansion/rnscreens/utils/DeviceUtils.kt +12 -0
  37. package/ios/RNSScreen.h +5 -0
  38. package/ios/RNSScreen.mm +163 -7
  39. package/ios/RNSScreenStack.mm +18 -0
  40. package/ios/RNSScreenStackHeaderConfig.mm +17 -0
  41. package/ios/events/RNSHeaderHeightChangeEvent.h +8 -0
  42. package/ios/events/RNSHeaderHeightChangeEvent.mm +44 -0
  43. package/lib/commonjs/fabric/ScreenNativeComponent.js.map +1 -1
  44. package/lib/commonjs/index.native.js +11 -11
  45. package/lib/commonjs/index.native.js.map +1 -1
  46. package/lib/commonjs/native-stack/index.js +14 -0
  47. package/lib/commonjs/native-stack/index.js.map +1 -1
  48. package/lib/commonjs/native-stack/navigators/createNativeStackNavigator.js +1 -1
  49. package/lib/commonjs/native-stack/navigators/createNativeStackNavigator.js.map +1 -1
  50. package/lib/commonjs/native-stack/types.js.map +1 -1
  51. package/lib/commonjs/native-stack/utils/AnimatedHeaderHeightContext.js +13 -0
  52. package/lib/commonjs/native-stack/utils/AnimatedHeaderHeightContext.js.map +1 -0
  53. package/lib/commonjs/native-stack/utils/SafeAreaProviderCompat.js.map +1 -1
  54. package/lib/commonjs/native-stack/utils/getStatusBarHeight.js +22 -0
  55. package/lib/commonjs/native-stack/utils/getStatusBarHeight.js.map +1 -0
  56. package/lib/commonjs/native-stack/utils/useAnimatedHeaderHeight.js +19 -0
  57. package/lib/commonjs/native-stack/utils/useAnimatedHeaderHeight.js.map +1 -0
  58. package/lib/commonjs/native-stack/utils/useBackPressSubscription.js +2 -2
  59. package/lib/commonjs/native-stack/utils/useBackPressSubscription.js.map +1 -1
  60. package/lib/commonjs/native-stack/views/HeaderConfig.js +2 -2
  61. package/lib/commonjs/native-stack/views/HeaderConfig.js.map +1 -1
  62. package/lib/commonjs/native-stack/views/NativeStackView.js +39 -21
  63. package/lib/commonjs/native-stack/views/NativeStackView.js.map +1 -1
  64. package/lib/commonjs/reanimated/ReanimatedHeaderHeightContext.js +13 -0
  65. package/lib/commonjs/reanimated/ReanimatedHeaderHeightContext.js.map +1 -0
  66. package/lib/commonjs/reanimated/ReanimatedNativeStackScreen.js +37 -6
  67. package/lib/commonjs/reanimated/ReanimatedNativeStackScreen.js.map +1 -1
  68. package/lib/commonjs/reanimated/ReanimatedScreenProvider.js +2 -2
  69. package/lib/commonjs/reanimated/ReanimatedScreenProvider.js.map +1 -1
  70. package/lib/commonjs/reanimated/index.js +7 -0
  71. package/lib/commonjs/reanimated/index.js.map +1 -1
  72. package/lib/commonjs/reanimated/useReanimatedHeaderHeight.js +19 -0
  73. package/lib/commonjs/reanimated/useReanimatedHeaderHeight.js.map +1 -0
  74. package/lib/commonjs/types.js.map +1 -1
  75. package/lib/module/fabric/ScreenNativeComponent.js.map +1 -1
  76. package/lib/module/index.native.js +12 -12
  77. package/lib/module/index.native.js.map +1 -1
  78. package/lib/module/native-stack/index.js +2 -0
  79. package/lib/module/native-stack/index.js.map +1 -1
  80. package/lib/module/native-stack/navigators/createNativeStackNavigator.js +1 -1
  81. package/lib/module/native-stack/navigators/createNativeStackNavigator.js.map +1 -1
  82. package/lib/module/native-stack/types.js.map +1 -1
  83. package/lib/module/native-stack/utils/AnimatedHeaderHeightContext.js +4 -0
  84. package/lib/module/native-stack/utils/AnimatedHeaderHeightContext.js.map +1 -0
  85. package/lib/module/native-stack/utils/SafeAreaProviderCompat.js.map +1 -1
  86. package/lib/module/native-stack/utils/getStatusBarHeight.js +16 -0
  87. package/lib/module/native-stack/utils/getStatusBarHeight.js.map +1 -0
  88. package/lib/module/native-stack/utils/useAnimatedHeaderHeight.js +10 -0
  89. package/lib/module/native-stack/utils/useAnimatedHeaderHeight.js.map +1 -0
  90. package/lib/module/native-stack/utils/useBackPressSubscription.js +2 -2
  91. package/lib/module/native-stack/utils/useBackPressSubscription.js.map +1 -1
  92. package/lib/module/native-stack/views/HeaderConfig.js +2 -2
  93. package/lib/module/native-stack/views/HeaderConfig.js.map +1 -1
  94. package/lib/module/native-stack/views/NativeStackView.js +40 -22
  95. package/lib/module/native-stack/views/NativeStackView.js.map +1 -1
  96. package/lib/module/reanimated/ReanimatedHeaderHeightContext.js +5 -0
  97. package/lib/module/reanimated/ReanimatedHeaderHeightContext.js.map +1 -0
  98. package/lib/module/reanimated/ReanimatedNativeStackScreen.js +37 -6
  99. package/lib/module/reanimated/ReanimatedNativeStackScreen.js.map +1 -1
  100. package/lib/module/reanimated/ReanimatedScreenProvider.js +2 -2
  101. package/lib/module/reanimated/ReanimatedScreenProvider.js.map +1 -1
  102. package/lib/module/reanimated/index.js +1 -0
  103. package/lib/module/reanimated/index.js.map +1 -1
  104. package/lib/module/reanimated/useReanimatedHeaderHeight.js +10 -0
  105. package/lib/module/reanimated/useReanimatedHeaderHeight.js.map +1 -0
  106. package/lib/module/types.js.map +1 -1
  107. package/lib/typescript/fabric/ScreenNativeComponent.d.ts +4 -0
  108. package/lib/typescript/native-stack/index.d.ts +2 -0
  109. package/lib/typescript/native-stack/types.d.ts +8 -0
  110. package/lib/typescript/native-stack/utils/AnimatedHeaderHeightContext.d.ts +4 -0
  111. package/lib/typescript/native-stack/utils/getStatusBarHeight.d.ts +2 -0
  112. package/lib/typescript/native-stack/utils/useAnimatedHeaderHeight.d.ts +1 -0
  113. package/lib/typescript/reanimated/ReanimatedHeaderHeightContext.d.ts +4 -0
  114. package/lib/typescript/reanimated/index.d.ts +1 -0
  115. package/lib/typescript/reanimated/useReanimatedHeaderHeight.d.ts +3 -0
  116. package/lib/typescript/types.d.ts +11 -0
  117. package/native-stack/README.md +16 -1
  118. package/package.json +36 -38
  119. package/src/fabric/ScreenNativeComponent.ts +5 -0
  120. package/src/index.native.tsx +17 -19
  121. package/src/native-stack/index.tsx +3 -0
  122. package/src/native-stack/types.tsx +10 -1
  123. package/src/native-stack/utils/AnimatedHeaderHeightContext.tsx +8 -0
  124. package/src/native-stack/utils/SafeAreaProviderCompat.tsx +1 -1
  125. package/src/native-stack/utils/getStatusBarHeight.tsx +22 -0
  126. package/src/native-stack/utils/useAnimatedHeaderHeight.tsx +15 -0
  127. package/src/native-stack/views/HeaderConfig.tsx +1 -2
  128. package/src/native-stack/views/NativeStackView.tsx +78 -44
  129. package/src/reanimated/ReanimatedHeaderHeightContext.tsx +7 -0
  130. package/src/reanimated/ReanimatedNativeStackScreen.tsx +58 -11
  131. package/src/reanimated/index.tsx +1 -0
  132. package/src/reanimated/useReanimatedHeaderHeight.tsx +14 -0
  133. package/src/types.tsx +14 -0
  134. package/windows/RNScreens/RNScreens.vcxproj +6 -3
  135. package/windows/RNScreens/ScreenStack.cpp +16 -0
  136. package/windows/RNScreens/ScreenStack.h +1 -0
  137. /package/ios/{RNSScreenViewEvent.h → events/RNSScreenViewEvent.h} +0 -0
  138. /package/ios/{RNSScreenViewEvent.mm → events/RNSScreenViewEvent.mm} +0 -0
package/README.md CHANGED
@@ -114,7 +114,7 @@ To configure react-navigation to use screens instead of plain RN Views for rende
114
114
  yarn add react-native-screens
115
115
 
116
116
  # if you use Expo managed workflow
117
- expo install react-native-screens
117
+ npx expo install react-native-screens
118
118
  ```
119
119
 
120
120
  Just make sure that the version of [react-navigation](https://github.com/react-navigation/react-navigation) you are using is 2.14.0 or higher.
package/RNScreens.podspec CHANGED
@@ -2,10 +2,54 @@ require "json"
2
2
 
3
3
  package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4
4
 
5
- fabric_enabled = ENV['RCT_NEW_ARCH_ENABLED'] == '1'
5
+ new_arch_enabled = ENV['RCT_NEW_ARCH_ENABLED'] == '1'
6
+ platform = new_arch_enabled ? "11.0" : "9.0"
7
+ source_files = new_arch_enabled ? 'ios/**/*.{h,m,mm,cpp}' : "ios/**/*.{h,m,mm}"
6
8
 
7
9
  folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
8
10
 
11
+ # Helper class to avoid clashing with Cocoapods install_dependencies function
12
+ class RNScreensDependencyHelper
13
+ # Helper class to add the Common subspec
14
+ def self.add_common_subspec(s, new_arch_enabled)
15
+ unless new_arch_enabled
16
+ return
17
+ end
18
+
19
+ s.subspec "common" do |ss|
20
+ ss.source_files = "common/cpp/**/*.{cpp,h}"
21
+ ss.header_dir = "rnscreens"
22
+ ss.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/common/cpp\"" }
23
+ end
24
+ end
25
+
26
+ # Function to support older versions of React Native which do not provide the
27
+ # install_modules_dependencies function
28
+ def self.install_dependencies(s, new_arch_enabled)
29
+ if new_arch_enabled
30
+ s.pod_target_xcconfig = {
31
+ 'HEADER_SEARCH_PATHS' => '"$(PODS_ROOT)/boost" "$(PODS_ROOT)/boost-for-react-native" "$(PODS_ROOT)/RCT-Folly"',
32
+ "CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
33
+ }
34
+
35
+ s.compiler_flags = folly_compiler_flags + ' ' + '-DRCT_NEW_ARCH_ENABLED'
36
+
37
+ s.dependency "React"
38
+ s.dependency "React-RCTFabric"
39
+ s.dependency "React-Codegen"
40
+ s.dependency "RCT-Folly"
41
+ s.dependency "RCTRequired"
42
+ s.dependency "RCTTypeSafety"
43
+ s.dependency "ReactCommon/turbomodule/core"
44
+
45
+ self.add_common_subspec(s, new_arch_enabled)
46
+ else
47
+ s.dependency "React-Core"
48
+ s.dependency "React-RCTImage"
49
+ end
50
+ end
51
+ end
52
+
9
53
  Pod::Spec.new do |s|
10
54
  s.name = "RNScreens"
11
55
  s.version = package["version"]
@@ -15,39 +59,16 @@ Pod::Spec.new do |s|
15
59
  DESC
16
60
  s.homepage = "https://github.com/software-mansion/react-native-screens"
17
61
  s.license = "MIT"
18
- # s.license = { :type => "MIT", :file => "FILE_LICENSE" }
19
62
  s.author = { "author" => "author@domain.cn" }
20
- s.platforms = { :ios => "9.0", :tvos => "11.0" }
63
+ s.platforms = { :ios => platform, :tvos => "11.0" }
21
64
  s.source = { :git => "https://github.com/software-mansion/react-native-screens.git", :tag => "#{s.version}" }
65
+ s.source_files = source_files
66
+ s.requires_arc = true
22
67
 
23
- if fabric_enabled
24
- s.pod_target_xcconfig = {
25
- 'HEADER_SEARCH_PATHS' => '"$(PODS_ROOT)/boost" "$(PODS_ROOT)/boost-for-react-native" "$(PODS_ROOT)/RCT-Folly"',
26
- "CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
27
- }
28
- s.platforms = { ios: '11.0', tvos: '11.0' }
29
- s.compiler_flags = folly_compiler_flags + ' ' + '-DRCT_NEW_ARCH_ENABLED'
30
- s.source_files = 'ios/**/*.{h,m,mm,cpp}'
31
- s.requires_arc = true
32
-
33
- s.dependency "React"
34
- s.dependency "React-RCTFabric"
35
- s.dependency "React-Codegen"
36
- s.dependency "RCT-Folly"
37
- s.dependency "RCTRequired"
38
- s.dependency "RCTTypeSafety"
39
- s.dependency "ReactCommon/turbomodule/core"
40
-
41
- s.subspec "common" do |ss|
42
- ss.source_files = "common/cpp/**/*.{cpp,h}"
43
- ss.header_dir = "rnscreens"
44
- ss.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/common/cpp\"" }
45
- end
46
- else
47
- s.source_files = "ios/**/*.{h,m,mm}"
48
- s.requires_arc = true
49
-
50
- s.dependency "React-Core"
51
- s.dependency "React-RCTImage"
68
+ if defined?(install_modules_dependencies()) != nil
69
+ install_modules_dependencies(s)
70
+ RNScreensDependencyHelper.add_common_subspec(s, new_arch_enabled)
71
+ else
72
+ RNScreensDependencyHelper.install_dependencies(s, new_arch_enabled)
52
73
  end
53
74
  end
@@ -1,9 +1,11 @@
1
+ import com.android.Version
2
+
1
3
  buildscript {
2
4
  ext {
3
- rnsDefaultTargetSdkVersion = 31
4
- rnsDefaultCompileSdkVersion = 31
5
+ rnsDefaultTargetSdkVersion = 34
6
+ rnsDefaultCompileSdkVersion = 34
5
7
  rnsDefaultMinSdkVersion = 21
6
- rnsDefaultKotlinVersion = '1.6.21'
8
+ rnsDefaultKotlinVersion = '1.8.0'
7
9
  }
8
10
  ext.safeExtGet = {prop, fallback ->
9
11
  rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
@@ -15,7 +17,7 @@ buildscript {
15
17
  dependencies {
16
18
  classpath('com.android.tools.build:gradle:4.2.2')
17
19
  classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${safeExtGet('kotlinVersion', rnsDefaultKotlinVersion)}"
18
- classpath "com.diffplug.spotless:spotless-plugin-gradle:5.15.0"
20
+ classpath "com.diffplug.spotless:spotless-plugin-gradle:6.11.0"
19
21
  }
20
22
  }
21
23
 
@@ -45,7 +47,7 @@ def reactNativeArchitectures() {
45
47
 
46
48
  android {
47
49
  compileSdkVersion safeExtGet('compileSdkVersion', rnsDefaultCompileSdkVersion)
48
- def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION
50
+ def agpVersion = Version.ANDROID_GRADLE_PLUGIN_VERSION
49
51
  if (agpVersion.tokenize('.')[0].toInteger() >= 7) {
50
52
  namespace "com.swmansion.rnscreens"
51
53
  }
@@ -122,10 +124,10 @@ repositories {
122
124
 
123
125
  dependencies {
124
126
  implementation 'com.facebook.react:react-native:+'
125
- implementation 'androidx.appcompat:appcompat:1.1.0'
126
- implementation 'androidx.fragment:fragment:1.2.1'
127
- implementation 'androidx.coordinatorlayout:coordinatorlayout:1.1.0'
128
- implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0'
129
- implementation 'com.google.android.material:material:1.1.0'
130
- implementation "androidx.core:core-ktx:1.5.0"
127
+ implementation 'androidx.appcompat:appcompat:1.6.1'
128
+ implementation 'androidx.fragment:fragment-ktx:1.6.1'
129
+ implementation 'androidx.coordinatorlayout:coordinatorlayout:1.2.0'
130
+ implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
131
+ implementation 'com.google.android.material:material:1.9.0'
132
+ implementation "androidx.core:core-ktx:1.10.1"
131
133
  }
@@ -0,0 +1,7 @@
1
+ package com.swmansion.rnscreens
2
+
3
+ import androidx.fragment.app.Fragment
4
+
5
+ interface FragmentHolder {
6
+ val fragment: Fragment
7
+ }
@@ -5,18 +5,26 @@ 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
8
9
  import android.view.ViewGroup
9
10
  import android.view.WindowManager
10
11
  import android.webkit.WebView
12
+ import androidx.core.view.children
13
+ import androidx.fragment.app.Fragment
11
14
  import com.facebook.react.bridge.GuardedRunnable
12
15
  import com.facebook.react.bridge.ReactContext
16
+ import com.facebook.react.uimanager.PixelUtil
17
+ import com.facebook.react.uimanager.UIManagerHelper
13
18
  import com.facebook.react.uimanager.UIManagerModule
19
+ import com.swmansion.rnscreens.events.HeaderHeightChangeEvent
14
20
 
15
21
  @SuppressLint("ViewConstructor")
16
22
  class Screen constructor(context: ReactContext?) : FabricEnabledViewGroup(context) {
23
+ val fragment: Fragment?
24
+ get() = fragmentWrapper?.fragment
17
25
 
18
- var fragment: ScreenFragment? = null
19
- var container: ScreenContainer<*>? = null
26
+ var fragmentWrapper: ScreenFragmentWrapper? = null
27
+ var container: ScreenContainer? = null
20
28
  var activityState: ActivityState? = null
21
29
  private set
22
30
  private var mTransitioning = false
@@ -63,6 +71,8 @@ class Screen constructor(context: ReactContext?) : FabricEnabledViewGroup(contex
63
71
  if (changed) {
64
72
  val width = r - l
65
73
  val height = b - t
74
+
75
+ calculateHeaderHeight()
66
76
  if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
67
77
  updateScreenSizeFabric(width, height)
68
78
  } else {
@@ -84,7 +94,7 @@ class Screen constructor(context: ReactContext?) : FabricEnabledViewGroup(contex
84
94
  }
85
95
 
86
96
  val headerConfig: ScreenStackHeaderConfig?
87
- get() = getChildAt(0) as? ScreenStackHeaderConfig
97
+ get() = children.find { it is ScreenStackHeaderConfig } as? ScreenStackHeaderConfig
88
98
 
89
99
  /**
90
100
  * While transitioning this property allows to optimize rendering behavior on Android and provide
@@ -149,7 +159,7 @@ class Screen constructor(context: ReactContext?) : FabricEnabledViewGroup(contex
149
159
  else -> ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
150
160
  }
151
161
 
152
- fragment?.let { ScreenWindowTraits.setOrientation(this, it.tryGetActivity()) }
162
+ fragmentWrapper?.let { ScreenWindowTraits.setOrientation(this, it.tryGetActivity()) }
153
163
  }
154
164
 
155
165
  // Accepts one of 4 accessibility flags
@@ -166,7 +176,7 @@ class Screen constructor(context: ReactContext?) : FabricEnabledViewGroup(contex
166
176
  ScreenWindowTraits.applyDidSetStatusBarAppearance()
167
177
  }
168
178
  mStatusBarStyle = statusBarStyle
169
- fragment?.let { ScreenWindowTraits.setStyle(this, it.tryGetActivity(), it.tryGetContext()) }
179
+ fragmentWrapper?.let { ScreenWindowTraits.setStyle(this, it.tryGetActivity(), it.tryGetContext()) }
170
180
  }
171
181
 
172
182
  var isStatusBarHidden: Boolean?
@@ -176,7 +186,7 @@ class Screen constructor(context: ReactContext?) : FabricEnabledViewGroup(contex
176
186
  ScreenWindowTraits.applyDidSetStatusBarAppearance()
177
187
  }
178
188
  mStatusBarHidden = statusBarHidden
179
- fragment?.let { ScreenWindowTraits.setHidden(this, it.tryGetActivity()) }
189
+ fragmentWrapper?.let { ScreenWindowTraits.setHidden(this, it.tryGetActivity()) }
180
190
  }
181
191
 
182
192
  var isStatusBarTranslucent: Boolean?
@@ -186,7 +196,7 @@ class Screen constructor(context: ReactContext?) : FabricEnabledViewGroup(contex
186
196
  ScreenWindowTraits.applyDidSetStatusBarAppearance()
187
197
  }
188
198
  mStatusBarTranslucent = statusBarTranslucent
189
- fragment?.let {
199
+ fragmentWrapper?.let {
190
200
  ScreenWindowTraits.setTranslucent(
191
201
  this,
192
202
  it.tryGetActivity(),
@@ -202,7 +212,7 @@ class Screen constructor(context: ReactContext?) : FabricEnabledViewGroup(contex
202
212
  ScreenWindowTraits.applyDidSetStatusBarAppearance()
203
213
  }
204
214
  mStatusBarColor = statusBarColor
205
- fragment?.let { ScreenWindowTraits.setColor(this, it.tryGetActivity(), it.tryGetContext()) }
215
+ fragmentWrapper?.let { ScreenWindowTraits.setColor(this, it.tryGetActivity(), it.tryGetContext()) }
206
216
  }
207
217
 
208
218
  var navigationBarColor: Int?
@@ -212,7 +222,7 @@ class Screen constructor(context: ReactContext?) : FabricEnabledViewGroup(contex
212
222
  ScreenWindowTraits.applyDidSetNavigationBarAppearance()
213
223
  }
214
224
  mNavigationBarColor = navigationBarColor
215
- fragment?.let { ScreenWindowTraits.setNavigationBarColor(this, it.tryGetActivity()) }
225
+ fragmentWrapper?.let { ScreenWindowTraits.setNavigationBarColor(this, it.tryGetActivity()) }
216
226
  }
217
227
 
218
228
  var isNavigationBarHidden: Boolean?
@@ -222,7 +232,7 @@ class Screen constructor(context: ReactContext?) : FabricEnabledViewGroup(contex
222
232
  ScreenWindowTraits.applyDidSetNavigationBarAppearance()
223
233
  }
224
234
  mNavigationBarHidden = navigationBarHidden
225
- fragment?.let {
235
+ fragmentWrapper?.let {
226
236
  ScreenWindowTraits.setNavigationBarHidden(
227
237
  this,
228
238
  it.tryGetActivity(),
@@ -236,6 +246,27 @@ class Screen constructor(context: ReactContext?) : FabricEnabledViewGroup(contex
236
246
  mNativeBackButtonDismissalEnabled = enableNativeBackButtonDismissal
237
247
  }
238
248
 
249
+ private fun calculateHeaderHeight() {
250
+ val actionBarTv = TypedValue()
251
+ val resolvedActionBarSize = context.theme.resolveAttribute(android.R.attr.actionBarSize, actionBarTv, true)
252
+
253
+ // Check if it's possible to get an attribute from theme context and assign a value from it.
254
+ // Otherwise, the default value will be returned.
255
+ val actionBarHeight = TypedValue.complexToDimensionPixelSize(actionBarTv.data, resources.displayMetrics)
256
+ .takeIf { resolvedActionBarSize && headerConfig?.mIsHidden != true }
257
+ ?.let { PixelUtil.toDIPFromPixel(it.toFloat()).toDouble() } ?: 0.0
258
+
259
+ val statusBarHeight = context.resources.getIdentifier("status_bar_height", "dimen", "android")
260
+ .takeIf { it > 0 && isStatusBarHidden != true }
261
+ ?.let { (context.resources::getDimensionPixelSize)(it) }
262
+ ?.let { PixelUtil.toDIPFromPixel(it.toFloat()).toDouble() }
263
+ ?: 0.0
264
+
265
+ val totalHeight = actionBarHeight + statusBarHeight
266
+ UIManagerHelper.getEventDispatcherForReactTag(context as ReactContext, id)
267
+ ?.dispatchEvent(HeaderHeightChangeEvent(id, totalHeight))
268
+ }
269
+
239
270
  enum class StackPresentation {
240
271
  PUSH, MODAL, TRANSPARENT_MODAL
241
272
  }
@@ -16,9 +16,9 @@ import com.facebook.react.modules.core.ChoreographerCompat
16
16
  import com.facebook.react.modules.core.ReactChoreographer
17
17
  import com.swmansion.rnscreens.Screen.ActivityState
18
18
 
19
- open class ScreenContainer<T : ScreenFragment>(context: Context?) : ViewGroup(context) {
19
+ open class ScreenContainer(context: Context?) : ViewGroup(context) {
20
20
  @JvmField
21
- protected val mScreenFragments = ArrayList<T>()
21
+ protected val mScreenFragments = ArrayList<ScreenFragmentWrapper>()
22
22
  @JvmField
23
23
  protected var mFragmentManager: FragmentManager? = null
24
24
  private var mIsAttached = false
@@ -34,7 +34,7 @@ open class ScreenContainer<T : ScreenFragment>(context: Context?) : ViewGroup(co
34
34
  layout(left, top, right, bottom)
35
35
  }
36
36
  }
37
- private var mParentScreenFragment: ScreenFragment? = null
37
+ private var mParentScreenFragment: ScreenFragmentWrapper? = null
38
38
 
39
39
  override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
40
40
  var i = 0
@@ -87,14 +87,11 @@ open class ScreenContainer<T : ScreenFragment>(context: Context?) : ViewGroup(co
87
87
  performUpdatesNow()
88
88
  }
89
89
 
90
- protected open fun adapt(screen: Screen): T {
91
- @Suppress("UNCHECKED_CAST")
92
- return ScreenFragment(screen) as T
93
- }
90
+ protected open fun adapt(screen: Screen): ScreenFragmentWrapper = ScreenFragment(screen)
94
91
 
95
92
  fun addScreen(screen: Screen, index: Int) {
96
93
  val fragment = adapt(screen)
97
- screen.fragment = fragment
94
+ screen.fragmentWrapper = fragment
98
95
  mScreenFragments.add(index, fragment)
99
96
  screen.container = this
100
97
  onScreenChanged()
@@ -119,6 +116,8 @@ open class ScreenContainer<T : ScreenFragment>(context: Context?) : ViewGroup(co
119
116
 
120
117
  fun getScreenAt(index: Int): Screen = mScreenFragments[index].screen
121
118
 
119
+ fun getScreenFragmentWrapperAt(index: Int): ScreenFragmentWrapper = mScreenFragments[index]
120
+
122
121
  open val topScreen: Screen?
123
122
  get() = mScreenFragments.firstOrNull { getActivityState(it) === ActivityState.ON_TOP }?.screen
124
123
 
@@ -174,10 +173,10 @@ open class ScreenContainer<T : ScreenFragment>(context: Context?) : ViewGroup(co
174
173
  // Otherwise we expect to connect directly with root view and get root fragment manager
175
174
  if (parent is Screen) {
176
175
  checkNotNull(
177
- parent.fragment?.let { screenFragment ->
178
- mParentScreenFragment = screenFragment
179
- screenFragment.registerChildScreenContainer(this)
180
- setFragmentManager(screenFragment.childFragmentManager)
176
+ parent.fragmentWrapper?.let { fragmentWrapper ->
177
+ mParentScreenFragment = fragmentWrapper
178
+ fragmentWrapper.addChildScreenContainer(this)
179
+ setFragmentManager(fragmentWrapper.fragment.childFragmentManager)
181
180
  }
182
181
  ) { "Parent Screen does not have its Fragment attached" }
183
182
  } else {
@@ -197,19 +196,19 @@ open class ScreenContainer<T : ScreenFragment>(context: Context?) : ViewGroup(co
197
196
  .setReorderingAllowed(true)
198
197
  }
199
198
 
200
- private fun attachScreen(transaction: FragmentTransaction, screenFragment: ScreenFragment) {
201
- transaction.add(id, screenFragment)
199
+ private fun attachScreen(transaction: FragmentTransaction, fragment: Fragment) {
200
+ transaction.add(id, fragment)
202
201
  }
203
202
 
204
- private fun detachScreen(transaction: FragmentTransaction, screenFragment: ScreenFragment) {
205
- transaction.remove(screenFragment)
203
+ private fun detachScreen(transaction: FragmentTransaction, fragment: Fragment) {
204
+ transaction.remove(fragment)
206
205
  }
207
206
 
208
- private fun getActivityState(screenFragment: ScreenFragment): ActivityState? =
209
- screenFragment.screen.activityState
207
+ private fun getActivityState(screenFragmentWrapper: ScreenFragmentWrapper): ActivityState? =
208
+ screenFragmentWrapper.screen.activityState
210
209
 
211
- open fun hasScreen(screenFragment: ScreenFragment?): Boolean =
212
- mScreenFragments.contains(screenFragment)
210
+ open fun hasScreen(screenFragmentWrapper: ScreenFragmentWrapper?): Boolean =
211
+ mScreenFragments.contains(screenFragmentWrapper)
213
212
 
214
213
  override fun onAttachedToWindow() {
215
214
  super.onAttachedToWindow()
@@ -246,7 +245,7 @@ open class ScreenContainer<T : ScreenFragment>(context: Context?) : ViewGroup(co
246
245
  }
247
246
  }
248
247
 
249
- mParentScreenFragment?.unregisterChildScreenContainer(this)
248
+ mParentScreenFragment?.removeChildScreenContainer(this)
250
249
  mParentScreenFragment = null
251
250
 
252
251
  super.onDetachedFromWindow()
@@ -320,13 +319,13 @@ open class ScreenContainer<T : ScreenFragment>(context: Context?) : ViewGroup(co
320
319
  "mFragmentManager is null when performing update in ScreenContainer"
321
320
  }.fragments
322
321
  )
323
- for (screenFragment in mScreenFragments) {
324
- if (getActivityState(screenFragment) === ActivityState.INACTIVE &&
325
- screenFragment.isAdded
322
+ for (fragmentWrapper in mScreenFragments) {
323
+ if (getActivityState(fragmentWrapper) === ActivityState.INACTIVE &&
324
+ fragmentWrapper.fragment.isAdded
326
325
  ) {
327
- detachScreen(it, screenFragment)
326
+ detachScreen(it, fragmentWrapper.fragment)
328
327
  }
329
- orphaned.remove(screenFragment)
328
+ orphaned.remove(fragmentWrapper.fragment)
330
329
  }
331
330
  if (orphaned.isNotEmpty()) {
332
331
  val orphanedAry = orphaned.toTypedArray()
@@ -344,23 +343,23 @@ open class ScreenContainer<T : ScreenFragment>(context: Context?) : ViewGroup(co
344
343
 
345
344
  // attach newly activated screens
346
345
  var addedBefore = false
347
- val pendingFront: ArrayList<T> = ArrayList()
346
+ val pendingFront: ArrayList<ScreenFragmentWrapper> = ArrayList()
348
347
 
349
- for (screenFragment in mScreenFragments) {
350
- val activityState = getActivityState(screenFragment)
351
- if (activityState !== ActivityState.INACTIVE && !screenFragment.isAdded) {
348
+ for (fragmentWrapper in mScreenFragments) {
349
+ val activityState = getActivityState(fragmentWrapper)
350
+ if (activityState !== ActivityState.INACTIVE && !fragmentWrapper.fragment.isAdded) {
352
351
  addedBefore = true
353
- attachScreen(it, screenFragment)
352
+ attachScreen(it, fragmentWrapper.fragment)
354
353
  } else if (activityState !== ActivityState.INACTIVE && addedBefore) {
355
354
  // we detach the screen and then reattach it later to make it appear on front
356
- detachScreen(it, screenFragment)
357
- pendingFront.add(screenFragment)
355
+ detachScreen(it, fragmentWrapper.fragment)
356
+ pendingFront.add(fragmentWrapper)
358
357
  }
359
- screenFragment.screen.setTransitioning(transitioning)
358
+ fragmentWrapper.screen.setTransitioning(transitioning)
360
359
  }
361
360
 
362
361
  for (screenFragment in pendingFront) {
363
- attachScreen(it, screenFragment)
362
+ attachScreen(it, screenFragment.fragment)
364
363
  }
365
364
 
366
365
  it.commitNowAllowingStateLoss()
@@ -368,6 +367,6 @@ open class ScreenContainer<T : ScreenFragment>(context: Context?) : ViewGroup(co
368
367
  }
369
368
 
370
369
  protected open fun notifyContainerUpdate() {
371
- topScreen?.fragment?.onContainerUpdate()
370
+ topScreen?.fragmentWrapper?.onContainerUpdate()
372
371
  }
373
372
  }
@@ -8,27 +8,27 @@ import com.facebook.react.uimanager.ThemedReactContext
8
8
  import com.facebook.react.uimanager.ViewGroupManager
9
9
 
10
10
  @ReactModule(name = ScreenContainerViewManager.REACT_CLASS)
11
- class ScreenContainerViewManager : ViewGroupManager<ScreenContainer<*>>() {
11
+ class ScreenContainerViewManager : ViewGroupManager<ScreenContainer>() {
12
12
  override fun getName(): String = REACT_CLASS
13
13
 
14
- override fun createViewInstance(reactContext: ThemedReactContext): ScreenContainer<ScreenFragment> = ScreenContainer(reactContext)
14
+ override fun createViewInstance(reactContext: ThemedReactContext): ScreenContainer = ScreenContainer(reactContext)
15
15
 
16
- override fun addView(parent: ScreenContainer<*>, child: View, index: Int) {
16
+ override fun addView(parent: ScreenContainer, child: View, index: Int) {
17
17
  require(child is Screen) { "Attempt attach child that is not of type RNScreens" }
18
18
  parent.addScreen(child, index)
19
19
  }
20
20
 
21
- override fun removeViewAt(parent: ScreenContainer<*>, index: Int) {
21
+ override fun removeViewAt(parent: ScreenContainer, index: Int) {
22
22
  parent.removeScreenAt(index)
23
23
  }
24
24
 
25
- override fun removeAllViews(parent: ScreenContainer<*>) {
25
+ override fun removeAllViews(parent: ScreenContainer) {
26
26
  parent.removeAllScreens()
27
27
  }
28
28
 
29
- override fun getChildCount(parent: ScreenContainer<*>): Int = parent.screenCount
29
+ override fun getChildCount(parent: ScreenContainer): Int = parent.screenCount
30
30
 
31
- override fun getChildAt(parent: ScreenContainer<*>, index: Int): View = parent.getScreenAt(index)
31
+ override fun getChildAt(parent: ScreenContainer, index: Int): View = parent.getScreenAt(index)
32
32
 
33
33
  override fun createShadowNodeInstance(context: ReactApplicationContext): LayoutShadowNode = ScreensShadowNode(context)
34
34
 
@@ -0,0 +1,21 @@
1
+ package com.swmansion.rnscreens
2
+
3
+ interface ScreenEventDispatcher {
4
+ fun canDispatchLifecycleEvent(event: ScreenFragment.ScreenLifecycleEvent): Boolean
5
+ fun updateLastEventDispatched(event: ScreenFragment.ScreenLifecycleEvent)
6
+
7
+ /**
8
+ * Dispatches given screen lifecycle event to JS using screen from given fragment `fragmentWrapper`
9
+ */
10
+ fun dispatchLifecycleEvent(event: ScreenFragment.ScreenLifecycleEvent, fragmentWrapper: ScreenFragmentWrapper)
11
+
12
+ /**
13
+ * Dispatches given screen lifecycle event from all non-empty child containers to JS
14
+ */
15
+ fun dispatchLifecycleEventInChildContainers(event: ScreenFragment.ScreenLifecycleEvent)
16
+
17
+ fun dispatchHeaderBackButtonClickedEvent()
18
+ fun dispatchTransitionProgressEvent(alpha: Float, closing: Boolean)
19
+
20
+ // Concrete dispatchers
21
+ }