@lodev09/react-native-true-sheet 3.0.0-beta.13 → 3.0.0-beta.15
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/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +20 -20
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewController.kt +49 -14
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt +10 -1
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetDialogObserver.kt +17 -43
- package/android/src/main/java/com/lodev09/truesheet/events/TrueSheetDragEvents.kt +71 -0
- package/android/src/main/java/com/lodev09/truesheet/events/TrueSheetFocusEvents.kt +65 -0
- package/android/src/main/java/com/lodev09/truesheet/events/TrueSheetLifecycleEvents.kt +94 -0
- package/android/src/main/java/com/lodev09/truesheet/events/{PositionChangeEvent.kt → TrueSheetStateEvents.kt} +25 -3
- package/ios/TrueSheetView.mm +39 -25
- package/ios/TrueSheetViewController.h +7 -1
- package/ios/TrueSheetViewController.mm +101 -51
- package/ios/core/TrueSheetBlurView.h +24 -0
- package/ios/{utils/ConversionUtil.mm → core/TrueSheetBlurView.mm} +65 -3
- package/ios/events/TrueSheetDragEvents.h +39 -0
- package/ios/events/TrueSheetDragEvents.mm +62 -0
- package/ios/events/{OnPositionChangeEvent.h → TrueSheetFocusEvents.h} +8 -6
- package/ios/events/TrueSheetFocusEvents.mm +49 -0
- package/ios/events/TrueSheetLifecycleEvents.h +40 -0
- package/ios/events/TrueSheetLifecycleEvents.mm +71 -0
- package/ios/events/TrueSheetStateEvents.h +35 -0
- package/ios/events/TrueSheetStateEvents.mm +49 -0
- package/ios/utils/GestureUtil.h +7 -0
- package/ios/utils/GestureUtil.mm +12 -0
- package/lib/module/TrueSheet.js +12 -0
- package/lib/module/TrueSheet.js.map +1 -1
- package/lib/module/fabric/TrueSheetViewNativeComponent.ts +8 -1
- package/lib/module/reanimated/ReanimatedTrueSheet.js +6 -6
- package/lib/module/reanimated/ReanimatedTrueSheet.js.map +1 -1
- package/lib/typescript/src/TrueSheet.d.ts +2 -0
- package/lib/typescript/src/TrueSheet.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheet.types.d.ts +37 -3
- package/lib/typescript/src/TrueSheet.types.d.ts.map +1 -1
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts +6 -1
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/TrueSheet.tsx +16 -0
- package/src/TrueSheet.types.ts +42 -3
- package/src/fabric/TrueSheetViewNativeComponent.ts +8 -1
- package/src/reanimated/ReanimatedTrueSheet.tsx +6 -6
- package/android/src/main/java/com/lodev09/truesheet/events/BlurEvent.kt +0 -20
- package/android/src/main/java/com/lodev09/truesheet/events/DetentChangeEvent.kt +0 -27
- package/android/src/main/java/com/lodev09/truesheet/events/DidDismissEvent.kt +0 -20
- package/android/src/main/java/com/lodev09/truesheet/events/DidPresentEvent.kt +0 -27
- package/android/src/main/java/com/lodev09/truesheet/events/DragBeginEvent.kt +0 -27
- package/android/src/main/java/com/lodev09/truesheet/events/DragChangeEvent.kt +0 -27
- package/android/src/main/java/com/lodev09/truesheet/events/DragEndEvent.kt +0 -27
- package/android/src/main/java/com/lodev09/truesheet/events/FocusEvent.kt +0 -20
- package/android/src/main/java/com/lodev09/truesheet/events/MountEvent.kt +0 -20
- package/android/src/main/java/com/lodev09/truesheet/events/WillDismissEvent.kt +0 -20
- package/android/src/main/java/com/lodev09/truesheet/events/WillPresentEvent.kt +0 -27
- package/ios/events/OnDetentChangeEvent.h +0 -29
- package/ios/events/OnDetentChangeEvent.mm +0 -32
- package/ios/events/OnDidBlurEvent.h +0 -26
- package/ios/events/OnDidBlurEvent.mm +0 -25
- package/ios/events/OnDidDismissEvent.h +0 -26
- package/ios/events/OnDidDismissEvent.mm +0 -25
- package/ios/events/OnDidFocusEvent.h +0 -26
- package/ios/events/OnDidFocusEvent.mm +0 -25
- package/ios/events/OnDidPresentEvent.h +0 -29
- package/ios/events/OnDidPresentEvent.mm +0 -32
- package/ios/events/OnDragBeginEvent.h +0 -29
- package/ios/events/OnDragBeginEvent.mm +0 -32
- package/ios/events/OnDragChangeEvent.h +0 -29
- package/ios/events/OnDragChangeEvent.mm +0 -32
- package/ios/events/OnDragEndEvent.h +0 -29
- package/ios/events/OnDragEndEvent.mm +0 -32
- package/ios/events/OnMountEvent.h +0 -26
- package/ios/events/OnMountEvent.mm +0 -25
- package/ios/events/OnPositionChangeEvent.mm +0 -34
- package/ios/events/OnWillDismissEvent.h +0 -26
- package/ios/events/OnWillDismissEvent.mm +0 -25
- package/ios/events/OnWillPresentEvent.h +0 -29
- package/ios/events/OnWillPresentEvent.mm +0 -32
- package/ios/utils/ConversionUtil.h +0 -24
|
@@ -14,18 +14,7 @@ import com.facebook.react.uimanager.UIManagerHelper
|
|
|
14
14
|
import com.facebook.react.uimanager.events.EventDispatcher
|
|
15
15
|
import com.facebook.react.views.view.ReactViewGroup
|
|
16
16
|
import com.lodev09.truesheet.core.TrueSheetDialogObserver
|
|
17
|
-
import com.lodev09.truesheet.events
|
|
18
|
-
import com.lodev09.truesheet.events.DetentChangeEvent
|
|
19
|
-
import com.lodev09.truesheet.events.DidDismissEvent
|
|
20
|
-
import com.lodev09.truesheet.events.DidPresentEvent
|
|
21
|
-
import com.lodev09.truesheet.events.DragBeginEvent
|
|
22
|
-
import com.lodev09.truesheet.events.DragChangeEvent
|
|
23
|
-
import com.lodev09.truesheet.events.DragEndEvent
|
|
24
|
-
import com.lodev09.truesheet.events.FocusEvent
|
|
25
|
-
import com.lodev09.truesheet.events.MountEvent
|
|
26
|
-
import com.lodev09.truesheet.events.PositionChangeEvent
|
|
27
|
-
import com.lodev09.truesheet.events.WillDismissEvent
|
|
28
|
-
import com.lodev09.truesheet.events.WillPresentEvent
|
|
17
|
+
import com.lodev09.truesheet.events.*
|
|
29
18
|
|
|
30
19
|
/**
|
|
31
20
|
* Main TrueSheet host view that manages the sheet dialog and dispatches events to JavaScript.
|
|
@@ -187,12 +176,11 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
|
|
|
187
176
|
containerView?.footerView?.eventDispatcher = null
|
|
188
177
|
}
|
|
189
178
|
|
|
190
|
-
override fun viewControllerDidDismiss() {
|
|
179
|
+
override fun viewControllerDidDismiss(hadParent: Boolean) {
|
|
191
180
|
val surfaceId = UIManagerHelper.getSurfaceId(this)
|
|
192
181
|
eventDispatcher?.dispatchEvent(DidDismissEvent(surfaceId, id))
|
|
193
182
|
|
|
194
|
-
|
|
195
|
-
TrueSheetDialogObserver.onSheetDidDismiss(this)
|
|
183
|
+
TrueSheetDialogObserver.onSheetDidDismiss(this, hadParent)
|
|
196
184
|
}
|
|
197
185
|
|
|
198
186
|
override fun viewControllerDidChangeDetent(index: Int, position: Float, detent: Float) {
|
|
@@ -215,20 +203,30 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
|
|
|
215
203
|
eventDispatcher?.dispatchEvent(DragEndEvent(surfaceId, id, index, position, detent))
|
|
216
204
|
}
|
|
217
205
|
|
|
218
|
-
override fun viewControllerDidChangePosition(index: Float, position: Float, detent: Float,
|
|
206
|
+
override fun viewControllerDidChangePosition(index: Float, position: Float, detent: Float, realtime: Boolean) {
|
|
219
207
|
val surfaceId = UIManagerHelper.getSurfaceId(this)
|
|
220
|
-
eventDispatcher?.dispatchEvent(PositionChangeEvent(surfaceId, id, index, position, detent,
|
|
208
|
+
eventDispatcher?.dispatchEvent(PositionChangeEvent(surfaceId, id, index, position, detent, realtime))
|
|
221
209
|
}
|
|
222
210
|
|
|
223
211
|
override fun viewControllerDidChangeSize(width: Int, height: Int) {
|
|
224
212
|
updateState(width, height)
|
|
225
213
|
}
|
|
226
214
|
|
|
215
|
+
override fun viewControllerWillFocus() {
|
|
216
|
+
val surfaceId = UIManagerHelper.getSurfaceId(this)
|
|
217
|
+
eventDispatcher?.dispatchEvent(WillFocusEvent(surfaceId, id))
|
|
218
|
+
}
|
|
219
|
+
|
|
227
220
|
override fun viewControllerDidFocus() {
|
|
228
221
|
val surfaceId = UIManagerHelper.getSurfaceId(this)
|
|
229
222
|
eventDispatcher?.dispatchEvent(FocusEvent(surfaceId, id))
|
|
230
223
|
}
|
|
231
224
|
|
|
225
|
+
override fun viewControllerWillBlur() {
|
|
226
|
+
val surfaceId = UIManagerHelper.getSurfaceId(this)
|
|
227
|
+
eventDispatcher?.dispatchEvent(WillBlurEvent(surfaceId, id))
|
|
228
|
+
}
|
|
229
|
+
|
|
232
230
|
override fun viewControllerDidBlur() {
|
|
233
231
|
val surfaceId = UIManagerHelper.getSurfaceId(this)
|
|
234
232
|
eventDispatcher?.dispatchEvent(BlurEvent(surfaceId, id))
|
|
@@ -275,6 +273,10 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
|
|
|
275
273
|
viewController.dismissible = dismissible
|
|
276
274
|
}
|
|
277
275
|
|
|
276
|
+
fun setDraggable(draggable: Boolean) {
|
|
277
|
+
viewController.draggable = draggable
|
|
278
|
+
}
|
|
279
|
+
|
|
278
280
|
fun setGrabber(grabber: Boolean) {
|
|
279
281
|
viewController.grabber = grabber
|
|
280
282
|
}
|
|
@@ -309,11 +311,9 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
|
|
|
309
311
|
|
|
310
312
|
@UiThread
|
|
311
313
|
fun present(detentIndex: Int, animated: Boolean = true, promiseCallback: () -> Unit) {
|
|
312
|
-
// Notify observer that this sheet will present (will hide/blur topmost sheet)
|
|
313
314
|
if (!viewController.isPresented) {
|
|
314
|
-
TrueSheetDialogObserver.onSheetWillPresent(this, detentIndex)
|
|
315
|
+
viewController.parentSheetView = TrueSheetDialogObserver.onSheetWillPresent(this, detentIndex)
|
|
315
316
|
}
|
|
316
|
-
|
|
317
317
|
viewController.presentPromise = promiseCallback
|
|
318
318
|
viewController.present(detentIndex, animated)
|
|
319
319
|
}
|
|
@@ -34,14 +34,16 @@ interface TrueSheetViewControllerDelegate {
|
|
|
34
34
|
fun viewControllerWillPresent(index: Int, position: Float, detent: Float)
|
|
35
35
|
fun viewControllerDidPresent(index: Int, position: Float, detent: Float)
|
|
36
36
|
fun viewControllerWillDismiss()
|
|
37
|
-
fun viewControllerDidDismiss()
|
|
37
|
+
fun viewControllerDidDismiss(hadParent: Boolean)
|
|
38
38
|
fun viewControllerDidChangeDetent(index: Int, position: Float, detent: Float)
|
|
39
39
|
fun viewControllerDidDragBegin(index: Int, position: Float, detent: Float)
|
|
40
40
|
fun viewControllerDidDragChange(index: Int, position: Float, detent: Float)
|
|
41
41
|
fun viewControllerDidDragEnd(index: Int, position: Float, detent: Float)
|
|
42
|
-
fun viewControllerDidChangePosition(index: Float, position: Float, detent: Float,
|
|
42
|
+
fun viewControllerDidChangePosition(index: Float, position: Float, detent: Float, realtime: Boolean)
|
|
43
43
|
fun viewControllerDidChangeSize(width: Int, height: Int)
|
|
44
|
+
fun viewControllerWillFocus()
|
|
44
45
|
fun viewControllerDidFocus()
|
|
46
|
+
fun viewControllerWillBlur()
|
|
45
47
|
fun viewControllerDidBlur()
|
|
46
48
|
}
|
|
47
49
|
|
|
@@ -109,6 +111,9 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
109
111
|
var isPresented = false
|
|
110
112
|
private set
|
|
111
113
|
|
|
114
|
+
var isDialogVisible = false
|
|
115
|
+
private set
|
|
116
|
+
|
|
112
117
|
var currentDetentIndex: Int = -1
|
|
113
118
|
private set
|
|
114
119
|
|
|
@@ -119,6 +124,9 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
119
124
|
var presentPromise: (() -> Unit)? = null
|
|
120
125
|
var dismissPromise: (() -> Unit)? = null
|
|
121
126
|
|
|
127
|
+
// Reference to parent TrueSheetView (if presented from another sheet)
|
|
128
|
+
var parentSheetView: TrueSheetView? = null
|
|
129
|
+
|
|
122
130
|
// ====================================================================
|
|
123
131
|
// MARK: - Configuration Properties
|
|
124
132
|
// ====================================================================
|
|
@@ -145,6 +153,12 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
145
153
|
}
|
|
146
154
|
}
|
|
147
155
|
|
|
156
|
+
var draggable: Boolean = true
|
|
157
|
+
set(value) {
|
|
158
|
+
field = value
|
|
159
|
+
behavior?.isDraggable = value
|
|
160
|
+
}
|
|
161
|
+
|
|
148
162
|
// ====================================================================
|
|
149
163
|
// MARK: - Computed Properties
|
|
150
164
|
// ====================================================================
|
|
@@ -226,6 +240,7 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
226
240
|
setCanceledOnTouchOutside(dismissible)
|
|
227
241
|
setCancelable(dismissible)
|
|
228
242
|
behavior.isHideable = dismissible
|
|
243
|
+
behavior.isDraggable = draggable
|
|
229
244
|
}
|
|
230
245
|
}
|
|
231
246
|
|
|
@@ -242,12 +257,14 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
242
257
|
dialog = null
|
|
243
258
|
isDragging = false
|
|
244
259
|
isPresented = false
|
|
260
|
+
isDialogVisible = false
|
|
245
261
|
lastEmittedPositionPx = -1
|
|
246
262
|
}
|
|
247
263
|
|
|
248
264
|
private fun setupDialogListeners(dialog: BottomSheetDialog) {
|
|
249
265
|
dialog.setOnShowListener {
|
|
250
266
|
isPresented = true
|
|
267
|
+
isDialogVisible = true
|
|
251
268
|
resetAnimation()
|
|
252
269
|
setupBackground()
|
|
253
270
|
setupGrabber()
|
|
@@ -257,7 +274,10 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
257
274
|
val detent = getDetentValueForIndex(detentInfo.index)
|
|
258
275
|
val positionPx = bottomSheetView?.let { ScreenUtils.getScreenY(it) } ?: screenHeight
|
|
259
276
|
delegate?.viewControllerDidPresent(detentInfo.index, detentInfo.position, detent)
|
|
260
|
-
emitChangePositionDelegate(detentInfo.index, positionPx,
|
|
277
|
+
emitChangePositionDelegate(detentInfo.index, positionPx, realtime = false)
|
|
278
|
+
|
|
279
|
+
// Notify parent sheet that it has lost focus (after this sheet appeared)
|
|
280
|
+
parentSheetView?.viewControllerDidBlur()
|
|
261
281
|
|
|
262
282
|
presentPromise?.invoke()
|
|
263
283
|
presentPromise = null
|
|
@@ -267,13 +287,22 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
267
287
|
}
|
|
268
288
|
|
|
269
289
|
dialog.setOnCancelListener {
|
|
290
|
+
// Notify parent sheet that it is about to regain focus
|
|
291
|
+
parentSheetView?.viewControllerWillFocus()
|
|
292
|
+
|
|
270
293
|
delegate?.viewControllerWillDismiss()
|
|
271
294
|
}
|
|
272
295
|
|
|
273
296
|
dialog.setOnDismissListener {
|
|
297
|
+
val hadParent = parentSheetView != null
|
|
298
|
+
|
|
299
|
+
// Notify parent sheet that it has regained focus
|
|
300
|
+
parentSheetView?.viewControllerDidFocus()
|
|
301
|
+
parentSheetView = null
|
|
302
|
+
|
|
274
303
|
dismissPromise?.invoke()
|
|
275
304
|
dismissPromise = null
|
|
276
|
-
delegate?.viewControllerDidDismiss()
|
|
305
|
+
delegate?.viewControllerDidDismiss(hadParent)
|
|
277
306
|
cleanupDialog()
|
|
278
307
|
}
|
|
279
308
|
}
|
|
@@ -286,7 +315,7 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
286
315
|
val positionPx = getCurrentPositionPx(sheetView)
|
|
287
316
|
val detentIndex = getDetentIndexForPosition(positionPx)
|
|
288
317
|
|
|
289
|
-
emitChangePositionDelegate(detentIndex, positionPx,
|
|
318
|
+
emitChangePositionDelegate(detentIndex, positionPx, realtime = true)
|
|
290
319
|
|
|
291
320
|
when (behavior.state) {
|
|
292
321
|
BottomSheetBehavior.STATE_DRAGGING,
|
|
@@ -374,13 +403,14 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
374
403
|
|
|
375
404
|
/**
|
|
376
405
|
* Hides the dialog without dismissing it.
|
|
377
|
-
* Used when another TrueSheet presents on top.
|
|
406
|
+
* Used when another TrueSheet presents on top or when RN screen is presented.
|
|
378
407
|
*/
|
|
379
408
|
fun hideDialog() {
|
|
409
|
+
isDialogVisible = false
|
|
380
410
|
dialog?.window?.decorView?.visibility = View.INVISIBLE
|
|
381
411
|
|
|
382
412
|
// Emit off-screen position (detent = 0 since sheet is fully hidden)
|
|
383
|
-
emitChangePositionDelegate(currentDetentIndex, screenHeight,
|
|
413
|
+
emitChangePositionDelegate(currentDetentIndex, screenHeight, realtime = false)
|
|
384
414
|
}
|
|
385
415
|
|
|
386
416
|
/**
|
|
@@ -388,11 +418,12 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
388
418
|
* Used when the sheet on top dismisses.
|
|
389
419
|
*/
|
|
390
420
|
fun showDialog() {
|
|
421
|
+
isDialogVisible = true
|
|
391
422
|
dialog?.window?.decorView?.visibility = View.VISIBLE
|
|
392
423
|
|
|
393
424
|
// Emit current position
|
|
394
425
|
val positionPx = bottomSheetView?.let { ScreenUtils.getScreenY(it) } ?: screenHeight
|
|
395
|
-
emitChangePositionDelegate(currentDetentIndex, positionPx,
|
|
426
|
+
emitChangePositionDelegate(currentDetentIndex, positionPx, realtime = false)
|
|
396
427
|
}
|
|
397
428
|
|
|
398
429
|
// ====================================================================
|
|
@@ -420,6 +451,10 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
420
451
|
|
|
421
452
|
val detentInfo = getDetentInfoForIndex(detentIndex)
|
|
422
453
|
val detent = getDetentValueForIndex(detentInfo.index)
|
|
454
|
+
|
|
455
|
+
// Notify parent sheet that it is about to lose focus (before this sheet appears)
|
|
456
|
+
parentSheetView?.viewControllerWillBlur()
|
|
457
|
+
|
|
423
458
|
delegate?.viewControllerWillPresent(detentInfo.index, detentInfo.position, detent)
|
|
424
459
|
|
|
425
460
|
if (!animated) {
|
|
@@ -433,7 +468,7 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
433
468
|
fun dismiss() {
|
|
434
469
|
this.post {
|
|
435
470
|
// Emit off-screen position (detent = 0 since sheet is fully hidden)
|
|
436
|
-
emitChangePositionDelegate(currentDetentIndex, screenHeight,
|
|
471
|
+
emitChangePositionDelegate(currentDetentIndex, screenHeight, realtime = false)
|
|
437
472
|
}
|
|
438
473
|
dialog?.dismiss()
|
|
439
474
|
}
|
|
@@ -487,7 +522,7 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
487
522
|
bottomSheet.removeView(it)
|
|
488
523
|
}
|
|
489
524
|
|
|
490
|
-
if (!grabber) return
|
|
525
|
+
if (!grabber || !draggable) return
|
|
491
526
|
|
|
492
527
|
val grabberView = View(reactContext).apply {
|
|
493
528
|
tag = GRABBER_TAG
|
|
@@ -607,16 +642,16 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
607
642
|
* Emits position change to the delegate if the position has changed.
|
|
608
643
|
* @param index The current detent index (discrete, used as fallback)
|
|
609
644
|
* @param positionPx The current position in pixels (screen Y coordinate)
|
|
610
|
-
* @param
|
|
645
|
+
* @param realtime Whether the position is a real-time value (during drag or animation tracking)
|
|
611
646
|
*/
|
|
612
|
-
private fun emitChangePositionDelegate(index: Int, positionPx: Int,
|
|
647
|
+
private fun emitChangePositionDelegate(index: Int, positionPx: Int, realtime: Boolean) {
|
|
613
648
|
if (positionPx == lastEmittedPositionPx) return
|
|
614
649
|
|
|
615
650
|
lastEmittedPositionPx = positionPx
|
|
616
651
|
val position = positionPx.pxToDp()
|
|
617
652
|
val interpolatedIndex = getInterpolatedIndexForPosition(positionPx)
|
|
618
653
|
val detent = getDetentValueForIndex(kotlin.math.round(interpolatedIndex).toInt())
|
|
619
|
-
delegate?.viewControllerDidChangePosition(interpolatedIndex, position, detent,
|
|
654
|
+
delegate?.viewControllerDidChangePosition(interpolatedIndex, position, detent, realtime)
|
|
620
655
|
}
|
|
621
656
|
|
|
622
657
|
/**
|
|
@@ -835,7 +870,7 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
835
870
|
this.post {
|
|
836
871
|
positionFooter()
|
|
837
872
|
val positionPx = bottomSheetView?.let { ScreenUtils.getScreenY(it) } ?: screenHeight
|
|
838
|
-
emitChangePositionDelegate(currentDetentIndex, positionPx,
|
|
873
|
+
emitChangePositionDelegate(currentDetentIndex, positionPx, realtime = false)
|
|
839
874
|
}
|
|
840
875
|
}
|
|
841
876
|
}
|
|
@@ -67,7 +67,11 @@ class TrueSheetViewManager :
|
|
|
67
67
|
DragBeginEvent.EVENT_NAME to hashMapOf("registrationName" to DragBeginEvent.REGISTRATION_NAME),
|
|
68
68
|
DragChangeEvent.EVENT_NAME to hashMapOf("registrationName" to DragChangeEvent.REGISTRATION_NAME),
|
|
69
69
|
DragEndEvent.EVENT_NAME to hashMapOf("registrationName" to DragEndEvent.REGISTRATION_NAME),
|
|
70
|
-
PositionChangeEvent.EVENT_NAME to hashMapOf("registrationName" to PositionChangeEvent.REGISTRATION_NAME)
|
|
70
|
+
PositionChangeEvent.EVENT_NAME to hashMapOf("registrationName" to PositionChangeEvent.REGISTRATION_NAME),
|
|
71
|
+
WillFocusEvent.EVENT_NAME to hashMapOf("registrationName" to WillFocusEvent.REGISTRATION_NAME),
|
|
72
|
+
FocusEvent.EVENT_NAME to hashMapOf("registrationName" to FocusEvent.REGISTRATION_NAME),
|
|
73
|
+
WillBlurEvent.EVENT_NAME to hashMapOf("registrationName" to WillBlurEvent.REGISTRATION_NAME),
|
|
74
|
+
BlurEvent.EVENT_NAME to hashMapOf("registrationName" to BlurEvent.REGISTRATION_NAME)
|
|
71
75
|
)
|
|
72
76
|
|
|
73
77
|
// ==================== Props ====================
|
|
@@ -110,6 +114,11 @@ class TrueSheetViewManager :
|
|
|
110
114
|
view.setDismissible(dismissible)
|
|
111
115
|
}
|
|
112
116
|
|
|
117
|
+
@ReactProp(name = "draggable", defaultBoolean = true)
|
|
118
|
+
override fun setDraggable(view: TrueSheetView, draggable: Boolean) {
|
|
119
|
+
view.setDraggable(draggable)
|
|
120
|
+
}
|
|
121
|
+
|
|
113
122
|
@ReactProp(name = "dimmed", defaultBoolean = true)
|
|
114
123
|
override fun setDimmed(view: TrueSheetView, dimmed: Boolean) {
|
|
115
124
|
view.setDimmed(dimmed)
|
|
@@ -3,76 +3,54 @@ package com.lodev09.truesheet.core
|
|
|
3
3
|
import com.lodev09.truesheet.TrueSheetView
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* when sheets are presented on top of each other.
|
|
6
|
+
* Manages TrueSheet stacking behavior.
|
|
7
|
+
* Tracks presented sheets and handles visibility when sheets stack on top of each other.
|
|
9
8
|
*/
|
|
10
9
|
object TrueSheetDialogObserver {
|
|
11
10
|
|
|
12
|
-
/**
|
|
13
|
-
* Stack of currently presented sheet views (most recent on top)
|
|
14
|
-
*/
|
|
15
11
|
private val presentedSheetStack = mutableListOf<TrueSheetView>()
|
|
16
12
|
|
|
17
13
|
/**
|
|
18
14
|
* Called when a sheet is about to be presented.
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* @param sheetView The sheet that is about to be presented
|
|
22
|
-
* @param detentIndex The detent index the sheet will be presented at
|
|
15
|
+
* Returns the visible parent sheet to stack on, or null if none.
|
|
23
16
|
*/
|
|
24
17
|
@JvmStatic
|
|
25
|
-
fun onSheetWillPresent(sheetView: TrueSheetView, detentIndex: Int) {
|
|
18
|
+
fun onSheetWillPresent(sheetView: TrueSheetView, detentIndex: Int): TrueSheetView? {
|
|
26
19
|
synchronized(presentedSheetStack) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
// Hide and blur the topmost sheet if it exists
|
|
31
|
-
topSheet?.let {
|
|
32
|
-
// Don't hide if the top sheet is fully expanded (covers the screen)
|
|
33
|
-
// or if the top sheet is smaller than the presenting sheet
|
|
34
|
-
// A smaller topSheetTop value means the sheet is taller (closer to top of screen)
|
|
35
|
-
val topSheetTop = it.viewController.currentSheetTop
|
|
36
|
-
val presentingSheetTop = sheetView.viewController.getExpectedSheetTop(detentIndex)
|
|
20
|
+
val parentSheet = presentedSheetStack.lastOrNull()
|
|
21
|
+
?.takeIf { it.viewController.isPresented && it.viewController.isDialogVisible }
|
|
37
22
|
|
|
38
|
-
|
|
23
|
+
// Hide parent if the new sheet would cover it
|
|
24
|
+
parentSheet?.let {
|
|
25
|
+
val parentTop = it.viewController.currentSheetTop
|
|
26
|
+
val newSheetTop = sheetView.viewController.getExpectedSheetTop(detentIndex)
|
|
27
|
+
if (!it.viewController.isExpanded && parentTop <= newSheetTop) {
|
|
39
28
|
it.viewController.hideDialog()
|
|
40
29
|
}
|
|
41
|
-
it.viewControllerDidBlur()
|
|
42
30
|
}
|
|
43
31
|
|
|
44
|
-
// Add new sheet to stack
|
|
45
32
|
if (!presentedSheetStack.contains(sheetView)) {
|
|
46
33
|
presentedSheetStack.add(sheetView)
|
|
47
34
|
}
|
|
35
|
+
|
|
36
|
+
return parentSheet
|
|
48
37
|
}
|
|
49
38
|
}
|
|
50
39
|
|
|
51
40
|
/**
|
|
52
41
|
* Called when a sheet has been dismissed.
|
|
53
|
-
* Shows
|
|
54
|
-
*
|
|
55
|
-
* @param sheetView The sheet that was dismissed
|
|
42
|
+
* Shows the parent sheet if this sheet was stacked on it.
|
|
56
43
|
*/
|
|
57
44
|
@JvmStatic
|
|
58
|
-
fun onSheetDidDismiss(sheetView: TrueSheetView) {
|
|
45
|
+
fun onSheetDidDismiss(sheetView: TrueSheetView, hadParent: Boolean) {
|
|
59
46
|
synchronized(presentedSheetStack) {
|
|
60
47
|
presentedSheetStack.remove(sheetView)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
presentedSheetStack.lastOrNull()?.let {
|
|
64
|
-
it.viewController.showDialog()
|
|
65
|
-
it.viewControllerDidFocus()
|
|
48
|
+
if (hadParent) {
|
|
49
|
+
presentedSheetStack.lastOrNull()?.viewController?.showDialog()
|
|
66
50
|
}
|
|
67
51
|
}
|
|
68
52
|
}
|
|
69
53
|
|
|
70
|
-
/**
|
|
71
|
-
* Removes a sheet from the stack without triggering focus events.
|
|
72
|
-
* Used when a sheet is being destroyed/cleaned up.
|
|
73
|
-
*
|
|
74
|
-
* @param sheetView The sheet to remove
|
|
75
|
-
*/
|
|
76
54
|
@JvmStatic
|
|
77
55
|
fun removeSheet(sheetView: TrueSheetView) {
|
|
78
56
|
synchronized(presentedSheetStack) {
|
|
@@ -80,10 +58,6 @@ object TrueSheetDialogObserver {
|
|
|
80
58
|
}
|
|
81
59
|
}
|
|
82
60
|
|
|
83
|
-
/**
|
|
84
|
-
* Clears all tracked sheets.
|
|
85
|
-
* Used when the module is invalidated.
|
|
86
|
-
*/
|
|
87
61
|
@JvmStatic
|
|
88
62
|
fun clear() {
|
|
89
63
|
synchronized(presentedSheetStack) {
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
package com.lodev09.truesheet.events
|
|
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
|
+
/**
|
|
8
|
+
* Fired when dragging begins
|
|
9
|
+
* Payload: { index: number, position: number, detent: number }
|
|
10
|
+
*/
|
|
11
|
+
class DragBeginEvent(surfaceId: Int, viewId: Int, private val index: Int, private val position: Float, private val detent: Float) :
|
|
12
|
+
Event<DragBeginEvent>(surfaceId, viewId) {
|
|
13
|
+
|
|
14
|
+
override fun getEventName(): String = EVENT_NAME
|
|
15
|
+
|
|
16
|
+
override fun getEventData(): WritableMap =
|
|
17
|
+
Arguments.createMap().apply {
|
|
18
|
+
putInt("index", index)
|
|
19
|
+
putDouble("position", position.toDouble())
|
|
20
|
+
putDouble("detent", detent.toDouble())
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
companion object {
|
|
24
|
+
const val EVENT_NAME = "topDragBegin"
|
|
25
|
+
const val REGISTRATION_NAME = "onDragBegin"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Fired continuously during dragging
|
|
31
|
+
* Payload: { index: number, position: number, detent: number }
|
|
32
|
+
*/
|
|
33
|
+
class DragChangeEvent(surfaceId: Int, viewId: Int, private val index: Int, private val position: Float, private val detent: Float) :
|
|
34
|
+
Event<DragChangeEvent>(surfaceId, viewId) {
|
|
35
|
+
|
|
36
|
+
override fun getEventName(): String = EVENT_NAME
|
|
37
|
+
|
|
38
|
+
override fun getEventData(): WritableMap =
|
|
39
|
+
Arguments.createMap().apply {
|
|
40
|
+
putInt("index", index)
|
|
41
|
+
putDouble("position", position.toDouble())
|
|
42
|
+
putDouble("detent", detent.toDouble())
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
companion object {
|
|
46
|
+
const val EVENT_NAME = "topDragChange"
|
|
47
|
+
const val REGISTRATION_NAME = "onDragChange"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Fired when dragging ends
|
|
53
|
+
* Payload: { index: number, position: number, detent: number }
|
|
54
|
+
*/
|
|
55
|
+
class DragEndEvent(surfaceId: Int, viewId: Int, private val index: Int, private val position: Float, private val detent: Float) :
|
|
56
|
+
Event<DragEndEvent>(surfaceId, viewId) {
|
|
57
|
+
|
|
58
|
+
override fun getEventName(): String = EVENT_NAME
|
|
59
|
+
|
|
60
|
+
override fun getEventData(): WritableMap =
|
|
61
|
+
Arguments.createMap().apply {
|
|
62
|
+
putInt("index", index)
|
|
63
|
+
putDouble("position", position.toDouble())
|
|
64
|
+
putDouble("detent", detent.toDouble())
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
companion object {
|
|
68
|
+
const val EVENT_NAME = "topDragEnd"
|
|
69
|
+
const val REGISTRATION_NAME = "onDragEnd"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
package com.lodev09.truesheet.events
|
|
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
|
+
/**
|
|
8
|
+
* Fired when the sheet is about to regain focus because a sheet on top of it is being dismissed
|
|
9
|
+
*/
|
|
10
|
+
class WillFocusEvent(surfaceId: Int, viewId: Int) : Event<WillFocusEvent>(surfaceId, viewId) {
|
|
11
|
+
|
|
12
|
+
override fun getEventName(): String = EVENT_NAME
|
|
13
|
+
|
|
14
|
+
override fun getEventData(): WritableMap = Arguments.createMap()
|
|
15
|
+
|
|
16
|
+
companion object {
|
|
17
|
+
const val EVENT_NAME = "topWillFocus"
|
|
18
|
+
const val REGISTRATION_NAME = "onWillFocus"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Fired when the sheet regains focus after a sheet on top of it is dismissed
|
|
24
|
+
*/
|
|
25
|
+
class FocusEvent(surfaceId: Int, viewId: Int) : Event<FocusEvent>(surfaceId, viewId) {
|
|
26
|
+
|
|
27
|
+
override fun getEventName(): String = EVENT_NAME
|
|
28
|
+
|
|
29
|
+
override fun getEventData(): WritableMap = Arguments.createMap()
|
|
30
|
+
|
|
31
|
+
companion object {
|
|
32
|
+
const val EVENT_NAME = "topDidFocus"
|
|
33
|
+
const val REGISTRATION_NAME = "onDidFocus"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Fired when the sheet is about to lose focus because another sheet is being presented on top of it
|
|
39
|
+
*/
|
|
40
|
+
class WillBlurEvent(surfaceId: Int, viewId: Int) : Event<WillBlurEvent>(surfaceId, viewId) {
|
|
41
|
+
|
|
42
|
+
override fun getEventName(): String = EVENT_NAME
|
|
43
|
+
|
|
44
|
+
override fun getEventData(): WritableMap = Arguments.createMap()
|
|
45
|
+
|
|
46
|
+
companion object {
|
|
47
|
+
const val EVENT_NAME = "topWillBlur"
|
|
48
|
+
const val REGISTRATION_NAME = "onWillBlur"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Fired when the sheet loses focus because another sheet is presented on top of it
|
|
54
|
+
*/
|
|
55
|
+
class BlurEvent(surfaceId: Int, viewId: Int) : Event<BlurEvent>(surfaceId, viewId) {
|
|
56
|
+
|
|
57
|
+
override fun getEventName(): String = EVENT_NAME
|
|
58
|
+
|
|
59
|
+
override fun getEventData(): WritableMap = Arguments.createMap()
|
|
60
|
+
|
|
61
|
+
companion object {
|
|
62
|
+
const val EVENT_NAME = "topDidBlur"
|
|
63
|
+
const val REGISTRATION_NAME = "onDidBlur"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
package com.lodev09.truesheet.events
|
|
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
|
+
/**
|
|
8
|
+
* Fired when the sheet component is mounted and ready
|
|
9
|
+
*/
|
|
10
|
+
class MountEvent(surfaceId: Int, viewId: Int) : Event<MountEvent>(surfaceId, viewId) {
|
|
11
|
+
|
|
12
|
+
override fun getEventName(): String = EVENT_NAME
|
|
13
|
+
|
|
14
|
+
override fun getEventData(): WritableMap = Arguments.createMap()
|
|
15
|
+
|
|
16
|
+
companion object {
|
|
17
|
+
const val EVENT_NAME = "topMount"
|
|
18
|
+
const val REGISTRATION_NAME = "onMount"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Fired before the sheet is presented
|
|
24
|
+
* Payload: { index: number, position: number, detent: number }
|
|
25
|
+
*/
|
|
26
|
+
class WillPresentEvent(surfaceId: Int, viewId: Int, private val index: Int, private val position: Float, private val detent: Float) :
|
|
27
|
+
Event<WillPresentEvent>(surfaceId, viewId) {
|
|
28
|
+
|
|
29
|
+
override fun getEventName(): String = EVENT_NAME
|
|
30
|
+
|
|
31
|
+
override fun getEventData(): WritableMap =
|
|
32
|
+
Arguments.createMap().apply {
|
|
33
|
+
putInt("index", index)
|
|
34
|
+
putDouble("position", position.toDouble())
|
|
35
|
+
putDouble("detent", detent.toDouble())
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
companion object {
|
|
39
|
+
const val EVENT_NAME = "topWillPresent"
|
|
40
|
+
const val REGISTRATION_NAME = "onWillPresent"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Fired after the sheet is presented
|
|
46
|
+
* Payload: { index: number, position: number, detent: number }
|
|
47
|
+
*/
|
|
48
|
+
class DidPresentEvent(surfaceId: Int, viewId: Int, private val index: Int, private val position: Float, private val detent: Float) :
|
|
49
|
+
Event<DidPresentEvent>(surfaceId, viewId) {
|
|
50
|
+
|
|
51
|
+
override fun getEventName(): String = EVENT_NAME
|
|
52
|
+
|
|
53
|
+
override fun getEventData(): WritableMap =
|
|
54
|
+
Arguments.createMap().apply {
|
|
55
|
+
putInt("index", index)
|
|
56
|
+
putDouble("position", position.toDouble())
|
|
57
|
+
putDouble("detent", detent.toDouble())
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
companion object {
|
|
61
|
+
const val EVENT_NAME = "topDidPresent"
|
|
62
|
+
const val REGISTRATION_NAME = "onDidPresent"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Fired before the sheet is dismissed
|
|
68
|
+
*/
|
|
69
|
+
class WillDismissEvent(surfaceId: Int, viewId: Int) : Event<WillDismissEvent>(surfaceId, viewId) {
|
|
70
|
+
|
|
71
|
+
override fun getEventName(): String = EVENT_NAME
|
|
72
|
+
|
|
73
|
+
override fun getEventData(): WritableMap = Arguments.createMap()
|
|
74
|
+
|
|
75
|
+
companion object {
|
|
76
|
+
const val EVENT_NAME = "topWillDismiss"
|
|
77
|
+
const val REGISTRATION_NAME = "onWillDismiss"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Fired after the sheet is dismissed
|
|
83
|
+
*/
|
|
84
|
+
class DidDismissEvent(surfaceId: Int, viewId: Int) : Event<DidDismissEvent>(surfaceId, viewId) {
|
|
85
|
+
|
|
86
|
+
override fun getEventName(): String = EVENT_NAME
|
|
87
|
+
|
|
88
|
+
override fun getEventData(): WritableMap = Arguments.createMap()
|
|
89
|
+
|
|
90
|
+
companion object {
|
|
91
|
+
const val EVENT_NAME = "topDidDismiss"
|
|
92
|
+
const val REGISTRATION_NAME = "onDidDismiss"
|
|
93
|
+
}
|
|
94
|
+
}
|