react-native-screens 3.35.0-rc.0 → 4.0.0-beta.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 (115) hide show
  1. package/android/build.gradle +2 -2
  2. package/android/src/main/java/com/swmansion/rnscreens/InsetsObserverProxy.kt +67 -0
  3. package/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.kt +2 -0
  4. package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +101 -4
  5. package/android/src/main/java/com/swmansion/rnscreens/ScreenContentWrapper.kt +38 -0
  6. package/android/src/main/java/com/swmansion/rnscreens/ScreenContentWrapperManager.kt +25 -0
  7. package/android/src/main/java/com/swmansion/rnscreens/ScreenFooter.kt +287 -0
  8. package/android/src/main/java/com/swmansion/rnscreens/ScreenFooterManager.kt +25 -0
  9. package/android/src/main/java/com/swmansion/rnscreens/ScreenFragment.kt +11 -19
  10. package/android/src/main/java/com/swmansion/rnscreens/ScreenFragmentWrapper.kt +4 -0
  11. package/android/src/main/java/com/swmansion/rnscreens/ScreenModalFragment.kt +281 -0
  12. package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +62 -19
  13. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt +403 -41
  14. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragmentWrapper.kt +4 -1
  15. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt +2 -2
  16. package/android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.kt +95 -11
  17. package/android/src/main/java/com/swmansion/rnscreens/ScreenWindowTraits.kt +39 -28
  18. package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/BottomSheetDialogRootView.kt +104 -0
  19. package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/BottomSheetDialogScreen.kt +26 -0
  20. package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/DimmingFragment.kt +488 -0
  21. package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/DimmingView.kt +66 -0
  22. package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/GestureTransparentViewGroup.kt +24 -0
  23. package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/SheetUtils.kt +127 -0
  24. package/android/src/main/java/com/swmansion/rnscreens/events/SheetDetentChangedEvent.kt +27 -0
  25. package/android/src/main/java/com/swmansion/rnscreens/ext/NumericExt.kt +12 -0
  26. package/android/src/main/java/com/swmansion/rnscreens/ext/ViewExt.kt +32 -0
  27. package/android/src/main/java/com/swmansion/rnscreens/utils/ScreenDummyLayoutHelper.kt +45 -8
  28. package/android/src/main/res/base/drawable/rns_rounder_top_corners_shape.xml +8 -0
  29. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenContentWrapperManagerDelegate.java +25 -0
  30. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenContentWrapperManagerInterface.java +16 -0
  31. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenFooterManagerDelegate.java +25 -0
  32. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenFooterManagerInterface.java +16 -0
  33. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerDelegate.java +9 -2
  34. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerInterface.java +5 -2
  35. package/ios/RNSConvert.h +5 -3
  36. package/ios/RNSConvert.mm +14 -20
  37. package/ios/RNSScreen.h +3 -2
  38. package/ios/RNSScreen.mm +433 -49
  39. package/ios/RNSScreenContentWrapper.h +44 -0
  40. package/ios/RNSScreenContentWrapper.mm +61 -0
  41. package/ios/RNSScreenFooter.h +30 -0
  42. package/ios/RNSScreenFooter.mm +137 -0
  43. package/lib/commonjs/components/Screen.js +6 -2
  44. package/lib/commonjs/components/Screen.js.map +1 -1
  45. package/lib/commonjs/components/ScreenContentWrapper.js +19 -0
  46. package/lib/commonjs/components/ScreenContentWrapper.js.map +1 -0
  47. package/lib/commonjs/components/ScreenFooter.js +23 -0
  48. package/lib/commonjs/components/ScreenFooter.js.map +1 -0
  49. package/lib/commonjs/fabric/ModalScreenNativeComponent.js.map +1 -1
  50. package/lib/commonjs/fabric/ScreenContentWrapperNativeComponent.js +10 -0
  51. package/lib/commonjs/fabric/ScreenContentWrapperNativeComponent.js.map +1 -0
  52. package/lib/commonjs/fabric/ScreenFooterNativeComponent.js +10 -0
  53. package/lib/commonjs/fabric/ScreenFooterNativeComponent.js.map +1 -0
  54. package/lib/commonjs/fabric/ScreenNativeComponent.js.map +1 -1
  55. package/lib/commonjs/index.js +30 -0
  56. package/lib/commonjs/index.js.map +1 -1
  57. package/lib/commonjs/native-stack/views/FooterComponent.js +18 -0
  58. package/lib/commonjs/native-stack/views/FooterComponent.js.map +1 -0
  59. package/lib/commonjs/native-stack/views/NativeStackView.js +59 -14
  60. package/lib/commonjs/native-stack/views/NativeStackView.js.map +1 -1
  61. package/lib/module/components/Screen.js +6 -2
  62. package/lib/module/components/Screen.js.map +1 -1
  63. package/lib/module/components/ScreenContentWrapper.js +12 -0
  64. package/lib/module/components/ScreenContentWrapper.js.map +1 -0
  65. package/lib/module/components/ScreenFooter.js +17 -0
  66. package/lib/module/components/ScreenFooter.js.map +1 -0
  67. package/lib/module/fabric/ModalScreenNativeComponent.js.map +1 -1
  68. package/lib/module/fabric/ScreenContentWrapperNativeComponent.js +3 -0
  69. package/lib/module/fabric/ScreenContentWrapperNativeComponent.js.map +1 -0
  70. package/lib/module/fabric/ScreenFooterNativeComponent.js +3 -0
  71. package/lib/module/fabric/ScreenFooterNativeComponent.js.map +1 -0
  72. package/lib/module/fabric/ScreenNativeComponent.js.map +1 -1
  73. package/lib/module/index.js +2 -0
  74. package/lib/module/index.js.map +1 -1
  75. package/lib/module/native-stack/views/FooterComponent.js +11 -0
  76. package/lib/module/native-stack/views/FooterComponent.js.map +1 -0
  77. package/lib/module/native-stack/views/NativeStackView.js +61 -15
  78. package/lib/module/native-stack/views/NativeStackView.js.map +1 -1
  79. package/lib/typescript/components/Screen.d.ts.map +1 -1
  80. package/lib/typescript/components/ScreenContentWrapper.d.ts +6 -0
  81. package/lib/typescript/components/ScreenContentWrapper.d.ts.map +1 -0
  82. package/lib/typescript/components/ScreenFooter.d.ts +12 -0
  83. package/lib/typescript/components/ScreenFooter.d.ts.map +1 -0
  84. package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts +2 -3
  85. package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts.map +1 -1
  86. package/lib/typescript/fabric/ScreenContentWrapperNativeComponent.d.ts +7 -0
  87. package/lib/typescript/fabric/ScreenContentWrapperNativeComponent.d.ts.map +1 -0
  88. package/lib/typescript/fabric/ScreenFooterNativeComponent.d.ts +7 -0
  89. package/lib/typescript/fabric/ScreenFooterNativeComponent.d.ts.map +1 -0
  90. package/lib/typescript/fabric/ScreenNativeComponent.d.ts +9 -3
  91. package/lib/typescript/fabric/ScreenNativeComponent.d.ts.map +1 -1
  92. package/lib/typescript/index.d.ts +2 -0
  93. package/lib/typescript/index.d.ts.map +1 -1
  94. package/lib/typescript/native-stack/types.d.ts +63 -23
  95. package/lib/typescript/native-stack/types.d.ts.map +1 -1
  96. package/lib/typescript/native-stack/views/FooterComponent.d.ts +7 -0
  97. package/lib/typescript/native-stack/views/FooterComponent.d.ts.map +1 -0
  98. package/lib/typescript/native-stack/views/NativeStackView.d.ts.map +1 -1
  99. package/lib/typescript/types.d.ts +42 -17
  100. package/lib/typescript/types.d.ts.map +1 -1
  101. package/native-stack/README.md +16 -14
  102. package/package.json +1 -1
  103. package/react-native.config.js +18 -16
  104. package/src/components/Screen.tsx +6 -2
  105. package/src/components/ScreenContentWrapper.tsx +12 -0
  106. package/src/components/ScreenFooter.tsx +18 -0
  107. package/src/fabric/ModalScreenNativeComponent.ts +2 -4
  108. package/src/fabric/ScreenContentWrapperNativeComponent.ts +9 -0
  109. package/src/fabric/ScreenFooterNativeComponent.ts +6 -0
  110. package/src/fabric/ScreenNativeComponent.ts +10 -4
  111. package/src/index.tsx +10 -0
  112. package/src/native-stack/types.tsx +57 -23
  113. package/src/native-stack/views/FooterComponent.tsx +10 -0
  114. package/src/native-stack/views/NativeStackView.tsx +74 -11
  115. package/src/types.tsx +41 -16
