@lodev09/react-native-true-sheet 1.1.1 → 2.0.1
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/android/build.gradle +11 -18
- package/android/gradle.properties +5 -5
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetDialog.kt +26 -7
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetEvent.kt +22 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +133 -53
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt +11 -13
- package/android/src/main/java/com/lodev09/truesheet/core/RootSheetView.kt +5 -5
- package/ios/Extensions/UIView+pinTo.swift +5 -0
- package/ios/TrueSheetEvent.swift +48 -0
- package/ios/TrueSheetView.swift +109 -69
- package/ios/TrueSheetViewController.swift +96 -31
- package/ios/TrueSheetViewManager.m +3 -0
- package/lib/commonjs/TrueSheet.js +17 -2
- package/lib/commonjs/TrueSheet.js.map +1 -1
- package/lib/module/TrueSheet.js +17 -2
- package/lib/module/TrueSheet.js.map +1 -1
- package/lib/typescript/commonjs/src/TrueSheet.d.ts +8 -0
- package/lib/typescript/commonjs/src/TrueSheet.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/TrueSheet.types.d.ts +33 -5
- package/lib/typescript/commonjs/src/TrueSheet.types.d.ts.map +1 -1
- package/lib/typescript/module/src/TrueSheet.d.ts +8 -0
- package/lib/typescript/module/src/TrueSheet.d.ts.map +1 -1
- package/lib/typescript/module/src/TrueSheet.types.d.ts +33 -5
- package/lib/typescript/module/src/TrueSheet.types.d.ts.map +1 -1
- package/package.json +8 -6
- package/react-native-true-sheet.podspec +1 -1
- package/src/TrueSheet.tsx +31 -10
- package/src/TrueSheet.types.ts +43 -5
- package/android/src/main/java/com/lodev09/truesheet/events/ContainerSizeChangeEvent.kt +0 -23
- package/android/src/main/java/com/lodev09/truesheet/events/DismissEvent.kt +0 -16
- package/android/src/main/java/com/lodev09/truesheet/events/MountEvent.kt +0 -16
- package/android/src/main/java/com/lodev09/truesheet/events/PresentEvent.kt +0 -23
- package/android/src/main/java/com/lodev09/truesheet/events/SizeChangeEvent.kt +0 -23
package/android/build.gradle
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
buildscript {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
ext.getExtOrDefault = {name ->
|
|
3
|
+
return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['TrueSheet_' + name]
|
|
4
|
+
}
|
|
4
5
|
|
|
5
6
|
repositories {
|
|
6
7
|
google()
|
|
@@ -8,16 +9,12 @@ buildscript {
|
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
dependencies {
|
|
11
|
-
classpath "com.android.tools.build:gradle:7.2
|
|
12
|
+
classpath "com.android.tools.build:gradle:8.7.2"
|
|
12
13
|
// noinspection DifferentKotlinGradleVersion
|
|
13
|
-
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$
|
|
14
|
+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}"
|
|
14
15
|
}
|
|
15
16
|
}
|
|
16
17
|
|
|
17
|
-
def reactNativeArchitectures() {
|
|
18
|
-
def value = rootProject.getProperties().get("reactNativeArchitectures")
|
|
19
|
-
return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
|
|
20
|
-
}
|
|
21
18
|
|
|
22
19
|
def isNewArchitectureEnabled() {
|
|
23
20
|
return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
|
|
@@ -26,14 +23,13 @@ def isNewArchitectureEnabled() {
|
|
|
26
23
|
apply plugin: "com.android.library"
|
|
27
24
|
apply plugin: "kotlin-android"
|
|
28
25
|
|
|
26
|
+
// TODO:
|
|
27
|
+
// When running example, comment this block!
|
|
28
|
+
// Not sure what's going on but we are getting multiple definition error when this is enabled.
|
|
29
29
|
if (isNewArchitectureEnabled()) {
|
|
30
30
|
apply plugin: "com.facebook.react"
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
def getExtOrDefault(name) {
|
|
34
|
-
return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties["TrueSheet_" + name]
|
|
35
|
-
}
|
|
36
|
-
|
|
37
33
|
def getExtOrIntegerDefault(name) {
|
|
38
34
|
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["TrueSheet_" + name]).toInteger()
|
|
39
35
|
}
|
|
@@ -49,7 +45,7 @@ def supportsNamespace() {
|
|
|
49
45
|
|
|
50
46
|
android {
|
|
51
47
|
if (supportsNamespace()) {
|
|
52
|
-
namespace "com.
|
|
48
|
+
namespace "com.truesheet"
|
|
53
49
|
|
|
54
50
|
sourceSets {
|
|
55
51
|
main {
|
|
@@ -90,11 +86,8 @@ repositories {
|
|
|
90
86
|
def kotlin_version = getExtOrDefault("kotlinVersion")
|
|
91
87
|
|
|
92
88
|
dependencies {
|
|
93
|
-
|
|
94
|
-
// For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
|
|
95
|
-
//noinspection GradleDynamicVersion
|
|
96
|
-
implementation "com.facebook.react:react-native:+"
|
|
89
|
+
implementation "com.facebook.react:react-android"
|
|
97
90
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
98
|
-
implementation
|
|
91
|
+
implementation "com.google.android.material:material:1.12.0"
|
|
99
92
|
}
|
|
100
93
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
TrueSheet_kotlinVersion=
|
|
2
|
-
TrueSheet_minSdkVersion=
|
|
3
|
-
TrueSheet_targetSdkVersion=
|
|
4
|
-
TrueSheet_compileSdkVersion=
|
|
5
|
-
|
|
1
|
+
TrueSheet_kotlinVersion=2.0.21
|
|
2
|
+
TrueSheet_minSdkVersion=24
|
|
3
|
+
TrueSheet_targetSdkVersion=34
|
|
4
|
+
TrueSheet_compileSdkVersion=35
|
|
5
|
+
TrueSheet_ndkVersion=27.1.12297006
|
|
@@ -21,9 +21,19 @@ class TrueSheetDialog(private val reactContext: ThemedReactContext, private val
|
|
|
21
21
|
BottomSheetDialog(reactContext) {
|
|
22
22
|
|
|
23
23
|
private var keyboardManager = KeyboardManager(reactContext)
|
|
24
|
-
private var sheetView: ViewGroup
|
|
25
24
|
private var windowAnimation: Int = 0
|
|
26
25
|
|
|
26
|
+
// First child of the rootSheetView
|
|
27
|
+
private val containerView: ViewGroup?
|
|
28
|
+
get() = if (rootSheetView.childCount > 0) {
|
|
29
|
+
rootSheetView.getChildAt(0) as? ViewGroup
|
|
30
|
+
} else {
|
|
31
|
+
null
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
private val sheetContainerView: ViewGroup?
|
|
35
|
+
get() = rootSheetView.parent?.let { it as? ViewGroup }
|
|
36
|
+
|
|
27
37
|
/**
|
|
28
38
|
* Specify whether the sheet background is dimmed.
|
|
29
39
|
* Set to `false` to allow interaction with the background components.
|
|
@@ -62,15 +72,22 @@ class TrueSheetDialog(private val reactContext: ThemedReactContext, private val
|
|
|
62
72
|
|
|
63
73
|
var cornerRadius: Float = 0f
|
|
64
74
|
var backgroundColor: Int = Color.WHITE
|
|
65
|
-
|
|
75
|
+
|
|
76
|
+
// 1st child is the content view
|
|
77
|
+
val contentView: ViewGroup?
|
|
78
|
+
get() = containerView?.getChildAt(0) as? ViewGroup
|
|
79
|
+
|
|
80
|
+
// 2nd child is the footer view
|
|
81
|
+
val footerView: ViewGroup?
|
|
82
|
+
get() = containerView?.getChildAt(1) as? ViewGroup
|
|
66
83
|
|
|
67
84
|
var sizes: Array<Any> = arrayOf("medium", "large")
|
|
68
85
|
|
|
69
86
|
init {
|
|
70
87
|
setContentView(rootSheetView)
|
|
71
88
|
|
|
72
|
-
|
|
73
|
-
|
|
89
|
+
sheetContainerView?.setBackgroundColor(backgroundColor)
|
|
90
|
+
sheetContainerView?.clipToOutline = true
|
|
74
91
|
|
|
75
92
|
// Setup window params to adjust layout based on Keyboard state
|
|
76
93
|
window?.apply {
|
|
@@ -118,7 +135,7 @@ class TrueSheetDialog(private val reactContext: ThemedReactContext, private val
|
|
|
118
135
|
|
|
119
136
|
// Use current background color
|
|
120
137
|
background.paint.color = backgroundColor
|
|
121
|
-
|
|
138
|
+
sheetContainerView?.background = background
|
|
122
139
|
}
|
|
123
140
|
|
|
124
141
|
/**
|
|
@@ -183,8 +200,10 @@ class TrueSheetDialog(private val reactContext: ThemedReactContext, private val
|
|
|
183
200
|
}
|
|
184
201
|
|
|
185
202
|
fun positionFooter() {
|
|
186
|
-
footerView?.
|
|
187
|
-
|
|
203
|
+
footerView?.let { footer ->
|
|
204
|
+
sheetContainerView?.let { container ->
|
|
205
|
+
footer.y = (maxScreenHeight - container.top - footerHeight).toFloat()
|
|
206
|
+
}
|
|
188
207
|
}
|
|
189
208
|
}
|
|
190
209
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
package com.lodev09.truesheet
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Arguments
|
|
4
|
+
import com.facebook.react.bridge.WritableMap
|
|
5
|
+
import com.facebook.react.uimanager.events.Event
|
|
6
|
+
|
|
7
|
+
class TrueSheetEvent(surfaceId: Int, viewId: Int, private val name: String, private val data: WritableMap?) :
|
|
8
|
+
Event<TrueSheetEvent>(surfaceId, viewId) {
|
|
9
|
+
override fun getEventName() = name
|
|
10
|
+
override fun getEventData(): WritableMap = data ?: Arguments.createMap()
|
|
11
|
+
|
|
12
|
+
companion object {
|
|
13
|
+
const val MOUNT = "topMount"
|
|
14
|
+
const val PRESENT = "topPresent"
|
|
15
|
+
const val DISMISS = "topDismiss"
|
|
16
|
+
const val SIZE_CHANGE = "topSizeChange"
|
|
17
|
+
const val DRAG_BEGIN = "topDragBegin"
|
|
18
|
+
const val DRAG_CHANGE = "topDragChange"
|
|
19
|
+
const val DRAG_END = "topDragEnd"
|
|
20
|
+
const val CONTAINER_SIZE_CHANGE = "topContainerSizeChange"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -5,19 +5,16 @@ import android.view.View
|
|
|
5
5
|
import android.view.ViewGroup
|
|
6
6
|
import android.view.ViewStructure
|
|
7
7
|
import android.view.accessibility.AccessibilityEvent
|
|
8
|
+
import com.facebook.react.bridge.Arguments
|
|
8
9
|
import com.facebook.react.bridge.LifecycleEventListener
|
|
9
10
|
import com.facebook.react.bridge.UiThreadUtil
|
|
11
|
+
import com.facebook.react.bridge.WritableMap
|
|
10
12
|
import com.facebook.react.uimanager.ThemedReactContext
|
|
11
13
|
import com.facebook.react.uimanager.UIManagerHelper
|
|
12
14
|
import com.facebook.react.uimanager.events.EventDispatcher
|
|
13
15
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
|
14
16
|
import com.lodev09.truesheet.core.RootSheetView
|
|
15
17
|
import com.lodev09.truesheet.core.Utils
|
|
16
|
-
import com.lodev09.truesheet.events.ContainerSizeChangeEvent
|
|
17
|
-
import com.lodev09.truesheet.events.DismissEvent
|
|
18
|
-
import com.lodev09.truesheet.events.MountEvent
|
|
19
|
-
import com.lodev09.truesheet.events.PresentEvent
|
|
20
|
-
import com.lodev09.truesheet.events.SizeChangeEvent
|
|
21
18
|
|
|
22
19
|
class TrueSheetView(context: Context) :
|
|
23
20
|
ViewGroup(context),
|
|
@@ -33,6 +30,11 @@ class TrueSheetView(context: Context) :
|
|
|
33
30
|
var initialIndex: Int = -1
|
|
34
31
|
var initialIndexAnimated: Boolean = true
|
|
35
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Determines if the sheet is being dragged by the user.
|
|
35
|
+
*/
|
|
36
|
+
private var isDragging = false
|
|
37
|
+
|
|
36
38
|
/**
|
|
37
39
|
* Current activeIndex.
|
|
38
40
|
*/
|
|
@@ -70,7 +72,11 @@ class TrueSheetView(context: Context) :
|
|
|
70
72
|
// Configure Sheet Dialog
|
|
71
73
|
sheetDialog.apply {
|
|
72
74
|
setOnSizeChangeListener { w, h ->
|
|
73
|
-
|
|
75
|
+
val data = Arguments.createMap()
|
|
76
|
+
data.putDouble("width", Utils.toDIP(w.toFloat()).toDouble())
|
|
77
|
+
data.putDouble("height", Utils.toDIP(h.toFloat()).toDouble())
|
|
78
|
+
|
|
79
|
+
dispatchEvent(TrueSheetEvent.CONTAINER_SIZE_CHANGE, data)
|
|
74
80
|
}
|
|
75
81
|
|
|
76
82
|
// Setup listener when the dialog has been presented.
|
|
@@ -92,7 +98,7 @@ class TrueSheetView(context: Context) :
|
|
|
92
98
|
}
|
|
93
99
|
|
|
94
100
|
// Dispatch onPresent event
|
|
95
|
-
|
|
101
|
+
dispatchEvent(TrueSheetEvent.PRESENT, sizeInfoData(getSizeInfoForIndex(currentSizeIndex)))
|
|
96
102
|
}
|
|
97
103
|
|
|
98
104
|
// Setup listener when the dialog has been dismissed.
|
|
@@ -106,13 +112,21 @@ class TrueSheetView(context: Context) :
|
|
|
106
112
|
}
|
|
107
113
|
|
|
108
114
|
// Dispatch onDismiss event
|
|
109
|
-
|
|
115
|
+
dispatchEvent(TrueSheetEvent.DISMISS)
|
|
110
116
|
}
|
|
111
117
|
|
|
112
118
|
// Configure sheet behavior events
|
|
113
119
|
behavior.addBottomSheetCallback(
|
|
114
120
|
object : BottomSheetBehavior.BottomSheetCallback() {
|
|
115
121
|
override fun onSlide(sheetView: View, slideOffset: Float) {
|
|
122
|
+
when (behavior.state) {
|
|
123
|
+
// For consistency with IOS, we consider SETTLING as dragging change.
|
|
124
|
+
BottomSheetBehavior.STATE_DRAGGING,
|
|
125
|
+
BottomSheetBehavior.STATE_SETTLING -> handleDragChange(sheetView)
|
|
126
|
+
|
|
127
|
+
else -> { }
|
|
128
|
+
}
|
|
129
|
+
|
|
116
130
|
footerView?.let {
|
|
117
131
|
val y = (maxScreenHeight - sheetView.top - footerHeight).toFloat()
|
|
118
132
|
if (slideOffset >= 0) {
|
|
@@ -125,23 +139,20 @@ class TrueSheetView(context: Context) :
|
|
|
125
139
|
}
|
|
126
140
|
}
|
|
127
141
|
|
|
128
|
-
override fun onStateChanged(
|
|
142
|
+
override fun onStateChanged(sheetView: View, newState: Int) {
|
|
129
143
|
if (!isShowing) return
|
|
130
144
|
|
|
131
|
-
|
|
132
|
-
|
|
145
|
+
when (newState) {
|
|
146
|
+
// When changed to dragging, we know that the drag has started
|
|
147
|
+
BottomSheetBehavior.STATE_DRAGGING -> handleDragBegin(sheetView)
|
|
133
148
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
}
|
|
149
|
+
// Either of the following state determines drag end
|
|
150
|
+
BottomSheetBehavior.STATE_EXPANDED,
|
|
151
|
+
BottomSheetBehavior.STATE_COLLAPSED,
|
|
152
|
+
BottomSheetBehavior.STATE_HALF_EXPANDED -> handleDragEnd(newState)
|
|
139
153
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
// Dispatch onSizeChange event
|
|
144
|
-
eventDispatcher?.dispatchEvent(SizeChangeEvent(surfaceId, id, sizeInfo))
|
|
154
|
+
else -> { }
|
|
155
|
+
}
|
|
145
156
|
}
|
|
146
157
|
}
|
|
147
158
|
)
|
|
@@ -162,39 +173,35 @@ class TrueSheetView(context: Context) :
|
|
|
162
173
|
// Do nothing as we are laid out by UIManager
|
|
163
174
|
}
|
|
164
175
|
|
|
176
|
+
override fun onAttachedToWindow() {
|
|
177
|
+
super.onAttachedToWindow()
|
|
178
|
+
|
|
179
|
+
// Initialize content
|
|
180
|
+
UiThreadUtil.runOnUiThread {
|
|
181
|
+
sheetDialog.contentView?.height?.let { setContentHeight(it) }
|
|
182
|
+
sheetDialog.footerView?.height?.let { setFooterHeight(it) }
|
|
183
|
+
|
|
184
|
+
if (initialIndex >= 0) {
|
|
185
|
+
currentSizeIndex = initialIndex
|
|
186
|
+
sheetDialog.present(initialIndex, initialIndexAnimated)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Dispatch onMount event
|
|
190
|
+
dispatchEvent(TrueSheetEvent.MOUNT)
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
165
194
|
override fun onDetachedFromWindow() {
|
|
166
195
|
super.onDetachedFromWindow()
|
|
167
196
|
sheetDialog.dismiss()
|
|
168
197
|
}
|
|
169
198
|
|
|
170
199
|
override fun addView(child: View, index: Int) {
|
|
200
|
+
UiThreadUtil.assertOnUiThread()
|
|
201
|
+
rootSheetView.addView(child, index)
|
|
202
|
+
|
|
171
203
|
// Hide this host view
|
|
172
204
|
visibility = GONE
|
|
173
|
-
|
|
174
|
-
(child as ViewGroup).let {
|
|
175
|
-
// rootView's first child is the Container View
|
|
176
|
-
rootSheetView.addView(it, index)
|
|
177
|
-
|
|
178
|
-
// Initialize content
|
|
179
|
-
UiThreadUtil.runOnUiThread {
|
|
180
|
-
// 1st child is the content view
|
|
181
|
-
val contentView = it.getChildAt(0) as ViewGroup?
|
|
182
|
-
setContentHeight(contentView?.height ?: 0)
|
|
183
|
-
|
|
184
|
-
// 2nd child is the footer view
|
|
185
|
-
val footerView = it.getChildAt(1) as ViewGroup?
|
|
186
|
-
sheetDialog.footerView = footerView
|
|
187
|
-
setFooterHeight(footerView?.height ?: 0)
|
|
188
|
-
|
|
189
|
-
if (initialIndex >= 0) {
|
|
190
|
-
currentSizeIndex = initialIndex
|
|
191
|
-
sheetDialog.present(initialIndex, initialIndexAnimated)
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// Dispatch onMount event
|
|
195
|
-
eventDispatcher?.dispatchEvent(MountEvent(surfaceId, id))
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
205
|
}
|
|
199
206
|
|
|
200
207
|
override fun getChildCount(): Int {
|
|
@@ -206,10 +213,13 @@ class TrueSheetView(context: Context) :
|
|
|
206
213
|
override fun getChildAt(index: Int): View = rootSheetView.getChildAt(index)
|
|
207
214
|
|
|
208
215
|
override fun removeView(child: View) {
|
|
216
|
+
UiThreadUtil.assertOnUiThread()
|
|
209
217
|
rootSheetView.removeView(child)
|
|
210
218
|
}
|
|
211
219
|
|
|
212
220
|
override fun removeViewAt(index: Int) {
|
|
221
|
+
UiThreadUtil.assertOnUiThread()
|
|
222
|
+
|
|
213
223
|
val child = getChildAt(index)
|
|
214
224
|
rootSheetView.removeView(child)
|
|
215
225
|
}
|
|
@@ -239,6 +249,68 @@ class TrueSheetView(context: Context) :
|
|
|
239
249
|
sheetDialog.dismiss()
|
|
240
250
|
}
|
|
241
251
|
|
|
252
|
+
private fun sizeInfoData(sizeInfo: SizeInfo): WritableMap {
|
|
253
|
+
val data = Arguments.createMap()
|
|
254
|
+
data.putInt("index", sizeInfo.index)
|
|
255
|
+
data.putDouble("value", sizeInfo.value.toDouble())
|
|
256
|
+
|
|
257
|
+
return data
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
private fun getCurrentSizeInfo(sheetView: View): SizeInfo {
|
|
261
|
+
val height = sheetDialog.maxScreenHeight - sheetView.top
|
|
262
|
+
val currentSizeInfo = SizeInfo(currentSizeIndex, Utils.toDIP(height.toFloat()))
|
|
263
|
+
|
|
264
|
+
return currentSizeInfo
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
private fun handleDragBegin(sheetView: View) {
|
|
268
|
+
// Dispatch drag started event
|
|
269
|
+
dispatchEvent(TrueSheetEvent.DRAG_BEGIN, sizeInfoData(getCurrentSizeInfo(sheetView)))
|
|
270
|
+
// Flag sheet is being dragged
|
|
271
|
+
isDragging = true
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
private fun handleDragChange(sheetView: View) {
|
|
275
|
+
if (!isDragging) return
|
|
276
|
+
|
|
277
|
+
// Dispatch drag change event
|
|
278
|
+
dispatchEvent(TrueSheetEvent.DRAG_CHANGE, sizeInfoData(getCurrentSizeInfo(sheetView)))
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
private fun handleDragEnd(state: Int) {
|
|
282
|
+
if (!isDragging) return
|
|
283
|
+
|
|
284
|
+
// For consistency with IOS,
|
|
285
|
+
// we only handle state changes after dragging.
|
|
286
|
+
//
|
|
287
|
+
// Changing size programmatically is handled via the present method.
|
|
288
|
+
val sizeInfo = sheetDialog.getSizeInfoForState(state)
|
|
289
|
+
sizeInfo?.let {
|
|
290
|
+
// Dispatch drag ended after dragging
|
|
291
|
+
dispatchEvent(TrueSheetEvent.DRAG_END, sizeInfoData(it))
|
|
292
|
+
if (it.index != currentSizeIndex) {
|
|
293
|
+
// Invoke promise when sheet resized programmatically
|
|
294
|
+
presentPromise?.let { promise ->
|
|
295
|
+
promise()
|
|
296
|
+
presentPromise = null
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
currentSizeIndex = it.index
|
|
300
|
+
sheetDialog.setupDimmedBackground(it.index)
|
|
301
|
+
|
|
302
|
+
// Dispatch onSizeChange event
|
|
303
|
+
dispatchEvent(TrueSheetEvent.SIZE_CHANGE, sizeInfoData(it))
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
isDragging = false
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
private fun dispatchEvent(name: String, data: WritableMap? = null) {
|
|
311
|
+
eventDispatcher?.dispatchEvent(TrueSheetEvent(surfaceId, id, name, data))
|
|
312
|
+
}
|
|
313
|
+
|
|
242
314
|
private fun configureIfShowing() {
|
|
243
315
|
if (sheetDialog.isShowing) {
|
|
244
316
|
sheetDialog.configure()
|
|
@@ -322,11 +394,21 @@ class TrueSheetView(context: Context) :
|
|
|
322
394
|
* Present the sheet at given size index.
|
|
323
395
|
*/
|
|
324
396
|
fun present(sizeIndex: Int, promiseCallback: () -> Unit) {
|
|
325
|
-
|
|
326
|
-
|
|
397
|
+
UiThreadUtil.assertOnUiThread()
|
|
398
|
+
|
|
399
|
+
currentSizeIndex = sizeIndex
|
|
400
|
+
|
|
401
|
+
if (sheetDialog.isShowing) {
|
|
402
|
+
// For consistency with IOS, we are not waiting
|
|
403
|
+
// for the state to change before dispatching onSizeChange event.
|
|
404
|
+
val sizeInfo = sheetDialog.getSizeInfoForIndex(sizeIndex)
|
|
405
|
+
dispatchEvent(TrueSheetEvent.SIZE_CHANGE, sizeInfoData(sizeInfo))
|
|
406
|
+
|
|
407
|
+
promiseCallback()
|
|
408
|
+
} else {
|
|
409
|
+
presentPromise = promiseCallback
|
|
327
410
|
}
|
|
328
411
|
|
|
329
|
-
presentPromise = promiseCallback
|
|
330
412
|
sheetDialog.present(sizeIndex)
|
|
331
413
|
}
|
|
332
414
|
|
|
@@ -334,11 +416,9 @@ class TrueSheetView(context: Context) :
|
|
|
334
416
|
* Dismisses the sheet.
|
|
335
417
|
*/
|
|
336
418
|
fun dismiss(promiseCallback: () -> Unit) {
|
|
419
|
+
UiThreadUtil.assertOnUiThread()
|
|
420
|
+
|
|
337
421
|
dismissPromise = promiseCallback
|
|
338
422
|
sheetDialog.dismiss()
|
|
339
423
|
}
|
|
340
|
-
|
|
341
|
-
companion object {
|
|
342
|
-
const val TAG = "TrueSheetView"
|
|
343
|
-
}
|
|
344
424
|
}
|
|
@@ -11,11 +11,6 @@ import com.facebook.react.uimanager.ThemedReactContext
|
|
|
11
11
|
import com.facebook.react.uimanager.ViewGroupManager
|
|
12
12
|
import com.facebook.react.uimanager.annotations.ReactProp
|
|
13
13
|
import com.lodev09.truesheet.core.Utils
|
|
14
|
-
import com.lodev09.truesheet.events.ContainerSizeChangeEvent
|
|
15
|
-
import com.lodev09.truesheet.events.DismissEvent
|
|
16
|
-
import com.lodev09.truesheet.events.MountEvent
|
|
17
|
-
import com.lodev09.truesheet.events.PresentEvent
|
|
18
|
-
import com.lodev09.truesheet.events.SizeChangeEvent
|
|
19
14
|
|
|
20
15
|
class TrueSheetViewManager : ViewGroupManager<TrueSheetView>() {
|
|
21
16
|
override fun getName() = TAG
|
|
@@ -27,14 +22,17 @@ class TrueSheetViewManager : ViewGroupManager<TrueSheetView>() {
|
|
|
27
22
|
view.onHostDestroy()
|
|
28
23
|
}
|
|
29
24
|
|
|
30
|
-
override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any
|
|
31
|
-
|
|
32
|
-
.
|
|
33
|
-
.
|
|
34
|
-
.
|
|
35
|
-
.
|
|
36
|
-
.
|
|
37
|
-
.
|
|
25
|
+
override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any> =
|
|
26
|
+
mutableMapOf(
|
|
27
|
+
TrueSheetEvent.MOUNT to MapBuilder.of("registrationName", "onMount"),
|
|
28
|
+
TrueSheetEvent.PRESENT to MapBuilder.of("registrationName", "onPresent"),
|
|
29
|
+
TrueSheetEvent.DISMISS to MapBuilder.of("registrationName", "onDismiss"),
|
|
30
|
+
TrueSheetEvent.SIZE_CHANGE to MapBuilder.of("registrationName", "onSizeChange"),
|
|
31
|
+
TrueSheetEvent.DRAG_BEGIN to MapBuilder.of("registrationName", "onDragBegin"),
|
|
32
|
+
TrueSheetEvent.DRAG_CHANGE to MapBuilder.of("registrationName", "onDragChange"),
|
|
33
|
+
TrueSheetEvent.DRAG_END to MapBuilder.of("registrationName", "onDragEnd"),
|
|
34
|
+
TrueSheetEvent.CONTAINER_SIZE_CHANGE to MapBuilder.of("registrationName", "onContainerSizeChange")
|
|
35
|
+
)
|
|
38
36
|
|
|
39
37
|
@ReactProp(name = "edgeToEdge")
|
|
40
38
|
fun setEdgeToEdge(view: TrueSheetView, edgeToEdge: Boolean) {
|
|
@@ -36,15 +36,15 @@ class RootSheetView(private val context: Context?) :
|
|
|
36
36
|
|
|
37
37
|
var eventDispatcher: EventDispatcher? = null
|
|
38
38
|
|
|
39
|
+
private val reactContext: ThemedReactContext
|
|
40
|
+
get() = context as ThemedReactContext
|
|
41
|
+
|
|
39
42
|
init {
|
|
40
43
|
if (ReactFeatureFlags.dispatchPointerEvents) {
|
|
41
44
|
jSPointerDispatcher = JSPointerDispatcher(this)
|
|
42
45
|
}
|
|
43
46
|
}
|
|
44
47
|
|
|
45
|
-
private val reactContext: ThemedReactContext
|
|
46
|
-
get() = context as ThemedReactContext
|
|
47
|
-
|
|
48
48
|
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
|
|
49
49
|
super.onSizeChanged(w, h, oldw, oldh)
|
|
50
50
|
|
|
@@ -86,7 +86,7 @@ class RootSheetView(private val context: Context?) :
|
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
@Deprecated("Deprecated in Java")
|
|
89
|
-
override fun onChildStartedNativeGesture(ev: MotionEvent
|
|
89
|
+
override fun onChildStartedNativeGesture(ev: MotionEvent) {
|
|
90
90
|
eventDispatcher?.let {
|
|
91
91
|
if (ev != null) {
|
|
92
92
|
jSTouchDispatcher.onChildStartedNativeGesture(ev, it)
|
|
@@ -94,7 +94,7 @@ class RootSheetView(private val context: Context?) :
|
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
override fun onChildStartedNativeGesture(childView: View
|
|
97
|
+
override fun onChildStartedNativeGesture(childView: View?, ev: MotionEvent) {
|
|
98
98
|
eventDispatcher?.let { jSTouchDispatcher.onChildStartedNativeGesture(ev, it) }
|
|
99
99
|
jSPointerDispatcher?.onChildStartedNativeGesture(childView, ev, eventDispatcher)
|
|
100
100
|
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Created by Jovanni Lo (@lodev09)
|
|
3
|
+
// Copyright (c) 2024-present. All rights reserved.
|
|
4
|
+
//
|
|
5
|
+
// This source code is licensed under the MIT license found in the
|
|
6
|
+
// LICENSE file in the root directory of this source tree.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
class TrueSheetEvent: NSObject, RCTEvent {
|
|
10
|
+
var viewTag: NSNumber
|
|
11
|
+
|
|
12
|
+
private var name: String
|
|
13
|
+
private var data: [String: Any]?
|
|
14
|
+
|
|
15
|
+
var eventName: String {
|
|
16
|
+
return name
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
var coalescingKey: UInt16 {
|
|
20
|
+
return 0
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
init(viewTag: NSNumber, name: String, data: [String: Any]?) {
|
|
24
|
+
self.name = name
|
|
25
|
+
self.viewTag = viewTag
|
|
26
|
+
self.data = data
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
static func moduleDotMethod() -> String {
|
|
30
|
+
return "RCTEventEmitter.receiveEvent"
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
func arguments() -> [Any] {
|
|
34
|
+
return [
|
|
35
|
+
viewTag,
|
|
36
|
+
RCTNormalizeInputEventName(eventName)!,
|
|
37
|
+
data ?? [:],
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
func canCoalesce() -> Bool {
|
|
42
|
+
return true
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
func coalesce(with newEvent: RCTEvent) -> RCTEvent {
|
|
46
|
+
return newEvent
|
|
47
|
+
}
|
|
48
|
+
}
|