@lodev09/react-native-true-sheet 4.0.0-beta.1 → 4.0.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -4
- package/android/build.gradle +22 -1
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContainerView.kt +24 -7
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentView.kt +211 -182
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentViewManager.kt +5 -1
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetFooterView.kt +14 -19
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetOverlayView.kt +106 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetOverlayViewManager.kt +45 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetPackage.kt +2 -1
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetStateUpdater.kt +18 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +82 -39
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewController.kt +275 -88
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt +26 -1
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetCoordinatorLayout.kt +75 -3
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetDetentCalculator.kt +56 -34
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetOverlayRootView.kt +137 -0
- package/android/src/main/java/com/lodev09/truesheet/events/TrueSheetLifecycleEvents.kt +15 -0
- package/android/src/main/java/com/lodev09/truesheet/utils/KeyboardUtils.kt +1 -1
- package/android/src/main/java/com/lodev09/truesheet/utils/TouchEventDeduper.kt +31 -0
- package/android/src/main/java/com/lodev09/truesheet/utils/ViewUtils.kt +19 -7
- package/android/src/main/jni/TrueSheetSpec.h +1 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewComponentDescriptor.h +0 -8
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.cpp +54 -29
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.h +6 -1
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewState.cpp +1 -1
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewState.h +6 -4
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.cpp +7 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetLayoutUtils.h +46 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewComponentDescriptor.h +21 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewShadowNode.cpp +17 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewShadowNode.h +36 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.cpp +4 -35
- package/ios/TrueSheetContainerView.h +14 -7
- package/ios/TrueSheetContainerView.mm +10 -7
- package/ios/TrueSheetContentView.h +31 -15
- package/ios/TrueSheetContentView.mm +133 -179
- package/ios/TrueSheetFooterView.h +6 -0
- package/ios/TrueSheetFooterView.mm +48 -2
- package/ios/TrueSheetModule.h +2 -7
- package/ios/TrueSheetModule.mm +7 -16
- package/ios/TrueSheetOverlayView.h +32 -0
- package/ios/TrueSheetOverlayView.mm +161 -0
- package/ios/TrueSheetView.mm +171 -29
- package/ios/TrueSheetViewController.h +10 -0
- package/ios/TrueSheetViewController.mm +256 -74
- package/ios/core/TrueSheetGrabberView.mm +13 -3
- package/ios/core/TrueSheetOverlayContainerView.h +31 -0
- package/ios/core/TrueSheetOverlayContainerView.mm +35 -0
- package/ios/events/TrueSheetLifecycleEvents.h +2 -0
- package/ios/events/TrueSheetLifecycleEvents.mm +8 -0
- package/ios/tvos/TrueSheetStubs.mm +12 -0
- package/ios/utils/UIView+ScrollEdgeInteraction.h +1 -0
- package/ios/utils/UIView+ScrollEdgeInteraction.mm +24 -2
- package/lib/module/TrueSheet.js +149 -34
- package/lib/module/TrueSheet.js.map +1 -1
- package/lib/module/TrueSheet.web.js +122 -53
- package/lib/module/TrueSheet.web.js.map +1 -1
- package/lib/module/TrueSheetOverlay.js +30 -0
- package/lib/module/TrueSheetOverlay.js.map +1 -0
- package/lib/module/TrueSheetOverlay.web.js +35 -0
- package/lib/module/TrueSheetOverlay.web.js.map +1 -0
- package/lib/module/TrueSheetPeek.web.js +3 -3
- package/lib/module/TrueSheetPeek.web.js.map +1 -1
- package/lib/module/fabric/TrueSheetContentViewNativeComponent.ts +1 -1
- package/lib/module/fabric/TrueSheetOverlayViewNativeComponent.ts +12 -0
- package/lib/module/fabric/TrueSheetViewNativeComponent.ts +5 -0
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/mocks/index.js +10 -0
- package/lib/module/mocks/index.js.map +1 -1
- package/lib/module/mocks/navigation.js +31 -21
- package/lib/module/mocks/navigation.js.map +1 -1
- package/lib/module/mocks/navigationExpoRouter.js +21 -0
- package/lib/module/mocks/navigationExpoRouter.js.map +1 -0
- package/lib/module/mocks/reanimated.js +1 -1
- package/lib/module/mocks/reanimated.js.map +1 -1
- package/lib/module/navigation/{TrueSheetView.js → TrueSheetNavigatorContent.js} +14 -12
- package/lib/module/navigation/TrueSheetNavigatorContent.js.map +1 -0
- package/lib/module/navigation/actions.js +50 -0
- package/lib/module/navigation/actions.js.map +1 -0
- package/lib/module/navigation/base-types.js +2 -0
- package/lib/module/navigation/base-types.js.map +1 -0
- package/lib/module/navigation/{TrueSheetRouter.js → createTrueSheetRouter.js} +11 -24
- package/lib/module/navigation/createTrueSheetRouter.js.map +1 -0
- package/lib/module/navigation/expo-router/base-types.js +2 -0
- package/lib/module/navigation/expo-router/base-types.js.map +1 -0
- package/lib/module/navigation/expo-router/index.js +50 -0
- package/lib/module/navigation/expo-router/index.js.map +1 -0
- package/lib/module/navigation/expo-router/types.js +4 -0
- package/lib/module/navigation/expo-router/types.js.map +1 -0
- package/lib/module/navigation/index.js +43 -2
- package/lib/module/navigation/index.js.map +1 -1
- package/lib/module/navigation/navigator.js +10 -0
- package/lib/module/navigation/navigator.js.map +1 -0
- package/lib/module/navigation/screen/ReanimatedTrueSheetScreen.js +2 -2
- package/lib/module/navigation/screen/ReanimatedTrueSheetScreen.js.map +1 -1
- package/lib/module/navigation/screen/TrueSheetScreen.js +2 -2
- package/lib/module/navigation/screen/TrueSheetScreen.js.map +1 -1
- package/lib/module/navigation/screen/useSheetScreenState.js +5 -4
- package/lib/module/navigation/screen/useSheetScreenState.js.map +1 -1
- package/lib/module/navigation/useTrueSheetNavigation.js +1 -1
- package/lib/module/navigation/useTrueSheetNavigation.js.map +1 -1
- package/lib/module/web/dom.js +10 -0
- package/lib/module/web/dom.js.map +1 -0
- package/lib/module/web/vaul/constants.js +4 -0
- package/lib/module/web/vaul/constants.js.map +1 -1
- package/lib/module/web/vaul/context.js.map +1 -1
- package/lib/module/web/vaul/helpers.js +10 -4
- package/lib/module/web/vaul/helpers.js.map +1 -1
- package/lib/module/web/vaul/index.js +35 -2
- package/lib/module/web/vaul/index.js.map +1 -1
- package/lib/typescript/src/TrueSheet.d.ts +6 -0
- package/lib/typescript/src/TrueSheet.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheet.types.d.ts +72 -1
- package/lib/typescript/src/TrueSheet.types.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheet.web.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheetOverlay.d.ts +8 -0
- package/lib/typescript/src/TrueSheetOverlay.d.ts.map +1 -0
- package/lib/typescript/src/TrueSheetOverlay.web.d.ts +8 -0
- package/lib/typescript/src/TrueSheetOverlay.web.d.ts.map +1 -0
- package/lib/typescript/src/TrueSheetPeek.web.d.ts.map +1 -1
- package/lib/typescript/src/fabric/TrueSheetOverlayViewNativeComponent.d.ts +6 -0
- package/lib/typescript/src/fabric/TrueSheetOverlayViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts +4 -0
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/mocks/index.d.ts +4 -0
- package/lib/typescript/src/mocks/index.d.ts.map +1 -1
- package/lib/typescript/src/mocks/navigation.d.ts +5 -1
- package/lib/typescript/src/mocks/navigation.d.ts.map +1 -1
- package/lib/typescript/src/mocks/navigationExpoRouter.d.ts +22 -0
- package/lib/typescript/src/mocks/navigationExpoRouter.d.ts.map +1 -0
- package/lib/typescript/src/mocks/reanimated.d.ts.map +1 -1
- package/lib/typescript/src/navigation/TrueSheetNavigatorContent.d.ts +5 -0
- package/lib/typescript/src/navigation/TrueSheetNavigatorContent.d.ts.map +1 -0
- package/lib/typescript/src/navigation/actions.d.ts +71 -0
- package/lib/typescript/src/navigation/actions.d.ts.map +1 -0
- package/lib/typescript/src/navigation/base-types.d.ts +9 -0
- package/lib/typescript/src/navigation/base-types.d.ts.map +1 -0
- package/lib/typescript/src/navigation/createTrueSheetRouter.d.ts +3 -0
- package/lib/typescript/src/navigation/createTrueSheetRouter.d.ts.map +1 -0
- package/lib/typescript/src/navigation/expo-router/base-types.d.ts +8 -0
- package/lib/typescript/src/navigation/expo-router/base-types.d.ts.map +1 -0
- package/lib/typescript/src/navigation/expo-router/index.d.ts +37 -0
- package/lib/typescript/src/navigation/expo-router/index.d.ts.map +1 -0
- package/lib/typescript/src/navigation/expo-router/types.d.ts +44 -0
- package/lib/typescript/src/navigation/expo-router/types.d.ts.map +1 -0
- package/lib/typescript/src/navigation/index.d.ts +42 -3
- package/lib/typescript/src/navigation/index.d.ts.map +1 -1
- package/lib/typescript/src/navigation/navigator.d.ts +7 -0
- package/lib/typescript/src/navigation/navigator.d.ts.map +1 -0
- package/lib/typescript/src/navigation/screen/ReanimatedTrueSheetScreen.d.ts +1 -1
- package/lib/typescript/src/navigation/screen/ReanimatedTrueSheetScreen.d.ts.map +1 -1
- package/lib/typescript/src/navigation/screen/TrueSheetScreen.d.ts +1 -1
- package/lib/typescript/src/navigation/screen/TrueSheetScreen.d.ts.map +1 -1
- package/lib/typescript/src/navigation/screen/types.d.ts +3 -4
- package/lib/typescript/src/navigation/screen/types.d.ts.map +1 -1
- package/lib/typescript/src/navigation/screen/useSheetScreenState.d.ts +5 -6
- package/lib/typescript/src/navigation/screen/useSheetScreenState.d.ts.map +1 -1
- package/lib/typescript/src/navigation/types.d.ts +65 -5
- package/lib/typescript/src/navigation/types.d.ts.map +1 -1
- package/lib/typescript/src/navigation/useTrueSheetNavigation.d.ts +1 -1
- package/lib/typescript/src/navigation/useTrueSheetNavigation.d.ts.map +1 -1
- package/lib/typescript/src/web/dom.d.ts +7 -0
- package/lib/typescript/src/web/dom.d.ts.map +1 -0
- package/lib/typescript/src/web/vaul/constants.d.ts +1 -0
- package/lib/typescript/src/web/vaul/constants.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/context.d.ts +1 -0
- package/lib/typescript/src/web/vaul/context.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/helpers.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/index.d.ts +7 -1
- package/lib/typescript/src/web/vaul/index.d.ts.map +1 -1
- package/package.json +32 -9
- package/react-native.config.js +1 -0
- package/src/TrueSheet.tsx +184 -46
- package/src/TrueSheet.types.ts +77 -1
- package/src/TrueSheet.web.tsx +135 -64
- package/src/TrueSheetOverlay.tsx +24 -0
- package/src/TrueSheetOverlay.web.tsx +33 -0
- package/src/TrueSheetPeek.web.tsx +4 -3
- package/src/fabric/TrueSheetContentViewNativeComponent.ts +1 -1
- package/src/fabric/TrueSheetOverlayViewNativeComponent.ts +12 -0
- package/src/fabric/TrueSheetViewNativeComponent.ts +5 -0
- package/src/index.ts +1 -0
- package/src/mocks/index.ts +7 -0
- package/src/mocks/navigation.ts +32 -25
- package/src/mocks/navigationExpoRouter.ts +41 -0
- package/src/mocks/reanimated.ts +8 -9
- package/src/navigation/{TrueSheetView.tsx → TrueSheetNavigatorContent.tsx} +24 -17
- package/src/navigation/actions.ts +78 -0
- package/src/navigation/base-types.ts +20 -0
- package/src/navigation/createTrueSheetRouter.ts +194 -0
- package/src/navigation/expo-router/base-types.ts +18 -0
- package/src/navigation/expo-router/index.ts +90 -0
- package/src/navigation/expo-router/types.ts +116 -0
- package/src/navigation/index.ts +68 -2
- package/src/navigation/navigator.ts +18 -0
- package/src/navigation/screen/ReanimatedTrueSheetScreen.tsx +2 -2
- package/src/navigation/screen/TrueSheetScreen.tsx +2 -2
- package/src/navigation/screen/types.ts +4 -6
- package/src/navigation/screen/useSheetScreenState.ts +10 -15
- package/src/navigation/types.ts +99 -16
- package/src/navigation/useTrueSheetNavigation.ts +1 -1
- package/src/web/dom.ts +9 -0
- package/src/web/vaul/constants.ts +4 -0
- package/src/web/vaul/context.ts +1 -0
- package/src/web/vaul/helpers.ts +13 -6
- package/src/web/vaul/index.tsx +46 -1
- package/lib/module/navigation/TrueSheetRouter.js.map +0 -1
- package/lib/module/navigation/TrueSheetView.js.map +0 -1
- package/lib/module/navigation/createTrueSheetNavigator.js +0 -63
- package/lib/module/navigation/createTrueSheetNavigator.js.map +0 -1
- package/lib/typescript/src/navigation/TrueSheetRouter.d.ts +0 -57
- package/lib/typescript/src/navigation/TrueSheetRouter.d.ts.map +0 -1
- package/lib/typescript/src/navigation/TrueSheetView.d.ts +0 -10
- package/lib/typescript/src/navigation/TrueSheetView.d.ts.map +0 -1
- package/lib/typescript/src/navigation/createTrueSheetNavigator.d.ts +0 -35
- package/lib/typescript/src/navigation/createTrueSheetNavigator.d.ts.map +0 -1
- package/src/navigation/TrueSheetRouter.ts +0 -234
- package/src/navigation/createTrueSheetNavigator.tsx +0 -93
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
package com.lodev09.truesheet
|
|
2
|
+
|
|
3
|
+
import android.annotation.SuppressLint
|
|
4
|
+
import android.view.View
|
|
5
|
+
import android.view.ViewGroup
|
|
6
|
+
import android.view.accessibility.AccessibilityEvent
|
|
7
|
+
import com.facebook.react.uimanager.StateWrapper
|
|
8
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
9
|
+
import com.facebook.react.uimanager.events.EventDispatcher
|
|
10
|
+
import com.facebook.react.views.view.ReactViewGroup
|
|
11
|
+
import com.lodev09.truesheet.core.TrueSheetOverlayRootView
|
|
12
|
+
import com.lodev09.truesheet.core.TrueSheetOverlayRootViewDelegate
|
|
13
|
+
import com.lodev09.truesheet.utils.findRootContainerView
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Hidden host that renders its children in a root view attached to the
|
|
17
|
+
* activity's content view, above every presented sheet.
|
|
18
|
+
*/
|
|
19
|
+
@SuppressLint("ViewConstructor")
|
|
20
|
+
class TrueSheetOverlayView(private val reactContext: ThemedReactContext) :
|
|
21
|
+
ReactViewGroup(reactContext),
|
|
22
|
+
TrueSheetOverlayRootViewDelegate {
|
|
23
|
+
|
|
24
|
+
private val rootView = TrueSheetOverlayRootView(reactContext).apply {
|
|
25
|
+
delegate = this@TrueSheetOverlayView
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
private var rootContainerView: ViewGroup? = null
|
|
29
|
+
|
|
30
|
+
override var eventDispatcher: EventDispatcher? = null
|
|
31
|
+
|
|
32
|
+
private var lastWidth = 0
|
|
33
|
+
private var lastHeight = 0
|
|
34
|
+
|
|
35
|
+
var stateWrapper: StateWrapper? = null
|
|
36
|
+
set(value) {
|
|
37
|
+
field = value
|
|
38
|
+
pushState()
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
init {
|
|
42
|
+
// The host stays in the React tree for layout only — children render in the root view
|
|
43
|
+
visibility = GONE
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// ==================== View Hierarchy Management ====================
|
|
47
|
+
|
|
48
|
+
override fun onAttachedToWindow() {
|
|
49
|
+
super.onAttachedToWindow()
|
|
50
|
+
attachRootView()
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
override fun onDetachedFromWindow() {
|
|
54
|
+
detachRootView()
|
|
55
|
+
super.onDetachedFromWindow()
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
private fun attachRootView() {
|
|
59
|
+
if (rootView.parent != null) return
|
|
60
|
+
|
|
61
|
+
val container = findRootContainerView(reactContext) ?: return
|
|
62
|
+
container.addView(rootView)
|
|
63
|
+
rootContainerView = container
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private fun detachRootView() {
|
|
67
|
+
rootContainerView?.removeView(rootView)
|
|
68
|
+
rootContainerView = null
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
fun onDropInstance() {
|
|
72
|
+
detachRootView()
|
|
73
|
+
rootView.delegate = null
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
override fun addView(child: View?, index: Int) {
|
|
77
|
+
rootView.addView(child, index)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
override fun getChildCount(): Int = rootView.childCount
|
|
81
|
+
|
|
82
|
+
override fun getChildAt(index: Int): View? = rootView.getChildAt(index)
|
|
83
|
+
|
|
84
|
+
override fun removeViewAt(index: Int) {
|
|
85
|
+
rootView.removeViewAt(index)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Accessibility: children live in the root view since this view is hidden
|
|
89
|
+
override fun addChildrenForAccessibility(outChildren: ArrayList<View>) {}
|
|
90
|
+
override fun dispatchPopulateAccessibilityEvent(event: AccessibilityEvent): Boolean = false
|
|
91
|
+
|
|
92
|
+
// ==================== State ====================
|
|
93
|
+
|
|
94
|
+
override fun overlayRootViewDidChangeSize(width: Int, height: Int) {
|
|
95
|
+
if (width == lastWidth && height == lastHeight) return
|
|
96
|
+
|
|
97
|
+
lastWidth = width
|
|
98
|
+
lastHeight = height
|
|
99
|
+
pushState()
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
private fun pushState() {
|
|
103
|
+
if (lastWidth == 0 && lastHeight == 0) return
|
|
104
|
+
stateWrapper?.let { TrueSheetStateUpdater.updateContainerSize(it, lastWidth, lastHeight) }
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
package com.lodev09.truesheet
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.module.annotations.ReactModule
|
|
4
|
+
import com.facebook.react.uimanager.PointerEvents
|
|
5
|
+
import com.facebook.react.uimanager.ReactStylesDiffMap
|
|
6
|
+
import com.facebook.react.uimanager.StateWrapper
|
|
7
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
8
|
+
import com.facebook.react.uimanager.UIManagerHelper
|
|
9
|
+
import com.facebook.react.uimanager.ViewGroupManager
|
|
10
|
+
import com.facebook.react.uimanager.annotations.ReactProp
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* ViewManager for TrueSheetOverlayView
|
|
14
|
+
* Renders content above every presented sheet
|
|
15
|
+
*/
|
|
16
|
+
@ReactModule(name = TrueSheetOverlayViewManager.REACT_CLASS)
|
|
17
|
+
class TrueSheetOverlayViewManager : ViewGroupManager<TrueSheetOverlayView>() {
|
|
18
|
+
|
|
19
|
+
override fun getName(): String = REACT_CLASS
|
|
20
|
+
|
|
21
|
+
override fun createViewInstance(reactContext: ThemedReactContext): TrueSheetOverlayView = TrueSheetOverlayView(reactContext)
|
|
22
|
+
|
|
23
|
+
override fun onDropViewInstance(view: TrueSheetOverlayView) {
|
|
24
|
+
super.onDropViewInstance(view)
|
|
25
|
+
view.onDropInstance()
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
override fun addEventEmitters(reactContext: ThemedReactContext, view: TrueSheetOverlayView) {
|
|
29
|
+
view.eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag(reactContext, view.id)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
override fun updateState(view: TrueSheetOverlayView, props: ReactStylesDiffMap?, stateWrapper: StateWrapper?): Any? {
|
|
33
|
+
view.stateWrapper = stateWrapper
|
|
34
|
+
return null
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@ReactProp(name = "pointerEvents")
|
|
38
|
+
fun setPointerEvents(view: TrueSheetOverlayView, pointerEventsStr: String?) {
|
|
39
|
+
view.pointerEvents = PointerEvents.parsePointerEvents(pointerEventsStr)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
companion object {
|
|
43
|
+
const val REACT_CLASS = "TrueSheetOverlayView"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
package com.lodev09.truesheet
|
|
2
2
|
|
|
3
|
+
import com.facebook.react.bridge.WritableNativeMap
|
|
4
|
+
import com.facebook.react.uimanager.PixelUtil.pxToDp
|
|
3
5
|
import com.facebook.react.uimanager.StateWrapper
|
|
4
6
|
|
|
5
7
|
/**
|
|
@@ -22,6 +24,22 @@ object TrueSheetStateUpdater {
|
|
|
22
24
|
fun updateState(stateWrapper: StateWrapper, widthDp: Float, heightDp: Float): Boolean =
|
|
23
25
|
isAvailable && nativeUpdateState(stateWrapper, widthDp, heightDp)
|
|
24
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Pushes the container size (px) into the Fabric state — synchronously when
|
|
29
|
+
* the bridge is available, async otherwise.
|
|
30
|
+
*/
|
|
31
|
+
fun updateContainerSize(stateWrapper: StateWrapper, widthPx: Int, heightPx: Int) {
|
|
32
|
+
val widthDp = widthPx.toFloat().pxToDp()
|
|
33
|
+
val heightDp = heightPx.toFloat().pxToDp()
|
|
34
|
+
|
|
35
|
+
if (updateState(stateWrapper, widthDp, heightDp)) return
|
|
36
|
+
|
|
37
|
+
val newStateData = WritableNativeMap()
|
|
38
|
+
newStateData.putDouble("containerWidth", widthDp.toDouble())
|
|
39
|
+
newStateData.putDouble("containerHeight", heightDp.toDouble())
|
|
40
|
+
stateWrapper.updateState(newStateData)
|
|
41
|
+
}
|
|
42
|
+
|
|
25
43
|
/** Returns false when unavailable — caller should fall back to async updateState. */
|
|
26
44
|
fun updateFooterState(stateWrapper: StateWrapper, bottomInsetDp: Float): Boolean =
|
|
27
45
|
isAvailable && nativeUpdateFooterState(stateWrapper, bottomInsetDp)
|
|
@@ -6,7 +6,6 @@ import android.view.ViewGroup
|
|
|
6
6
|
import android.view.accessibility.AccessibilityEvent
|
|
7
7
|
import androidx.annotation.UiThread
|
|
8
8
|
import com.facebook.react.bridge.LifecycleEventListener
|
|
9
|
-
import com.facebook.react.bridge.WritableNativeMap
|
|
10
9
|
import com.facebook.react.uimanager.PixelUtil.dpToPx
|
|
11
10
|
import com.facebook.react.uimanager.PixelUtil.pxToDp
|
|
12
11
|
import com.facebook.react.uimanager.StateWrapper
|
|
@@ -22,6 +21,7 @@ import com.lodev09.truesheet.core.RNScreensEventObserverDelegate
|
|
|
22
21
|
import com.lodev09.truesheet.core.TrueSheetStackManager
|
|
23
22
|
import com.lodev09.truesheet.events.*
|
|
24
23
|
import com.lodev09.truesheet.utils.KeyboardUtils
|
|
24
|
+
import com.lodev09.truesheet.utils.findRootContainerView
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* Main TrueSheet host view that manages the sheet and dispatches events to JavaScript.
|
|
@@ -101,13 +101,30 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
|
|
|
101
101
|
|
|
102
102
|
override fun onAttachedToWindow() {
|
|
103
103
|
super.onAttachedToWindow()
|
|
104
|
+
presentInitialIfNeeded()
|
|
105
|
+
}
|
|
104
106
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
107
|
+
/**
|
|
108
|
+
* JS holds initialDetentIndex back one commit so effect-driven content (e.g. a
|
|
109
|
+
* navigation footer set via setOptions) commits together with it. The prop then
|
|
110
|
+
* arrives after attach, so the ViewManager triggers this on prop update too.
|
|
111
|
+
* Posted so sibling mounts from the current transaction land before measuring.
|
|
112
|
+
*/
|
|
113
|
+
fun presentInitialIfNeeded() {
|
|
114
|
+
if (initialDetentIndex < 0 || didInitiallyPresent || !isAttachedToWindow) return
|
|
115
|
+
|
|
116
|
+
didInitiallyPresent = true
|
|
117
|
+
post {
|
|
118
|
+
// The view may have been dropped (flag reset) or detached before this
|
|
119
|
+
// ran — roll back so a later attach retries instead of presenting a
|
|
120
|
+
// sheet with no live host.
|
|
121
|
+
if (!didInitiallyPresent) return@post
|
|
122
|
+
if (!isAttachedToWindow) {
|
|
123
|
+
didInitiallyPresent = false
|
|
124
|
+
return@post
|
|
125
|
+
}
|
|
126
|
+
if (!viewController.isPresented) {
|
|
127
|
+
present(initialDetentIndex, initialDetentAnimated) { }
|
|
111
128
|
}
|
|
112
129
|
}
|
|
113
130
|
}
|
|
@@ -287,6 +304,12 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
|
|
|
287
304
|
setupScrollable()
|
|
288
305
|
}
|
|
289
306
|
|
|
307
|
+
fun setScrollableHandle(handle: Int) {
|
|
308
|
+
if (viewController.scrollableHandle == handle) return
|
|
309
|
+
viewController.scrollableHandle = handle
|
|
310
|
+
setupScrollable()
|
|
311
|
+
}
|
|
312
|
+
|
|
290
313
|
fun setAbsoluteHeader(absolute: Boolean) {
|
|
291
314
|
viewController.absoluteHeader = absolute
|
|
292
315
|
}
|
|
@@ -302,10 +325,9 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
|
|
|
302
325
|
|
|
303
326
|
private fun setupScrollable() {
|
|
304
327
|
viewController.containerView?.let {
|
|
305
|
-
it.insetAdjustment = viewController.insetAdjustment
|
|
306
|
-
it.scrollViewBottomInset = viewController.contentBottomInset
|
|
307
328
|
it.scrollableOptions = viewController.scrollableOptions
|
|
308
|
-
it.
|
|
329
|
+
it.scrollableHandle = viewController.scrollableHandle
|
|
330
|
+
it.scrollableBottomInset = viewController.contentBottomInset
|
|
309
331
|
it.footerBottomInset = viewController.contentBottomInset
|
|
310
332
|
it.absoluteFooter = viewController.absoluteFooter
|
|
311
333
|
it.setupScrollable()
|
|
@@ -354,18 +376,7 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
|
|
|
354
376
|
lastContainerWidth = width
|
|
355
377
|
lastContainerHeight = height
|
|
356
378
|
|
|
357
|
-
|
|
358
|
-
val widthDp = width.toFloat().pxToDp()
|
|
359
|
-
val heightDp = height.toFloat().pxToDp()
|
|
360
|
-
|
|
361
|
-
// Synchronous update — commits and mounts within the same UI-thread frame
|
|
362
|
-
if (TrueSheetStateUpdater.updateState(sw, widthDp, heightDp)) return
|
|
363
|
-
|
|
364
|
-
// Fallback: async state update
|
|
365
|
-
val newStateData = WritableNativeMap()
|
|
366
|
-
newStateData.putDouble("containerWidth", widthDp.toDouble())
|
|
367
|
-
newStateData.putDouble("containerHeight", heightDp.toDouble())
|
|
368
|
-
sw.updateState(newStateData)
|
|
379
|
+
stateWrapper?.let { TrueSheetStateUpdater.updateContainerSize(it, width, height) }
|
|
369
380
|
}
|
|
370
381
|
|
|
371
382
|
// ==================== Sheet Actions ====================
|
|
@@ -469,7 +480,13 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
|
|
|
469
480
|
if (viewController.containerView == null) return@post
|
|
470
481
|
|
|
471
482
|
viewController.setupSheetDetentsForSizeChange()
|
|
472
|
-
|
|
483
|
+
// While settling, onSlide drives the parent translation in realtime —
|
|
484
|
+
// an animated update here would race it frame-by-frame, staggering the
|
|
485
|
+
// emitted position. Keyboard-driven resizes leave the parent alone (like
|
|
486
|
+
// iOS); keyboardDidHide resizes again once the detents are keyboard-free.
|
|
487
|
+
if (!viewController.isSettling && !viewController.isKeyboardActive) {
|
|
488
|
+
TrueSheetStackManager.updateParentTranslation(this)
|
|
489
|
+
}
|
|
473
490
|
}
|
|
474
491
|
}
|
|
475
492
|
|
|
@@ -497,14 +514,46 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
|
|
|
497
514
|
}
|
|
498
515
|
}
|
|
499
516
|
|
|
517
|
+
/**
|
|
518
|
+
* Realtime counterpart of updateTranslationForChild, driven by the child's
|
|
519
|
+
* onSlide frames so stacked sheets move in lockstep instead of on
|
|
520
|
+
* independently-timed animations.
|
|
521
|
+
*/
|
|
522
|
+
fun syncTranslationForChild(childSheetTop: Int, childMinSheetTop: Int) {
|
|
523
|
+
if (!viewController.isSheetVisible || viewController.isExpanded) return
|
|
524
|
+
|
|
525
|
+
val mySheetTop = viewController.detentCalculator.getSheetTopForDetentIndex(viewController.currentDetentIndex)
|
|
526
|
+
val targetTranslation = maxOf(0, childMinSheetTop - mySheetTop)
|
|
527
|
+
val actualTranslation = maxOf(0, childSheetTop - mySheetTop)
|
|
528
|
+
val currentTranslation = viewController.currentTranslationY
|
|
529
|
+
|
|
530
|
+
// Ride the child's actual position, but only between the current
|
|
531
|
+
// translation and the settled target — tracks the child frame-by-frame
|
|
532
|
+
// when the alignment changes (auto detent resize) while staying put when
|
|
533
|
+
// the child moves between detents above its minimum. Returning early on
|
|
534
|
+
// no-ops avoids cancelling an in-flight realign animation.
|
|
535
|
+
val newTranslation = actualTranslation.coerceIn(
|
|
536
|
+
minOf(currentTranslation, targetTranslation),
|
|
537
|
+
maxOf(currentTranslation, targetTranslation)
|
|
538
|
+
)
|
|
539
|
+
if (newTranslation == currentTranslation) return
|
|
540
|
+
|
|
541
|
+
viewController.translateSheet(newTranslation, animated = false)
|
|
542
|
+
|
|
543
|
+
val additionalTranslation = newTranslation - currentTranslation
|
|
544
|
+
if (additionalTranslation > 0) {
|
|
545
|
+
TrueSheetStackManager.getParentSheet(this)?.addTranslation(additionalTranslation, animated = false)
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
|
|
500
549
|
/**
|
|
501
550
|
* Recursively adds translation to this sheet and all parent sheets.
|
|
502
551
|
*/
|
|
503
|
-
private fun addTranslation(amount: Int) {
|
|
552
|
+
private fun addTranslation(amount: Int, animated: Boolean = true) {
|
|
504
553
|
if (viewController.isExpanded) return
|
|
505
554
|
|
|
506
|
-
viewController.translateSheet(viewController.currentTranslationY + amount)
|
|
507
|
-
TrueSheetStackManager.getParentSheet(this)?.addTranslation(amount)
|
|
555
|
+
viewController.translateSheet(viewController.currentTranslationY + amount, animated)
|
|
556
|
+
TrueSheetStackManager.getParentSheet(this)?.addTranslation(amount, animated)
|
|
508
557
|
}
|
|
509
558
|
|
|
510
559
|
/**
|
|
@@ -542,6 +591,11 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
|
|
|
542
591
|
eventDispatcher?.dispatchEvent(WillDismissEvent(surfaceId, id))
|
|
543
592
|
}
|
|
544
593
|
|
|
594
|
+
override fun viewControllerDidAttemptDismiss() {
|
|
595
|
+
val surfaceId = UIManagerHelper.getSurfaceId(this)
|
|
596
|
+
eventDispatcher?.dispatchEvent(DismissAttemptEvent(surfaceId, id))
|
|
597
|
+
}
|
|
598
|
+
|
|
545
599
|
override fun viewControllerDidDismiss(parent: TrueSheetView?) {
|
|
546
600
|
// Detach coordinator from the root container view
|
|
547
601
|
viewController.coordinatorLayout?.let { rootContainerView?.removeView(it) }
|
|
@@ -626,7 +680,7 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
|
|
|
626
680
|
viewController.commitKeyboardDetent()
|
|
627
681
|
}
|
|
628
682
|
|
|
629
|
-
// When the ScrollView changes (e.g. conditional remount), re-
|
|
683
|
+
// When the ScrollView changes (e.g. conditional remount), re-detect the new ScrollView
|
|
630
684
|
// and request layout so BottomSheetBehavior re-discovers the nested scrolling child.
|
|
631
685
|
override fun containerViewScrollViewDidChange() {
|
|
632
686
|
setupScrollable()
|
|
@@ -672,16 +726,5 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
|
|
|
672
726
|
* of whichever window this view is in - whether that's the activity's window or a
|
|
673
727
|
* Modal's dialog window.
|
|
674
728
|
*/
|
|
675
|
-
override fun findRootContainerView(): ViewGroup?
|
|
676
|
-
var current: android.view.ViewParent? = parent
|
|
677
|
-
|
|
678
|
-
while (current != null) {
|
|
679
|
-
if (current is ViewGroup && current.id == android.R.id.content) {
|
|
680
|
-
return current
|
|
681
|
-
}
|
|
682
|
-
current = current.parent
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
return reactContext.currentActivity?.findViewById(android.R.id.content)
|
|
686
|
-
}
|
|
729
|
+
override fun findRootContainerView(): ViewGroup? = findRootContainerView(reactContext)
|
|
687
730
|
}
|