@@ -1,6 +1,8 @@
1
1
  package com.swmansion.rnscreens
2
2
 
3
+ import android.view.View
3
4
  import com.facebook.react.bridge.JSApplicationIllegalArgumentException
5
+ import com.facebook.react.bridge.ReadableArray
4
6
  import com.facebook.react.bridge.ReadableMap
5
7
  import com.facebook.react.common.MapBuilder
6
8
  import com.facebook.react.module.annotations.ReactModule
@@ -20,6 +22,7 @@ import com.swmansion.rnscreens.events.ScreenDismissedEvent
20
22
  import com.swmansion.rnscreens.events.ScreenTransitionProgressEvent
21
23
  import com.swmansion.rnscreens.events.ScreenWillAppearEvent
22
24
  import com.swmansion.rnscreens.events.ScreenWillDisappearEvent
25
+ import com.swmansion.rnscreens.events.SheetDetentChangedEvent
23
26
 
24
27
  @ReactModule(name = ScreenViewManager.REACT_CLASS)
25
28
  open class ScreenViewManager :
@@ -42,6 +45,42 @@ open class ScreenViewManager :
42
45
  setActivityState(view, activityState.toInt())
43
46
  }
44
47
 
48
+ override fun addView(
49
+ parent: Screen,
50
+ child: View,
51
+ index: Int,
52
+ ) {
53
+ if (child is ScreenContentWrapper) {
54
+ parent.registerLayoutCallbackForWrapper(child)
55
+ } else if (child is ScreenFooter) {
56
+ parent.footer = child
57
+ }
58
+ super.addView(parent, child, index)
59
+ }
60
+
61
+ // Overriding all three remove methods despite the fact, that they all do use removeViewAt in parent
62
+ // class implementation to make it safe in case this changes. Relying on implementation details in this
63
+ // case in unnecessary.
64
+ override fun removeViewAt(
65
+ parent: Screen,
66
+ index: Int,
67
+ ) {
68
+ if (parent.getChildAt(index) is ScreenFooter) {
69
+ parent.footer = null
70
+ }
71
+ super.removeViewAt(parent, index)
72
+ }
73
+
74
+ override fun removeView(
75
+ parent: Screen,
76
+ view: View,
77
+ ) {
78
+ super.removeView(parent, view)
79
+ if (view is ScreenFooter) {
80
+ parent.footer = null
81
+ }
82
+ }
83
+
45
84
  override fun updateState(
46
85
  view: Screen,
47
86
  props: ReactStylesDiffMap?,
@@ -81,7 +120,8 @@ open class ScreenViewManager :
81
120
  view.stackPresentation =
82
121
  when (presentation) {
83
122
  "push" -> Screen.StackPresentation.PUSH
84
- "modal", "containedModal", "fullScreenModal", "formSheet" ->
123
+ "formSheet" -> Screen.StackPresentation.FORM_SHEET
124
+ "modal", "containedModal", "fullScreenModal" ->
85
125
  Screen.StackPresentation.MODAL
86
126
  "transparentModal", "containedTransparentModal" ->
87
127
  Screen.StackPresentation.TRANSPARENT_MODAL
@@ -210,6 +250,14 @@ open class ScreenViewManager :
210
250
  view.nativeBackButtonDismissalEnabled = nativeBackButtonDismissalEnabled
211
251
  }
212
252
 
253
+ @ReactProp(name = "sheetElevation")
254
+ override fun setSheetElevation(
255
+ view: Screen?,
256
+ value: Int,
257
+ ) {
258
+ view?.sheetElevation = value.toFloat()
259
+ }
260
+
213
261
  // these props are not available on Android, however we must override their setters
214
262
  override fun setFullScreenSwipeEnabled(
215
263
  view: Screen?,
@@ -256,30 +304,65 @@ open class ScreenViewManager :
256
304
  value: String?,
257
305
  ) = Unit
258
306
 
307
+ @ReactProp(name = "sheetAllowedDetents")
259
308
  override fun setSheetAllowedDetents(
260
309
  view: Screen,
261
- value: String?,
262
- ) = Unit
310
+ value: ReadableArray?,
311
+ ) {
312
+ view.sheetDetents.clear()
313
+
314
+ if (value == null || value.size() == 0) {
315
+ view.sheetDetents.add(1.0)
316
+ return
317
+ }
318
+
319
+ IntProgression
320
+ .fromClosedRange(0, value.size() - 1, 1)
321
+ .asSequence()
322
+ .map { idx -> value.getDouble(idx) }
323
+ .toCollection(view.sheetDetents)
324
+ }
263
325
 
