@lodev09/react-native-true-sheet 4.0.0-beta.2 → 4.0.0-beta.20
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 +50 -16
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentView.kt +302 -184
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentViewManager.kt +5 -1
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetFooterView.kt +21 -110
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetOverlayView.kt +116 -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 +119 -50
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewController.kt +360 -163
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt +54 -12
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetBottomSheetView.kt +22 -9
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetCoordinatorLayout.kt +84 -5
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetDetentCalculator.kt +104 -39
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetDimView.kt +3 -0
- 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 +15 -2
- package/android/src/main/java/com/lodev09/truesheet/utils/ScreenUtils.kt +0 -12
- 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 +1 -9
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.cpp +110 -30
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.h +30 -7
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewState.cpp +2 -2
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewState.h +9 -8
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewComponentDescriptor.h +3 -5
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.cpp +9 -3
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.h +3 -6
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewState.cpp +1 -1
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewState.h +4 -6
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetInsets.cpp +1 -1
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetInsets.h +1 -1
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetLayoutUtils.h +43 -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 +33 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewComponentDescriptor.h +3 -5
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.cpp +7 -40
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.h +3 -7
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewState.cpp +3 -5
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewState.h +4 -5
- package/ios/TrueSheetContainerView.h +27 -7
- package/ios/TrueSheetContainerView.mm +31 -11
- package/ios/TrueSheetContentView.h +43 -15
- package/ios/TrueSheetContentView.mm +211 -189
- package/ios/TrueSheetFooterView.h +6 -0
- package/ios/TrueSheetFooterView.mm +93 -17
- 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 +212 -55
- package/ios/TrueSheetViewController.h +31 -3
- package/ios/TrueSheetViewController.mm +393 -94
- package/ios/core/TrueSheetBlurView.h +0 -2
- package/ios/core/TrueSheetBlurView.mm +3 -36
- package/ios/core/TrueSheetDetentCalculator.h +7 -1
- package/ios/core/TrueSheetDetentCalculator.mm +27 -4
- package/ios/core/TrueSheetGrabberView.mm +13 -3
- package/ios/core/TrueSheetKeyboardObserver.mm +2 -0
- 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 +173 -39
- package/lib/module/TrueSheet.js.map +1 -1
- package/lib/module/TrueSheet.web.js +218 -243
- package/lib/module/TrueSheet.web.js.map +1 -1
- package/lib/module/TrueSheetBackground.js +15 -0
- package/lib/module/TrueSheetBackground.js.map +1 -0
- 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 +20 -15
- package/lib/module/TrueSheetPeek.web.js.map +1 -1
- package/lib/module/detentBackgrounds.js +21 -0
- package/lib/module/detentBackgrounds.js.map +1 -0
- package/lib/module/fabric/TrueSheetContentViewNativeComponent.ts +1 -1
- package/lib/module/fabric/TrueSheetOverlayViewNativeComponent.ts +12 -0
- package/lib/module/fabric/TrueSheetViewNativeComponent.ts +14 -10
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/mocks/index.js +18 -2
- package/lib/module/mocks/index.js.map +1 -1
- package/lib/module/mocks/navigationExpoRouter.js.map +1 -1
- package/lib/module/navigation/base-types.js +2 -0
- package/lib/module/navigation/base-types.js.map +1 -0
- package/lib/module/navigation/createTrueSheetRouter.js +0 -9
- package/lib/module/navigation/createTrueSheetRouter.js.map +1 -1
- 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 +10 -7
- package/lib/module/navigation/expo-router/index.js.map +1 -1
- 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.map +1 -1
- package/lib/module/navigation/screen/useSheetScreenState.js +1 -0
- package/lib/module/navigation/screen/useSheetScreenState.js.map +1 -1
- package/lib/module/web/constants.js +1 -1
- package/lib/module/web/constants.js.map +1 -1
- package/lib/module/web/layout.js +168 -0
- package/lib/module/web/layout.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 +1 -0
- package/lib/module/web/vaul/helpers.js.map +1 -1
- package/lib/module/web/vaul/index.js +44 -6
- package/lib/module/web/vaul/index.js.map +1 -1
- package/lib/module/web/vaul/use-snap-points.js +6 -8
- package/lib/module/web/vaul/use-snap-points.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 +135 -34
- 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/TrueSheetBackground.d.ts +3 -0
- package/lib/typescript/src/TrueSheetBackground.d.ts.map +1 -0
- 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 +8 -4
- package/lib/typescript/src/TrueSheetPeek.web.d.ts.map +1 -1
- package/lib/typescript/src/detentBackgrounds.d.ts +10 -0
- package/lib/typescript/src/detentBackgrounds.d.ts.map +1 -0
- 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 +11 -7
- 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/navigationExpoRouter.d.ts +3 -3
- package/lib/typescript/src/mocks/navigationExpoRouter.d.ts.map +1 -1
- 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 +2 -13
- package/lib/typescript/src/navigation/createTrueSheetRouter.d.ts.map +1 -1
- 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 +8 -6
- package/lib/typescript/src/navigation/expo-router/index.d.ts.map +1 -1
- 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 +3 -4
- package/lib/typescript/src/navigation/index.d.ts.map +1 -1
- package/lib/typescript/src/navigation/screen/useSheetScreenState.d.ts +2 -1
- package/lib/typescript/src/navigation/screen/useSheetScreenState.d.ts.map +1 -1
- package/lib/typescript/src/navigation/types.d.ts +41 -5
- package/lib/typescript/src/navigation/types.d.ts.map +1 -1
- package/lib/typescript/src/web/constants.d.ts +1 -1
- package/lib/typescript/src/web/constants.d.ts.map +1 -1
- package/lib/typescript/src/web/layout.d.ts +19 -0
- package/lib/typescript/src/web/layout.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 +1 -0
- 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/lib/typescript/src/web/vaul/use-snap-points.d.ts.map +1 -1
- package/package.json +17 -8
- package/react-native.config.js +1 -0
- package/src/TrueSheet.tsx +206 -48
- package/src/TrueSheet.types.ts +142 -35
- package/src/TrueSheet.web.tsx +270 -290
- package/src/TrueSheetBackground.tsx +17 -0
- package/src/TrueSheetOverlay.tsx +24 -0
- package/src/TrueSheetOverlay.web.tsx +33 -0
- package/src/TrueSheetPeek.web.tsx +25 -23
- package/src/detentBackgrounds.ts +24 -0
- package/src/fabric/TrueSheetContentViewNativeComponent.ts +1 -1
- package/src/fabric/TrueSheetOverlayViewNativeComponent.ts +12 -0
- package/src/fabric/TrueSheetViewNativeComponent.ts +14 -10
- package/src/index.ts +1 -0
- package/src/mocks/index.ts +17 -2
- package/src/mocks/navigationExpoRouter.ts +6 -5
- package/src/navigation/base-types.ts +20 -0
- package/src/navigation/createTrueSheetRouter.ts +5 -33
- package/src/navigation/expo-router/base-types.ts +18 -0
- package/src/navigation/expo-router/index.ts +28 -30
- package/src/navigation/expo-router/types.ts +116 -0
- package/src/navigation/index.ts +6 -7
- package/src/navigation/screen/useSheetScreenState.ts +2 -0
- package/src/navigation/types.ts +75 -22
- package/src/web/constants.ts +1 -1
- package/src/web/layout.ts +196 -0
- package/src/web/vaul/constants.ts +4 -0
- package/src/web/vaul/context.ts +1 -0
- package/src/web/vaul/helpers.ts +5 -0
- package/src/web/vaul/index.tsx +67 -5
- package/src/web/vaul/use-snap-points.ts +6 -14
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
package com.lodev09.truesheet.core
|
|
2
|
+
|
|
3
|
+
import android.annotation.SuppressLint
|
|
4
|
+
import android.view.MotionEvent
|
|
5
|
+
import android.view.View
|
|
6
|
+
import android.widget.FrameLayout
|
|
7
|
+
import com.facebook.react.uimanager.JSPointerDispatcher
|
|
8
|
+
import com.facebook.react.uimanager.JSTouchDispatcher
|
|
9
|
+
import com.facebook.react.uimanager.RootView
|
|
10
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
11
|
+
import com.facebook.react.uimanager.TouchTargetHelper
|
|
12
|
+
import com.facebook.react.uimanager.events.EventDispatcher
|
|
13
|
+
import com.lodev09.truesheet.utils.TouchEventDeduper
|
|
14
|
+
|
|
15
|
+
interface TrueSheetOverlayRootViewDelegate {
|
|
16
|
+
val eventDispatcher: EventDispatcher?
|
|
17
|
+
fun overlayRootViewDidChangeSize(width: Int, height: Int)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Window-level view hosting an overlay's children, attached to the activity's
|
|
22
|
+
* content view above the sheet coordinators.
|
|
23
|
+
*
|
|
24
|
+
* Implements RootView to dispatch touches to JS. Touches that miss every child
|
|
25
|
+
* fall through to the views beneath.
|
|
26
|
+
*/
|
|
27
|
+
@SuppressLint("ViewConstructor")
|
|
28
|
+
class TrueSheetOverlayRootView(private val reactContext: ThemedReactContext) :
|
|
29
|
+
FrameLayout(reactContext),
|
|
30
|
+
RootView {
|
|
31
|
+
|
|
32
|
+
var delegate: TrueSheetOverlayRootViewDelegate? = null
|
|
33
|
+
|
|
34
|
+
private val eventDispatcher: EventDispatcher?
|
|
35
|
+
get() = delegate?.eventDispatcher
|
|
36
|
+
|
|
37
|
+
private val jsTouchDispatcher = JSTouchDispatcher(this)
|
|
38
|
+
private val jsPointerDispatcher = JSPointerDispatcher(this)
|
|
39
|
+
private val touchDeduper = TouchEventDeduper()
|
|
40
|
+
|
|
41
|
+
// Whether the current touch stream landed on a child
|
|
42
|
+
private var isHandlingStream = false
|
|
43
|
+
|
|
44
|
+
init {
|
|
45
|
+
layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
|
|
46
|
+
|
|
47
|
+
// Draws and receives touches above the sheet coordinators regardless of add order
|
|
48
|
+
translationZ = OVERLAY_Z
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Children are positioned by Fabric — a FrameLayout pass would stretch them to match_parent
|
|
52
|
+
override fun onLayout(
|
|
53
|
+
changed: Boolean,
|
|
54
|
+
left: Int,
|
|
55
|
+
top: Int,
|
|
56
|
+
right: Int,
|
|
57
|
+
bottom: Int
|
|
58
|
+
) {
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
|
|
62
|
+
super.onSizeChanged(w, h, oldw, oldh)
|
|
63
|
+
delegate?.overlayRootViewDidChangeSize(w, h)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
|
|
67
|
+
if (ev.actionMasked == MotionEvent.ACTION_DOWN) {
|
|
68
|
+
// The path ends with this root, so a touch that misses every child resolves to it
|
|
69
|
+
val target = TouchTargetHelper
|
|
70
|
+
.findTargetPathAndCoordinatesForTouch(ev.x, ev.y, this, FloatArray(2))
|
|
71
|
+
.firstNotNullOfOrNull { it.getView() }
|
|
72
|
+
isHandlingStream = target != null && target !== this
|
|
73
|
+
}
|
|
74
|
+
if (!isHandlingStream) return false
|
|
75
|
+
return super.dispatchTouchEvent(ev)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// ==================== RootView Implementation ====================
|
|
79
|
+
|
|
80
|
+
override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
|
|
81
|
+
eventDispatcher?.let { dispatcher ->
|
|
82
|
+
if (touchDeduper.shouldDispatch(event)) {
|
|
83
|
+
jsTouchDispatcher.handleTouchEvent(event, dispatcher, reactContext)
|
|
84
|
+
}
|
|
85
|
+
jsPointerDispatcher.handleMotionEvent(event, dispatcher, true)
|
|
86
|
+
}
|
|
87
|
+
return super.onInterceptTouchEvent(event)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
override fun requestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {
|
|
91
|
+
// Mirrors ReactSurfaceView: keep receiving onInterceptTouchEvent so
|
|
92
|
+
// jsTouchDispatcher sees the gesture end, but forward the request up the tree.
|
|
93
|
+
parent?.requestDisallowInterceptTouchEvent(disallowIntercept)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
@SuppressLint("ClickableViewAccessibility")
|
|
97
|
+
override fun onTouchEvent(event: MotionEvent): Boolean {
|
|
98
|
+
eventDispatcher?.let { dispatcher ->
|
|
99
|
+
if (touchDeduper.shouldDispatch(event)) {
|
|
100
|
+
jsTouchDispatcher.handleTouchEvent(event, dispatcher, reactContext)
|
|
101
|
+
}
|
|
102
|
+
jsPointerDispatcher.handleMotionEvent(event, dispatcher, false)
|
|
103
|
+
}
|
|
104
|
+
super.onTouchEvent(event)
|
|
105
|
+
return true
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
override fun onInterceptHoverEvent(event: MotionEvent): Boolean {
|
|
109
|
+
eventDispatcher?.let { jsPointerDispatcher.handleMotionEvent(event, it, true) }
|
|
110
|
+
return super.onHoverEvent(event)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
override fun onHoverEvent(event: MotionEvent): Boolean {
|
|
114
|
+
eventDispatcher?.let { jsPointerDispatcher.handleMotionEvent(event, it, false) }
|
|
115
|
+
return super.onHoverEvent(event)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
override fun onChildStartedNativeGesture(childView: View?, ev: MotionEvent) {
|
|
119
|
+
eventDispatcher?.let { dispatcher ->
|
|
120
|
+
jsTouchDispatcher.onChildStartedNativeGesture(ev, dispatcher)
|
|
121
|
+
jsPointerDispatcher.onChildStartedNativeGesture(childView, ev, dispatcher)
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
override fun onChildEndedNativeGesture(childView: View, ev: MotionEvent) {
|
|
126
|
+
eventDispatcher?.let { jsTouchDispatcher.onChildEndedNativeGesture(ev, it) }
|
|
127
|
+
jsPointerDispatcher.onChildEndedNativeGesture()
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
override fun handleException(t: Throwable) {
|
|
131
|
+
reactContext.reactApplicationContext.handleException(RuntimeException(t))
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
companion object {
|
|
135
|
+
private const val OVERLAY_Z = 1000f
|
|
136
|
+
}
|
|
137
|
+
}
|
|
@@ -93,6 +93,21 @@ class DidDismissEvent(surfaceId: Int, viewId: Int) : Event<DidDismissEvent>(surf
|
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
+
/**
|
|
97
|
+
* Fired when the user tries to dismiss a non-dismissible sheet
|
|
98
|
+
*/
|
|
99
|
+
class DismissAttemptEvent(surfaceId: Int, viewId: Int) : Event<DismissAttemptEvent>(surfaceId, viewId) {
|
|
100
|
+
|
|
101
|
+
override fun getEventName(): String = EVENT_NAME
|
|
102
|
+
|
|
103
|
+
override fun getEventData(): WritableMap = Arguments.createMap()
|
|
104
|
+
|
|
105
|
+
companion object {
|
|
106
|
+
const val EVENT_NAME = "topDismissAttempt"
|
|
107
|
+
const val REGISTRATION_NAME = "onDismissAttempt"
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
96
111
|
/**
|
|
97
112
|
* Fired when the sheet visibility changes due to screen transitions
|
|
98
113
|
*/
|
|
@@ -3,6 +3,7 @@ package com.lodev09.truesheet.utils
|
|
|
3
3
|
import android.content.Context
|
|
4
4
|
import android.os.Build
|
|
5
5
|
import android.view.View
|
|
6
|
+
import android.view.WindowInsets
|
|
6
7
|
import android.view.inputmethod.InputMethodManager
|
|
7
8
|
import androidx.core.view.ViewCompat
|
|
8
9
|
import androidx.core.view.WindowInsetsAnimationCompat
|
|
@@ -19,7 +20,7 @@ object KeyboardUtils {
|
|
|
19
20
|
return isKeyboardVisible(rootView)
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
fun isKeyboardVisible(view: View): Boolean {
|
|
23
24
|
val insets = ViewCompat.getRootWindowInsets(view) ?: return false
|
|
24
25
|
return insets.isVisible(WindowInsetsCompat.Type.ime())
|
|
25
26
|
}
|
|
@@ -36,10 +37,22 @@ object KeyboardUtils {
|
|
|
36
37
|
* Dismisses the soft keyboard with an optional callback when the animation completes.
|
|
37
38
|
*/
|
|
38
39
|
fun dismiss(view: View, onComplete: (() -> Unit)?) {
|
|
40
|
+
if (!isKeyboardVisible(view)) {
|
|
41
|
+
onComplete?.invoke()
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
|
|
39
45
|
val imm = view.context.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager
|
|
40
46
|
val focusedView = view.rootView.findFocus()
|
|
41
47
|
|
|
42
|
-
|
|
48
|
+
// A keyboard can stay up with nothing focused, e.g. a blur that lands after focus was restored,
|
|
49
|
+
// so hide it through the window instead of treating it as already hidden.
|
|
50
|
+
if (focusedView == null) {
|
|
51
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
|
52
|
+
view.windowInsetsController?.hide(WindowInsets.Type.ime())
|
|
53
|
+
} else {
|
|
54
|
+
imm?.hideSoftInputFromWindow(view.windowToken, 0)
|
|
55
|
+
}
|
|
43
56
|
onComplete?.invoke()
|
|
44
57
|
return
|
|
45
58
|
}
|
|
@@ -104,18 +104,6 @@ object ScreenUtils {
|
|
|
104
104
|
*/
|
|
105
105
|
fun getScreenHeight(reactContext: ReactContext): Int = reactContext.resources.displayMetrics.heightPixels
|
|
106
106
|
|
|
107
|
-
/**
|
|
108
|
-
* Get the location of a view in screen coordinates
|
|
109
|
-
*
|
|
110
|
-
* @param view The view to get screen location for
|
|
111
|
-
* @return IntArray with [x, y] coordinates in screen space
|
|
112
|
-
*/
|
|
113
|
-
fun getScreenLocation(view: View): IntArray {
|
|
114
|
-
val location = IntArray(2)
|
|
115
|
-
view.getLocationOnScreen(location)
|
|
116
|
-
return location
|
|
117
|
-
}
|
|
118
|
-
|
|
119
107
|
/**
|
|
120
108
|
* Returns true if the device is a phone in portrait orientation.
|
|
121
109
|
*/
|
|
@@ -2,8 +2,10 @@ package com.lodev09.truesheet.utils
|
|
|
2
2
|
|
|
3
3
|
import android.view.View
|
|
4
4
|
import android.view.ViewGroup
|
|
5
|
+
import android.view.ViewParent
|
|
5
6
|
import android.widget.ScrollView
|
|
6
7
|
import androidx.core.widget.NestedScrollView
|
|
8
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
7
9
|
|
|
8
10
|
fun View.isDescendantOf(ancestor: View): Boolean {
|
|
9
11
|
if (!isAttachedToWindow) return false
|
|
@@ -15,16 +17,26 @@ fun View.isDescendantOf(ancestor: View): Boolean {
|
|
|
15
17
|
return false
|
|
16
18
|
}
|
|
17
19
|
|
|
18
|
-
fun ViewGroup.smoothScrollBy(dx: Int, dy: Int) {
|
|
19
|
-
when (this) {
|
|
20
|
-
is ScrollView -> smoothScrollBy(dx, dy)
|
|
21
|
-
is NestedScrollView -> smoothScrollBy(dx, dy)
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
20
|
fun ViewGroup.smoothScrollTo(x: Int, y: Int) {
|
|
26
21
|
when (this) {
|
|
27
22
|
is ScrollView -> smoothScrollTo(x, y)
|
|
28
23
|
is NestedScrollView -> smoothScrollTo(x, y)
|
|
29
24
|
}
|
|
30
25
|
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The content view hosting this view — the activity's, or a Modal dialog's.
|
|
29
|
+
* Window-level views (sheet coordinators, overlays) attach here.
|
|
30
|
+
*/
|
|
31
|
+
fun View.findRootContainerView(reactContext: ThemedReactContext): ViewGroup? {
|
|
32
|
+
var current: ViewParent? = parent
|
|
33
|
+
|
|
34
|
+
while (current != null) {
|
|
35
|
+
if (current is ViewGroup && current.id == android.R.id.content) {
|
|
36
|
+
return current
|
|
37
|
+
}
|
|
38
|
+
current = current.parent
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return reactContext.currentActivity?.findViewById(android.R.id.content)
|
|
42
|
+
}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
#include <jsi/jsi.h>
|
|
6
6
|
#include <react/renderer/components/TrueSheetSpec/TrueSheetContentViewComponentDescriptor.h>
|
|
7
7
|
#include <react/renderer/components/TrueSheetSpec/TrueSheetFooterViewComponentDescriptor.h>
|
|
8
|
+
#include <react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewComponentDescriptor.h>
|
|
8
9
|
#include <react/renderer/components/TrueSheetSpec/TrueSheetViewComponentDescriptor.h>
|
|
9
10
|
|
|
10
11
|
namespace facebook {
|
package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewComponentDescriptor.h
CHANGED
|
@@ -11,14 +11,6 @@ namespace facebook::react {
|
|
|
11
11
|
class TrueSheetContentViewComponentDescriptor final
|
|
12
12
|
: public ConcreteComponentDescriptor<TrueSheetContentViewShadowNode> {
|
|
13
13
|
using ConcreteComponentDescriptor::ConcreteComponentDescriptor;
|
|
14
|
-
|
|
15
|
-
void adopt(ShadowNode &shadowNode) const override {
|
|
16
|
-
auto &concreteShadowNode =
|
|
17
|
-
static_cast<TrueSheetContentViewShadowNode &>(shadowNode);
|
|
18
|
-
concreteShadowNode.adjustLayoutWithState();
|
|
19
|
-
|
|
20
|
-
ConcreteComponentDescriptor::adopt(shadowNode);
|
|
21
|
-
}
|
|
22
14
|
};
|
|
23
15
|
|
|
24
|
-
}
|
|
16
|
+
} // namespace facebook::react
|
package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.cpp
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
#include "TrueSheetContentViewShadowNode.h"
|
|
2
2
|
|
|
3
|
+
#include <folly/ScopeGuard.h>
|
|
3
4
|
#include <react/renderer/components/view/conversions.h>
|
|
5
|
+
#include <react/renderer/core/ComponentDescriptor.h>
|
|
6
|
+
#include <react/renderer/core/LayoutConstraints.h>
|
|
7
|
+
#include <react/renderer/core/LayoutContext.h>
|
|
8
|
+
|
|
9
|
+
#include <limits>
|
|
4
10
|
|
|
5
11
|
namespace facebook::react {
|
|
6
12
|
|
|
@@ -8,36 +14,110 @@ using namespace yoga;
|
|
|
8
14
|
|
|
9
15
|
extern const char TrueSheetContentViewComponentName[] = "TrueSheetContentView";
|
|
10
16
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
17
|
+
// The measurement pass re-enters layout() on a clone — guard so it doesn't
|
|
18
|
+
// measure again recursively.
|
|
19
|
+
static thread_local bool gIsMeasuringNaturalHeight = false;
|
|
20
|
+
|
|
21
|
+
TrueSheetContentViewShadowNode::TrueSheetContentViewShadowNode(
|
|
22
|
+
const ShadowNode &sourceShadowNode, const ShadowNodeFragment &fragment)
|
|
23
|
+
: ConcreteViewShadowNode(sourceShadowNode, fragment),
|
|
24
|
+
measurement_(static_cast<const TrueSheetContentViewShadowNode &>(sourceShadowNode).measurement_),
|
|
25
|
+
measurementSourceChildren_(
|
|
26
|
+
static_cast<const TrueSheetContentViewShadowNode &>(sourceShadowNode).measurementSourceChildren_),
|
|
27
|
+
contentChanged_(static_cast<const TrueSheetContentViewShadowNode &>(sourceShadowNode).contentChanged_ ||
|
|
28
|
+
fragment.props || fragment.children) {
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
void TrueSheetContentViewShadowNode::layout(LayoutContext layoutContext) {
|
|
32
|
+
// The sizing tree needs Yoga's result, not Fabric state updates or events.
|
|
33
|
+
if (gIsMeasuringNaturalHeight) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
ConcreteViewShadowNode::layout(layoutContext);
|
|
37
|
+
updateNaturalHeightIfNeeded(layoutContext);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Every descendant must be detached from React's runtime references before
|
|
41
|
+
// Yoga clones it during measurement. Disabling transfer only on the root
|
|
42
|
+
// still lets descendant clones replace React's live nodes. Reuse unchanged
|
|
43
|
+
// measurement subtrees; Yoga owns copy-on-write when their layout changes.
|
|
44
|
+
std::shared_ptr<ShadowNode> TrueSheetContentViewShadowNode::cloneForMeasurement(
|
|
45
|
+
const ShadowNode &node, const Children &previousSourceChildren, const Children &previousMeasurementChildren) {
|
|
46
|
+
auto children = std::make_shared<Children>();
|
|
47
|
+
children->reserve(node.getChildren().size());
|
|
48
|
+
for (size_t index = 0; index < node.getChildren().size(); index++) {
|
|
49
|
+
const auto &child = node.getChildren()[index];
|
|
50
|
+
if (index < previousSourceChildren.size() && ShadowNode::sameFamily(*child, *previousSourceChildren[index])) {
|
|
51
|
+
const auto &previousSource = previousSourceChildren[index];
|
|
52
|
+
const auto &previousMeasurement = previousMeasurementChildren[index];
|
|
53
|
+
children->push_back(child == previousSource ? previousMeasurement
|
|
54
|
+
: cloneForMeasurement(*child, previousSource->getChildren(),
|
|
55
|
+
previousMeasurement->getChildren()));
|
|
56
|
+
} else {
|
|
57
|
+
children->push_back(cloneForMeasurement(*child, {}, {}));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
auto clone = node.getComponentDescriptor().cloneShadowNode(
|
|
62
|
+
node, {.children = children, .state = node.getState(), .runtimeShadowNodeReference = false});
|
|
63
|
+
if (auto content = dynamic_cast<TrueSheetContentViewShadowNode *>(clone.get())) {
|
|
64
|
+
content->measurement_.reset();
|
|
65
|
+
content->measurementSourceChildren_.reset();
|
|
66
|
+
}
|
|
67
|
+
return clone;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// The natural height is the height the content wants when unbounded — the
|
|
71
|
+
// source for the auto detent. When the content's height derives from the
|
|
72
|
+
// container, the committed layout doesn't reflect it — lay out a clone of the
|
|
73
|
+
// subtree with an unconstrained height instead. Yoga respects the user's
|
|
74
|
+
// styles: an explicit-height ScrollView keeps its height while a flexible one
|
|
75
|
+
// expands to its content — no ScrollView discovery involved.
|
|
76
|
+
void TrueSheetContentViewShadowNode::updateNaturalHeightIfNeeded(const LayoutContext &layoutContext) {
|
|
77
|
+
auto stateData = getStateData();
|
|
78
|
+
auto size = getLayoutMetrics().frame.size;
|
|
79
|
+
|
|
80
|
+
Float naturalHeight = size.height;
|
|
81
|
+
// Auto-height content can also be capped by a shrinking ScrollView. Only
|
|
82
|
+
// a fixed, non-flexible height can be taken from the viewport layout.
|
|
83
|
+
if (yogaNode_.isNodeFlexible() || !getConcreteProps().yogaStyle.dimension(Dimension::Height).isPoints()) {
|
|
84
|
+
auto constraints = LayoutConstraints{};
|
|
85
|
+
constraints.minimumSize = {size.width, 0};
|
|
86
|
+
constraints.maximumSize = {size.width, std::numeric_limits<Float>::infinity()};
|
|
87
|
+
constraints.layoutDirection = getLayoutMetrics().layoutDirection;
|
|
88
|
+
|
|
89
|
+
auto measurementContext = layoutContext;
|
|
90
|
+
measurementContext.affectedNodes = nullptr;
|
|
91
|
+
auto errata = YGConfigGetErrata(&yogaConfig_);
|
|
92
|
+
|
|
93
|
+
// Yoga's viewport-only clones carry no new props or children. Reuse the
|
|
94
|
+
// intrinsic height across those layouts instead of measuring each drag frame.
|
|
95
|
+
if (contentChanged_ || !measurement_ || !(measurement_->constraints == constraints) ||
|
|
96
|
+
!(measurement_->context == measurementContext) || measurement_->errata != errata) {
|
|
97
|
+
gIsMeasuringNaturalHeight = true;
|
|
98
|
+
auto restoreMeasurement = folly::makeGuard([] { gIsMeasuringNaturalHeight = false; });
|
|
99
|
+
auto measurementNode =
|
|
100
|
+
measurement_ ? cloneForMeasurement(*this, *measurementSourceChildren_, measurement_->root->getChildren())
|
|
101
|
+
: cloneForMeasurement(*this, {}, {});
|
|
102
|
+
auto &measurement = static_cast<LayoutableShadowNode &>(*measurementNode);
|
|
103
|
+
measurement.layoutTree(measurementContext, constraints);
|
|
104
|
+
measurement_ = std::make_shared<const Measurement>(Measurement{.root = measurementNode,
|
|
105
|
+
.constraints = constraints,
|
|
106
|
+
.context = measurementContext,
|
|
107
|
+
.errata = errata,
|
|
108
|
+
.height = measurement.getLayoutMetrics().frame.size.height});
|
|
109
|
+
}
|
|
110
|
+
naturalHeight = measurement_->height;
|
|
111
|
+
} else {
|
|
112
|
+
measurement_.reset();
|
|
113
|
+
}
|
|
114
|
+
measurementSourceChildren_ = children_;
|
|
115
|
+
contentChanged_ = false;
|
|
116
|
+
|
|
117
|
+
if (stateData.naturalHeight != naturalHeight) {
|
|
118
|
+
stateData.naturalHeight = naturalHeight;
|
|
119
|
+
setStateData(std::move(stateData));
|
|
40
120
|
}
|
|
41
121
|
}
|
|
42
122
|
|
|
43
|
-
}
|
|
123
|
+
} // namespace facebook::react
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
#include <react/renderer/components/TrueSheetSpec/Props.h>
|
|
6
6
|
#include <react/renderer/components/TrueSheetSpec/TrueSheetContentViewState.h>
|
|
7
7
|
#include <react/renderer/components/view/ConcreteViewShadowNode.h>
|
|
8
|
+
#include <react/renderer/core/LayoutConstraints.h>
|
|
9
|
+
#include <react/renderer/core/LayoutContext.h>
|
|
8
10
|
|
|
9
11
|
namespace facebook::react {
|
|
10
12
|
|
|
@@ -14,15 +16,36 @@ JSI_EXPORT extern const char TrueSheetContentViewComponentName[];
|
|
|
14
16
|
* `ShadowNode` for <TrueSheetContentView> component.
|
|
15
17
|
*/
|
|
16
18
|
class JSI_EXPORT TrueSheetContentViewShadowNode final
|
|
17
|
-
: public ConcreteViewShadowNode<
|
|
18
|
-
|
|
19
|
-
TrueSheetContentViewProps,
|
|
20
|
-
TrueSheetContentViewEventEmitter,
|
|
21
|
-
TrueSheetContentViewState> {
|
|
19
|
+
: public ConcreteViewShadowNode<TrueSheetContentViewComponentName, TrueSheetContentViewProps,
|
|
20
|
+
TrueSheetContentViewEventEmitter, TrueSheetContentViewState> {
|
|
22
21
|
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
|
23
22
|
|
|
24
23
|
public:
|
|
25
|
-
|
|
24
|
+
TrueSheetContentViewShadowNode(const ShadowNode &sourceShadowNode, const ShadowNodeFragment &fragment);
|
|
25
|
+
|
|
26
|
+
#pragma mark - LayoutableShadowNode
|
|
27
|
+
|
|
28
|
+
void layout(LayoutContext layoutContext) override;
|
|
29
|
+
|
|
30
|
+
private:
|
|
31
|
+
using Children = std::vector<std::shared_ptr<const ShadowNode>>;
|
|
32
|
+
|
|
33
|
+
struct Measurement {
|
|
34
|
+
std::shared_ptr<const ShadowNode> root;
|
|
35
|
+
LayoutConstraints constraints;
|
|
36
|
+
LayoutContext context;
|
|
37
|
+
YGErrata errata;
|
|
38
|
+
Float height;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
std::shared_ptr<const Measurement> measurement_;
|
|
42
|
+
std::shared_ptr<const Children> measurementSourceChildren_;
|
|
43
|
+
bool contentChanged_{true};
|
|
44
|
+
|
|
45
|
+
static std::shared_ptr<ShadowNode> cloneForMeasurement(
|
|
46
|
+
const ShadowNode &node, const Children &previousSourceChildren, const Children &previousMeasurementChildren);
|
|
47
|
+
|
|
48
|
+
void updateNaturalHeightIfNeeded(const LayoutContext &layoutContext);
|
|
26
49
|
};
|
|
27
50
|
|
|
28
|
-
}
|
|
51
|
+
} // namespace facebook::react
|
|
@@ -4,8 +4,8 @@ namespace facebook::react {
|
|
|
4
4
|
|
|
5
5
|
#ifdef ANDROID
|
|
6
6
|
folly::dynamic TrueSheetContentViewState::getDynamic() const {
|
|
7
|
-
return folly::dynamic::object("
|
|
7
|
+
return folly::dynamic::object("naturalHeight", naturalHeight);
|
|
8
8
|
}
|
|
9
9
|
#endif
|
|
10
10
|
|
|
11
|
-
}
|
|
11
|
+
} // namespace facebook::react
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
+
#include <react/renderer/graphics/Float.h>
|
|
4
|
+
|
|
3
5
|
#ifdef ANDROID
|
|
4
6
|
#include <folly/dynamic.h>
|
|
5
7
|
#include <react/renderer/mapbuffer/MapBuffer.h>
|
|
@@ -10,21 +12,20 @@ namespace facebook::react {
|
|
|
10
12
|
|
|
11
13
|
/*
|
|
12
14
|
* State for <TrueSheetContentView> component.
|
|
13
|
-
*
|
|
14
|
-
* content
|
|
15
|
+
* `naturalHeight` is measured by the shadow node during layout — the height
|
|
16
|
+
* the content wants when unbounded (see TrueSheetContentViewShadowNode).
|
|
15
17
|
*/
|
|
16
18
|
class TrueSheetContentViewState final {
|
|
17
19
|
public:
|
|
18
20
|
TrueSheetContentViewState() = default;
|
|
19
21
|
|
|
20
22
|
#ifdef ANDROID
|
|
21
|
-
TrueSheetContentViewState(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
: scrollableBounded(data["scrollableBounded"].getBool()) {}
|
|
23
|
+
TrueSheetContentViewState(TrueSheetContentViewState const &previousState, folly::dynamic data)
|
|
24
|
+
: naturalHeight(previousState.naturalHeight) {
|
|
25
|
+
}
|
|
25
26
|
#endif
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
Float naturalHeight{0};
|
|
28
29
|
|
|
29
30
|
#ifdef ANDROID
|
|
30
31
|
folly::dynamic getDynamic() const;
|
|
@@ -34,4 +35,4 @@ class TrueSheetContentViewState final {
|
|
|
34
35
|
#endif
|
|
35
36
|
};
|
|
36
37
|
|
|
37
|
-
}
|
|
38
|
+
} // namespace facebook::react
|
package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewComponentDescriptor.h
CHANGED
|
@@ -8,17 +8,15 @@ namespace facebook::react {
|
|
|
8
8
|
/*
|
|
9
9
|
* Descriptor for <TrueSheetFooterView> component.
|
|
10
10
|
*/
|
|
11
|
-
class TrueSheetFooterViewComponentDescriptor final
|
|
12
|
-
: public ConcreteComponentDescriptor<TrueSheetFooterViewShadowNode> {
|
|
11
|
+
class TrueSheetFooterViewComponentDescriptor final : public ConcreteComponentDescriptor<TrueSheetFooterViewShadowNode> {
|
|
13
12
|
using ConcreteComponentDescriptor::ConcreteComponentDescriptor;
|
|
14
13
|
|
|
15
14
|
void adopt(ShadowNode &shadowNode) const override {
|
|
16
|
-
auto &concreteShadowNode =
|
|
17
|
-
static_cast<TrueSheetFooterViewShadowNode &>(shadowNode);
|
|
15
|
+
auto &concreteShadowNode = static_cast<TrueSheetFooterViewShadowNode &>(shadowNode);
|
|
18
16
|
concreteShadowNode.adjustLayoutWithState();
|
|
19
17
|
|
|
20
18
|
ConcreteComponentDescriptor::adopt(shadowNode);
|
|
21
19
|
}
|
|
22
20
|
};
|
|
23
21
|
|
|
24
|
-
}
|
|
22
|
+
} // namespace facebook::react
|
package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.cpp
CHANGED
|
@@ -13,8 +13,7 @@ extern const char TrueSheetFooterViewComponentName[] = "TrueSheetFooterView";
|
|
|
13
13
|
void TrueSheetFooterViewShadowNode::adjustLayoutWithState() {
|
|
14
14
|
ensureUnsealed();
|
|
15
15
|
|
|
16
|
-
auto state = std::static_pointer_cast<
|
|
17
|
-
const TrueSheetFooterViewShadowNode::ConcreteState>(getState());
|
|
16
|
+
auto state = std::static_pointer_cast<const TrueSheetFooterViewShadowNode::ConcreteState>(getState());
|
|
18
17
|
auto stateData = state->getData();
|
|
19
18
|
|
|
20
19
|
auto &props = getConcreteProps();
|
|
@@ -25,6 +24,13 @@ void TrueSheetFooterViewShadowNode::adjustLayoutWithState() {
|
|
|
25
24
|
float bottomInset = stateData.bottomInset;
|
|
26
25
|
if (!stateData.initialized && props.autoBottomInset) {
|
|
27
26
|
bottomInset = TrueSheetInsets::bottomSafeArea();
|
|
27
|
+
if (bottomInset != stateData.bottomInset) {
|
|
28
|
+
// Record the seeded value so the mounted view reads exactly the inset
|
|
29
|
+
// baked into this layout — the global may change before mount.
|
|
30
|
+
auto seededData = stateData;
|
|
31
|
+
seededData.bottomInset = bottomInset;
|
|
32
|
+
setStateData(std::move(seededData));
|
|
33
|
+
}
|
|
28
34
|
}
|
|
29
35
|
|
|
30
36
|
// A footer pinned to the sheet's bottom edge owns the bottom safe-area
|
|
@@ -53,4 +59,4 @@ void TrueSheetFooterViewShadowNode::adjustLayoutWithState() {
|
|
|
53
59
|
}
|
|
54
60
|
}
|
|
55
61
|
|
|
56
|
-
}
|
|
62
|
+
} // namespace facebook::react
|
|
@@ -14,15 +14,12 @@ JSI_EXPORT extern const char TrueSheetFooterViewComponentName[];
|
|
|
14
14
|
* `ShadowNode` for <TrueSheetFooterView> component.
|
|
15
15
|
*/
|
|
16
16
|
class JSI_EXPORT TrueSheetFooterViewShadowNode final
|
|
17
|
-
: public ConcreteViewShadowNode<
|
|
18
|
-
|
|
19
|
-
TrueSheetFooterViewProps,
|
|
20
|
-
TrueSheetFooterViewEventEmitter,
|
|
21
|
-
TrueSheetFooterViewState> {
|
|
17
|
+
: public ConcreteViewShadowNode<TrueSheetFooterViewComponentName, TrueSheetFooterViewProps,
|
|
18
|
+
TrueSheetFooterViewEventEmitter, TrueSheetFooterViewState> {
|
|
22
19
|
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
|
23
20
|
|
|
24
21
|
public:
|
|
25
22
|
void adjustLayoutWithState();
|
|
26
23
|
};
|
|
27
24
|
|
|
28
|
-
}
|
|
25
|
+
} // namespace facebook::react
|
|
@@ -18,11 +18,9 @@ class TrueSheetFooterViewState final {
|
|
|
18
18
|
TrueSheetFooterViewState() = default;
|
|
19
19
|
|
|
20
20
|
#ifdef ANDROID
|
|
21
|
-
TrueSheetFooterViewState(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
: bottomInset(static_cast<float>(data["bottomInset"].getDouble())),
|
|
25
|
-
initialized(true) {}
|
|
21
|
+
TrueSheetFooterViewState(TrueSheetFooterViewState const &previousState, folly::dynamic data)
|
|
22
|
+
: bottomInset(static_cast<float>(data["bottomInset"].getDouble())), initialized(true) {
|
|
23
|
+
}
|
|
26
24
|
#endif
|
|
27
25
|
|
|
28
26
|
float bottomInset{0};
|
|
@@ -38,4 +36,4 @@ class TrueSheetFooterViewState final {
|
|
|
38
36
|
#endif
|
|
39
37
|
};
|
|
40
38
|
|
|
41
|
-
}
|
|
39
|
+
} // namespace facebook::react
|