react-native-screens 4.9.0-beta.1 → 4.9.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 (20) hide show
  1. package/README.md +2 -1
  2. package/android/build.gradle +7 -0
  3. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt +8 -7
  4. package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/DimmingView.kt +20 -6
  5. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenContainerManagerInterface.java +2 -2
  6. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenContentWrapperManagerInterface.java +2 -2
  7. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenFooterManagerInterface.java +2 -2
  8. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerInterface.java +2 -2
  9. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerInterface.java +2 -2
  10. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderSubviewManagerInterface.java +2 -2
  11. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackManagerInterface.java +2 -2
  12. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSSearchBarManagerInterface.java +2 -2
  13. package/android/src/versioned/pointerevents/77/com/swmansion/rnscreens/ScreensCoordinatorLayoutPointerEventsImpl.kt +11 -0
  14. package/android/src/versioned/pointerevents/77/com/swmansion/rnscreens/bottomsheet/DimmingViewPointerEvents.kt +15 -0
  15. package/android/src/versioned/pointerevents/latest/com/swmansion/rnscreens/ScreensCoordinatorLayoutPointerEventsImpl.kt +11 -0
  16. package/android/src/versioned/pointerevents/latest/com/swmansion/rnscreens/bottomsheet/DimmingViewPointerEvents.kt +16 -0
  17. package/ios/RNSScreenStack.mm +1 -1
  18. package/ios/utils/RNSDefines.h +15 -0
  19. package/package.json +1 -1
  20. package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/GestureTransparentViewGroup.kt +0 -23
package/README.md CHANGED
@@ -107,7 +107,7 @@ Screens are already integrated with the React Native's most popular navigation l
107
107
  ## Supported react-native version
108
108
 
109
109
  Below we present tables with mapping of the library version to the last supported react-native version. These tables are for the `4.x` line of the library. For compat tables