326
+ @ReactProp(name = "sheetLargestUndimmedDetent")
264
327
  override fun setSheetLargestUndimmedDetent(
265
328
  view: Screen,
266
- value: String?,
267
- ) = Unit
329
+ value: Int,
330
+ ) {
331
+ check(value in -1..2) { "[RNScreens] sheetLargestUndimmedDetent on Android supports values between -1 and 2" }
332
+ view.sheetLargestUndimmedDetentIndex = value
333
+ }
268
334
 
335
+ @ReactProp(name = "sheetGrabberVisible")
269
336
  override fun setSheetGrabberVisible(
270
- view: Screen?,
337
+ view: Screen,
271
338
  value: Boolean,
272
- ) = Unit
339
+ ) {
340
+ view.isSheetGrabberVisible = value
341
+ }
273
342
 
343
+ @ReactProp(name = "sheetCornerRadius")
274
344
  override fun setSheetCornerRadius(
275
- view: Screen?,
345
+ view: Screen,
276
346
  value: Float,
277
- ) = Unit
347
+ ) {
348
+ view.sheetCornerRadius = value
349
+ }
278
350
 
351
+ @ReactProp(name = "sheetExpandsWhenScrolledToEdge")
279
352
  override fun setSheetExpandsWhenScrolledToEdge(
280
- view: Screen?,
353
+ view: Screen,
281
354
  value: Boolean,
282
- ) = Unit
355
+ ) {
356
+ view.sheetExpandsWhenScrolledToEdge = value
357
+ }
358
+
359
+ @ReactProp(name = "sheetInitialDetent")
360
+ override fun setSheetInitialDetent(
361
+ view: Screen,
362
+ value: Int,
363
+ ) {
364
+ view.sheetInitialDetentIndex = value
365
+ }
283
366
 
