@lodev09/react-native-true-sheet 0.2.2 → 0.3.0
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 +2 -5
- package/android/build.gradle +1 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetPackage.kt +2 -7
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +233 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt +42 -10
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewModule.kt +63 -0
- package/android/src/main/java/com/lodev09/truesheet/core/Events.kt +43 -0
- package/android/src/main/java/com/lodev09/truesheet/core/RootViewGroup.kt +136 -0
- package/android/src/main/java/com/lodev09/truesheet/core/SheetBehavior.kt +198 -0
- package/android/src/main/java/com/lodev09/truesheet/utils/maxSize.kt +49 -0
- package/android/src/main/java/com/lodev09/truesheet/utils/toDIP.kt +5 -0
- package/android/src/main/java/com/lodev09/truesheet/utils/withPromise.kt +13 -0
- package/ios/TrueSheetView.swift +3 -3
- package/ios/TrueSheetViewManager.m +1 -1
- package/lib/commonjs/TrueSheet.js +12 -5
- package/lib/commonjs/TrueSheet.js.map +1 -1
- package/lib/commonjs/TrueSheetModule.js +3 -1
- package/lib/commonjs/TrueSheetModule.js.map +1 -1
- package/lib/module/TrueSheet.js +12 -5
- package/lib/module/TrueSheet.js.map +1 -1
- package/lib/module/TrueSheetModule.js +3 -1
- package/lib/module/TrueSheetModule.js.map +1 -1
- package/lib/typescript/src/TrueSheet.d.ts +1 -1
- package/lib/typescript/src/TrueSheet.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheetModule.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +4 -3
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/TrueSheet.tsx +21 -10
- package/src/TrueSheetModule.ts +3 -2
- package/src/types.ts +4 -3
package/README.md
CHANGED
|
@@ -11,6 +11,7 @@ The true native bottom sheet.
|
|
|
11
11
|
* ✅ **_NOT_** your pure JS, (re)animated View.
|
|
12
12
|
* ✅ Clean, fast and lightweight.
|
|
13
13
|
* ✅ Handles your Sscrolling needs, easy.
|
|
14
|
+
* ✅ Asynchronus `ref` methods.
|
|
14
15
|
|
|
15
16
|
## Installation
|
|
16
17
|
|
|
@@ -34,7 +35,7 @@ const openSheet = () => {
|
|
|
34
35
|
return (
|
|
35
36
|
<View>
|
|
36
37
|
<Button onPress={openSheet} title="Open Sheet" />
|
|
37
|
-
<TrueSheet ref={sheet}>
|
|
38
|
+
<TrueSheet sizes={['auto', 'large']} ref={sheet}>
|
|
38
39
|
// ...
|
|
39
40
|
</TrueSheet>
|
|
40
41
|
</View>
|
|
@@ -51,7 +52,3 @@ See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the
|
|
|
51
52
|
## License
|
|
52
53
|
|
|
53
54
|
MIT
|
|
54
|
-
|
|
55
|
-
---
|
|
56
|
-
|
|
57
|
-
Made with [create-react-native-library](https://github.com/callstack/react-native-builder-bob)
|
package/android/build.gradle
CHANGED
|
@@ -5,13 +5,8 @@ import com.facebook.react.bridge.NativeModule
|
|
|
5
5
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
6
|
import com.facebook.react.uimanager.ViewManager
|
|
7
7
|
|
|
8
|
-
|
|
9
8
|
class TrueSheetPackage : ReactPackage {
|
|
10
|
-
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule>
|
|
11
|
-
return emptyList()
|
|
12
|
-
}
|
|
9
|
+
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> = listOf(TrueSheetViewModule(reactContext))
|
|
13
10
|
|
|
14
|
-
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>>
|
|
15
|
-
return listOf(TrueSheetViewManager())
|
|
16
|
-
}
|
|
11
|
+
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> = listOf(TrueSheetViewManager())
|
|
17
12
|
}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
package com.lodev09.truesheet
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.view.View
|
|
5
|
+
import android.view.ViewGroup
|
|
6
|
+
import android.view.ViewStructure
|
|
7
|
+
import android.view.accessibility.AccessibilityEvent
|
|
8
|
+
import android.widget.LinearLayout
|
|
9
|
+
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
|
10
|
+
import com.facebook.react.bridge.LifecycleEventListener
|
|
11
|
+
import com.facebook.react.bridge.UiThreadUtil
|
|
12
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
13
|
+
import com.facebook.react.uimanager.UIManagerHelper
|
|
14
|
+
import com.facebook.react.uimanager.events.EventDispatcher
|
|
15
|
+
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
|
16
|
+
import com.google.android.material.bottomsheet.BottomSheetDialog
|
|
17
|
+
import com.lodev09.truesheet.core.DismissEvent
|
|
18
|
+
import com.lodev09.truesheet.core.PresentEvent
|
|
19
|
+
import com.lodev09.truesheet.core.RootViewGroup
|
|
20
|
+
import com.lodev09.truesheet.core.SheetBehavior
|
|
21
|
+
import com.lodev09.truesheet.core.SizeChangeEvent
|
|
22
|
+
import com.lodev09.truesheet.utils.maxSize
|
|
23
|
+
|
|
24
|
+
class TrueSheetView(context: Context) :
|
|
25
|
+
ViewGroup(context),
|
|
26
|
+
LifecycleEventListener {
|
|
27
|
+
private var eventDispatcher: EventDispatcher? = null
|
|
28
|
+
|
|
29
|
+
private val reactContext: ThemedReactContext
|
|
30
|
+
get() = context as ThemedReactContext
|
|
31
|
+
|
|
32
|
+
private val surfaceId: Int
|
|
33
|
+
get() = UIManagerHelper.getSurfaceId(this)
|
|
34
|
+
|
|
35
|
+
private var sizeIndex: Int = 0
|
|
36
|
+
private var sizes: Array<Any> = arrayOf("medium", "large")
|
|
37
|
+
|
|
38
|
+
private var presentPromise: (() -> Unit)? = null
|
|
39
|
+
private var dismissPromise: (() -> Unit)? = null
|
|
40
|
+
|
|
41
|
+
private val sheetDialog: BottomSheetDialog
|
|
42
|
+
private val sheetLayout: LinearLayout
|
|
43
|
+
private val sheetRootView: RootViewGroup
|
|
44
|
+
|
|
45
|
+
// 1st child of the container view
|
|
46
|
+
private var contentView: ViewGroup? = null
|
|
47
|
+
|
|
48
|
+
// 2nd child of the container view
|
|
49
|
+
private var footerView: ViewGroup? = null
|
|
50
|
+
|
|
51
|
+
private var sheetBehavior: SheetBehavior<ViewGroup>
|
|
52
|
+
|
|
53
|
+
init {
|
|
54
|
+
reactContext.addLifecycleEventListener(this)
|
|
55
|
+
eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag(reactContext, id)
|
|
56
|
+
|
|
57
|
+
sheetRootView = RootViewGroup(context)
|
|
58
|
+
sheetRootView.eventDispatcher = eventDispatcher
|
|
59
|
+
|
|
60
|
+
sheetDialog = BottomSheetDialog(context)
|
|
61
|
+
sheetBehavior = SheetBehavior()
|
|
62
|
+
sheetLayout = LinearLayout(context)
|
|
63
|
+
|
|
64
|
+
// Configure Sheet events
|
|
65
|
+
sheetBehavior.apply {
|
|
66
|
+
maxSize = maxSize(context)
|
|
67
|
+
|
|
68
|
+
addBottomSheetCallback(
|
|
69
|
+
object : BottomSheetBehavior.BottomSheetCallback() {
|
|
70
|
+
override fun onSlide(sheetView: View, slideOffset: Float) {
|
|
71
|
+
footerView?.let {
|
|
72
|
+
it.y = (sheetView.height - sheetView.top - it.height).toFloat()
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
override fun onStateChanged(view: View, newState: Int) {
|
|
77
|
+
val sizeInfo = getSizeInfoForState(sizes.size, newState)
|
|
78
|
+
if (sizeInfo != null && sizeInfo.index != sizeIndex) {
|
|
79
|
+
sizeIndex = sizeInfo.index
|
|
80
|
+
|
|
81
|
+
// dispatch onSizeChange event
|
|
82
|
+
eventDispatcher?.dispatchEvent(SizeChangeEvent(surfaceId, id, sizeInfo))
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
when (newState) {
|
|
86
|
+
BottomSheetBehavior.STATE_HIDDEN -> sheetDialog.dismiss()
|
|
87
|
+
else -> {}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Configure the sheet layout
|
|
95
|
+
sheetLayout.apply {
|
|
96
|
+
addView(sheetRootView)
|
|
97
|
+
sheetDialog.setContentView(this)
|
|
98
|
+
|
|
99
|
+
val layoutParent = parent as ViewGroup
|
|
100
|
+
(layoutParent.layoutParams as CoordinatorLayout.LayoutParams).behavior = sheetBehavior
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Configure Sheet Dialog
|
|
104
|
+
sheetDialog.apply {
|
|
105
|
+
setOnShowListener {
|
|
106
|
+
UiThreadUtil.runOnUiThread {
|
|
107
|
+
footerView?.let {
|
|
108
|
+
val sheetView = sheetLayout.parent as ViewGroup
|
|
109
|
+
it.y = (sheetView.height - sheetView.top - it.height).toFloat()
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
presentPromise?.invoke()
|
|
114
|
+
presentPromise = null
|
|
115
|
+
|
|
116
|
+
// dispatch onPresent event
|
|
117
|
+
eventDispatcher?.dispatchEvent(PresentEvent(surfaceId, id))
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
setOnDismissListener {
|
|
121
|
+
dismissPromise?.invoke()
|
|
122
|
+
dismissPromise = null
|
|
123
|
+
|
|
124
|
+
// dispatch onDismiss event
|
|
125
|
+
eventDispatcher?.dispatchEvent(DismissEvent(surfaceId, id))
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
override fun dispatchProvideStructure(structure: ViewStructure) {
|
|
131
|
+
sheetRootView.dispatchProvideStructure(structure)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
override fun onLayout(
|
|
135
|
+
changed: Boolean,
|
|
136
|
+
l: Int,
|
|
137
|
+
t: Int,
|
|
138
|
+
r: Int,
|
|
139
|
+
b: Int
|
|
140
|
+
) {
|
|
141
|
+
// Do nothing as we are laid out by UIManager
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
override fun onDetachedFromWindow() {
|
|
145
|
+
super.onDetachedFromWindow()
|
|
146
|
+
sheetDialog.dismiss()
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
override fun addView(child: View, index: Int) {
|
|
150
|
+
// Hide this host view
|
|
151
|
+
visibility = GONE
|
|
152
|
+
|
|
153
|
+
(child as ViewGroup).let {
|
|
154
|
+
// Container View's first child is the Content View
|
|
155
|
+
contentView = it.getChildAt(0) as ViewGroup
|
|
156
|
+
footerView = it.getChildAt(1) as ViewGroup
|
|
157
|
+
|
|
158
|
+
sheetBehavior.contentView = contentView
|
|
159
|
+
sheetBehavior.footerView = footerView
|
|
160
|
+
|
|
161
|
+
// rootView's first child is the Container View
|
|
162
|
+
sheetRootView.addView(it, index)
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
override fun getChildCount(): Int {
|
|
167
|
+
// This method may be called by the parent constructor
|
|
168
|
+
// before rootView is initialized.
|
|
169
|
+
return sheetRootView.childCount
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
override fun getChildAt(index: Int): View = sheetRootView.getChildAt(index)
|
|
173
|
+
|
|
174
|
+
override fun removeView(child: View) {
|
|
175
|
+
sheetRootView.removeView(child)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
override fun removeViewAt(index: Int) {
|
|
179
|
+
val child = getChildAt(index)
|
|
180
|
+
sheetRootView.removeView(child)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
override fun addChildrenForAccessibility(outChildren: ArrayList<View>) {
|
|
184
|
+
// Explicitly override this to prevent accessibility events being passed down to children
|
|
185
|
+
// Those will be handled by the rootView which lives in the dialog
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
override fun dispatchPopulateAccessibilityEvent(event: AccessibilityEvent): Boolean {
|
|
189
|
+
// Explicitly override this to prevent accessibility events being passed down to children
|
|
190
|
+
// Those will be handled by the rootView which lives in the dialog
|
|
191
|
+
return false
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
override fun onHostResume() {
|
|
195
|
+
// do nothing
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
override fun onHostPause() {
|
|
199
|
+
// do nothing
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
override fun onHostDestroy() {
|
|
203
|
+
// Drop the instance if the host is destroyed which will dismiss the dialog
|
|
204
|
+
reactContext.removeLifecycleEventListener(this)
|
|
205
|
+
sheetDialog.dismiss()
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
fun setSizes(newSizes: Array<Any>) {
|
|
209
|
+
sizes = newSizes
|
|
210
|
+
sheetBehavior.configure(sizes)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
fun present(index: Int, promiseCallback: () -> Unit) {
|
|
214
|
+
sheetBehavior.setStateForSizeIndex(sizes.size, index)
|
|
215
|
+
|
|
216
|
+
if (sheetDialog.isShowing) {
|
|
217
|
+
promiseCallback()
|
|
218
|
+
} else {
|
|
219
|
+
sheetBehavior.configure(sizes)
|
|
220
|
+
presentPromise = promiseCallback
|
|
221
|
+
sheetDialog.show()
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
fun dismiss(promiseCallback: () -> Unit) {
|
|
226
|
+
dismissPromise = promiseCallback
|
|
227
|
+
sheetDialog.dismiss()
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
companion object {
|
|
231
|
+
const val TAG = "TrueSheetView"
|
|
232
|
+
}
|
|
233
|
+
}
|
|
@@ -1,20 +1,52 @@
|
|
|
1
1
|
package com.lodev09.truesheet
|
|
2
2
|
|
|
3
|
-
import android.
|
|
4
|
-
import
|
|
5
|
-
import com.facebook.react.
|
|
3
|
+
import android.util.Log
|
|
4
|
+
import com.facebook.react.bridge.ReadableArray
|
|
5
|
+
import com.facebook.react.bridge.ReadableType
|
|
6
|
+
import com.facebook.react.common.MapBuilder
|
|
6
7
|
import com.facebook.react.uimanager.ThemedReactContext
|
|
8
|
+
import com.facebook.react.uimanager.ViewGroupManager
|
|
7
9
|
import com.facebook.react.uimanager.annotations.ReactProp
|
|
10
|
+
import com.lodev09.truesheet.core.DismissEvent
|
|
11
|
+
import com.lodev09.truesheet.core.PresentEvent
|
|
12
|
+
import com.lodev09.truesheet.core.SizeChangeEvent
|
|
8
13
|
|
|
9
|
-
class TrueSheetViewManager :
|
|
10
|
-
override fun getName() =
|
|
14
|
+
class TrueSheetViewManager : ViewGroupManager<TrueSheetView>() {
|
|
15
|
+
override fun getName() = TAG
|
|
11
16
|
|
|
12
|
-
override fun createViewInstance(reactContext: ThemedReactContext):
|
|
13
|
-
|
|
17
|
+
override fun createViewInstance(reactContext: ThemedReactContext): TrueSheetView = TrueSheetView(reactContext)
|
|
18
|
+
|
|
19
|
+
override fun onDropViewInstance(view: TrueSheetView) {
|
|
20
|
+
super.onDropViewInstance(view)
|
|
21
|
+
view.onHostDestroy()
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any>? =
|
|
25
|
+
MapBuilder.builder<String, Any>()
|
|
26
|
+
.put(PresentEvent.EVENT_NAME, MapBuilder.of("registrationName", "onPresent"))
|
|
27
|
+
.put(DismissEvent.EVENT_NAME, MapBuilder.of("registrationName", "onDismiss"))
|
|
28
|
+
.put(SizeChangeEvent.EVENT_NAME, MapBuilder.of("registrationName", "onSizeChange"))
|
|
29
|
+
.build()
|
|
30
|
+
|
|
31
|
+
@ReactProp(name = "sizes")
|
|
32
|
+
fun setSizes(view: TrueSheetView, sizes: ReadableArray?) {
|
|
33
|
+
if (sizes != null) {
|
|
34
|
+
val result = ArrayList<Any>()
|
|
35
|
+
for (i in 0 until minOf(sizes.size(), 3)) {
|
|
36
|
+
when (sizes.getType(i)) {
|
|
37
|
+
ReadableType.Number -> result.add(sizes.getDouble(i))
|
|
38
|
+
ReadableType.String -> result.add(sizes.getString(i))
|
|
39
|
+
else -> Log.d(TAG, "Invalid type")
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
view.setSizes(result.toArray())
|
|
44
|
+
} else {
|
|
45
|
+
view.setSizes(arrayOf("medium", "large"))
|
|
46
|
+
}
|
|
14
47
|
}
|
|
15
48
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
view.setBackgroundColor(Color.parseColor(color))
|
|
49
|
+
companion object {
|
|
50
|
+
const val TAG = "TrueSheetView"
|
|
19
51
|
}
|
|
20
52
|
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
package com.lodev09.truesheet
|
|
2
|
+
|
|
3
|
+
import android.util.Log
|
|
4
|
+
import com.facebook.react.bridge.Promise
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
|
7
|
+
import com.facebook.react.bridge.ReactMethod
|
|
8
|
+
import com.facebook.react.bridge.UiThreadUtil
|
|
9
|
+
import com.facebook.react.module.annotations.ReactModule
|
|
10
|
+
import com.facebook.react.uimanager.UIManagerHelper
|
|
11
|
+
import com.lodev09.truesheet.utils.withPromise
|
|
12
|
+
|
|
13
|
+
@ReactModule(name = TrueSheetViewModule.TAG)
|
|
14
|
+
class TrueSheetViewModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
|
|
15
|
+
override fun getName(): String = TAG
|
|
16
|
+
|
|
17
|
+
private fun withTrueSheetView(tag: Int, closure: (trueSheetView: TrueSheetView) -> Unit) {
|
|
18
|
+
UiThreadUtil.runOnUiThread {
|
|
19
|
+
try {
|
|
20
|
+
val manager = UIManagerHelper.getUIManagerForReactTag(reactApplicationContext, tag)
|
|
21
|
+
val view = manager?.resolveView(tag)
|
|
22
|
+
if (view == null) {
|
|
23
|
+
Log.d(TAG, "Tag $tag not found")
|
|
24
|
+
return@runOnUiThread
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (view is TrueSheetView) {
|
|
28
|
+
closure(view)
|
|
29
|
+
} else {
|
|
30
|
+
Log.d(TAG, "Tag $tag does not match")
|
|
31
|
+
}
|
|
32
|
+
} catch (e: Exception) {
|
|
33
|
+
e.printStackTrace()
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@ReactMethod
|
|
39
|
+
fun present(tag: Int, index: Int, promise: Promise) {
|
|
40
|
+
withTrueSheetView(tag) {
|
|
41
|
+
it.present(index) {
|
|
42
|
+
withPromise(promise) {
|
|
43
|
+
return@withPromise null
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@ReactMethod
|
|
50
|
+
fun dismiss(tag: Int, promise: Promise) {
|
|
51
|
+
withTrueSheetView(tag) {
|
|
52
|
+
it.dismiss {
|
|
53
|
+
withPromise(promise) {
|
|
54
|
+
return@withPromise null
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
companion object {
|
|
61
|
+
const val TAG = "TrueSheetView"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
package com.lodev09.truesheet.core
|
|
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
|
+
// onPresent
|
|
8
|
+
class PresentEvent(surfaceId: Int, viewId: Int) : Event<PresentEvent>(surfaceId, viewId) {
|
|
9
|
+
override fun getEventName() = EVENT_NAME
|
|
10
|
+
|
|
11
|
+
override fun getEventData(): WritableMap = Arguments.createMap()
|
|
12
|
+
|
|
13
|
+
companion object {
|
|
14
|
+
const val EVENT_NAME = "present"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// onDismiss
|
|
19
|
+
class DismissEvent(surfaceId: Int, viewId: Int) : Event<PresentEvent>(surfaceId, viewId) {
|
|
20
|
+
override fun getEventName() = EVENT_NAME
|
|
21
|
+
|
|
22
|
+
override fun getEventData(): WritableMap = Arguments.createMap()
|
|
23
|
+
|
|
24
|
+
companion object {
|
|
25
|
+
const val EVENT_NAME = "dismiss"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
class SizeChangeEvent(surfaceId: Int, viewId: Int, private val sizeInfo: SizeInfo) : Event<SizeChangeEvent>(surfaceId, viewId) {
|
|
30
|
+
override fun getEventName() = EVENT_NAME
|
|
31
|
+
|
|
32
|
+
override fun getEventData(): WritableMap {
|
|
33
|
+
val data = Arguments.createMap()
|
|
34
|
+
data.putInt("index", sizeInfo.index)
|
|
35
|
+
data.putDouble("value", sizeInfo.value.toDouble())
|
|
36
|
+
|
|
37
|
+
return data
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
companion object {
|
|
41
|
+
const val EVENT_NAME = "sizeChange"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
package com.lodev09.truesheet.core
|
|
2
|
+
|
|
3
|
+
import android.annotation.SuppressLint
|
|
4
|
+
import android.content.Context
|
|
5
|
+
import android.view.MotionEvent
|
|
6
|
+
import android.view.View
|
|
7
|
+
import com.facebook.react.bridge.GuardedRunnable
|
|
8
|
+
import com.facebook.react.config.ReactFeatureFlags
|
|
9
|
+
import com.facebook.react.uimanager.JSPointerDispatcher
|
|
10
|
+
import com.facebook.react.uimanager.JSTouchDispatcher
|
|
11
|
+
import com.facebook.react.uimanager.RootView
|
|
12
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
13
|
+
import com.facebook.react.uimanager.UIManagerModule
|
|
14
|
+
import com.facebook.react.uimanager.events.EventDispatcher
|
|
15
|
+
import com.facebook.react.views.view.ReactViewGroup
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* RootViewGroup is the ViewGroup which contains all the children of a Modal. It gets all
|
|
19
|
+
* child information forwarded from ReactModalHostView and uses that to create children. It is
|
|
20
|
+
* also responsible for acting as a RootView and handling touch events. It does this the same way
|
|
21
|
+
* as ReactRootView.
|
|
22
|
+
*
|
|
23
|
+
*
|
|
24
|
+
* To get layout to work properly, we need to layout all the elements within the Modal as if
|
|
25
|
+
* they can fill the entire window. To do that, we need to explicitly set the styleWidth and
|
|
26
|
+
* styleHeight on the LayoutShadowNode to be the window size. This is done through the
|
|
27
|
+
* UIManagerModule, and will then cause the children to layout as if they can fill the window.
|
|
28
|
+
*/
|
|
29
|
+
internal class RootViewGroup(context: Context?) :
|
|
30
|
+
ReactViewGroup(context),
|
|
31
|
+
RootView {
|
|
32
|
+
private var hasAdjustedSize = false
|
|
33
|
+
private var viewWidth = 0
|
|
34
|
+
private var viewHeight = 0
|
|
35
|
+
|
|
36
|
+
private val mJSTouchDispatcher = JSTouchDispatcher(this)
|
|
37
|
+
|
|
38
|
+
private var mJSPointerDispatcher: JSPointerDispatcher? = null
|
|
39
|
+
|
|
40
|
+
var eventDispatcher: EventDispatcher? = null
|
|
41
|
+
|
|
42
|
+
init {
|
|
43
|
+
if (ReactFeatureFlags.dispatchPointerEvents) {
|
|
44
|
+
mJSPointerDispatcher = JSPointerDispatcher(this)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
|
|
49
|
+
super.onSizeChanged(w, h, oldw, oldh)
|
|
50
|
+
|
|
51
|
+
viewWidth = w
|
|
52
|
+
viewHeight = h
|
|
53
|
+
updateFirstChildView()
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
private fun updateFirstChildView() {
|
|
57
|
+
if (childCount > 0) {
|
|
58
|
+
hasAdjustedSize = false
|
|
59
|
+
val viewTag = getChildAt(0).id
|
|
60
|
+
reactContext.runOnNativeModulesQueueThread(
|
|
61
|
+
object : GuardedRunnable(reactContext) {
|
|
62
|
+
override fun runGuarded() {
|
|
63
|
+
val uiManager: UIManagerModule =
|
|
64
|
+
reactContext
|
|
65
|
+
.reactApplicationContext
|
|
66
|
+
.getNativeModule(UIManagerModule::class.java) ?: return
|
|
67
|
+
|
|
68
|
+
uiManager.updateNodeSize(viewTag, viewWidth, viewHeight)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
)
|
|
72
|
+
} else {
|
|
73
|
+
hasAdjustedSize = true
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
override fun addView(child: View, index: Int, params: LayoutParams) {
|
|
78
|
+
super.addView(child, index, params)
|
|
79
|
+
if (hasAdjustedSize) {
|
|
80
|
+
updateFirstChildView()
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
override fun handleException(t: Throwable) {
|
|
85
|
+
reactContext.reactApplicationContext.handleException(RuntimeException(t))
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private val reactContext: ThemedReactContext
|
|
89
|
+
get() = context as ThemedReactContext
|
|
90
|
+
|
|
91
|
+
override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
|
|
92
|
+
mJSTouchDispatcher.handleTouchEvent(event, eventDispatcher)
|
|
93
|
+
mJSPointerDispatcher?.handleMotionEvent(event, eventDispatcher, true)
|
|
94
|
+
return super.onInterceptTouchEvent(event)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
@SuppressLint("ClickableViewAccessibility")
|
|
98
|
+
override fun onTouchEvent(event: MotionEvent): Boolean {
|
|
99
|
+
mJSTouchDispatcher.handleTouchEvent(event, eventDispatcher)
|
|
100
|
+
mJSPointerDispatcher?.handleMotionEvent(event, eventDispatcher, false)
|
|
101
|
+
super.onTouchEvent(event)
|
|
102
|
+
|
|
103
|
+
// In case when there is no children interested in handling touch event, we return true from
|
|
104
|
+
// the root view in order to receive subsequent events related to that gesture
|
|
105
|
+
return true
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
override fun onInterceptHoverEvent(event: MotionEvent): Boolean {
|
|
109
|
+
mJSPointerDispatcher?.handleMotionEvent(event, eventDispatcher, true)
|
|
110
|
+
return super.onHoverEvent(event)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
override fun onHoverEvent(event: MotionEvent): Boolean {
|
|
114
|
+
mJSPointerDispatcher?.handleMotionEvent(event, eventDispatcher, false)
|
|
115
|
+
return super.onHoverEvent(event)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
override fun onChildStartedNativeGesture(childView: View, ev: MotionEvent) {
|
|
119
|
+
mJSTouchDispatcher.onChildStartedNativeGesture(ev, eventDispatcher)
|
|
120
|
+
mJSPointerDispatcher?.onChildStartedNativeGesture(childView, ev, eventDispatcher)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
override fun onChildEndedNativeGesture(childView: View, ev: MotionEvent) {
|
|
124
|
+
mJSTouchDispatcher.onChildEndedNativeGesture(ev, eventDispatcher)
|
|
125
|
+
mJSPointerDispatcher?.onChildEndedNativeGesture()
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
override fun requestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {
|
|
129
|
+
// No-op - override in order to still receive events to onInterceptTouchEvent
|
|
130
|
+
// even when some other view disallow that
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
companion object {
|
|
134
|
+
const val TAG = "TrueSheetView"
|
|
135
|
+
}
|
|
136
|
+
}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
package com.lodev09.truesheet.core
|
|
2
|
+
|
|
3
|
+
import android.graphics.Point
|
|
4
|
+
import android.view.MotionEvent
|
|
5
|
+
import android.view.ViewGroup
|
|
6
|
+
import android.widget.ScrollView
|
|
7
|
+
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
|
8
|
+
import com.facebook.react.uimanager.PixelUtil
|
|
9
|
+
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
|
10
|
+
import com.lodev09.truesheet.utils.toDIP
|
|
11
|
+
|
|
12
|
+
data class SizeInfo(val index: Int, val value: Float)
|
|
13
|
+
|
|
14
|
+
class SheetBehavior<T : ViewGroup> : BottomSheetBehavior<T>() {
|
|
15
|
+
var maxSize: Point = Point()
|
|
16
|
+
|
|
17
|
+
var contentView: ViewGroup? = null
|
|
18
|
+
var footerView: ViewGroup? = null
|
|
19
|
+
|
|
20
|
+
override fun onInterceptTouchEvent(parent: CoordinatorLayout, child: T, event: MotionEvent): Boolean {
|
|
21
|
+
contentView?.let {
|
|
22
|
+
val isDownEvent = (event.actionMasked == MotionEvent.ACTION_DOWN)
|
|
23
|
+
val expanded = state == STATE_EXPANDED
|
|
24
|
+
|
|
25
|
+
if (isDownEvent && expanded) {
|
|
26
|
+
for (i in 0 until it.childCount) {
|
|
27
|
+
val contentChild = it.getChildAt(i)
|
|
28
|
+
val scrolled = (contentChild is ScrollView && contentChild.scrollY > 0)
|
|
29
|
+
|
|
30
|
+
if (!scrolled) continue
|
|
31
|
+
if (isInsideSheet(contentChild as ScrollView, event)) {
|
|
32
|
+
return false
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return super.onInterceptTouchEvent(parent, child, event)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
private fun isInsideSheet(scrollView: ScrollView, event: MotionEvent): Boolean {
|
|
42
|
+
val x = event.x
|
|
43
|
+
val y = event.y
|
|
44
|
+
|
|
45
|
+
val position = IntArray(2)
|
|
46
|
+
scrollView.getLocationOnScreen(position)
|
|
47
|
+
|
|
48
|
+
val nestedX = position[0]
|
|
49
|
+
val nestedY = position[1]
|
|
50
|
+
|
|
51
|
+
val boundRight = nestedX + scrollView.width
|
|
52
|
+
val boundBottom = nestedY + scrollView.height
|
|
53
|
+
|
|
54
|
+
return (x > nestedX && x < boundRight && y > nestedY && y < boundBottom) ||
|
|
55
|
+
event.action == MotionEvent.ACTION_CANCEL
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
private fun getSizeHeight(size: Any, contentHeight: Int): Int {
|
|
59
|
+
val maxHeight = maxSize.y
|
|
60
|
+
|
|
61
|
+
val height =
|
|
62
|
+
when (size) {
|
|
63
|
+
is Double -> PixelUtil.toPixelFromDIP(size).toInt()
|
|
64
|
+
|
|
65
|
+
is Int -> PixelUtil.toPixelFromDIP(size.toDouble()).toInt()
|
|
66
|
+
|
|
67
|
+
is String -> {
|
|
68
|
+
return when (size) {
|
|
69
|
+
"auto" -> contentHeight
|
|
70
|
+
|
|
71
|
+
"large" -> maxHeight
|
|
72
|
+
|
|
73
|
+
"medium" -> (maxHeight * 0.50).toInt()
|
|
74
|
+
|
|
75
|
+
"small" -> (maxHeight * 0.25).toInt()
|
|
76
|
+
|
|
77
|
+
else -> {
|
|
78
|
+
if (size.endsWith('%')) {
|
|
79
|
+
val percent = size.trim('%').toDoubleOrNull()
|
|
80
|
+
return if (percent == null) {
|
|
81
|
+
0
|
|
82
|
+
} else {
|
|
83
|
+
((percent / 100) * maxHeight).toInt()
|
|
84
|
+
}
|
|
85
|
+
} else {
|
|
86
|
+
val fixedHeight = size.toDoubleOrNull()
|
|
87
|
+
return if (fixedHeight == null) {
|
|
88
|
+
0
|
|
89
|
+
} else {
|
|
90
|
+
PixelUtil.toPixelFromDIP(fixedHeight).toInt()
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
else -> (maxHeight * 0.5).toInt()
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return minOf(height, maxHeight)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
fun configure(sizes: Array<Any>) {
|
|
104
|
+
var contentHeight = 0
|
|
105
|
+
|
|
106
|
+
contentView?.let { contentHeight = it.height }
|
|
107
|
+
footerView?.let { contentHeight += it.height }
|
|
108
|
+
|
|
109
|
+
// Configure sheet sizes
|
|
110
|
+
apply {
|
|
111
|
+
isFitToContents = true
|
|
112
|
+
isHideable = true
|
|
113
|
+
skipCollapsed = false
|
|
114
|
+
|
|
115
|
+
when (sizes.size) {
|
|
116
|
+
1 -> {
|
|
117
|
+
maxHeight = getSizeHeight(sizes[0], contentHeight)
|
|
118
|
+
skipCollapsed = true
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
2 -> {
|
|
122
|
+
peekHeight = getSizeHeight(sizes[0], contentHeight)
|
|
123
|
+
maxHeight = getSizeHeight(sizes[1], contentHeight)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
3 -> {
|
|
127
|
+
// Enables half expanded
|
|
128
|
+
isFitToContents = false
|
|
129
|
+
|
|
130
|
+
peekHeight = getSizeHeight(sizes[0], contentHeight)
|
|
131
|
+
halfExpandedRatio = getSizeHeight(sizes[1], contentHeight).toFloat() / maxSize.y.toFloat()
|
|
132
|
+
maxHeight = getSizeHeight(sizes[2], contentHeight)
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
fun getSizeInfoForState(sizeCount: Int, state: Int): SizeInfo? =
|
|
139
|
+
when (sizeCount) {
|
|
140
|
+
1 -> {
|
|
141
|
+
when (state) {
|
|
142
|
+
STATE_EXPANDED -> SizeInfo(0, PixelUtil.toDIPFromPixel(maxHeight.toFloat()))
|
|
143
|
+
else -> null
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
2 -> {
|
|
148
|
+
when (state) {
|
|
149
|
+
STATE_COLLAPSED -> SizeInfo(0, toDIP(peekHeight))
|
|
150
|
+
STATE_EXPANDED -> SizeInfo(1, toDIP(maxHeight))
|
|
151
|
+
else -> null
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
3 -> {
|
|
156
|
+
when (state) {
|
|
157
|
+
STATE_COLLAPSED -> SizeInfo(0, toDIP(peekHeight))
|
|
158
|
+
|
|
159
|
+
STATE_HALF_EXPANDED -> {
|
|
160
|
+
val height = halfExpandedRatio * maxSize.y
|
|
161
|
+
SizeInfo(1, toDIP(height.toInt()))
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
STATE_EXPANDED -> SizeInfo(2, toDIP(maxHeight))
|
|
165
|
+
|
|
166
|
+
else -> null
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
else -> null
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
fun setStateForSizeIndex(sizeCount: Int, index: Int) {
|
|
174
|
+
state =
|
|
175
|
+
when (sizeCount) {
|
|
176
|
+
1 -> STATE_EXPANDED
|
|
177
|
+
|
|
178
|
+
2 -> {
|
|
179
|
+
when (index) {
|
|
180
|
+
0 -> STATE_COLLAPSED
|
|
181
|
+
1 -> STATE_EXPANDED
|
|
182
|
+
else -> STATE_HIDDEN
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
3 -> {
|
|
187
|
+
when (index) {
|
|
188
|
+
0 -> STATE_COLLAPSED
|
|
189
|
+
1 -> STATE_HALF_EXPANDED
|
|
190
|
+
2 -> STATE_EXPANDED
|
|
191
|
+
else -> STATE_HIDDEN
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
else -> STATE_HIDDEN
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
package com.lodev09.truesheet.utils
|
|
2
|
+
|
|
3
|
+
import android.annotation.SuppressLint
|
|
4
|
+
import android.content.Context
|
|
5
|
+
import android.graphics.Point
|
|
6
|
+
import android.view.WindowManager
|
|
7
|
+
import com.facebook.infer.annotation.Assertions
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* To get the size of the screen, we use information from the WindowManager and default Display.
|
|
11
|
+
* We don't use DisplayMetricsHolder, or Display#getSize() because they return values that include
|
|
12
|
+
* the status bar. We only want the values of what will actually be shown on screen. We use
|
|
13
|
+
* Display#getSize() to determine if the screen is in portrait or landscape. We don't use
|
|
14
|
+
* getRotation because the 'natural' rotation will be portrait on phones and landscape on tablets.
|
|
15
|
+
* This should only be called on the native modules/shadow nodes thread.
|
|
16
|
+
*/
|
|
17
|
+
@SuppressLint("DiscouragedApi", "InternalInsetResource")
|
|
18
|
+
fun maxSize(context: Context): Point {
|
|
19
|
+
val minPoint = Point()
|
|
20
|
+
val maxPoint = Point()
|
|
21
|
+
val sizePoint = Point()
|
|
22
|
+
|
|
23
|
+
val wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
|
|
24
|
+
val display = Assertions.assertNotNull(wm).defaultDisplay
|
|
25
|
+
// getCurrentSizeRange will return the min and max width and height that the window can be
|
|
26
|
+
display.getCurrentSizeRange(minPoint, maxPoint)
|
|
27
|
+
// getSize will return the dimensions of the screen in its current orientation
|
|
28
|
+
display.getSize(sizePoint)
|
|
29
|
+
val attrs = intArrayOf(android.R.attr.windowFullscreen)
|
|
30
|
+
val theme = context.theme
|
|
31
|
+
val ta = theme.obtainStyledAttributes(attrs)
|
|
32
|
+
val windowFullscreen = ta.getBoolean(0, false)
|
|
33
|
+
|
|
34
|
+
// We need to add the status bar height to the height if we have a fullscreen window,
|
|
35
|
+
// because Display.getCurrentSizeRange doesn't include it.
|
|
36
|
+
val resources = context.resources
|
|
37
|
+
val statusBarId = resources.getIdentifier("status_bar_height", "dimen", "android")
|
|
38
|
+
var statusBarHeight = 0
|
|
39
|
+
if (windowFullscreen && statusBarId > 0) {
|
|
40
|
+
statusBarHeight = resources.getDimension(statusBarId).toInt()
|
|
41
|
+
}
|
|
42
|
+
return if (sizePoint.x < sizePoint.y) {
|
|
43
|
+
// If we are vertical the width value comes from min width and height comes from max height
|
|
44
|
+
Point(minPoint.x, maxPoint.y + statusBarHeight)
|
|
45
|
+
} else {
|
|
46
|
+
// If we are horizontal the width value comes from max width and height comes from min height
|
|
47
|
+
Point(maxPoint.x, minPoint.y + statusBarHeight)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
package com.lodev09.truesheet.utils
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Promise
|
|
4
|
+
|
|
5
|
+
inline fun withPromise(promise: Promise, closure: () -> Any?) {
|
|
6
|
+
try {
|
|
7
|
+
val result = closure()
|
|
8
|
+
promise.resolve(result)
|
|
9
|
+
} catch (e: Throwable) {
|
|
10
|
+
e.printStackTrace()
|
|
11
|
+
promise.reject("Error", e.message, e.cause)
|
|
12
|
+
}
|
|
13
|
+
}
|
package/ios/TrueSheetView.swift
CHANGED
|
@@ -152,7 +152,7 @@ class TrueSheetView: UIView, RCTInvalidating, TrueSheetViewControllerDelegate {
|
|
|
152
152
|
|
|
153
153
|
@objc
|
|
154
154
|
func setSizes(_ sizes: [Any]) {
|
|
155
|
-
self.sizes = sizes
|
|
155
|
+
self.sizes = Array(sizes.prefix(3))
|
|
156
156
|
configureSheetIfPresented()
|
|
157
157
|
}
|
|
158
158
|
|
|
@@ -178,7 +178,7 @@ class TrueSheetView: UIView, RCTInvalidating, TrueSheetViewControllerDelegate {
|
|
|
178
178
|
func dismiss(promise: Promise) {
|
|
179
179
|
if isPresented {
|
|
180
180
|
viewController.dismiss(animated: true) {
|
|
181
|
-
promise.resolve(
|
|
181
|
+
promise.resolve(nil)
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
184
|
}
|
|
@@ -241,7 +241,7 @@ class TrueSheetView: UIView, RCTInvalidating, TrueSheetViewControllerDelegate {
|
|
|
241
241
|
self.isPresented = true
|
|
242
242
|
self.onPresent?(nil)
|
|
243
243
|
|
|
244
|
-
promise.resolve(
|
|
244
|
+
promise.resolve(nil)
|
|
245
245
|
}
|
|
246
246
|
}
|
|
247
247
|
}
|
|
@@ -37,7 +37,7 @@ class TrueSheet extends _react.PureComponent {
|
|
|
37
37
|
}
|
|
38
38
|
return nodeHandle;
|
|
39
39
|
}
|
|
40
|
-
|
|
40
|
+
updateState() {
|
|
41
41
|
const scrollableHandle = this.props.scrollRef?.current ? (0, _reactNative.findNodeHandle)(this.props.scrollRef.current) : null;
|
|
42
42
|
this.setState({
|
|
43
43
|
scrollableHandle
|
|
@@ -53,10 +53,13 @@ class TrueSheet extends _react.PureComponent {
|
|
|
53
53
|
this.props.onDismiss?.();
|
|
54
54
|
}
|
|
55
55
|
componentDidMount() {
|
|
56
|
-
this.
|
|
56
|
+
if (this.props.sizes && this.props.sizes.length > 3) {
|
|
57
|
+
console.warn('TrueSheet only supports a maximum of 3 sizes; collapsed, half-expanded and expanded. Check your `sizes` prop.');
|
|
58
|
+
}
|
|
59
|
+
this.updateState();
|
|
57
60
|
}
|
|
58
61
|
componentDidUpdate() {
|
|
59
|
-
this.
|
|
62
|
+
this.updateState();
|
|
60
63
|
}
|
|
61
64
|
|
|
62
65
|
/**
|
|
@@ -84,17 +87,21 @@ class TrueSheet extends _react.PureComponent {
|
|
|
84
87
|
onDismiss: this.onDismiss,
|
|
85
88
|
onSizeChange: this.onSizeChange
|
|
86
89
|
}, /*#__PURE__*/_react.default.createElement(_reactNative.View, {
|
|
90
|
+
collapsable: false,
|
|
87
91
|
style: {
|
|
88
92
|
backgroundColor: this.props.backgroundColor ?? 'white'
|
|
89
93
|
}
|
|
90
94
|
}, /*#__PURE__*/_react.default.createElement(_reactNative.View, {
|
|
95
|
+
collapsable: false,
|
|
91
96
|
style: this.props.style
|
|
92
|
-
}, this.props.children), /*#__PURE__*/_react.default.createElement(_reactNative.View,
|
|
97
|
+
}, this.props.children), /*#__PURE__*/_react.default.createElement(_reactNative.View, {
|
|
98
|
+
collapsable: false
|
|
99
|
+
}, !!FooterComponent && /*#__PURE__*/_react.default.createElement(FooterComponent, null))));
|
|
93
100
|
}
|
|
94
101
|
}
|
|
95
102
|
exports.TrueSheet = TrueSheet;
|
|
96
103
|
const $nativeSheet = {
|
|
97
104
|
position: 'absolute',
|
|
98
|
-
zIndex: -
|
|
105
|
+
zIndex: -9999
|
|
99
106
|
};
|
|
100
107
|
//# sourceMappingURL=TrueSheet.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_TrueSheetModule","_getRequireWildcardCache","e","WeakMap","r","t","__esModule","default","has","get","n","__proto__","a","Object","defineProperty","getOwnPropertyDescriptor","u","prototype","hasOwnProperty","call","i","set","LINKING_ERROR","Platform","select","ios","ComponentName","TrueSheetNativeView","requireNativeComponent","Error","TrueSheet","PureComponent","displayName","constructor","props","ref","createRef","onDismiss","bind","onPresent","onSizeChange","state","scrollableHandle","handle","nodeHandle","findNodeHandle","current","
|
|
1
|
+
{"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_TrueSheetModule","_getRequireWildcardCache","e","WeakMap","r","t","__esModule","default","has","get","n","__proto__","a","Object","defineProperty","getOwnPropertyDescriptor","u","prototype","hasOwnProperty","call","i","set","LINKING_ERROR","Platform","select","ios","ComponentName","TrueSheetNativeView","requireNativeComponent","Error","TrueSheet","PureComponent","displayName","constructor","props","ref","createRef","onDismiss","bind","onPresent","onSizeChange","state","scrollableHandle","handle","nodeHandle","findNodeHandle","current","updateState","scrollRef","setState","event","nativeEvent","componentDidMount","sizes","length","console","warn","componentDidUpdate","present","index","TrueSheetModule","dismiss","render","FooterComponent","createElement","style","$nativeSheet","View","collapsable","backgroundColor","children","exports","position","zIndex"],"sourceRoot":"../../src","sources":["TrueSheet.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -9,7 +9,9 @@ const LINKING_ERROR = `The package '@lodev09/react-native-true-sheet' doesn't se
|
|
|
9
9
|
ios: "- You have run 'pod install'\n",
|
|
10
10
|
default: ''
|
|
11
11
|
}) + '- You rebuilt the app after installing the package\n' + '- You are not using Expo Go\n';
|
|
12
|
-
|
|
12
|
+
|
|
13
|
+
// NativeModules automatically resolves 'TrueSheetView' to 'TrueSheetViewModule'
|
|
14
|
+
const TrueSheetModule = exports.TrueSheetModule = _reactNative.NativeModules.TrueSheetView ? _reactNative.NativeModules.TrueSheetView : new Proxy({}, {
|
|
13
15
|
get() {
|
|
14
16
|
throw new Error(LINKING_ERROR);
|
|
15
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_reactNative","require","LINKING_ERROR","Platform","select","ios","default","TrueSheetModule","exports","NativeModules","
|
|
1
|
+
{"version":3,"names":["_reactNative","require","LINKING_ERROR","Platform","select","ios","default","TrueSheetModule","exports","NativeModules","TrueSheetView","Proxy","get","Error"],"sourceRoot":"../../src","sources":["TrueSheetModule.ts"],"mappings":";;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAEA,MAAMC,aAAa,GAChB,2FAA0F,GAC3FC,qBAAQ,CAACC,MAAM,CAAC;EAAEC,GAAG,EAAE,gCAAgC;EAAEC,OAAO,EAAE;AAAG,CAAC,CAAC,GACvE,sDAAsD,GACtD,+BAA+B;;AAEjC;AACO,MAAMC,eAAe,GAAAC,OAAA,CAAAD,eAAA,GAAGE,0BAAa,CAACC,aAAa,GACtDD,0BAAa,CAACC,aAAa,GAC3B,IAAIC,KAAK,CACP,CAAC,CAAC,EACF;EACEC,GAAGA,CAAA,EAAG;IACJ,MAAM,IAAIC,KAAK,CAACX,aAAa,CAAC;EAChC;AACF,CACF,CAAC","ignoreList":[]}
|
package/lib/module/TrueSheet.js
CHANGED
|
@@ -29,7 +29,7 @@ export class TrueSheet extends PureComponent {
|
|
|
29
29
|
}
|
|
30
30
|
return nodeHandle;
|
|
31
31
|
}
|
|
32
|
-
|
|
32
|
+
updateState() {
|
|
33
33
|
const scrollableHandle = this.props.scrollRef?.current ? findNodeHandle(this.props.scrollRef.current) : null;
|
|
34
34
|
this.setState({
|
|
35
35
|
scrollableHandle
|
|
@@ -45,10 +45,13 @@ export class TrueSheet extends PureComponent {
|
|
|
45
45
|
this.props.onDismiss?.();
|
|
46
46
|
}
|
|
47
47
|
componentDidMount() {
|
|
48
|
-
this.
|
|
48
|
+
if (this.props.sizes && this.props.sizes.length > 3) {
|
|
49
|
+
console.warn('TrueSheet only supports a maximum of 3 sizes; collapsed, half-expanded and expanded. Check your `sizes` prop.');
|
|
50
|
+
}
|
|
51
|
+
this.updateState();
|
|
49
52
|
}
|
|
50
53
|
componentDidUpdate() {
|
|
51
|
-
this.
|
|
54
|
+
this.updateState();
|
|
52
55
|
}
|
|
53
56
|
|
|
54
57
|
/**
|
|
@@ -76,16 +79,20 @@ export class TrueSheet extends PureComponent {
|
|
|
76
79
|
onDismiss: this.onDismiss,
|
|
77
80
|
onSizeChange: this.onSizeChange
|
|
78
81
|
}, /*#__PURE__*/React.createElement(View, {
|
|
82
|
+
collapsable: false,
|
|
79
83
|
style: {
|
|
80
84
|
backgroundColor: this.props.backgroundColor ?? 'white'
|
|
81
85
|
}
|
|
82
86
|
}, /*#__PURE__*/React.createElement(View, {
|
|
87
|
+
collapsable: false,
|
|
83
88
|
style: this.props.style
|
|
84
|
-
}, this.props.children), /*#__PURE__*/React.createElement(View,
|
|
89
|
+
}, this.props.children), /*#__PURE__*/React.createElement(View, {
|
|
90
|
+
collapsable: false
|
|
91
|
+
}, !!FooterComponent && /*#__PURE__*/React.createElement(FooterComponent, null))));
|
|
85
92
|
}
|
|
86
93
|
}
|
|
87
94
|
const $nativeSheet = {
|
|
88
95
|
position: 'absolute',
|
|
89
|
-
zIndex: -
|
|
96
|
+
zIndex: -9999
|
|
90
97
|
};
|
|
91
98
|
//# sourceMappingURL=TrueSheet.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","PureComponent","createRef","requireNativeComponent","Platform","findNodeHandle","View","TrueSheetModule","LINKING_ERROR","select","ios","default","ComponentName","TrueSheetNativeView","Error","TrueSheet","displayName","constructor","props","ref","onDismiss","bind","onPresent","onSizeChange","state","scrollableHandle","handle","nodeHandle","current","
|
|
1
|
+
{"version":3,"names":["React","PureComponent","createRef","requireNativeComponent","Platform","findNodeHandle","View","TrueSheetModule","LINKING_ERROR","select","ios","default","ComponentName","TrueSheetNativeView","Error","TrueSheet","displayName","constructor","props","ref","onDismiss","bind","onPresent","onSizeChange","state","scrollableHandle","handle","nodeHandle","current","updateState","scrollRef","setState","event","nativeEvent","componentDidMount","sizes","length","console","warn","componentDidUpdate","present","index","dismiss","render","FooterComponent","createElement","style","$nativeSheet","collapsable","backgroundColor","children","position","zIndex"],"sourceRoot":"../../src","sources":["TrueSheet.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -3,7 +3,9 @@ const LINKING_ERROR = `The package '@lodev09/react-native-true-sheet' doesn't se
|
|
|
3
3
|
ios: "- You have run 'pod install'\n",
|
|
4
4
|
default: ''
|
|
5
5
|
}) + '- You rebuilt the app after installing the package\n' + '- You are not using Expo Go\n';
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
// NativeModules automatically resolves 'TrueSheetView' to 'TrueSheetViewModule'
|
|
8
|
+
export const TrueSheetModule = NativeModules.TrueSheetView ? NativeModules.TrueSheetView : new Proxy({}, {
|
|
7
9
|
get() {
|
|
8
10
|
throw new Error(LINKING_ERROR);
|
|
9
11
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["NativeModules","Platform","LINKING_ERROR","select","ios","default","TrueSheetModule","
|
|
1
|
+
{"version":3,"names":["NativeModules","Platform","LINKING_ERROR","select","ios","default","TrueSheetModule","TrueSheetView","Proxy","get","Error"],"sourceRoot":"../../src","sources":["TrueSheetModule.ts"],"mappings":"AAAA,SAASA,aAAa,EAAEC,QAAQ,QAAQ,cAAc;AAEtD,MAAMC,aAAa,GAChB,2FAA0F,GAC3FD,QAAQ,CAACE,MAAM,CAAC;EAAEC,GAAG,EAAE,gCAAgC;EAAEC,OAAO,EAAE;AAAG,CAAC,CAAC,GACvE,sDAAsD,GACtD,+BAA+B;;AAEjC;AACA,OAAO,MAAMC,eAAe,GAAGN,aAAa,CAACO,aAAa,GACtDP,aAAa,CAACO,aAAa,GAC3B,IAAIC,KAAK,CACP,CAAC,CAAC,EACF;EACEC,GAAGA,CAAA,EAAG;IACJ,MAAM,IAAIC,KAAK,CAACR,aAAa,CAAC;EAChC;AACF,CACF,CAAC","ignoreList":[]}
|
|
@@ -8,7 +8,7 @@ export declare class TrueSheet extends PureComponent<TrueSheetProps, TrueSheetSt
|
|
|
8
8
|
private readonly ref;
|
|
9
9
|
constructor(props: TrueSheetProps);
|
|
10
10
|
private get handle();
|
|
11
|
-
private
|
|
11
|
+
private updateState;
|
|
12
12
|
private onSizeChange;
|
|
13
13
|
private onPresent;
|
|
14
14
|
private onDismiss;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TrueSheet.d.ts","sourceRoot":"","sources":["../../../src/TrueSheet.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,aAAa,EAAwC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAYlG,OAAO,KAAK,EAAE,cAAc,EAAmB,MAAM,SAAS,CAAA;AA6B9D,UAAU,cAAc;IACtB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAA;CAChC;AAED,qBAAa,SAAU,SAAQ,aAAa,CAAC,cAAc,EAAE,cAAc,CAAC;IAC1E,WAAW,SAAc;IAEzB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAsB;gBAE9B,KAAK,EAAE,cAAc;IAcjC,OAAO,KAAK,MAAM,GAOjB;IAED,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"TrueSheet.d.ts","sourceRoot":"","sources":["../../../src/TrueSheet.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,aAAa,EAAwC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAYlG,OAAO,KAAK,EAAE,cAAc,EAAmB,MAAM,SAAS,CAAA;AA6B9D,UAAU,cAAc;IACtB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAA;CAChC;AAED,qBAAa,SAAU,SAAQ,aAAa,CAAC,cAAc,EAAE,cAAc,CAAC;IAC1E,WAAW,SAAc;IAEzB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAsB;gBAE9B,KAAK,EAAE,cAAc;IAcjC,OAAO,KAAK,MAAM,GAOjB;IAED,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,SAAS;IAIjB,iBAAiB,IAAI,IAAI;IAUzB,kBAAkB,IAAI,IAAI;IAI1B;;;OAGG;IACU,OAAO,CAAC,KAAK,GAAE,MAAU;IAItC;;OAEG;IACU,OAAO;IAIpB,MAAM,IAAI,SAAS;CAyBpB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TrueSheetModule.d.ts","sourceRoot":"","sources":["../../../src/TrueSheetModule.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TrueSheetModule.d.ts","sourceRoot":"","sources":["../../../src/TrueSheetModule.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,eAAe,KASvB,CAAA"}
|
|
@@ -57,16 +57,17 @@ export interface TrueSheetProps extends ViewProps {
|
|
|
57
57
|
*/
|
|
58
58
|
backgroundColor?: ColorValue;
|
|
59
59
|
/**
|
|
60
|
-
* The main scrollable ref that Sheet should handle.
|
|
60
|
+
* The main scrollable ref that Sheet should handle on IOS.
|
|
61
|
+
* @platform ios
|
|
61
62
|
*/
|
|
62
63
|
scrollRef?: RefObject<Component<unknown>>;
|
|
63
64
|
/**
|
|
64
65
|
* The sizes you want the Sheet to support.
|
|
65
|
-
*
|
|
66
|
+
* Maximum of 3 sizes only; collapsed, half-expanded, expanded.
|
|
66
67
|
*
|
|
67
68
|
* Example:
|
|
68
69
|
* ```ts
|
|
69
|
-
* size={['auto',
|
|
70
|
+
* size={['auto', '60%', 'large']}
|
|
70
71
|
* ```
|
|
71
72
|
*
|
|
72
73
|
* @default ['medium', 'large']
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAEzD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;AAED;;;GAGG;AACH,MAAM,MAAM,SAAS;AACnB;;;;;GAKG;AACD,MAAM;AAER;;;;;GAKG;GACD,MAAM;AAER;;;;;GAKG;GACD,GAAG,MAAM,GAAG;AAEd;;;;;GAKG;GACD,OAAO;AAET;;;;;GAKG;GACD,QAAQ;AAEV;;;;;GAKG;GACD,OAAO,CAAA;AAEX,MAAM,WAAW,cAAe,SAAQ,SAAS;IAC/C;;OAEG;IACH,eAAe,CAAC,EAAE,UAAU,CAAA;IAE5B
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAEzD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;AAED;;;GAGG;AACH,MAAM,MAAM,SAAS;AACnB;;;;;GAKG;AACD,MAAM;AAER;;;;;GAKG;GACD,MAAM;AAER;;;;;GAKG;GACD,GAAG,MAAM,GAAG;AAEd;;;;;GAKG;GACD,OAAO;AAET;;;;;GAKG;GACD,QAAQ;AAEV;;;;;GAKG;GACD,OAAO,CAAA;AAEX,MAAM,WAAW,cAAe,SAAQ,SAAS;IAC/C;;OAEG;IACH,eAAe,CAAC,EAAE,UAAU,CAAA;IAE5B;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;IAEzC;;;;;;;;;;OAUG;IACH,KAAK,CAAC,EAAE,SAAS,EAAE,CAAA;IAEnB;;OAEG;IACH,eAAe,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAA;IAExC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IAEtB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IAEtB;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAA;CAChD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lodev09/react-native-true-sheet",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "The true native bottom sheet. 💩",
|
|
5
5
|
"main": "lib/commonjs/index",
|
|
6
6
|
"module": "lib/module/index",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"typecheck": "tsc --noEmit",
|
|
32
32
|
"lint": "eslint --fix \"**/*.{js,ts,tsx}\"",
|
|
33
33
|
"format": "prettier --write \"**/*.{js,ts,tsx}\"",
|
|
34
|
-
"tidy": "yarn typecheck && yarn lint && yarn format && scripts/swiftlint.sh && scripts/
|
|
34
|
+
"tidy": "yarn typecheck && yarn lint && yarn format && scripts/swiftlint.sh && scripts/ktlint.sh",
|
|
35
35
|
"clean": "del-cli android/build lib && yarn workspace true-sheet-example clean",
|
|
36
36
|
"prepare": "bob build",
|
|
37
37
|
"release": "release-it"
|
package/src/TrueSheet.tsx
CHANGED
|
@@ -23,12 +23,12 @@ const ComponentName = 'TrueSheetView'
|
|
|
23
23
|
|
|
24
24
|
interface TrueSheetNativeViewProps {
|
|
25
25
|
scrollableHandle: number | null
|
|
26
|
+
style: StyleProp<ViewStyle>
|
|
27
|
+
sizes: TrueSheetProps['sizes']
|
|
28
|
+
children: ReactNode
|
|
26
29
|
onDismiss: () => void
|
|
27
30
|
onPresent: (event: NativeSyntheticEvent<{ index: number }>) => void
|
|
28
31
|
onSizeChange: (event: NativeSyntheticEvent<SizeChangeEvent>) => void
|
|
29
|
-
children: ReactNode
|
|
30
|
-
style: StyleProp<ViewStyle>
|
|
31
|
-
sizes: TrueSheetProps['sizes']
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
const TrueSheetNativeView = requireNativeComponent<TrueSheetNativeViewProps>(ComponentName)
|
|
@@ -71,7 +71,7 @@ export class TrueSheet extends PureComponent<TrueSheetProps, TrueSheetState> {
|
|
|
71
71
|
return nodeHandle
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
private
|
|
74
|
+
private updateState() {
|
|
75
75
|
const scrollableHandle = this.props.scrollRef?.current
|
|
76
76
|
? findNodeHandle(this.props.scrollRef.current)
|
|
77
77
|
: null
|
|
@@ -94,11 +94,17 @@ export class TrueSheet extends PureComponent<TrueSheetProps, TrueSheetState> {
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
componentDidMount(): void {
|
|
97
|
-
this.
|
|
97
|
+
if (this.props.sizes && this.props.sizes.length > 3) {
|
|
98
|
+
console.warn(
|
|
99
|
+
'TrueSheet only supports a maximum of 3 sizes; collapsed, half-expanded and expanded. Check your `sizes` prop.'
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
this.updateState()
|
|
98
104
|
}
|
|
99
105
|
|
|
100
106
|
componentDidUpdate(): void {
|
|
101
|
-
this.
|
|
107
|
+
this.updateState()
|
|
102
108
|
}
|
|
103
109
|
|
|
104
110
|
/**
|
|
@@ -129,9 +135,14 @@ export class TrueSheet extends PureComponent<TrueSheetProps, TrueSheetState> {
|
|
|
129
135
|
onDismiss={this.onDismiss}
|
|
130
136
|
onSizeChange={this.onSizeChange}
|
|
131
137
|
>
|
|
132
|
-
<View
|
|
133
|
-
|
|
134
|
-
|
|
138
|
+
<View
|
|
139
|
+
collapsable={false}
|
|
140
|
+
style={{ backgroundColor: this.props.backgroundColor ?? 'white' }}
|
|
141
|
+
>
|
|
142
|
+
<View collapsable={false} style={this.props.style}>
|
|
143
|
+
{this.props.children}
|
|
144
|
+
</View>
|
|
145
|
+
<View collapsable={false}>{!!FooterComponent && <FooterComponent />}</View>
|
|
135
146
|
</View>
|
|
136
147
|
</TrueSheetNativeView>
|
|
137
148
|
)
|
|
@@ -140,5 +151,5 @@ export class TrueSheet extends PureComponent<TrueSheetProps, TrueSheetState> {
|
|
|
140
151
|
|
|
141
152
|
const $nativeSheet: ViewStyle = {
|
|
142
153
|
position: 'absolute',
|
|
143
|
-
zIndex: -
|
|
154
|
+
zIndex: -9999,
|
|
144
155
|
}
|
package/src/TrueSheetModule.ts
CHANGED
|
@@ -6,8 +6,9 @@ const LINKING_ERROR =
|
|
|
6
6
|
'- You rebuilt the app after installing the package\n' +
|
|
7
7
|
'- You are not using Expo Go\n'
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
// NativeModules automatically resolves 'TrueSheetView' to 'TrueSheetViewModule'
|
|
10
|
+
export const TrueSheetModule = NativeModules.TrueSheetView
|
|
11
|
+
? NativeModules.TrueSheetView
|
|
11
12
|
: new Proxy(
|
|
12
13
|
{},
|
|
13
14
|
{
|
package/src/types.ts
CHANGED
|
@@ -66,17 +66,18 @@ export interface TrueSheetProps extends ViewProps {
|
|
|
66
66
|
backgroundColor?: ColorValue
|
|
67
67
|
|
|
68
68
|
/**
|
|
69
|
-
* The main scrollable ref that Sheet should handle.
|
|
69
|
+
* The main scrollable ref that Sheet should handle on IOS.
|
|
70
|
+
* @platform ios
|
|
70
71
|
*/
|
|
71
72
|
scrollRef?: RefObject<Component<unknown>>
|
|
72
73
|
|
|
73
74
|
/**
|
|
74
75
|
* The sizes you want the Sheet to support.
|
|
75
|
-
*
|
|
76
|
+
* Maximum of 3 sizes only; collapsed, half-expanded, expanded.
|
|
76
77
|
*
|
|
77
78
|
* Example:
|
|
78
79
|
* ```ts
|
|
79
|
-
* size={['auto',
|
|
80
|
+
* size={['auto', '60%', 'large']}
|
|
80
81
|
* ```
|
|
81
82
|
*
|
|
82
83
|
* @default ['medium', 'large']
|