@lodev09/react-native-true-sheet 4.0.0-beta.3 → 4.0.0-beta.30
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 +28 -5
- package/android/build.gradle +23 -1
- package/android/proguard-rules.pro +3 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContainerView.kt +50 -16
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentView.kt +303 -184
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentViewManager.kt +5 -1
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetFooterView.kt +38 -109
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetModule.kt +13 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetOverlayView.kt +127 -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 +29 -3
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +234 -66
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewController.kt +491 -186
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt +64 -10
- package/android/src/main/java/com/lodev09/truesheet/core/RNScreensEventObserver.kt +31 -14
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetBottomSheetBehavior.kt +135 -0
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetBottomSheetView.kt +23 -23
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetCoordinatorLayout.kt +130 -6
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetDetentCalculator.kt +104 -39
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetDimView.kt +14 -17
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetGrabberView.kt +2 -4
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetOverlayRootView.kt +148 -0
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetStackManager.kt +33 -40
- package/android/src/main/java/com/lodev09/truesheet/events/TrueSheetLifecycleEvents.kt +15 -0
- package/android/src/main/java/com/lodev09/truesheet/utils/ColorUtils.kt +19 -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/android/src/main/jni/TrueSheetStateUpdater.cpp +37 -6
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewComponentDescriptor.h +1 -9
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.cpp +114 -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 +14 -3
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.h +5 -6
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewState.cpp +1 -1
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewState.h +10 -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 +23 -7
- package/ios/TrueSheetContainerView.mm +45 -25
- package/ios/TrueSheetContentView.h +44 -15
- package/ios/TrueSheetContentView.mm +221 -190
- package/ios/TrueSheetFooterView.mm +133 -28
- package/ios/TrueSheetModule.h +2 -7
- package/ios/TrueSheetModule.mm +18 -18
- package/ios/TrueSheetOverlayView.h +42 -0
- package/ios/TrueSheetOverlayView.mm +175 -0
- package/ios/TrueSheetView.h +2 -0
- package/ios/TrueSheetView.mm +268 -52
- package/ios/TrueSheetViewController.h +36 -3
- package/ios/TrueSheetViewController.mm +797 -102
- package/ios/core/RNScreensEventObserver.mm +31 -28
- package/ios/core/TrueSheetBlurView.h +0 -2
- package/ios/core/TrueSheetBlurView.mm +3 -36
- package/ios/core/TrueSheetDetentCalculator.h +18 -1
- package/ios/core/TrueSheetDetentCalculator.mm +44 -9
- package/ios/core/TrueSheetDimView.h +27 -0
- package/ios/core/TrueSheetDimView.mm +41 -0
- package/ios/core/TrueSheetGrabberView.mm +13 -3
- package/ios/core/TrueSheetKeyboardObserver.h +7 -0
- package/ios/core/TrueSheetKeyboardObserver.mm +107 -15
- 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 +222 -54
- package/lib/module/TrueSheet.js.map +1 -1
- package/lib/module/TrueSheet.web.js +364 -275
- 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/TrueSheetProvider.web.js +13 -9
- package/lib/module/TrueSheetProvider.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/TrueSheetFooterViewNativeComponent.ts +2 -3
- package/lib/module/fabric/TrueSheetOverlayViewNativeComponent.ts +12 -0
- package/lib/module/fabric/TrueSheetViewNativeComponent.ts +89 -73
- 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 +158 -100
- 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/extendTrueSheetRouter.js +71 -0
- package/lib/module/navigation/expo-router/extendTrueSheetRouter.js.map +1 -0
- package/lib/module/navigation/expo-router/index.js +18 -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/scrollable.js +28 -0
- package/lib/module/scrollable.js.map +1 -0
- package/lib/module/web/constants.js +1 -1
- package/lib/module/web/constants.js.map +1 -1
- package/lib/module/web/keyboard.js +69 -0
- package/lib/module/web/keyboard.js.map +1 -0
- package/lib/module/web/layout.js +168 -0
- package/lib/module/web/layout.js.map +1 -0
- package/lib/module/web/vaul/constants.js +9 -0
- package/lib/module/web/vaul/constants.js.map +1 -1
- package/lib/module/web/vaul/context.js +4 -0
- 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 +83 -21
- package/lib/module/web/vaul/index.js.map +1 -1
- package/lib/module/web/vaul/use-snap-points.js +57 -28
- package/lib/module/web/vaul/use-snap-points.js.map +1 -1
- package/lib/typescript/src/TrueSheet.d.ts +18 -1
- package/lib/typescript/src/TrueSheet.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheet.types.d.ts +209 -35
- 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/TrueSheetProvider.web.d.ts +5 -1
- package/lib/typescript/src/TrueSheetProvider.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/TrueSheetFooterViewNativeComponent.d.ts +2 -3
- package/lib/typescript/src/fabric/TrueSheetFooterViewNativeComponent.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 +76 -65
- 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 +36 -10
- 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/extendTrueSheetRouter.d.ts +33 -0
- package/lib/typescript/src/navigation/expo-router/extendTrueSheetRouter.d.ts.map +1 -0
- package/lib/typescript/src/navigation/expo-router/index.d.ts +9 -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 +43 -6
- package/lib/typescript/src/navigation/types.d.ts.map +1 -1
- package/lib/typescript/src/scrollable.d.ts +2 -0
- package/lib/typescript/src/scrollable.d.ts.map +1 -0
- 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/keyboard.d.ts +15 -0
- package/lib/typescript/src/web/keyboard.d.ts.map +1 -0
- package/lib/typescript/src/web/layout.d.ts +20 -0
- package/lib/typescript/src/web/layout.d.ts.map +1 -0
- package/lib/typescript/src/web/vaul/constants.d.ts +3 -0
- package/lib/typescript/src/web/vaul/constants.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/context.d.ts +5 -1
- 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 +20 -1
- package/lib/typescript/src/web/vaul/index.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/types.d.ts +9 -0
- package/lib/typescript/src/web/vaul/types.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/use-snap-points.d.ts +6 -4
- package/lib/typescript/src/web/vaul/use-snap-points.d.ts.map +1 -1
- package/package.json +18 -8
- package/react-native.config.js +1 -0
- package/src/TrueSheet.tsx +257 -62
- package/src/TrueSheet.types.ts +225 -35
- package/src/TrueSheet.web.tsx +445 -333
- 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/TrueSheetProvider.web.tsx +22 -13
- package/src/detentBackgrounds.ts +24 -0
- package/src/fabric/TrueSheetContentViewNativeComponent.ts +1 -1
- package/src/fabric/TrueSheetFooterViewNativeComponent.ts +2 -3
- package/src/fabric/TrueSheetOverlayViewNativeComponent.ts +12 -0
- package/src/fabric/TrueSheetViewNativeComponent.ts +89 -73
- 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 +220 -144
- package/src/navigation/expo-router/base-types.ts +18 -0
- package/src/navigation/expo-router/extendTrueSheetRouter.ts +99 -0
- package/src/navigation/expo-router/index.ts +41 -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 +81 -23
- package/src/scrollable.ts +25 -0
- package/src/web/constants.ts +1 -1
- package/src/web/keyboard.ts +79 -0
- package/src/web/layout.ts +196 -0
- package/src/web/vaul/constants.ts +9 -0
- package/src/web/vaul/context.ts +7 -1
- package/src/web/vaul/helpers.ts +5 -0
- package/src/web/vaul/index.tsx +113 -16
- package/src/web/vaul/types.ts +10 -0
- package/src/web/vaul/use-snap-points.ts +86 -33
|
@@ -1,28 +1,18 @@
|
|
|
1
1
|
package com.lodev09.truesheet
|
|
2
2
|
|
|
3
3
|
import android.annotation.SuppressLint
|
|
4
|
-
import android.view.MotionEvent
|
|
5
|
-
import android.view.View
|
|
6
|
-
import android.view.ViewParent
|
|
7
4
|
import com.facebook.react.bridge.WritableNativeMap
|
|
8
|
-
import com.facebook.react.uimanager.JSPointerDispatcher
|
|
9
|
-
import com.facebook.react.uimanager.JSTouchDispatcher
|
|
10
5
|
import com.facebook.react.uimanager.PixelUtil.pxToDp
|
|
11
|
-
import com.facebook.react.uimanager.PointerEvents
|
|
12
|
-
import com.facebook.react.uimanager.RootView
|
|
13
6
|
import com.facebook.react.uimanager.StateWrapper
|
|
14
7
|
import com.facebook.react.uimanager.ThemedReactContext
|
|
15
|
-
import com.facebook.react.uimanager.events.EventDispatcher
|
|
16
8
|
import com.facebook.react.views.view.ReactViewGroup
|
|
17
|
-
import com.lodev09.truesheet.core.TrueSheetCoordinatorLayout
|
|
18
|
-
import com.lodev09.truesheet.utils.TouchEventDeduper
|
|
19
9
|
|
|
20
10
|
/**
|
|
21
|
-
* Delegate interface for footer view size changes
|
|
11
|
+
* Delegate interface for footer view size changes
|
|
22
12
|
*/
|
|
23
13
|
interface TrueSheetFooterViewDelegate {
|
|
24
14
|
fun footerViewDidChangeSize(width: Int, height: Int)
|
|
25
|
-
|
|
15
|
+
fun footerViewDidLayout()
|
|
26
16
|
}
|
|
27
17
|
|
|
28
18
|
/**
|
|
@@ -30,40 +20,43 @@ interface TrueSheetFooterViewDelegate {
|
|
|
30
20
|
* This is the second child of TrueSheetContainerView
|
|
31
21
|
* Positioned absolutely at the bottom of the sheet
|
|
32
22
|
*
|
|
33
|
-
*
|
|
23
|
+
* Touches reach it through the controller's RootView like any other sheet
|
|
24
|
+
* content — the container tracks the sheet's visible height, so the footer
|
|
25
|
+
* always lays out inside the container's bounds.
|
|
34
26
|
*/
|
|
35
27
|
@SuppressLint("ViewConstructor")
|
|
36
|
-
class TrueSheetFooterView(
|
|
37
|
-
ReactViewGroup(reactContext),
|
|
38
|
-
RootView {
|
|
28
|
+
class TrueSheetFooterView(reactContext: ThemedReactContext) : ReactViewGroup(reactContext) {
|
|
39
29
|
|
|
40
30
|
var delegate: TrueSheetFooterViewDelegate? = null
|
|
41
31
|
var stateWrapper: StateWrapper? = null
|
|
42
32
|
|
|
43
|
-
private val eventDispatcher: EventDispatcher?
|
|
44
|
-
get() = delegate?.eventDispatcher
|
|
45
|
-
|
|
46
33
|
private var lastWidth = 0
|
|
47
34
|
private var lastHeight = 0
|
|
48
|
-
private var
|
|
35
|
+
private var stateTranslationY = 0f
|
|
36
|
+
|
|
37
|
+
var bottomInset = 0
|
|
38
|
+
private set
|
|
49
39
|
|
|
50
40
|
/**
|
|
51
|
-
*
|
|
52
|
-
*
|
|
41
|
+
* positionFooter slides the footer off its Yoga position (above the
|
|
42
|
+
* keyboard, or riding the sheet). Mirror where it rests into the shadow
|
|
43
|
+
* node so measure() — and Pressability's press region — match where it's
|
|
44
|
+
* drawn. Called once the footer settles: every push is a commit.
|
|
53
45
|
*/
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
46
|
+
fun syncTranslationState() {
|
|
47
|
+
if (translationY == stateTranslationY) return
|
|
48
|
+
val sw = stateWrapper ?: return
|
|
49
|
+
stateTranslationY = translationY
|
|
50
|
+
TrueSheetStateUpdater.updateFooterTranslation(sw, translationY.pxToDp())
|
|
51
|
+
}
|
|
60
52
|
|
|
61
53
|
/**
|
|
62
54
|
* Height the footer occupies above the keyboard — its layout height minus
|
|
63
|
-
* the safe-area inset
|
|
55
|
+
* the safe-area inset, which rides below the keyboard's top edge while the
|
|
56
|
+
* keyboard is open (see positionFooter).
|
|
64
57
|
*/
|
|
65
58
|
val keyboardOcclusionHeight: Int
|
|
66
|
-
get() = maxOf(0, height -
|
|
59
|
+
get() = maxOf(0, height - bottomInset)
|
|
67
60
|
|
|
68
61
|
/**
|
|
69
62
|
* Tells the shadow node to pad the footer's bottom edge with the sheet's
|
|
@@ -73,31 +66,24 @@ class TrueSheetFooterView(private val reactContext: ThemedReactContext) :
|
|
|
73
66
|
fun setBottomInset(inset: Int) {
|
|
74
67
|
if (bottomInset == inset) return
|
|
75
68
|
bottomInset = inset
|
|
76
|
-
pushBottomInsetState()
|
|
77
|
-
}
|
|
78
69
|
|
|
79
|
-
private fun pushBottomInsetState() {
|
|
80
70
|
val sw = stateWrapper ?: return
|
|
81
|
-
val insetDp =
|
|
71
|
+
val insetDp = bottomInset.toFloat().pxToDp()
|
|
72
|
+
// Carried along — this update replaces a still-queued translation update
|
|
73
|
+
stateTranslationY = translationY
|
|
74
|
+
val translateYDp = translationY.pxToDp()
|
|
82
75
|
|
|
83
76
|
// Synchronous update — the footer must be padded before detents are
|
|
84
77
|
// configured, otherwise the auto detent is set up an inset short
|
|
85
|
-
if (TrueSheetStateUpdater.updateFooterState(sw, insetDp)) return
|
|
78
|
+
if (TrueSheetStateUpdater.updateFooterState(sw, insetDp, translateYDp)) return
|
|
86
79
|
|
|
87
80
|
// Fallback: async state update
|
|
88
81
|
val newState = WritableNativeMap()
|
|
89
82
|
newState.putDouble("bottomInset", insetDp.toDouble())
|
|
83
|
+
newState.putDouble("translateY", translateYDp.toDouble())
|
|
90
84
|
sw.updateState(newState)
|
|
91
85
|
}
|
|
92
86
|
|
|
93
|
-
private val jsTouchDispatcher = JSTouchDispatcher(this)
|
|
94
|
-
private var jsPointerDispatcher: JSPointerDispatcher? = null
|
|
95
|
-
private val touchDeduper = TouchEventDeduper()
|
|
96
|
-
|
|
97
|
-
init {
|
|
98
|
-
jsPointerDispatcher = JSPointerDispatcher(this)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
87
|
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
|
|
102
88
|
super.onSizeChanged(w, h, oldw, oldh)
|
|
103
89
|
|
|
@@ -108,72 +94,15 @@ class TrueSheetFooterView(private val reactContext: ThemedReactContext) :
|
|
|
108
94
|
}
|
|
109
95
|
}
|
|
110
96
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
return super.onInterceptTouchEvent(event)
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
override fun requestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {
|
|
124
|
-
// Mirrors ReactSurfaceView: keep receiving onInterceptTouchEvent so
|
|
125
|
-
// jsTouchDispatcher sees the gesture end, but forward the request up the tree.
|
|
126
|
-
parent?.requestDisallowInterceptTouchEvent(disallowIntercept)
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
override fun onTouchEvent(event: MotionEvent): Boolean {
|
|
130
|
-
if (pointerEvents == PointerEvents.NONE || pointerEvents == PointerEvents.BOX_NONE) {
|
|
131
|
-
return false
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
eventDispatcher?.let { dispatcher ->
|
|
135
|
-
if (touchDeduper.shouldDispatch(event)) {
|
|
136
|
-
jsTouchDispatcher.handleTouchEvent(event, dispatcher, reactContext)
|
|
137
|
-
}
|
|
138
|
-
jsPointerDispatcher?.handleMotionEvent(event, dispatcher, false)
|
|
139
|
-
}
|
|
140
|
-
super.onTouchEvent(event)
|
|
141
|
-
return true
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
override fun onInterceptHoverEvent(event: MotionEvent): Boolean {
|
|
145
|
-
eventDispatcher?.let { jsPointerDispatcher?.handleMotionEvent(event, it, true) }
|
|
146
|
-
return super.onHoverEvent(event)
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
override fun onHoverEvent(event: MotionEvent): Boolean {
|
|
150
|
-
eventDispatcher?.let { jsPointerDispatcher?.handleMotionEvent(event, it, false) }
|
|
151
|
-
return super.onHoverEvent(event)
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
override fun onChildStartedNativeGesture(childView: View?, ev: MotionEvent) {
|
|
155
|
-
findCoordinatorLayout()?.childDidClaimNativeGesture()
|
|
156
|
-
eventDispatcher?.let { dispatcher ->
|
|
157
|
-
jsTouchDispatcher.onChildStartedNativeGesture(ev, dispatcher)
|
|
158
|
-
jsPointerDispatcher?.onChildStartedNativeGesture(childView, ev, dispatcher)
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
private fun findCoordinatorLayout(): TrueSheetCoordinatorLayout? {
|
|
163
|
-
var current: ViewParent? = parent
|
|
164
|
-
while (current != null && current !is TrueSheetCoordinatorLayout) {
|
|
165
|
-
current = current.parent
|
|
166
|
-
}
|
|
167
|
-
return current as? TrueSheetCoordinatorLayout
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
override fun onChildEndedNativeGesture(childView: View, ev: MotionEvent) {
|
|
171
|
-
eventDispatcher?.let { jsTouchDispatcher.onChildEndedNativeGesture(ev, it) }
|
|
172
|
-
jsPointerDispatcher?.onChildEndedNativeGesture()
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
override fun handleException(t: Throwable) {
|
|
176
|
-
reactContext.reactApplicationContext.handleException(RuntimeException(t))
|
|
97
|
+
override fun onLayout(
|
|
98
|
+
changed: Boolean,
|
|
99
|
+
left: Int,
|
|
100
|
+
top: Int,
|
|
101
|
+
right: Int,
|
|
102
|
+
bottom: Int
|
|
103
|
+
) {
|
|
104
|
+
super.onLayout(changed, left, top, right, bottom)
|
|
105
|
+
delegate?.footerViewDidLayout()
|
|
177
106
|
}
|
|
178
107
|
|
|
179
108
|
companion object {
|
|
@@ -125,6 +125,9 @@ class TrueSheetModule(reactContext: ReactApplicationContext) :
|
|
|
125
125
|
fun dismissAll(animated: Boolean, promise: Promise) {
|
|
126
126
|
Handler(Looper.getMainLooper()).post {
|
|
127
127
|
try {
|
|
128
|
+
// Drop presents still waiting on the keyboard
|
|
129
|
+
viewRegistry.values.forEach { it.cancelPendingPresent() }
|
|
130
|
+
|
|
128
131
|
val rootSheet = TrueSheetStackManager.getRootSheet()
|
|
129
132
|
if (rootSheet == null) {
|
|
130
133
|
promise.resolve(null)
|
|
@@ -221,5 +224,15 @@ class TrueSheetModule(reactContext: ReactApplicationContext) :
|
|
|
221
224
|
*/
|
|
222
225
|
@JvmStatic
|
|
223
226
|
fun getSheetByTag(tag: Int): TrueSheetView? = viewRegistry[tag]
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Drop presents still waiting on the keyboard that would stack on [parent]
|
|
230
|
+
*/
|
|
231
|
+
@JvmStatic
|
|
232
|
+
fun cancelPendingPresents(parent: TrueSheetView, restoreFocus: Boolean = true) {
|
|
233
|
+
viewRegistry.values.forEach {
|
|
234
|
+
if (it.pendingPresentParent === parent) it.cancelPendingPresent(restoreFocus)
|
|
235
|
+
}
|
|
236
|
+
}
|
|
224
237
|
}
|
|
225
238
|
}
|
|
@@ -0,0 +1,127 @@
|
|
|
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.ViewTreeObserver
|
|
7
|
+
import android.view.accessibility.AccessibilityEvent
|
|
8
|
+
import com.facebook.react.uimanager.StateWrapper
|
|
9
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
10
|
+
import com.facebook.react.uimanager.events.EventDispatcher
|
|
11
|
+
import com.facebook.react.views.view.ReactViewGroup
|
|
12
|
+
import com.lodev09.truesheet.core.TrueSheetOverlayRootView
|
|
13
|
+
import com.lodev09.truesheet.core.TrueSheetOverlayRootViewDelegate
|
|
14
|
+
import com.lodev09.truesheet.utils.findRootContainerView
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Hidden host that renders its children in a root view attached to the
|
|
18
|
+
* activity's content view, above every presented sheet.
|
|
19
|
+
*/
|
|
20
|
+
@SuppressLint("ViewConstructor")
|
|
21
|
+
class TrueSheetOverlayView(private val reactContext: ThemedReactContext) :
|
|
22
|
+
ReactViewGroup(reactContext),
|
|
23
|
+
TrueSheetOverlayRootViewDelegate {
|
|
24
|
+
|
|
25
|
+
private val rootView = TrueSheetOverlayRootView(reactContext).apply {
|
|
26
|
+
delegate = this@TrueSheetOverlayView
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
private var rootContainerView: ViewGroup? = null
|
|
30
|
+
|
|
31
|
+
override var eventDispatcher: EventDispatcher? = null
|
|
32
|
+
|
|
33
|
+
private var lastWidth = 0
|
|
34
|
+
private var lastHeight = 0
|
|
35
|
+
|
|
36
|
+
// Fabric hands back a new StateWrapper on every state commit — including our
|
|
37
|
+
// own pushes — so pushState dedupes against the last pushed size to break the loop
|
|
38
|
+
private var lastStateWidth = 0
|
|
39
|
+
private var lastStateHeight = 0
|
|
40
|
+
|
|
41
|
+
var stateWrapper: StateWrapper? = null
|
|
42
|
+
set(value) {
|
|
43
|
+
field = value
|
|
44
|
+
pushState()
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
init {
|
|
48
|
+
// The host stays in the React tree for layout only — children render in the root view
|
|
49
|
+
visibility = GONE
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// ==================== View Hierarchy Management ====================
|
|
53
|
+
|
|
54
|
+
// When the whole window goes away (e.g. activity destroyed), the container is mid-way through
|
|
55
|
+
// detaching its children by then, so removing the root view in onDetachedFromWindow crashes.
|
|
56
|
+
// This fires before that pass begins.
|
|
57
|
+
private val windowAttachListener = object : ViewTreeObserver.OnWindowAttachListener {
|
|
58
|
+
override fun onWindowAttached() {}
|
|
59
|
+
override fun onWindowDetached() = detachRootView()
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
override fun onAttachedToWindow() {
|
|
63
|
+
super.onAttachedToWindow()
|
|
64
|
+
viewTreeObserver.addOnWindowAttachListener(windowAttachListener)
|
|
65
|
+
attachRootView()
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
override fun onDetachedFromWindow() {
|
|
69
|
+
viewTreeObserver.removeOnWindowAttachListener(windowAttachListener)
|
|
70
|
+
rootContainerView?.post { if (!isAttachedToWindow) detachRootView() }
|
|
71
|
+
super.onDetachedFromWindow()
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
private fun attachRootView() {
|
|
75
|
+
if (rootView.parent != null) return
|
|
76
|
+
|
|
77
|
+
val container = findRootContainerView(reactContext) ?: return
|
|
78
|
+
container.addView(rootView)
|
|
79
|
+
rootContainerView = container
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
private fun detachRootView() {
|
|
83
|
+
rootContainerView?.removeView(rootView)
|
|
84
|
+
rootContainerView = null
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
fun onDropInstance() {
|
|
88
|
+
detachRootView()
|
|
89
|
+
rootView.delegate = null
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
override fun addView(child: View?, index: Int) {
|
|
93
|
+
rootView.addView(child, index)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
override fun getChildCount(): Int = rootView.childCount
|
|
97
|
+
|
|
98
|
+
override fun getChildAt(index: Int): View? = rootView.getChildAt(index)
|
|
99
|
+
|
|
100
|
+
override fun removeViewAt(index: Int) {
|
|
101
|
+
rootView.removeViewAt(index)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Accessibility: children live in the root view since this view is hidden
|
|
105
|
+
override fun addChildrenForAccessibility(outChildren: ArrayList<View>) {}
|
|
106
|
+
override fun dispatchPopulateAccessibilityEvent(event: AccessibilityEvent): Boolean = false
|
|
107
|
+
|
|
108
|
+
// ==================== State ====================
|
|
109
|
+
|
|
110
|
+
override fun overlayRootViewDidChangeSize(width: Int, height: Int) {
|
|
111
|
+
if (width == lastWidth && height == lastHeight) return
|
|
112
|
+
|
|
113
|
+
lastWidth = width
|
|
114
|
+
lastHeight = height
|
|
115
|
+
pushState()
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
private fun pushState() {
|
|
119
|
+
if (lastWidth == 0 && lastHeight == 0) return
|
|
120
|
+
if (lastWidth == lastStateWidth && lastHeight == lastStateHeight) return
|
|
121
|
+
val sw = stateWrapper ?: return
|
|
122
|
+
|
|
123
|
+
lastStateWidth = lastWidth
|
|
124
|
+
lastStateHeight = lastHeight
|
|
125
|
+
TrueSheetStateUpdater.updateContainerSize(sw, lastWidth, lastHeight)
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -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,9 +24,30 @@ 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
|
-
fun updateFooterState(stateWrapper: StateWrapper, bottomInsetDp: Float): Boolean =
|
|
27
|
-
isAvailable && nativeUpdateFooterState(stateWrapper, bottomInsetDp)
|
|
44
|
+
fun updateFooterState(stateWrapper: StateWrapper, bottomInsetDp: Float, translateYDp: Float): Boolean =
|
|
45
|
+
isAvailable && nativeUpdateFooterState(stateWrapper, bottomInsetDp, translateYDp)
|
|
46
|
+
|
|
47
|
+
/** Mirrors the footer's native translation so measure() matches where it's drawn. */
|
|
48
|
+
fun updateFooterTranslation(stateWrapper: StateWrapper, translateYDp: Float) {
|
|
49
|
+
if (isAvailable) nativeUpdateFooterTranslation(stateWrapper, translateYDp)
|
|
50
|
+
}
|
|
28
51
|
|
|
29
52
|
/**
|
|
30
53
|
* Publishes the precalculated bottom safe-area inset so a late-mounted
|
|
@@ -38,7 +61,10 @@ object TrueSheetStateUpdater {
|
|
|
38
61
|
private external fun nativeUpdateState(stateWrapper: Any, width: Float, height: Float): Boolean
|
|
39
62
|
|
|
40
63
|
@JvmStatic
|
|
41
|
-
private external fun nativeUpdateFooterState(stateWrapper: Any, bottomInset: Float): Boolean
|
|
64
|
+
private external fun nativeUpdateFooterState(stateWrapper: Any, bottomInset: Float, translateY: Float): Boolean
|
|
65
|
+
|
|
66
|
+
@JvmStatic
|
|
67
|
+
private external fun nativeUpdateFooterTranslation(stateWrapper: Any, translateY: Float)
|
|
42
68
|
|
|
43
69
|
@JvmStatic
|
|
44
70
|
private external fun nativeSetBottomSafeArea(insetDp: Float)
|