284
367
  override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any> =
285
368
  mutableMapOf(
@@ -291,6 +374,7 @@ open class ScreenViewManager :
291
374
  HeaderHeightChangeEvent.EVENT_NAME to MapBuilder.of("registrationName", "onHeaderHeightChange"),
292
375
  HeaderBackButtonClickedEvent.EVENT_NAME to MapBuilder.of("registrationName", "onHeaderBackButtonClicked"),
293
376
  ScreenTransitionProgressEvent.EVENT_NAME to MapBuilder.of("registrationName", "onTransitionProgress"),
377
+ SheetDetentChangedEvent.EVENT_NAME to MapBuilder.of("registrationName", "onSheetDetentChanged"),
294
378
  )
295
379
 
296
380
  protected override fun getDelegate(): ViewManagerDelegate<Screen> = delegate
@@ -7,8 +7,10 @@ import android.app.Activity
7
7
  import android.content.pm.ActivityInfo
8
8
  import android.graphics.Color
9
9
  import android.os.Build
10
+ import android.view.View
10
11
  import android.view.ViewParent
11
12
  import androidx.core.graphics.Insets
13
+ import androidx.core.view.OnApplyWindowInsetsListener
12
14
  import androidx.core.view.ViewCompat
13
15
  import androidx.core.view.WindowCompat
14
16
  import androidx.core.view.WindowInsetsCompat
