@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
|
@@ -5,6 +5,7 @@ import com.facebook.react.bridge.ReadableArray
|
|
|
5
5
|
import com.facebook.react.bridge.ReadableMap
|
|
6
6
|
import com.facebook.react.module.annotations.ReactModule
|
|
7
7
|
import com.facebook.react.uimanager.PixelUtil.dpToPx
|
|
8
|
+
import com.facebook.react.uimanager.PointerEvents
|
|
8
9
|
import com.facebook.react.uimanager.ReactStylesDiffMap
|
|
9
10
|
import com.facebook.react.uimanager.StateWrapper
|
|
10
11
|
import com.facebook.react.uimanager.ThemedReactContext
|
|
@@ -17,6 +18,7 @@ import com.facebook.react.viewmanagers.TrueSheetViewManagerInterface
|
|
|
17
18
|
import com.lodev09.truesheet.core.AccessibilityOptions
|
|
18
19
|
import com.lodev09.truesheet.core.GrabberOptions
|
|
19
20
|
import com.lodev09.truesheet.events.*
|
|
21
|
+
import com.lodev09.truesheet.utils.getColorOrNull
|
|
20
22
|
|
|
21
23
|
/**
|
|
22
24
|
* ViewManager for TrueSheetView - Fabric architecture
|
|
@@ -55,6 +57,20 @@ class TrueSheetViewManager :
|
|
|
55
57
|
|
|
56
58
|
override fun getDelegate(): ViewManagerDelegate<TrueSheetView> = delegate
|
|
57
59
|
|
|
60
|
+
// The codegen delegate drops props outside the spec (pointerEvents comes from the
|
|
61
|
+
// host's style), so apply it here after the delegate pass.
|
|
62
|
+
override fun updateProperties(viewToUpdate: TrueSheetView, props: ReactStylesDiffMap) {
|
|
63
|
+
super.updateProperties(viewToUpdate, props)
|
|
64
|
+
if (props.hasKey("pointerEvents")) {
|
|
65
|
+
setPointerEvents(viewToUpdate, props.getString("pointerEvents"))
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@ReactProp(name = "pointerEvents")
|
|
70
|
+
fun setPointerEvents(view: TrueSheetView, pointerEventsStr: String?) {
|
|
71
|
+
view.pointerEvents = PointerEvents.parsePointerEvents(pointerEventsStr)
|
|
72
|
+
}
|
|
73
|
+
|
|
58
74
|
/**
|
|
59
75
|
* Export custom direct event types for Fabric
|
|
60
76
|
* Uses Kotlin native collections with decoupled event classes
|
|
@@ -66,6 +82,7 @@ class TrueSheetViewManager :
|
|
|
66
82
|
DidPresentEvent.EVENT_NAME to hashMapOf("registrationName" to DidPresentEvent.REGISTRATION_NAME),
|
|
67
83
|
WillDismissEvent.EVENT_NAME to hashMapOf("registrationName" to WillDismissEvent.REGISTRATION_NAME),
|
|
68
84
|
DidDismissEvent.EVENT_NAME to hashMapOf("registrationName" to DidDismissEvent.REGISTRATION_NAME),
|
|
85
|
+
DismissAttemptEvent.EVENT_NAME to hashMapOf("registrationName" to DismissAttemptEvent.REGISTRATION_NAME),
|
|
69
86
|
DetentChangeEvent.EVENT_NAME to hashMapOf("registrationName" to DetentChangeEvent.REGISTRATION_NAME),
|
|
70
87
|
DragBeginEvent.EVENT_NAME to hashMapOf("registrationName" to DragBeginEvent.REGISTRATION_NAME),
|
|
71
88
|
DragChangeEvent.EVENT_NAME to hashMapOf("registrationName" to DragChangeEvent.REGISTRATION_NAME),
|
|
@@ -98,6 +115,15 @@ class TrueSheetViewManager :
|
|
|
98
115
|
view.setDetents(detents)
|
|
99
116
|
}
|
|
100
117
|
|
|
118
|
+
@ReactProp(name = "detentBackgrounds")
|
|
119
|
+
override fun setDetentBackgrounds(view: TrueSheetView, value: ReadableArray?) {
|
|
120
|
+
view.setDetentBackgrounds(
|
|
121
|
+
(0 until (value?.size() ?: 0)).map { index ->
|
|
122
|
+
value?.getMap(index)?.getColorOrNull("color", view.context)
|
|
123
|
+
}
|
|
124
|
+
)
|
|
125
|
+
}
|
|
126
|
+
|
|
101
127
|
@ReactProp(name = "backgroundColor", customType = "Color")
|
|
102
128
|
override fun setBackgroundColor(view: TrueSheetView, color: Int?) {
|
|
103
129
|
view.setSheetBackgroundColor(color)
|
|
@@ -131,7 +157,7 @@ class TrueSheetViewManager :
|
|
|
131
157
|
} else {
|
|
132
158
|
null
|
|
133
159
|
},
|
|
134
|
-
color =
|
|
160
|
+
color = options.getColorOrNull("color", view.context),
|
|
135
161
|
adaptive = if (options.hasKey("adaptive")) options.getBoolean("adaptive") else true
|
|
136
162
|
)
|
|
137
163
|
view.setGrabberOptions(grabberOptions)
|
|
@@ -166,11 +192,26 @@ class TrueSheetViewManager :
|
|
|
166
192
|
view.setDraggable(draggable)
|
|
167
193
|
}
|
|
168
194
|
|
|
195
|
+
@ReactProp(name = "dismissThreshold")
|
|
196
|
+
override fun setDismissThreshold(view: TrueSheetView, value: String?) {
|
|
197
|
+
view.setDismissThreshold(value)
|
|
198
|
+
}
|
|
199
|
+
|
|
169
200
|
@ReactProp(name = "dimmed", defaultBoolean = true)
|
|
170
201
|
override fun setDimmed(view: TrueSheetView, dimmed: Boolean) {
|
|
171
202
|
view.setDimmed(dimmed)
|
|
172
203
|
}
|
|
173
204
|
|
|
205
|
+
@ReactProp(name = "dimColor", customType = "Color")
|
|
206
|
+
override fun setDimColor(view: TrueSheetView, color: Int?) {
|
|
207
|
+
view.setDimColor(color)
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
@ReactProp(name = "dimOpacity", defaultDouble = -1.0)
|
|
211
|
+
override fun setDimOpacity(view: TrueSheetView, opacity: Double) {
|
|
212
|
+
view.setDimOpacity(opacity.toFloat())
|
|
213
|
+
}
|
|
214
|
+
|
|
174
215
|
@ReactProp(name = "dimmedDetentIndex", defaultInt = 0)
|
|
175
216
|
override fun setDimmedDetentIndex(view: TrueSheetView, index: Int) {
|
|
176
217
|
view.setDimmedDetentIndex(index)
|
|
@@ -197,14 +238,14 @@ class TrueSheetViewManager :
|
|
|
197
238
|
view.setMaxContentWidth(if (width > 0) width.dpToPx().toInt() else null)
|
|
198
239
|
}
|
|
199
240
|
|
|
200
|
-
@ReactProp(name = "
|
|
201
|
-
override fun
|
|
202
|
-
view.
|
|
241
|
+
@ReactProp(name = "placement")
|
|
242
|
+
override fun setPlacement(view: TrueSheetView, placement: String?) {
|
|
243
|
+
view.setPlacement(placement)
|
|
203
244
|
}
|
|
204
245
|
|
|
205
|
-
@ReactProp(name = "
|
|
206
|
-
override fun
|
|
207
|
-
view.
|
|
246
|
+
@ReactProp(name = "placementOffset", defaultDouble = 0.0)
|
|
247
|
+
override fun setPlacementOffset(view: TrueSheetView, offset: Double) {
|
|
248
|
+
view.setPlacementOffset(if (offset > 0) offset.dpToPx().toInt() else 0)
|
|
208
249
|
}
|
|
209
250
|
|
|
210
251
|
@ReactProp(name = "backgroundBlur")
|
|
@@ -212,8 +253,8 @@ class TrueSheetViewManager :
|
|
|
212
253
|
// iOS-specific prop - no-op on Android
|
|
213
254
|
}
|
|
214
255
|
|
|
215
|
-
@ReactProp(name = "
|
|
216
|
-
override fun
|
|
256
|
+
@ReactProp(name = "foldOptions")
|
|
257
|
+
override fun setFoldOptions(view: TrueSheetView, options: ReadableMap?) {
|
|
217
258
|
// iOS-specific prop - no-op on Android
|
|
218
259
|
}
|
|
219
260
|
|
|
@@ -232,6 +273,11 @@ class TrueSheetViewManager :
|
|
|
232
273
|
view.setSheetElevation(elevation.toFloat())
|
|
233
274
|
}
|
|
234
275
|
|
|
276
|
+
@ReactProp(name = "scrollableHandle", defaultInt = -1)
|
|
277
|
+
override fun setScrollableHandle(view: TrueSheetView, handle: Int) {
|
|
278
|
+
view.setScrollableHandle(handle)
|
|
279
|
+
}
|
|
280
|
+
|
|
235
281
|
@ReactProp(name = "scrollableOptions")
|
|
236
282
|
override fun setScrollableOptions(view: TrueSheetView, options: ReadableMap?) {
|
|
237
283
|
if (options == null) {
|
|
@@ -241,7 +287,11 @@ class TrueSheetViewManager :
|
|
|
241
287
|
|
|
242
288
|
val scrollableOptions = ScrollableOptions(
|
|
243
289
|
keyboardScrollOffset = if (options.hasKey("keyboardScrollOffset")) options.getDouble("keyboardScrollOffset").toFloat() else 0f,
|
|
244
|
-
|
|
290
|
+
keyboardOffset = if (options.hasKey("keyboardOffset")) options.getDouble("keyboardOffset").toFloat() else 0f,
|
|
291
|
+
scrollingExpandsSheet = if (options.hasKey("scrollingExpandsSheet")) options.getBoolean("scrollingExpandsSheet") else true,
|
|
292
|
+
contentInsetAdjustment = TrueSheetContentInsetAdjustment.fromString(
|
|
293
|
+
if (options.hasKey("contentInsetAdjustment")) options.getString("contentInsetAdjustment") else null
|
|
294
|
+
)
|
|
245
295
|
)
|
|
246
296
|
view.setScrollableOptions(scrollableOptions)
|
|
247
297
|
}
|
|
@@ -260,6 +310,10 @@ class TrueSheetViewManager :
|
|
|
260
310
|
val keyboardOffset =
|
|
261
311
|
if (options != null && options.hasKey("keyboardOffset")) options.getDouble("keyboardOffset").toFloat() else 0f
|
|
262
312
|
view.setFooterKeyboardOffset(keyboardOffset)
|
|
313
|
+
|
|
314
|
+
val avoidKeyboard =
|
|
315
|
+
if (options != null && options.hasKey("avoidKeyboard")) options.getBoolean("avoidKeyboard") else true
|
|
316
|
+
view.setFooterAvoidsKeyboard(avoidKeyboard)
|
|
263
317
|
}
|
|
264
318
|
|
|
265
319
|
companion object {
|
|
@@ -22,6 +22,15 @@ class RNScreensEventObserver : EventDispatcherListener {
|
|
|
22
22
|
private var eventDispatcher: EventDispatcher? = null
|
|
23
23
|
var presenterScreenTag: Int = 0
|
|
24
24
|
|
|
25
|
+
// Screens enclosing the presenter. react-native-screens only dispatches lifecycle
|
|
26
|
+
// events for stack screens, so a presenter inside a plain screen container (e.g. a
|
|
27
|
+
// bottom tab) never receives them and an enclosing stack screen has to stand in.
|
|
28
|
+
var ancestorScreenTags: Set<Int> = emptySet()
|
|
29
|
+
|
|
30
|
+
// Only the screen that hid the sheet brings it back. An enclosing screen reappearing
|
|
31
|
+
// must not reveal a sheet whose own screen is still covered inside it.
|
|
32
|
+
private var disappearedScreenTag: Int = 0
|
|
33
|
+
|
|
25
34
|
fun startObserving(dispatcher: EventDispatcher?) {
|
|
26
35
|
if (eventDispatcher != null || dispatcher == null) return
|
|
27
36
|
|
|
@@ -35,29 +44,37 @@ class RNScreensEventObserver : EventDispatcherListener {
|
|
|
35
44
|
}
|
|
36
45
|
|
|
37
46
|
fun capturePresenterScreenFromView(view: View?) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
while (current != null) {
|
|
42
|
-
if (isScreenView(current)) {
|
|
43
|
-
presenterScreenTag = current.id
|
|
44
|
-
break
|
|
45
|
-
}
|
|
46
|
-
current = (current.parent as? View)
|
|
47
|
-
}
|
|
47
|
+
val tags = screenTags(view).toList()
|
|
48
|
+
presenterScreenTag = tags.firstOrNull() ?: 0
|
|
49
|
+
ancestorScreenTags = tags.drop(1).toSet()
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
override fun onEventDispatch(event: Event<*>) {
|
|
51
|
-
// Only process events for the presenter screen
|
|
52
|
-
if (presenterScreenTag == 0
|
|
53
|
+
// Only process events for the presenter screen and the screens enclosing it
|
|
54
|
+
if (presenterScreenTag == 0) return
|
|
55
|
+
if (event.viewTag != presenterScreenTag && event.viewTag !in ancestorScreenTags) return
|
|
53
56
|
|
|
54
57
|
when (event.eventName) {
|
|
55
|
-
"topWillDisappear" ->
|
|
56
|
-
|
|
58
|
+
"topWillDisappear" -> {
|
|
59
|
+
if (disappearedScreenTag != 0) return
|
|
60
|
+
disappearedScreenTag = event.viewTag
|
|
61
|
+
delegate?.presenterScreenWillDisappear()
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
"topWillAppear" -> {
|
|
65
|
+
if (event.viewTag != disappearedScreenTag) return
|
|
66
|
+
disappearedScreenTag = 0
|
|
67
|
+
delegate?.presenterScreenWillAppear()
|
|
68
|
+
}
|
|
57
69
|
}
|
|
58
70
|
}
|
|
59
71
|
|
|
60
72
|
companion object {
|
|
61
73
|
private fun isScreenView(view: View): Boolean = view.javaClass.name == RN_SCREENS_VIEW_CLASS
|
|
74
|
+
|
|
75
|
+
// Tags of the screens enclosing the view, innermost first
|
|
76
|
+
private fun screenTags(view: View?): Sequence<Int> = generateSequence(view) { it.parent as? View }.filter(::isScreenView).map { it.id }
|
|
77
|
+
|
|
78
|
+
fun findPresenterScreenTag(view: View?): Int = screenTags(view).firstOrNull() ?: 0
|
|
62
79
|
}
|
|
63
80
|
}
|
|
@@ -1,11 +1,82 @@
|
|
|
1
1
|
package com.lodev09.truesheet.core
|
|
2
2
|
|
|
3
|
+
import android.view.MotionEvent
|
|
4
|
+
import android.view.VelocityTracker
|
|
3
5
|
import android.view.View
|
|
4
6
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
|
7
|
+
import androidx.core.view.ViewCompat
|
|
8
|
+
import com.facebook.react.uimanager.PixelUtil.dpToPx
|
|
5
9
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
|
10
|
+
import kotlin.math.abs
|
|
11
|
+
|
|
12
|
+
enum class TrueSheetDismissThreshold {
|
|
13
|
+
HALF,
|
|
14
|
+
SHORT;
|
|
15
|
+
|
|
16
|
+
companion object {
|
|
17
|
+
fun fromString(value: String?): TrueSheetDismissThreshold =
|
|
18
|
+
when (value) {
|
|
19
|
+
"short" -> SHORT
|
|
20
|
+
else -> HALF
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
6
24
|
|
|
7
25
|
class TrueSheetBottomSheetBehavior<V : View> : BottomSheetBehavior<V>() {
|
|
8
26
|
var scrollingExpandsSheet: Boolean = true
|
|
27
|
+
var dismissThreshold: TrueSheetDismissThreshold = TrueSheetDismissThreshold.HALF
|
|
28
|
+
var lowestSheetTop: (() -> Int)? = null
|
|
29
|
+
|
|
30
|
+
private var nestedDragged = false
|
|
31
|
+
private var nestedReleaseVelocity = 0f
|
|
32
|
+
private var touchPointerId = MotionEvent.INVALID_POINTER_ID
|
|
33
|
+
private var trackedEventTime = -1L
|
|
34
|
+
private var trackedAction = -1
|
|
35
|
+
private var velocityTracker: VelocityTracker? = null
|
|
36
|
+
|
|
37
|
+
init {
|
|
38
|
+
// Material hides once the release point, projected by velocity * friction, passes half
|
|
39
|
+
// the lowest detent. A higher friction lets short flicks dismiss, closer to iOS sheets.
|
|
40
|
+
hideFriction = HIDE_FRICTION
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Material's first layout registers an IME callback that rides the sheet's translationY
|
|
44
|
+
// with the keyboard. TrueSheet positions sheets for the keyboard itself, and the callback
|
|
45
|
+
// overwrites a parent's stack translation when the keyboard rises mid-translation.
|
|
46
|
+
override fun onLayoutChild(parent: CoordinatorLayout, child: V, layoutDirection: Int): Boolean {
|
|
47
|
+
val handled = super.onLayoutChild(parent, child, layoutDirection)
|
|
48
|
+
ViewCompat.setWindowInsetsAnimationCallback(child, null)
|
|
49
|
+
return handled
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// With the short threshold, settle at or below the lowest detent like
|
|
53
|
+
// Compose Material3's sheet instead of Material's half-height rule.
|
|
54
|
+
private fun releaseState(child: V, dragged: Boolean, velocityY: Float): Int? {
|
|
55
|
+
if (dismissThreshold != TrueSheetDismissThreshold.SHORT || !isDraggable || !dragged) return null
|
|
56
|
+
val lowestTop = lowestSheetTop?.invoke() ?: return null
|
|
57
|
+
if (child.top < lowestTop) return null
|
|
58
|
+
val hides = if (abs(velocityY) > DISMISS_VELOCITY_DP.dpToPx()) {
|
|
59
|
+
velocityY > 0
|
|
60
|
+
} else {
|
|
61
|
+
child.top - lowestTop > DISMISS_DISTANCE_DP.dpToPx()
|
|
62
|
+
}
|
|
63
|
+
return if (hides && isHideable) STATE_HIDDEN else STATE_COLLAPSED
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
override fun onStartNestedScroll(
|
|
67
|
+
coordinatorLayout: CoordinatorLayout,
|
|
68
|
+
child: V,
|
|
69
|
+
directTargetChild: View,
|
|
70
|
+
target: View,
|
|
71
|
+
axes: Int,
|
|
72
|
+
type: Int
|
|
73
|
+
): Boolean {
|
|
74
|
+
if (type == ViewCompat.TYPE_TOUCH) {
|
|
75
|
+
nestedDragged = false
|
|
76
|
+
nestedReleaseVelocity = 0f
|
|
77
|
+
}
|
|
78
|
+
return super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, axes, type)
|
|
79
|
+
}
|
|
9
80
|
|
|
10
81
|
override fun onNestedPreScroll(
|
|
11
82
|
coordinatorLayout: CoordinatorLayout,
|
|
@@ -20,6 +91,13 @@ class TrueSheetBottomSheetBehavior<V : View> : BottomSheetBehavior<V>() {
|
|
|
20
91
|
// Block expansion from scroll, but allow if sheet is already being dragged
|
|
21
92
|
if (!scrollingExpandsSheet && dy > 0 && state != STATE_DRAGGING) return
|
|
22
93
|
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type)
|
|
94
|
+
if (type == ViewCompat.TYPE_TOUCH) {
|
|
95
|
+
if (state == STATE_EXPANDED) {
|
|
96
|
+
nestedDragged = false
|
|
97
|
+
} else if (consumed[1] != 0) {
|
|
98
|
+
nestedDragged = true
|
|
99
|
+
}
|
|
100
|
+
}
|
|
23
101
|
}
|
|
24
102
|
|
|
25
103
|
override fun onNestedPreFling(
|
|
@@ -29,8 +107,65 @@ class TrueSheetBottomSheetBehavior<V : View> : BottomSheetBehavior<V>() {
|
|
|
29
107
|
velocityX: Float,
|
|
30
108
|
velocityY: Float
|
|
31
109
|
): Boolean {
|
|
110
|
+
nestedReleaseVelocity = -velocityY
|
|
111
|
+
if (releaseState(child, nestedDragged, nestedReleaseVelocity) != null) return true
|
|
32
112
|
// Don't consume flings — let the ScrollView decelerate naturally
|
|
33
113
|
if (!scrollingExpandsSheet) return false
|
|
34
114
|
return super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY)
|
|
35
115
|
}
|
|
116
|
+
|
|
117
|
+
override fun onStopNestedScroll(coordinatorLayout: CoordinatorLayout, child: V, target: View, type: Int) {
|
|
118
|
+
if (type == ViewCompat.TYPE_TOUCH) {
|
|
119
|
+
releaseState(child, nestedDragged, nestedReleaseVelocity)?.let {
|
|
120
|
+
nestedDragged = false
|
|
121
|
+
state = it
|
|
122
|
+
return
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
super.onStopNestedScroll(coordinatorLayout, child, target, type)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
private fun trackTouch(event: MotionEvent) {
|
|
129
|
+
if (dismissThreshold != TrueSheetDismissThreshold.SHORT) return
|
|
130
|
+
if (event.eventTime == trackedEventTime && event.actionMasked == trackedAction) return
|
|
131
|
+
trackedEventTime = event.eventTime
|
|
132
|
+
trackedAction = event.actionMasked
|
|
133
|
+
if (event.actionMasked == MotionEvent.ACTION_DOWN) {
|
|
134
|
+
velocityTracker?.recycle()
|
|
135
|
+
velocityTracker = VelocityTracker.obtain()
|
|
136
|
+
touchPointerId = event.getPointerId(0)
|
|
137
|
+
}
|
|
138
|
+
velocityTracker?.addMovement(event)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
override fun onInterceptTouchEvent(parent: CoordinatorLayout, child: V, event: MotionEvent): Boolean {
|
|
142
|
+
trackTouch(event)
|
|
143
|
+
return super.onInterceptTouchEvent(parent, child, event)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
override fun onTouchEvent(parent: CoordinatorLayout, child: V, event: MotionEvent): Boolean {
|
|
147
|
+
trackTouch(event)
|
|
148
|
+
val wasDragging = state == STATE_DRAGGING
|
|
149
|
+
val handled = super.onTouchEvent(parent, child, event)
|
|
150
|
+
if (event.actionMasked == MotionEvent.ACTION_UP) {
|
|
151
|
+
val velocityY = velocityTracker?.run {
|
|
152
|
+
computeCurrentVelocity(1000)
|
|
153
|
+
getYVelocity(touchPointerId)
|
|
154
|
+
} ?: 0f
|
|
155
|
+
releaseState(child, wasDragging, velocityY)?.let { state = it }
|
|
156
|
+
}
|
|
157
|
+
if (event.actionMasked == MotionEvent.ACTION_UP || event.actionMasked == MotionEvent.ACTION_CANCEL) {
|
|
158
|
+
velocityTracker?.recycle()
|
|
159
|
+
velocityTracker = null
|
|
160
|
+
}
|
|
161
|
+
return handled
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
companion object {
|
|
165
|
+
private const val HIDE_FRICTION = 0.3f
|
|
166
|
+
|
|
167
|
+
// Compose Material3 SheetState's velocity and positional thresholds
|
|
168
|
+
private const val DISMISS_VELOCITY_DP = 125f
|
|
169
|
+
private const val DISMISS_DISTANCE_DP = 56f
|
|
170
|
+
}
|
|
36
171
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
package com.lodev09.truesheet.core
|
|
2
2
|
|
|
3
3
|
import android.annotation.SuppressLint
|
|
4
|
-
import android.content.res.Configuration
|
|
5
4
|
import android.graphics.Color
|
|
6
5
|
import android.graphics.Outline
|
|
7
6
|
import android.graphics.Rect
|
|
@@ -18,8 +17,9 @@ import androidx.core.view.ViewCompat
|
|
|
18
17
|
import com.facebook.react.uimanager.PixelUtil.dpToPx
|
|
19
18
|
import com.facebook.react.uimanager.ThemedReactContext
|
|
20
19
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
|
21
|
-
import com.lodev09.truesheet.
|
|
20
|
+
import com.lodev09.truesheet.TrueSheetPlacement
|
|
22
21
|
import com.lodev09.truesheet.utils.ScreenUtils
|
|
22
|
+
import com.lodev09.truesheet.utils.isDarkMode
|
|
23
23
|
|
|
24
24
|
interface TrueSheetBottomSheetViewDelegate {
|
|
25
25
|
val isTopmostSheet: Boolean
|
|
@@ -27,8 +27,8 @@ interface TrueSheetBottomSheetViewDelegate {
|
|
|
27
27
|
val sheetElevation: Float
|
|
28
28
|
val sheetBackgroundColor: Int?
|
|
29
29
|
val maxContentWidth: Int?
|
|
30
|
-
val
|
|
31
|
-
val
|
|
30
|
+
val placement: TrueSheetPlacement
|
|
31
|
+
val placementOffset: Int
|
|
32
32
|
val grabber: Boolean
|
|
33
33
|
val grabberOptions: GrabberOptions?
|
|
34
34
|
val accessibilityOptions: AccessibilityOptions?
|
|
@@ -81,26 +81,24 @@ class TrueSheetBottomSheetView(private val reactContext: ThemedReactContext) : F
|
|
|
81
81
|
clipToPadding = false
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
override fun setTranslationY(translationY: Float) {
|
|
85
|
-
// This prevents keyboard inset animations from resetting parent sheet translation
|
|
86
|
-
if (translationY == 0f && this.translationY != 0f) {
|
|
87
|
-
return
|
|
88
|
-
}
|
|
89
|
-
super.setTranslationY(translationY)
|
|
90
|
-
}
|
|
91
|
-
|
|
92
84
|
// =============================================================================
|
|
93
85
|
// MARK: - Layout
|
|
94
86
|
// =============================================================================
|
|
95
87
|
|
|
96
88
|
private fun resolveAnchor(): Pair<Int, Int> {
|
|
97
|
-
val
|
|
98
|
-
val gravity = when (
|
|
99
|
-
|
|
100
|
-
|
|
89
|
+
val placement = if (ScreenUtils.isPortraitPhone(reactContext)) null else delegate?.placement
|
|
90
|
+
val gravity = when (placement) {
|
|
91
|
+
TrueSheetPlacement.LEADING -> Gravity.START
|
|
92
|
+
TrueSheetPlacement.TRAILING -> Gravity.END
|
|
101
93
|
else -> Gravity.CENTER_HORIZONTAL
|
|
102
94
|
} or Gravity.BOTTOM
|
|
103
|
-
val margin = if (
|
|
95
|
+
val margin = if (placement == TrueSheetPlacement.LEADING ||
|
|
96
|
+
placement == TrueSheetPlacement.TRAILING
|
|
97
|
+
) {
|
|
98
|
+
delegate?.placementOffset ?: 0
|
|
99
|
+
} else {
|
|
100
|
+
0
|
|
101
|
+
}
|
|
104
102
|
return Pair(gravity, margin)
|
|
105
103
|
}
|
|
106
104
|
|
|
@@ -173,14 +171,16 @@ class TrueSheetBottomSheetView(private val reactContext: ThemedReactContext) : F
|
|
|
173
171
|
clipToOutline = true
|
|
174
172
|
}
|
|
175
173
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
return if (isNight) COLOR_SURFACE_CONTAINER_LOW_DARK else COLOR_SURFACE_CONTAINER_LOW_LIGHT
|
|
174
|
+
fun updateBackgroundColor(color: Int) {
|
|
175
|
+
(background as? ShapeDrawable)?.let {
|
|
176
|
+
it.paint.color = color
|
|
177
|
+
it.invalidateSelf()
|
|
178
|
+
}
|
|
182
179
|
}
|
|
183
180
|
|
|
181
|
+
fun getDefaultBackgroundColor(): Int =
|
|
182
|
+
if (reactContext.isDarkMode) COLOR_SURFACE_CONTAINER_LOW_DARK else COLOR_SURFACE_CONTAINER_LOW_LIGHT
|
|
183
|
+
|
|
184
184
|
fun setupElevation() {
|
|
185
185
|
val value = delegate?.sheetElevation ?: DEFAULT_ELEVATION
|
|
186
186
|
val effectiveElevation = if (value < 0) DEFAULT_ELEVATION else value
|