110
- of `3.x` line please see consult [readme on the `3.x` branch](https://github.com/software-mansion/react-native-screens/tree/3.x?tab=readme-ov-file#supported-react-native-version).
110
+ of `3.x` line please see [readme on the `3.x` branch](https://github.com/software-mansion/react-native-screens/tree/3.x?tab=readme-ov-file#supported-react-native-version).
111
111
 
112
112
  ### Support for Paper
113
113
 
@@ -115,6 +115,7 @@ Paper is the default rendering system for React Native versions prior to 0.76.
115
115
 
116
116
  | library version | react-native version |
117
117
  | --------------- | -------------------- |
118
+ | 4.9.0+ | 0.76.0+ |
118
119
  | 4.5.0+ | 0.74.0+ |
119
120
  | 4.0.0+ | 0.72.0+ |
120
121
 
@@ -194,6 +194,13 @@ android {
194
194
  } else {
195
195
  srcDirs += "src/versioned/backgroundcolor/latest"
196
196
  }
197
+
198
+ // Native only classes that use PointerEvents
199
+ if (REACT_NATIVE_MINOR_VERSION <= 77) {
200
+ srcDirs += "src/versioned/pointerevents/77"
201
+ } else {
202
+ srcDirs += "src/versioned/pointerevents/latest"
203
+ }
197
204
  }
198
205
  res {
199
206
  if (safeExtGet(['compileSdkVersion', 'compileSdk'], rnsDefaultCompileSdkVersion) >= 33) {
@@ -27,7 +27,6 @@ import androidx.appcompat.widget.Toolbar
27
27
  import androidx.coordinatorlayout.widget.CoordinatorLayout
28
28
  import androidx.core.view.WindowInsetsCompat
29
29
  import com.facebook.react.uimanager.PixelUtil
30
- import com.facebook.react.uimanager.PointerEvents
31
30
  import com.facebook.react.uimanager.ReactPointerEventsView
32
31
  import com.facebook.react.uimanager.UIManagerHelper
33
32
  import com.google.android.material.appbar.AppBarLayout
@@ -722,9 +721,16 @@ class ScreenStackFragment :
722
721
  private class ScreensCoordinatorLayout(
723
722
  context: Context,
724
723
  private val fragment: ScreenStackFragment,
724
+ private val pointerEventsImpl: ReactPointerEventsView,
725
725
  // ) : CoordinatorLayout(context), ReactCompoundViewGroup, ReactHitSlopView {
726
726
  ) : CoordinatorLayout(context),
727
- ReactPointerEventsView {
727
+ ReactPointerEventsView by pointerEventsImpl {
728
+ constructor(context: Context, fragment: ScreenStackFragment) : this(
729
+ context,
730
+ fragment,
731
+ ScreensCoordinatorLayoutPointerEventsImpl(),
732
+ )
733
+
728
734
  override fun onApplyWindowInsets(insets: WindowInsets?): WindowInsets = super.onApplyWindowInsets(insets)
729
735
 
730
736
  private val animationListener: Animation.AnimationListener =
@@ -801,11 +807,6 @@ class ScreenStackFragment :
801
807
  // // bottom – The Y coordinate of the bottom of the rectangle
802
808
  // return Rect(screen.x.toInt(), -screen.y.toInt(), screen.x.toInt() + screen.width, screen.y.toInt() + screen.height)
803
809
  // }
804
-
805
- // We set pointer events to BOX_NONE, because we don't want the ScreensCoordinatorLayout
806
- // to be target of react gestures and effectively prevent interaction with screens
807
- // underneath the current screen (useful in `modal` & `formSheet` presentation).
808
- override val pointerEvents: PointerEvents = PointerEvents.BOX_NONE
809
810
  }
810
811
 
811
812
  private class ScreensAnimation(
@@ -5,7 +5,6 @@ import android.content.Context
5
5
  import android.graphics.Color
6
6
  import android.view.MotionEvent
7
7
  import android.view.ViewGroup
8
- import com.facebook.react.uimanager.PointerEvents
9
8
  import com.facebook.react.uimanager.ReactCompoundViewGroup
10
9
  import com.facebook.react.uimanager.ReactPointerEventsView
11
10
  import com.swmansion.rnscreens.ext.equalWithRespectToEps
@@ -17,13 +16,24 @@ import com.swmansion.rnscreens.ext.equalWithRespectToEps
17
16
  * This dimming view has one more additional feature: it blocks gestures if its alpha > 0.
18
17
  */
19
18
  @SuppressLint("ViewConstructor") // Only we instantiate this view
20
- class DimmingView(
19
+ internal class DimmingView(
21
20
  context: Context,
22
21
  initialAlpha: Float = 0.6F,
22
+ private val pointerEventsProxy: DimmingViewPointerEventsProxy
23
23
  ) : ViewGroup(context),
24
24
  ReactCompoundViewGroup,
25
- ReactPointerEventsView {
26
- private val blockGestures
25
+ ReactPointerEventsView by pointerEventsProxy {
26
+
27
+ constructor(context: Context, initialAlpha: Float = 0.6F) : this(
28
+ context, initialAlpha,
29
+ DimmingViewPointerEventsProxy(null)
30
+ )
31
+
32
+ init {
33
+ pointerEventsProxy.pointerEventsImpl = DimmingViewPointerEventsImpl(this)
34
+ }
35
+
36
+ internal val blockGestures
27
37
  get() = !alpha.equalWithRespectToEps(0F)
28
38
 
29
39
  init {
@@ -59,8 +69,12 @@ class DimmingView(
59
69
  y: Float,
60
70
  ) = blockGestures
61
71
 
62
- override val pointerEvents: PointerEvents
63
- get() = if (blockGestures) PointerEvents.AUTO else PointerEvents.NONE
72
+ override fun onDetachedFromWindow() {
73
+ super.onDetachedFromWindow()
74
+
75
+ // Break reference cycle, since the pointerEventsImpl strongly retains this.
76
+ pointerEventsProxy.pointerEventsImpl = null
77
+ }
64
78
 
65
79
  companion object {
66
80
  const val TAG = "DimmingView"
@@ -10,8 +10,8 @@
10
10
  package com.facebook.react.viewmanagers;
11
11
 
12
12
  import android.view.View;
13
- import com.facebook.react.uimanager.ViewManagerWithGeneratedInterface;
14
13
 
15
- public interface RNSScreenContainerManagerInterface<T extends View> extends ViewManagerWithGeneratedInterface {
14
+
15
+ public interface RNSScreenContainerManagerInterface<T extends View> {
16
16
  // No props
17
17
  }
@@ -10,8 +10,8 @@
10
10
  package com.facebook.react.viewmanagers;
11
11
 
12
12
  import android.view.View;
13
- import com.facebook.react.uimanager.ViewManagerWithGeneratedInterface;
14
13
 
15
- public interface RNSScreenContentWrapperManagerInterface<T extends View> extends ViewManagerWithGeneratedInterface {
14
+
15
+ public interface RNSScreenContentWrapperManagerInterface<T extends View> {
16
16
  // No props
17
17
  }
@@ -10,8 +10,8 @@
10
10
  package com.facebook.react.viewmanagers;
11
11
 
12
12
  import android.view.View;
13
- import com.facebook.react.uimanager.ViewManagerWithGeneratedInterface;
14
13
 
15
- public interface RNSScreenFooterManagerInterface<T extends View> extends ViewManagerWithGeneratedInterface {
14
+
15
+ public interface RNSScreenFooterManagerInterface<T extends View> {
16
16
  // No props
17
17
  }
@@ -13,9 +13,9 @@ import android.view.View;
13
13
  import androidx.annotation.Nullable;
14
14
  import com.facebook.react.bridge.ReadableArray;
15
15
  import com.facebook.react.bridge.ReadableMap;
16
- import com.facebook.react.uimanager.ViewManagerWithGeneratedInterface;
17
16
 
18
- public interface RNSScreenManagerInterface<T extends View> extends ViewManagerWithGeneratedInterface {
17
+
18
+ public interface RNSScreenManagerInterface<T extends View> {
19
19
  void setSheetAllowedDetents(T view, @Nullable ReadableArray value);
20
20
  void setSheetLargestUndimmedDetent(T view, int value);
21
21
  void setSheetGrabberVisible(T view, boolean value);
@@ -11,9 +11,9 @@ package com.facebook.react.viewmanagers;
11
11
 
12
12
  import android.view.View;
13
13
  import androidx.annotation.Nullable;
14
- import com.facebook.react.uimanager.ViewManagerWithGeneratedInterface;
15
14
 
16
- public interface RNSScreenStackHeaderConfigManagerInterface<T extends View> extends ViewManagerWithGeneratedInterface {
15
+
16
+ public interface RNSScreenStackHeaderConfigManagerInterface<T extends View> {
17
17
  void setBackgroundColor(T view, @Nullable Integer value);
18
18
  void setBackTitle(T view, @Nullable String value);
19
19
  void setBackTitleFontFamily(T view, @Nullable String value);
@@ -11,8 +11,8 @@ package com.facebook.react.viewmanagers;
11
11
 
12
12
  import android.view.View;
13
13
  import androidx.annotation.Nullable;
14
- import com.facebook.react.uimanager.ViewManagerWithGeneratedInterface;
15
14
 
16
- public interface RNSScreenStackHeaderSubviewManagerInterface<T extends View> extends ViewManagerWithGeneratedInterface {
15
+
16
+ public interface RNSScreenStackHeaderSubviewManagerInterface<T extends View> {
17
17
  void setType(T view, @Nullable String value);
18
18
  }
@@ -10,8 +10,8 @@
10
10
  package com.facebook.react.viewmanagers;
11
11
 
12
12
  import android.view.View;
13
- import com.facebook.react.uimanager.ViewManagerWithGeneratedInterface;
14
13
 
15
- public interface RNSScreenStackManagerInterface<T extends View> extends ViewManagerWithGeneratedInterface {
14
+
15
+ public interface RNSScreenStackManagerInterface<T extends View> {
16
16
  // No props
17
17
  }
@@ -11,9 +11,9 @@ package com.facebook.react.viewmanagers;
11
11
 
12
12
  import android.view.View;
13
13
  import androidx.annotation.Nullable;
14
- import com.facebook.react.uimanager.ViewManagerWithGeneratedInterface;
15
14
 
16
- public interface RNSSearchBarManagerInterface<T extends View> extends ViewManagerWithGeneratedInterface {
15
+
16
+ public interface RNSSearchBarManagerInterface<T extends View> {
17
17
  void setHideWhenScrolling(T view, boolean value);
18
18
  void setAutoCapitalize(T view, @Nullable String value);
19
19
  void setPlaceholder(T view, @Nullable String value);
@@ -0,0 +1,11 @@
1
+ package com.swmansion.rnscreens
2
+
3
+ import com.facebook.react.uimanager.PointerEvents
4
+ import com.facebook.react.uimanager.ReactPointerEventsView
5
+
6
+ internal class ScreensCoordinatorLayoutPointerEventsImpl : ReactPointerEventsView {
7
+ // We set pointer events to BOX_NONE, because we don't want the ScreensCoordinatorLayout
8
+ // to be target of react gestures and effectively prevent interaction with screens
9
+ // underneath the current screen (useful in `modal` & `formSheet` presentation).
10
+ override fun getPointerEvents(): PointerEvents = PointerEvents.BOX_NONE
11
+ }
@@ -0,0 +1,15 @@
1
+ package com.swmansion.rnscreens.bottomsheet
2
+
3
+ import com.facebook.react.uimanager.PointerEvents
4
+ import com.facebook.react.uimanager.ReactPointerEventsView
5
+ import com.swmansion.rnscreens.bottomsheet.DimmingView
6
+
7
+
8
+ internal class DimmingViewPointerEventsImpl(val dimmingView: DimmingView) : ReactPointerEventsView {
9
+ override fun getPointerEvents(): PointerEvents = if (dimmingView.blockGestures == false) PointerEvents.AUTO else PointerEvents.NONE
10
+ }
11
+
12
+ internal class DimmingViewPointerEventsProxy(var pointerEventsImpl: DimmingViewPointerEventsImpl?) :
13
+ ReactPointerEventsView {
14
+ override fun getPointerEvents(): PointerEvents = pointerEventsImpl?.pointerEvents ?: PointerEvents.NONE
15
+ }
@@ -0,0 +1,11 @@
1
+ package com.swmansion.rnscreens
2
+
3
+ import com.facebook.react.uimanager.PointerEvents
4
+ import com.facebook.react.uimanager.ReactPointerEventsView
5
+
6
+ internal class ScreensCoordinatorLayoutPointerEventsImpl() : ReactPointerEventsView {
7
+ // We set pointer events to BOX_NONE, because we don't want the ScreensCoordinatorLayout
8
+ // to be target of react gestures and effectively prevent interaction with screens
9
+ // underneath the current screen (useful in `modal` & `formSheet` presentation).
10
+ override val pointerEvents: PointerEvents = PointerEvents.BOX_NONE
11
+ }
@@ -0,0 +1,16 @@
1
+ package com.swmansion.rnscreens.bottomsheet
2
+
3
+ import com.facebook.react.uimanager.PointerEvents
4
+ import com.facebook.react.uimanager.ReactPointerEventsView
5
+
6
+
7
+ internal class DimmingViewPointerEventsImpl(val dimmingView: DimmingView) : ReactPointerEventsView {
8
+ override val pointerEvents: PointerEvents
9
+ get() = if (dimmingView.blockGestures == false) PointerEvents.AUTO else PointerEvents.NONE
10
+ }
11
+
12
+ internal class DimmingViewPointerEventsProxy(var pointerEventsImpl: DimmingViewPointerEventsImpl?) :
13
+ ReactPointerEventsView {
14
+ override val pointerEvents: PointerEvents
15
+ get() = pointerEventsImpl?.pointerEvents ?: PointerEvents.NONE
16
+ }
@@ -1232,7 +1232,7 @@ RNS_IGNORE_SUPER_CALL_END
1232
1232
  withSurfaceTelemetry:(const facebook::react::SurfaceTelemetry &)surfaceTelemetry
1233
1233
  {
1234
1234
  for (const auto &mutation : transaction.getMutations()) {
1235
- if (mutation.parentTag == self.tag &&
1235
+ if (MUTATION_PARENT_TAG(mutation) == self.tag &&
1236
1236
  (mutation.type == react::ShadowViewMutation::Type::Insert ||
1237
1237
  mutation.type == react::ShadowViewMutation::Type::Remove)) {
1238
1238
  // we need to wait until children have their layout set. At this point they don't have the layout
@@ -5,3 +5,18 @@
5
5
  _Pragma("clang diagnostic ignored \"-Wobjc-missing-super-calls\"")
6
6
 
7
7
  #define RNS_IGNORE_SUPER_CALL_END _Pragma("clang diagnostic pop")
8
+
9
+ #if defined __has_include
10
+ #if __has_include( \
11
+ <React-RCTAppDelegate/RCTReactNativeFactory.h>) // added in 78
12
+ #define RNS_REACT_NATIVE_VERSION_MINOR_BELOW_78 0
13
+ #else
14
+ #define RNS_REACT_NATIVE_VERSION_MINOR_BELOW_78 1
15
+ #endif
16
+ #endif
17
+
18
+ #if RNS_REACT_NATIVE_VERSION_MINOR_BELOW_78
19
+ #define MUTATION_PARENT_TAG(mutation) mutation.parentShadowView.tag
20
+ #else
21
+ #define MUTATION_PARENT_TAG(mutation) mutation.parentTag
22
+ #endif
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-screens",
3
- "version": "4.9.0-beta.1",
3
+ "version": "4.9.0",
4
4
  "description": "Native navigation primitives for your React Native app.",
5
5
  "scripts": {
6
6
  "submodules": "git submodule update --init --recursive && (cd react-navigation && yarn && yarn build && cd ../)",
@@ -1,23 +0,0 @@
1
- package com.swmansion.rnscreens.bottomsheet
2
-
3
- import android.content.Context
4
- import android.widget.FrameLayout
5
- import com.facebook.react.uimanager.PointerEvents
6
- import com.facebook.react.uimanager.ReactPointerEventsView
7
-
8
- /**
9
- * View group that will be ignored by RN event system, and won't be target of touches.
10
- *
11
- * Currently used as container for the form sheet, so that user can interact with the view
12
- * under the sheet (otherwise RN captures the gestures).
13
- */
14
- class GestureTransparentViewGroup(
15
- context: Context,
16
- ) : FrameLayout(context),
17
- ReactPointerEventsView {
18
- override val pointerEvents: PointerEvents = PointerEvents.BOX_NONE
19
-
20
- companion object {
21
- const val TAG = "GestureTransparentFrameLayout"
22
- }
23
- }