@@ -26,6 +28,40 @@ object ScreenWindowTraits {
26
28
  private var didSetNavigationBarAppearance = false
27
29
  private var defaultStatusBarColor: Int? = null
28
30
 
31
+ private var windowInsetsListener =
32
+ object : OnApplyWindowInsetsListener {
33
+ override fun onApplyWindowInsets(
34
+ v: View,
35
+ insets: WindowInsetsCompat,
36
+ ): WindowInsetsCompat {
37
+ val defaultInsets = ViewCompat.onApplyWindowInsets(v, insets)
38
+
39
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
40
+ val windowInsets =
41
+ defaultInsets.getInsets(WindowInsetsCompat.Type.statusBars())
42
+
43
+ return WindowInsetsCompat
44
+ .Builder()
45
+ .setInsets(
46
+ WindowInsetsCompat.Type.statusBars(),
47
+ Insets.of(
48
+ windowInsets.left,
49
+ 0,
50
+ windowInsets.right,
51
+ windowInsets.bottom,
52
+ ),
53
+ ).build()
54
+ } else {
55
+ return defaultInsets.replaceSystemWindowInsets(
56
+ defaultInsets.systemWindowInsetLeft,
57
+ 0,
58
+ defaultInsets.systemWindowInsetRight,
59
+ defaultInsets.systemWindowInsetBottom,
60
+ )
61
+ }
62
+ }
63
+ }
64
+
29
65
  internal fun applyDidSetOrientation() {
30
66
  didSetOrientation = true
31
67
  }
@@ -124,35 +160,10 @@ object ScreenWindowTraits {
124
160
  // and consume all the top insets so no padding will be added under the status bar.
125
161
  val decorView = activity.window.decorView
126
162
  if (translucent) {
127
- ViewCompat.setOnApplyWindowInsetsListener(decorView) { v, insets ->
128
- val defaultInsets = ViewCompat.onApplyWindowInsets(v, insets)
129
-
130
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
131
- val windowInsets =
132
- defaultInsets.getInsets(WindowInsetsCompat.Type.statusBars())
133
-
134
- WindowInsetsCompat
135
- .Builder()
136
- .setInsets(
137
- WindowInsetsCompat.Type.statusBars(),
138
- Insets.of(
139
- windowInsets.left,
140
- 0,
141
- windowInsets.right,
142
- windowInsets.bottom,
143
- ),
144
- ).build()
145
- } else {
146
- defaultInsets.replaceSystemWindowInsets(
147
- defaultInsets.systemWindowInsetLeft,
148
- 0,
149
- defaultInsets.systemWindowInsetRight,
150
- defaultInsets.systemWindowInsetBottom,
151
- )
152
- }
153
- }
163
+ InsetsObserverProxy.registerOnView(decorView)
164
+ InsetsObserverProxy.addOnApplyWindowInsetsListener(windowInsetsListener)
154
165
  } else {
155
- ViewCompat.setOnApplyWindowInsetsListener(decorView, null)
166
+ InsetsObserverProxy.removeOnApplyWindowInsetsListener(windowInsetsListener)
156
167
  }
157
168
  ViewCompat.requestApplyInsets(decorView)
158
169
  }
