react-native-screens 4.5.0 → 4.6.0-beta.1
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/android/build.gradle +1 -1
- package/android/src/fabric/java/com/swmansion/rnscreens/FabricEnabledHeaderConfigViewGroup.kt +31 -10
- package/android/src/fabric/java/com/swmansion/rnscreens/FabricEnabledHeaderSubviewViewGroup.kt +51 -0
- package/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt +12 -2
- package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +0 -26
- package/android/src/main/java/com/swmansion/rnscreens/ScreenModalFragment.kt +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +16 -7
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt +5 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt +1 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubview.kt +12 -7
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubviewManager.kt +13 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.kt +7 -0
- package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/BottomSheetBehaviorExt.kt +6 -3
- package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/BottomSheetDialogRootView.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/DimmingView.kt +1 -2
- package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/GestureTransparentViewGroup.kt +0 -1
- package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/SheetUtils.kt +2 -2
- package/android/src/main/java/com/swmansion/rnscreens/utils/ScreenDummyLayoutHelper.kt +6 -3
- package/android/src/main/jni/rnscreens.h +1 -0
- package/android/src/paper/java/com/swmansion/rnscreens/FabricEnabledHeaderConfigViewGroup.kt +9 -1
- package/android/src/paper/java/com/swmansion/rnscreens/FabricEnabledHeaderSubviewViewGroup.kt +19 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSFullWindowOverlayComponentDescriptor.h +17 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSFullWindowOverlayShadowNode.cpp +7 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSFullWindowOverlayShadowNode.h +35 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSFullWindowOverlayState.h +30 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderConfigComponentDescriptor.h +12 -2
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderConfigShadowNode.cpp +12 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderConfigShadowNode.h +4 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderConfigState.cpp +4 -10
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderConfigState.h +15 -9
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderSubviewComponentDescriptor.h +20 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderSubviewShadowNode.cpp +14 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderSubviewShadowNode.h +2 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderSubviewState.cpp +3 -1
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderSubviewState.h +16 -2
- package/ios/RNSFullWindowOverlay.mm +10 -0
- package/ios/RNSScreenStack.mm +11 -7
- package/ios/RNSScreenStackHeaderConfig.h +21 -7
- package/ios/RNSScreenStackHeaderConfig.mm +77 -17
- package/ios/RNSScreenStackHeaderSubview.h +4 -0
- package/ios/RNSScreenStackHeaderSubview.mm +26 -1
- package/lib/commonjs/components/ScreenStackHeaderConfig.js +0 -1
- package/lib/commonjs/components/ScreenStackHeaderConfig.js.map +1 -1
- package/lib/commonjs/fabric/FullWindowOverlayNativeComponent.js +3 -1
- package/lib/commonjs/fabric/FullWindowOverlayNativeComponent.js.map +1 -1
- package/lib/commonjs/gesture-handler/ScreenGestureDetector.js +12 -0
- package/lib/commonjs/gesture-handler/ScreenGestureDetector.js.map +1 -1
- package/lib/commonjs/gesture-handler/defaults.js +1 -2
- package/lib/commonjs/gesture-handler/defaults.js.map +1 -1
- package/lib/module/components/ScreenStackHeaderConfig.js +0 -1
- package/lib/module/components/ScreenStackHeaderConfig.js.map +1 -1
- package/lib/module/fabric/FullWindowOverlayNativeComponent.js +3 -1
- package/lib/module/fabric/FullWindowOverlayNativeComponent.js.map +1 -1
- package/lib/module/gesture-handler/ScreenGestureDetector.js +12 -0
- package/lib/module/gesture-handler/ScreenGestureDetector.js.map +1 -1
- package/lib/module/gesture-handler/defaults.js +1 -2
- package/lib/module/gesture-handler/defaults.js.map +1 -1
- package/lib/typescript/fabric/FullWindowOverlayNativeComponent.d.ts.map +1 -1
- package/lib/typescript/gesture-handler/ScreenGestureDetector.d.ts.map +1 -1
- package/lib/typescript/gesture-handler/defaults.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +25 -3
- package/lib/typescript/types.d.ts.map +1 -1
- package/package.json +10 -9
- package/src/components/ScreenStackHeaderConfig.tsx +0 -1
- package/src/fabric/FullWindowOverlayNativeComponent.ts +3 -1
- package/src/gesture-handler/ScreenGestureDetector.tsx +14 -2
- package/src/gesture-handler/defaults.ts +0 -1
- package/src/types.tsx +25 -3
package/android/build.gradle
CHANGED
|
@@ -20,7 +20,7 @@ buildscript {
|
|
|
20
20
|
mavenCentral()
|
|
21
21
|
}
|
|
22
22
|
dependencies {
|
|
23
|
-
classpath('com.android.tools.build:gradle:
|
|
23
|
+
classpath('com.android.tools.build:gradle:8.2.1')
|
|
24
24
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${safeExtGet('kotlinVersion', rnsDefaultKotlinVersion)}"
|
|
25
25
|
classpath "com.diffplug.spotless:spotless-plugin-gradle:6.25.0"
|
|
26
26
|
}
|
package/android/src/fabric/java/com/swmansion/rnscreens/FabricEnabledHeaderConfigViewGroup.kt
CHANGED
|
@@ -14,6 +14,8 @@ abstract class FabricEnabledHeaderConfigViewGroup(
|
|
|
14
14
|
) : ViewGroup(context) {
|
|
15
15
|
private var mStateWrapper: StateWrapper? = null
|
|
16
16
|
|
|
17
|
+
private var lastWidth = 0f
|
|
18
|
+
private var lastHeight = 0f
|
|
17
19
|
private var lastPaddingStart = 0f
|
|
18
20
|
private var lastPaddingEnd = 0f
|
|
19
21
|
|
|
@@ -21,36 +23,55 @@ abstract class FabricEnabledHeaderConfigViewGroup(
|
|
|
21
23
|
mStateWrapper = wrapper
|
|
22
24
|
}
|
|
23
25
|
|
|
24
|
-
fun
|
|
26
|
+
fun updatePaddings(
|
|
25
27
|
paddingStart: Int,
|
|
26
28
|
paddingEnd: Int,
|
|
27
29
|
) {
|
|
28
|
-
|
|
30
|
+
// Do nothing on Fabric. This method is used only on Paper.
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
fun updateHeaderConfigState(
|
|
34
|
+
width: Int,
|
|
35
|
+
height: Int,
|
|
36
|
+
paddingStart: Int,
|
|
37
|
+
paddingEnd: Int,
|
|
38
|
+
) {
|
|
39
|
+
updateState(width, height, paddingStart, paddingEnd)
|
|
29
40
|
}
|
|
30
41
|
|
|
31
42
|
@UiThread
|
|
32
43
|
fun updateState(
|
|
44
|
+
width: Int,
|
|
45
|
+
height: Int,
|
|
33
46
|
paddingStart: Int,
|
|
34
47
|
paddingEnd: Int,
|
|
35
48
|
) {
|
|
36
|
-
val
|
|
37
|
-
val
|
|
49
|
+
val realWidth: Float = PixelUtil.toDIPFromPixel(width.toFloat())
|
|
50
|
+
val realHeight: Float = PixelUtil.toDIPFromPixel(height.toFloat())
|
|
51
|
+
val realPaddingStart: Float = PixelUtil.toDIPFromPixel(paddingStart.toFloat())
|
|
52
|
+
val realPaddingEnd: Float = PixelUtil.toDIPFromPixel(paddingEnd.toFloat())
|
|
38
53
|
|
|
39
54
|
// Check incoming state values. If they're already the correct value, return early to prevent
|
|
40
55
|
// infinite UpdateState/SetState loop.
|
|
41
|
-
if (abs(
|
|
42
|
-
abs(
|
|
56
|
+
if (abs(lastWidth - realWidth) < DELTA &&
|
|
57
|
+
abs(lastHeight - realHeight) < DELTA &&
|
|
58
|
+
abs(lastPaddingStart - realPaddingStart) < DELTA &&
|
|
59
|
+
abs(lastPaddingEnd - realPaddingEnd) < DELTA
|
|
43
60
|
) {
|
|
44
61
|
return
|
|
45
62
|
}
|
|
46
63
|
|
|
47
|
-
|
|
48
|
-
|
|
64
|
+
lastWidth = realWidth
|
|
65
|
+
lastHeight = realHeight
|
|
66
|
+
lastPaddingStart = realPaddingStart
|
|
67
|
+
lastPaddingEnd = realPaddingEnd
|
|
49
68
|
|
|
50
69
|
val map: WritableMap =
|
|
51
70
|
WritableNativeMap().apply {
|
|
52
|
-
putDouble("
|
|
53
|
-
putDouble("
|
|
71
|
+
putDouble("frameWidth", realWidth.toDouble())
|
|
72
|
+
putDouble("frameHeight", realHeight.toDouble())
|
|
73
|
+
putDouble("paddingStart", realPaddingStart.toDouble())
|
|
74
|
+
putDouble("paddingEnd", realPaddingEnd.toDouble())
|
|
54
75
|
}
|
|
55
76
|
mStateWrapper?.updateState(map)
|
|
56
77
|
}
|
package/android/src/fabric/java/com/swmansion/rnscreens/FabricEnabledHeaderSubviewViewGroup.kt
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
package com.swmansion.rnscreens
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.view.ViewGroup
|
|
5
|
+
import androidx.annotation.UiThread
|
|
6
|
+
import com.facebook.react.bridge.WritableMap
|
|
7
|
+
import com.facebook.react.bridge.WritableNativeMap
|
|
8
|
+
import com.facebook.react.uimanager.PixelUtil
|
|
9
|
+
import com.facebook.react.uimanager.StateWrapper
|
|
10
|
+
|
|
11
|
+
abstract class FabricEnabledHeaderSubviewViewGroup(
|
|
12
|
+
context: Context?,
|
|
13
|
+
) : ViewGroup(context) {
|
|
14
|
+
private var mStateWrapper: StateWrapper? = null
|
|
15
|
+
|
|
16
|
+
fun setStateWrapper(wrapper: StateWrapper?) {
|
|
17
|
+
mStateWrapper = wrapper
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
protected fun updateSubviewFrameState(
|
|
21
|
+
width: Int,
|
|
22
|
+
height: Int,
|
|
23
|
+
offsetX: Int,
|
|
24
|
+
offsetY: Int,
|
|
25
|
+
) {
|
|
26
|
+
updateState(width, height, offsetX, offsetY)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@UiThread
|
|
30
|
+
fun updateState(
|
|
31
|
+
width: Int,
|
|
32
|
+
height: Int,
|
|
33
|
+
offsetX: Int,
|
|
34
|
+
offsetY: Int,
|
|
35
|
+
) {
|
|
36
|
+
val realWidth: Float = PixelUtil.toDIPFromPixel(width.toFloat())
|
|
37
|
+
val realHeight: Float = PixelUtil.toDIPFromPixel(height.toFloat())
|
|
38
|
+
val offsetXDip: Float = PixelUtil.toDIPFromPixel(offsetX.toFloat())
|
|
39
|
+
val offsetYDip: Float = PixelUtil.toDIPFromPixel(offsetY.toFloat())
|
|
40
|
+
|
|
41
|
+
val map: WritableMap =
|
|
42
|
+
WritableNativeMap().apply {
|
|
43
|
+
putDouble("frameWidth", realWidth.toDouble())
|
|
44
|
+
putDouble("frameHeight", realHeight.toDouble())
|
|
45
|
+
putDouble("contentOffsetX", offsetXDip.toDouble())
|
|
46
|
+
putDouble("contentOffsetY", offsetYDip.toDouble())
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
mStateWrapper?.updateState(map)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -68,8 +68,18 @@ open class CustomToolbar(
|
|
|
68
68
|
) {
|
|
69
69
|
super.onLayout(changed, l, t, r, b)
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
if (!changed) {
|
|
72
|
+
return
|
|
73
|
+
}
|
|
74
|
+
|
|
72
75
|
val contentInsetStart = if (navigationIcon != null) contentInsetStartWithNavigation else contentInsetStart
|
|
73
|
-
|
|
76
|
+
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
|
77
|
+
val width = r - l
|
|
78
|
+
val height = b - t
|
|
79
|
+
config.updateHeaderConfigState(width, height, contentInsetStart, contentInsetEnd)
|
|
80
|
+
} else {
|
|
81
|
+
// our children are already laid out
|
|
82
|
+
config.updatePaddings(contentInsetStart, contentInsetEnd)
|
|
83
|
+
}
|
|
74
84
|
}
|
|
75
85
|
}
|
|
@@ -17,12 +17,9 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
|
|
17
17
|
import com.facebook.react.bridge.GuardedRunnable
|
|
18
18
|
import com.facebook.react.bridge.ReactContext
|
|
19
19
|
import com.facebook.react.uimanager.PixelUtil
|
|
20
|
-
import com.facebook.react.uimanager.ReactClippingViewGroup
|
|
21
20
|
import com.facebook.react.uimanager.UIManagerHelper
|
|
22
21
|
import com.facebook.react.uimanager.UIManagerModule
|
|
23
22
|
import com.facebook.react.uimanager.events.EventDispatcher
|
|
24
|
-
import com.facebook.react.views.scroll.ReactHorizontalScrollView
|
|
25
|
-
import com.facebook.react.views.scroll.ReactScrollView
|
|
26
23
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
|
27
24
|
import com.google.android.material.shape.CornerFamily
|
|
28
25
|
import com.google.android.material.shape.MaterialShapeDrawable
|
|
@@ -404,29 +401,6 @@ class Screen(
|
|
|
404
401
|
}
|
|
405
402
|
|
|
406
403
|
if (child is ViewGroup) {
|
|
407
|
-
// The children are miscounted when there's removeClippedSubviews prop
|
|
408
|
-
// set to true (which is the default for FlatLists).
|
|
409
|
-
// Unless the child is a ScrollView it's safe to assume that it's true
|
|
410
|
-
// and add a simple view for each possibly clipped item to make it work as expected.
|
|
411
|
-
// See https://github.com/software-mansion/react-native-screens/pull/2495
|
|
412
|
-
|
|
413
|
-
if (child is ReactClippingViewGroup &&
|
|
414
|
-
child.removeClippedSubviews &&
|
|
415
|
-
child !is ReactScrollView &&
|
|
416
|
-
child !is ReactHorizontalScrollView
|
|
417
|
-
) {
|
|
418
|
-
// We need to workaround the issue until our changes land in core.
|
|
419
|
-
// Some views do not accept any children or have set amount and they throw
|
|
420
|
-
// when we want to brute-forcefully manipulate that.
|
|
421
|
-
// Is this ugly? Very. Do we have better option before changes land in core?
|
|
422
|
-
// I'm not aware of any.
|
|
423
|
-
try {
|
|
424
|
-
for (j in 0 until child.childCount) {
|
|
425
|
-
child.addView(View(context))
|
|
426
|
-
}
|
|
427
|
-
} catch (_: Exception) {
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
404
|
startTransitionRecursive(child)
|
|
431
405
|
}
|
|
432
406
|
}
|
|
@@ -72,7 +72,10 @@ class ScreenModalFragment :
|
|
|
72
72
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
|
73
73
|
configureDialogAndBehaviour()
|
|
74
74
|
|
|
75
|
-
val reactEventDispatcher =
|
|
75
|
+
val reactEventDispatcher =
|
|
76
|
+
checkNotNull(
|
|
77
|
+
screen.reactEventDispatcher,
|
|
78
|
+
) { "[RNScreens] No ReactEventDispatcher attached to screen while creating modal fragment" }
|
|
76
79
|
val rootView = BottomSheetDialogRootView(screen.reactContext, reactEventDispatcher)
|
|
77
80
|
|
|
78
81
|
rootView.addView(screen.recycle())
|
|
@@ -248,7 +248,7 @@ class ScreenStack(
|
|
|
248
248
|
|
|
249
249
|
if (shouldUseOpenAnimation &&
|
|
250
250
|
newTop != null &&
|
|
251
|
-
needsDrawReordering(newTop) &&
|
|
251
|
+
needsDrawReordering(newTop, stackAnimation) &&
|
|
252
252
|
visibleBottom == null
|
|
253
253
|
) {
|
|
254
254
|
// When using an open animation in which two screens overlap (eg. fade_from_bottom or
|
|
@@ -258,6 +258,7 @@ class ScreenStack(
|
|
|
258
258
|
// appears on top of the previous one. You can read more about in the comment
|
|
259
259
|
// for the code we use to change that behavior:
|
|
260
260
|
// https://github.com/airbnb/native-navigation/blob/9cf50bf9b751b40778f473f3b19fcfe2c4d40599/lib/android/src/main/java/com/airbnb/android/react/navigation/ScreenCoordinatorLayout.java#L18
|
|
261
|
+
// Note: This should not be set in case there is only a single screen in stack or animation `none` is used. Atm needsDrawReordering implementation guards that assuming that first screen on stack uses `NONE` animation.
|
|
261
262
|
isDetachingCurrentScreen = true
|
|
262
263
|
}
|
|
263
264
|
|
|
@@ -426,14 +427,22 @@ class ScreenStack(
|
|
|
426
427
|
companion object {
|
|
427
428
|
const val TAG = "ScreenStack"
|
|
428
429
|
|
|
429
|
-
private fun needsDrawReordering(
|
|
430
|
+
private fun needsDrawReordering(
|
|
431
|
+
fragmentWrapper: ScreenFragmentWrapper,
|
|
432
|
+
resolvedStackAnimation: StackAnimation?,
|
|
433
|
+
): Boolean {
|
|
434
|
+
val stackAnimation = if (resolvedStackAnimation != null) resolvedStackAnimation else fragmentWrapper.screen.stackAnimation
|
|
430
435
|
// On Android sdk 33 and above the animation is different and requires draw reordering.
|
|
431
436
|
// For React Native 0.70 and lower versions, `Build.VERSION_CODES.TIRAMISU` is not defined yet.
|
|
432
437
|
// Hence, we're comparing numerical version here.
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
+
return (
|
|
439
|
+
Build.VERSION.SDK_INT >= 33 ||
|
|
440
|
+
stackAnimation === StackAnimation.SLIDE_FROM_BOTTOM ||
|
|
441
|
+
stackAnimation === StackAnimation.FADE_FROM_BOTTOM ||
|
|
442
|
+
stackAnimation === StackAnimation.IOS_FROM_RIGHT ||
|
|
443
|
+
stackAnimation === StackAnimation.IOS_FROM_LEFT
|
|
444
|
+
) &&
|
|
445
|
+
stackAnimation !== StackAnimation.NONE
|
|
446
|
+
}
|
|
438
447
|
}
|
|
439
448
|
}
|
|
@@ -478,6 +478,11 @@ class ScreenStackFragment :
|
|
|
478
478
|
screen.background = shape
|
|
479
479
|
}
|
|
480
480
|
|
|
481
|
+
override fun onStart() {
|
|
482
|
+
lastFocusedChild?.requestFocus()
|
|
483
|
+
super.onStart()
|
|
484
|
+
}
|
|
485
|
+
|
|
481
486
|
override fun onStop() {
|
|
482
487
|
if (DeviceUtils.isPlatformAndroidTV(context)) {
|
|
483
488
|
lastFocusedChild = findLastFocusedChild()
|
|
@@ -157,6 +157,7 @@ class ScreenStackHeaderConfigViewManager :
|
|
|
157
157
|
config.setHideBackButton(hideBackButton)
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
+
@Deprecated("For apps targeting SDK 35 or above edge-to-edge is enabled by default.")
|
|
160
161
|
@ReactProp(name = "topInsetEnabled")
|
|
161
162
|
override fun setTopInsetEnabled(
|
|
162
163
|
config: ScreenStackHeaderConfig,
|
|
@@ -3,12 +3,11 @@ package com.swmansion.rnscreens
|
|
|
3
3
|
import android.annotation.SuppressLint
|
|
4
4
|
import android.view.View
|
|
5
5
|
import com.facebook.react.bridge.ReactContext
|
|
6
|
-
import com.facebook.react.views.view.ReactViewGroup
|
|
7
6
|
|
|
8
7
|
@SuppressLint("ViewConstructor")
|
|
9
8
|
class ScreenStackHeaderSubview(
|
|
10
9
|
context: ReactContext?,
|
|
11
|
-
) :
|
|
10
|
+
) : FabricEnabledHeaderSubviewViewGroup(context) {
|
|
12
11
|
private var reactWidth = 0
|
|
13
12
|
private var reactHeight = 0
|
|
14
13
|
var type = Type.RIGHT
|
|
@@ -37,11 +36,17 @@ class ScreenStackHeaderSubview(
|
|
|
37
36
|
|
|
38
37
|
override fun onLayout(
|
|
39
38
|
changed: Boolean,
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
)
|
|
39
|
+
l: Int,
|
|
40
|
+
t: Int,
|
|
41
|
+
r: Int,
|
|
42
|
+
b: Int,
|
|
43
|
+
) {
|
|
44
|
+
if (changed && BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
|
45
|
+
val width = r - l
|
|
46
|
+
val height = b - t
|
|
47
|
+
updateSubviewFrameState(width, height, l, t)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
45
50
|
|
|
46
51
|
enum class Type {
|
|
47
52
|
LEFT,
|
|
@@ -2,6 +2,8 @@ package com.swmansion.rnscreens
|
|
|
2
2
|
|
|
3
3
|
import com.facebook.react.bridge.JSApplicationIllegalArgumentException
|
|
4
4
|
import com.facebook.react.module.annotations.ReactModule
|
|
5
|
+
import com.facebook.react.uimanager.ReactStylesDiffMap
|
|
6
|
+
import com.facebook.react.uimanager.StateWrapper
|
|
5
7
|
import com.facebook.react.uimanager.ThemedReactContext
|
|
6
8
|
import com.facebook.react.uimanager.ViewGroupManager
|
|
7
9
|
import com.facebook.react.uimanager.ViewManagerDelegate
|
|
@@ -39,6 +41,17 @@ class ScreenStackHeaderSubviewManager :
|
|
|
39
41
|
}
|
|
40
42
|
}
|
|
41
43
|
|
|
44
|
+
override fun updateState(
|
|
45
|
+
view: ScreenStackHeaderSubview,
|
|
46
|
+
props: ReactStylesDiffMap?,
|
|
47
|
+
stateWrapper: StateWrapper?,
|
|
48
|
+
): Any? {
|
|
49
|
+
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
|
50
|
+
view.setStateWrapper(stateWrapper)
|
|
51
|
+
}
|
|
52
|
+
return super.updateState(view, props, stateWrapper)
|
|
53
|
+
}
|
|
54
|
+
|
|
42
55
|
protected override fun getDelegate(): ViewManagerDelegate<ScreenStackHeaderSubview> = delegate
|
|
43
56
|
|
|
44
57
|
companion object {
|
|
@@ -192,6 +192,10 @@ open class ScreenViewManager :
|
|
|
192
192
|
view.isStatusBarAnimated = animated
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
+
@Deprecated(
|
|
196
|
+
"For apps targeting SDK 35 or above this prop has no effect. " +
|
|
197
|
+
"Since the edge-to-edge is enabled by default the color is always translucent.",
|
|
198
|
+
)
|
|
195
199
|
@ReactProp(name = "statusBarColor", customType = "Color")
|
|
196
200
|
override fun setStatusBarColor(
|
|
197
201
|
view: Screen,
|
|
@@ -208,6 +212,7 @@ open class ScreenViewManager :
|
|
|
208
212
|
view.statusBarStyle = statusBarStyle
|
|
209
213
|
}
|
|
210
214
|
|
|
215
|
+
@Deprecated("For apps targeting SDK 35 or above edge-to-edge is enabled by default and will be enforced in the future.")
|
|
211
216
|
@ReactProp(name = "statusBarTranslucent")
|
|
212
217
|
override fun setStatusBarTranslucent(
|
|
213
218
|
view: Screen,
|
|
@@ -224,6 +229,7 @@ open class ScreenViewManager :
|
|
|
224
229
|
view.isStatusBarHidden = statusBarHidden
|
|
225
230
|
}
|
|
226
231
|
|
|
232
|
+
@Deprecated("For apps targeting SDK 35 or above this prop has no effect")
|
|
227
233
|
@ReactProp(name = "navigationBarColor", customType = "Color")
|
|
228
234
|
override fun setNavigationBarColor(
|
|
229
235
|
view: Screen,
|
|
@@ -232,6 +238,7 @@ open class ScreenViewManager :
|
|
|
232
238
|
view.navigationBarColor = navigationBarColor
|
|
233
239
|
}
|
|
234
240
|
|
|
241
|
+
@Deprecated("For apps targeting SDK 35 or above edge-to-edge is enabled by default")
|
|
235
242
|
@ReactProp(name = "navigationBarTranslucent")
|
|
236
243
|
override fun setNavigationBarTranslucent(
|
|
237
244
|
view: Screen,
|
|
@@ -3,7 +3,10 @@ package com.swmansion.rnscreens.bottomsheet
|
|
|
3
3
|
import android.view.View
|
|
4
4
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
|
5
5
|
|
|
6
|
-
internal fun <T : View> BottomSheetBehavior<T>.useSingleDetent(
|
|
6
|
+
internal fun <T : View> BottomSheetBehavior<T>.useSingleDetent(
|
|
7
|
+
height: Int? = null,
|
|
8
|
+
forceExpandedState: Boolean = true,
|
|
9
|
+
): BottomSheetBehavior<T> {
|
|
7
10
|
this.skipCollapsed = true
|
|
8
11
|
this.isFitToContents = true
|
|
9
12
|
if (forceExpandedState) {
|
|
@@ -16,7 +19,7 @@ internal fun <T : View> BottomSheetBehavior<T>.useSingleDetent(height: Int? = nu
|
|
|
16
19
|
internal fun <T : View> BottomSheetBehavior<T>.useTwoDetents(
|
|
17
20
|
@BottomSheetBehavior.StableState state: Int? = null,
|
|
18
21
|
firstHeight: Int? = null,
|
|
19
|
-
secondHeight: Int? = null
|
|
22
|
+
secondHeight: Int? = null,
|
|
20
23
|
): BottomSheetBehavior<T> {
|
|
21
24
|
skipCollapsed = false
|
|
22
25
|
isFitToContents = true
|
|
@@ -30,7 +33,7 @@ internal fun <T : View> BottomSheetBehavior<T>.useThreeDetents(
|
|
|
30
33
|
@BottomSheetBehavior.StableState state: Int? = null,
|
|
31
34
|
firstHeight: Int? = null,
|
|
32
35
|
halfExpandedRatio: Float? = null,
|
|
33
|
-
expandedOffsetFromTop: Int? = null
|
|
36
|
+
expandedOffsetFromTop: Int? = null,
|
|
34
37
|
): BottomSheetBehavior<T> {
|
|
35
38
|
skipCollapsed = false
|
|
36
39
|
isFitToContents = false
|
package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/BottomSheetDialogRootView.kt
CHANGED
|
@@ -37,7 +37,7 @@ class BottomSheetDialogRootView(
|
|
|
37
37
|
if (changed) {
|
|
38
38
|
// This view is used right now only in ScreenModalFragment, where it is injected
|
|
39
39
|
// to view hierarchy as a parent of a Screen.
|
|
40
|
-
assert(childCount == 1) { "[RNScreens] Expected only a single child view under $
|
|
40
|
+
assert(childCount == 1) { "[RNScreens] Expected only a single child view under $TAG, received: $childCount" }
|
|
41
41
|
getChildAt(0).layout(l, t, r, b)
|
|
42
42
|
}
|
|
43
43
|
}
|
|
@@ -57,8 +57,7 @@ class DimmingView(
|
|
|
57
57
|
y: Float,
|
|
58
58
|
) = blockGestures
|
|
59
59
|
|
|
60
|
-
override fun getPointerEvents(): PointerEvents =
|
|
61
|
-
if (blockGestures) PointerEvents.AUTO else PointerEvents.NONE
|
|
60
|
+
override fun getPointerEvents(): PointerEvents = if (blockGestures) PointerEvents.AUTO else PointerEvents.NONE
|
|
62
61
|
|
|
63
62
|
companion object {
|
|
64
63
|
const val TAG = "DimmingView"
|
|
@@ -129,7 +129,7 @@ object SheetUtils {
|
|
|
129
129
|
|
|
130
130
|
fun Screen.isSheetFitToContents(): Boolean =
|
|
131
131
|
stackPresentation === Screen.StackPresentation.FORM_SHEET &&
|
|
132
|
-
|
|
133
|
-
|
|
132
|
+
sheetDetents.count() == 1 &&
|
|
133
|
+
sheetDetents.first() == Screen.SHEET_FIT_TO_CONTENTS
|
|
134
134
|
|
|
135
135
|
fun Screen.usesFormSheetPresentation(): Boolean = stackPresentation === Screen.StackPresentation.FORM_SHEET
|
|
@@ -82,7 +82,9 @@ internal class ScreenDummyLayoutHelper(
|
|
|
82
82
|
// We need to use activity here, as react context does not have theme attributes required by
|
|
83
83
|
// AppBarLayout attached leading to crash.
|
|
84
84
|
val contextWithTheme =
|
|
85
|
-
requireNotNull(reactContext.currentActivity) {
|
|
85
|
+
requireNotNull(reactContext.currentActivity) {
|
|
86
|
+
"[RNScreens] Attempt to use context detached from activity. This could happen only due to race-condition."
|
|
87
|
+
}
|
|
86
88
|
|
|
87
89
|
synchronized(this) {
|
|
88
90
|
// The layout could have been initialised when this thread waited for access to critical section.
|
|
@@ -166,7 +168,7 @@ internal class ScreenDummyLayoutHelper(
|
|
|
166
168
|
// is still null at this execution point. We don't wanna crash in such case, thus returning zeroed height.
|
|
167
169
|
Log.e(
|
|
168
170
|
TAG,
|
|
169
|
-
"[RNScreens] Failed to late-init layout while computing header height. This is most likely a race-condition-bug in react-native-screens, please file an issue at https://github.com/software-mansion/react-native-screens/issues"
|
|
171
|
+
"[RNScreens] Failed to late-init layout while computing header height. This is most likely a race-condition-bug in react-native-screens, please file an issue at https://github.com/software-mansion/react-native-screens/issues",
|
|
170
172
|
)
|
|
171
173
|
return 0.0f
|
|
172
174
|
}
|
|
@@ -214,7 +216,8 @@ internal class ScreenDummyLayoutHelper(
|
|
|
214
216
|
private fun requireReactContext(lazyMessage: (() -> Any)? = null): ReactApplicationContext =
|
|
215
217
|
requireNotNull(
|
|
216
218
|
reactContextRef.get(),
|
|
217
|
-
lazyMessage ?: { "[RNScreens] Attempt to require missing react context" }
|
|
219
|
+
lazyMessage ?: { "[RNScreens] Attempt to require missing react context" },
|
|
220
|
+
)
|
|
218
221
|
|
|
219
222
|
private fun requireActivity(): Activity =
|
|
220
223
|
requireNotNull(requireReactContext().currentActivity) {
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
#include <react/renderer/components/rnscreens/RNSModalScreenComponentDescriptor.h>
|
|
21
21
|
#include <react/renderer/components/rnscreens/RNSScreenStackHeaderSubviewComponentDescriptor.h>
|
|
22
22
|
#include <react/renderer/components/rnscreens/RNSScreenStackHeaderConfigComponentDescriptor.h>
|
|
23
|
+
#include <react/renderer/components/rnscreens/RNSFullWindowOverlayComponentDescriptor.h>
|
|
23
24
|
|
|
24
25
|
namespace facebook {
|
|
25
26
|
namespace react {
|
package/android/src/paper/java/com/swmansion/rnscreens/FabricEnabledHeaderConfigViewGroup.kt
CHANGED
|
@@ -16,7 +16,15 @@ abstract class FabricEnabledHeaderConfigViewGroup(
|
|
|
16
16
|
|
|
17
17
|
fun setStateWrapper(wrapper: StateWrapper?) = Unit
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
// Do nothing on Paper. This method is used only on Fabric.
|
|
20
|
+
fun updateHeaderConfigState(
|
|
21
|
+
width: Int,
|
|
22
|
+
height: Int,
|
|
23
|
+
paddingStart: Int,
|
|
24
|
+
paddingEnd: Int,
|
|
25
|
+
) = Unit
|
|
26
|
+
|
|
27
|
+
fun updatePaddings(
|
|
20
28
|
paddingStart: Int,
|
|
21
29
|
paddingEnd: Int,
|
|
22
30
|
) {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
package com.swmansion.rnscreens
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.view.ViewGroup
|
|
5
|
+
import com.facebook.react.uimanager.StateWrapper
|
|
6
|
+
|
|
7
|
+
abstract class FabricEnabledHeaderSubviewViewGroup(
|
|
8
|
+
context: Context?,
|
|
9
|
+
) : ViewGroup(context) {
|
|
10
|
+
fun setStateWrapper(wrapper: StateWrapper?) = Unit
|
|
11
|
+
|
|
12
|
+
// Fabric only
|
|
13
|
+
protected fun updateSubviewFrameState(
|
|
14
|
+
width: Int,
|
|
15
|
+
height: Int,
|
|
16
|
+
offsetX: Int,
|
|
17
|
+
offsetY: Int,
|
|
18
|
+
) = Unit
|
|
19
|
+
}
|
package/common/cpp/react/renderer/components/rnscreens/RNSFullWindowOverlayComponentDescriptor.h
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#ifdef ANDROID
|
|
4
|
+
#include <fbjni/fbjni.h>
|
|
5
|
+
#endif // ANDROID
|
|
6
|
+
#include <react/renderer/core/ConcreteComponentDescriptor.h>
|
|
7
|
+
#include "RNSFullWindowOverlayShadowNode.h"
|
|
8
|
+
|
|
9
|
+
namespace facebook::react {
|
|
10
|
+
|
|
11
|
+
class RNSFullWindowOverlayComponentDescriptor final
|
|
12
|
+
: public ConcreteComponentDescriptor<RNSFullWindowOverlayShadowNode> {
|
|
13
|
+
public:
|
|
14
|
+
using ConcreteComponentDescriptor::ConcreteComponentDescriptor;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
} // namespace facebook::react
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <jsi/jsi.h>
|
|
4
|
+
#include <react/renderer/components/rnscreens/EventEmitters.h>
|
|
5
|
+
#include <react/renderer/components/rnscreens/Props.h>
|
|
6
|
+
#include <react/renderer/components/view/ConcreteViewShadowNode.h>
|
|
7
|
+
#include <react/renderer/core/LayoutContext.h>
|
|
8
|
+
#include "RNSFullWindowOverlayState.h"
|
|
9
|
+
|
|
10
|
+
namespace facebook::react {
|
|
11
|
+
|
|
12
|
+
JSI_EXPORT extern const char RNSFullWindowOverlayComponentName[];
|
|
13
|
+
|
|
14
|
+
using ConcreteViewShadowNodeSuperType = ConcreteViewShadowNode<
|
|
15
|
+
RNSFullWindowOverlayComponentName,
|
|
16
|
+
RNSFullWindowOverlayProps,
|
|
17
|
+
RNSFullWindowOverlayEventEmitter,
|
|
18
|
+
RNSFullWindowOverlayState>;
|
|
19
|
+
|
|
20
|
+
class JSI_EXPORT RNSFullWindowOverlayShadowNode final
|
|
21
|
+
: public ConcreteViewShadowNodeSuperType {
|
|
22
|
+
public:
|
|
23
|
+
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
|
24
|
+
using StateData = ConcreteViewShadowNode::ConcreteStateData;
|
|
25
|
+
|
|
26
|
+
#if !defined(ANDROID)
|
|
27
|
+
static ShadowNodeTraits BaseTraits() {
|
|
28
|
+
auto traits = ConcreteViewShadowNodeSuperType::BaseTraits();
|
|
29
|
+
traits.set(ShadowNodeTraits::Trait::RootNodeKind);
|
|
30
|
+
return traits;
|
|
31
|
+
}
|
|
32
|
+
#endif
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
} // namespace facebook::react
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#if defined(ANDROID)
|
|
4
|
+
#include <folly/dynamic.h>
|
|
5
|
+
#include <react/renderer/mapbuffer/MapBuffer.h>
|
|
6
|
+
#include <react/renderer/mapbuffer/MapBufferBuilder.h>
|
|
7
|
+
#endif // ANDROID
|
|
8
|
+
|
|
9
|
+
#include <react/renderer/core/graphicsConversions.h>
|
|
10
|
+
#include <react/renderer/graphics/Float.h>
|
|
11
|
+
|
|
12
|
+
namespace facebook::react {
|
|
13
|
+
|
|
14
|
+
class JSI_EXPORT RNSFullWindowOverlayState final {
|
|
15
|
+
public:
|
|
16
|
+
using Shared = std::shared_ptr<const RNSFullWindowOverlayState>;
|
|
17
|
+
|
|
18
|
+
RNSFullWindowOverlayState() = default;
|
|
19
|
+
|
|
20
|
+
#if defined(ANDROID)
|
|
21
|
+
RNSFullWindowOverlayState(
|
|
22
|
+
const RNSFullWindowOverlayState &previousState,
|
|
23
|
+
folly::dynamic data) {}
|
|
24
|
+
folly::dynamic getDynamic() const {
|
|
25
|
+
return {};
|
|
26
|
+
}
|
|
27
|
+
#endif
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
} // namespace facebook::react
|
|
@@ -34,8 +34,18 @@ class RNSScreenStackHeaderConfigComponentDescriptor final
|
|
|
34
34
|
shadowNode.getState());
|
|
35
35
|
auto stateData = state->getData();
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
if (stateData.frameSize.width != 0 && stateData.frameSize.height != 0) {
|
|
38
|
+
layoutableShadowNode.setSize(
|
|
39
|
+
{stateData.frameSize.width, stateData.frameSize.height});
|
|
40
|
+
#ifdef ANDROID
|
|
41
|
+
layoutableShadowNode.setPadding({
|
|
42
|
+
stateData.paddingStart,
|
|
43
|
+
0,
|
|
44
|
+
stateData.paddingEnd,
|
|
45
|
+
0,
|
|
46
|
+
});
|
|
47
|
+
#endif // ANDROID
|
|
48
|
+
}
|
|
39
49
|
|
|
40
50
|
ConcreteComponentDescriptor::adopt(shadowNode);
|
|
41
51
|
#if !defined(ANDROID) && !defined(NDEBUG)
|