@@ -0,0 +1,104 @@
1
+ package com.swmansion.rnscreens.bottomsheet
2
+
3
+ import android.annotation.SuppressLint
4
+ import android.view.MotionEvent
5
+ import android.view.View
6
+ import com.facebook.react.bridge.ReactContext
7
+ import com.facebook.react.config.ReactFeatureFlags
8
+ import com.facebook.react.uimanager.JSPointerDispatcher
9
+ import com.facebook.react.uimanager.JSTouchDispatcher
10
+ import com.facebook.react.uimanager.RootView
11
+ import com.facebook.react.uimanager.events.EventDispatcher
12
+ import com.facebook.react.views.view.ReactViewGroup
13
+
14
+ @SuppressLint("ViewConstructor")
15
+ class BottomSheetDialogRootView(
16
+ val reactContext: ReactContext?,
17
+ private val eventDispatcher: EventDispatcher,
18
+ ) : ReactViewGroup(reactContext),
19
+ RootView {
20
+ private val jsTouchDispatcher: JSTouchDispatcher = JSTouchDispatcher(this)
21
+ private var jsPointerDispatcher: JSPointerDispatcher? = null
22
+
23
+ init {
24
+ // Can we safely use ReactFeatureFlags?
25
+ if (ReactFeatureFlags.dispatchPointerEvents) {
26
+ jsPointerDispatcher = JSPointerDispatcher(this)
27
+ }
28
+ }
29
+
30
+ override fun onLayout(
31
+ changed: Boolean,
32
+ l: Int,
33
+ t: Int,
34
+ r: Int,
35
+ b: Int,
36
+ ) {
37
+ if (changed) {
38
+ // This view is used right now only in ScreenModalFragment, where it is injected
39
+ // to view hierarchy as a parent of a Screen.
40
+ assert(childCount == 1) { "[RNScreens] Expected only a single child view under ${TAG}, received: ${childCount}"}
41
+ getChildAt(0).layout(l, t, r, b)
42
+ }
43
+ }
44
+
45
+ override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
46
+ jsTouchDispatcher.handleTouchEvent(event, eventDispatcher)
47
+ jsPointerDispatcher?.handleMotionEvent(event, eventDispatcher, true)
48
+ return super.onInterceptTouchEvent(event)
49
+ }
50
+
51
+ override fun onTouchEvent(event: MotionEvent): Boolean {
52
+ jsTouchDispatcher.handleTouchEvent(event, eventDispatcher)
53
+ jsPointerDispatcher?.handleMotionEvent(event, eventDispatcher, false)
54
+ super.onTouchEvent(event)
55
+ return true
56
+ }
57
+
58
+ override fun onInterceptHoverEvent(event: MotionEvent): Boolean {
59
+ jsPointerDispatcher?.handleMotionEvent(event, eventDispatcher, true)
60
+ // This is how DialogRootViewGroup implements this, it might be a copy-paste mistake
61
+ // on their side.
62
+ return super.onHoverEvent(event)
63
+ }
64
+
65
+ override fun onHoverEvent(event: MotionEvent): Boolean {
66
+ jsPointerDispatcher?.handleMotionEvent(event, eventDispatcher, false)
67
+ return super.onHoverEvent(event)
68
+ }
69
+
70
+ override fun onChildStartedNativeGesture(
71
+ view: View,
72
+ event: MotionEvent,
73
+ ) {
74
+ jsTouchDispatcher.onChildStartedNativeGesture(event, eventDispatcher)
75
+ jsPointerDispatcher?.onChildStartedNativeGesture(view, event, eventDispatcher)
76
+ }
77
+
78
+ @Deprecated("Deprecated by React Native")
79
+ override fun onChildStartedNativeGesture(event: MotionEvent): Unit =
80
+ throw IllegalStateException("Deprecated onChildStartedNativeGesture was called")
81
+
82
+ override fun onChildEndedNativeGesture(
83
+ view: View,
84
+ event: MotionEvent,
85
+ ) {
86
+ jsTouchDispatcher.onChildEndedNativeGesture(event, eventDispatcher)
87
+ jsPointerDispatcher?.onChildEndedNativeGesture()
88
+ }
89
+
90
+ override fun requestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {
91
+ // We do not pass through request of our child up the view hierarchy, as we
92
+ // need to keep receiving events.
93
+ }
94
+
95
+ override fun handleException(throwable: Throwable?) {
96
+ // TODO: I need ThemedReactContext here.
97
+ // TODO: Determine where it is initially created & verify its lifecycle
98
+ // reactContext?.reactApplicationContext?.handleException(RuntimeException(throwable))
99
+ }
100
+
101
+ companion object {
102
+ const val TAG = "BottomSheetDialogRootView"
103
+ }
104
+ }
@@ -0,0 +1,26 @@
1
+ package com.swmansion.rnscreens.bottomsheet
2
+
3
+ import android.content.Context
4
+ import com.google.android.material.bottomsheet.BottomSheetDialog
5
+ import com.swmansion.rnscreens.ScreenModalFragment
6
+ import java.lang.ref.WeakReference
7
+
8
+ class BottomSheetDialogScreen(
9
+ context: Context,
10
+ fragment: ScreenModalFragment,
11
+ ) : BottomSheetDialog(context) {
12
+ private val fragmentRef: WeakReference<ScreenModalFragment> = WeakReference(fragment)
13
+
14
+ // There are various code paths leading to this method, however the one I'm concerned with
15
+ // is dismissal via swipe-down. If the sheet is dismissed we don't want the native dismiss logic
16
+ // to run, as this will lead to inconsistencies in ScreenStack state. Instead we intercept
17
+ // dismiss intention and run our logic.
18
+ override fun cancel() {
19
+ fragmentRef.get()!!.dismissFromContainer()
20
+ this.show()
21
+ }
22
+
23
+ companion object {
24
+ val TAG = BottomSheetDialogScreen::class.simpleName
25
+ }
26
+ }