@swmansion/react-native-bottom-sheet 0.9.0-next.3 → 0.9.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.
|
@@ -17,8 +17,8 @@ import androidx.dynamicanimation.animation.SpringForce
|
|
|
17
17
|
import com.facebook.react.bridge.Arguments
|
|
18
18
|
import com.facebook.react.uimanager.PointerEvents
|
|
19
19
|
import com.facebook.react.uimanager.StateWrapper
|
|
20
|
-
import com.facebook.react.views.view.ReactViewGroup
|
|
21
20
|
import com.facebook.react.uimanager.events.NativeGestureUtil
|
|
21
|
+
import com.facebook.react.views.view.ReactViewGroup
|
|
22
22
|
import kotlin.math.abs
|
|
23
23
|
|
|
24
24
|
private enum class DetentKind {
|
|
@@ -27,11 +27,14 @@ private enum class DetentKind {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
private data class RawDetentSpec(val value: Float, val kind: DetentKind, val programmatic: Boolean)
|
|
30
|
+
|
|
30
31
|
private data class DetentSpec(val height: Float, val programmatic: Boolean)
|
|
31
32
|
|
|
32
33
|
interface BottomSheetViewListener {
|
|
33
34
|
fun onIndexChange(index: Int)
|
|
35
|
+
|
|
34
36
|
fun onSettle(index: Int)
|
|
37
|
+
|
|
35
38
|
fun onPositionChange(position: Double)
|
|
36
39
|
}
|
|
37
40
|
|
|
@@ -54,6 +57,7 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
|
|
|
54
57
|
updateInteractionState()
|
|
55
58
|
updateScrim()
|
|
56
59
|
}
|
|
60
|
+
|
|
57
61
|
var disableScrollableNegotiation: Boolean = false
|
|
58
62
|
private var pendingIndex: Int? = null
|
|
59
63
|
private var hasLaidOut = false
|
|
@@ -76,15 +80,14 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
|
|
|
76
80
|
private var lastTouchY = 0f
|
|
77
81
|
private var activePointerId = MotionEvent.INVALID_POINTER_ID
|
|
78
82
|
private var scrimPressed = false
|
|
83
|
+
private var scrimTouchActive = false
|
|
79
84
|
private var scrimColor = Color.TRANSPARENT
|
|
80
85
|
private var scrimProgress = 0f
|
|
81
86
|
private var maxDetentHeight = Float.NaN
|
|
82
87
|
private var contentHeightMarker: View? = null
|
|
83
88
|
|
|
84
89
|
private val contentHeightMarkerLayoutListener =
|
|
85
|
-
View.OnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
|
|
86
|
-
refreshDetentsFromLayout()
|
|
87
|
-
}
|
|
90
|
+
View.OnLayoutChangeListener { _, _, _, _, _, _, _, _, _ -> refreshDetentsFromLayout() }
|
|
88
91
|
|
|
89
92
|
init {
|
|
90
93
|
clipChildren = false
|
|
@@ -198,16 +201,17 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
|
|
|
198
201
|
// MARK: - Prop setters
|
|
199
202
|
|
|
200
203
|
fun setDetents(raw: List<Map<String, Any>>) {
|
|
201
|
-
rawDetentSpecs =
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
"
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
204
|
+
rawDetentSpecs =
|
|
205
|
+
raw.mapNotNull { dict ->
|
|
206
|
+
val value = (dict["value"] as? Number)?.toDouble() ?: return@mapNotNull null
|
|
207
|
+
val kind =
|
|
208
|
+
when ((dict["kind"] as? String)?.lowercase()) {
|
|
209
|
+
"content" -> DetentKind.CONTENT
|
|
210
|
+
else -> DetentKind.POINTS
|
|
211
|
+
}
|
|
212
|
+
val programmatic = dict["programmatic"] as? Boolean ?: false
|
|
213
|
+
RawDetentSpec(value = (value * density).toFloat(), kind = kind, programmatic = programmatic)
|
|
214
|
+
}
|
|
211
215
|
refreshDetentsFromLayout()
|
|
212
216
|
}
|
|
213
217
|
|
|
@@ -323,6 +327,12 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
|
|
|
323
327
|
return maxHeight - snapHeight
|
|
324
328
|
}
|
|
325
329
|
|
|
330
|
+
private val minDetentTranslationY: Float
|
|
331
|
+
get() = detentSpecs.indices.minOfOrNull(::translationY) ?: 0f
|
|
332
|
+
|
|
333
|
+
private val maxDetentTranslationY: Float
|
|
334
|
+
get() = detentSpecs.indices.maxOfOrNull(::translationY) ?: 0f
|
|
335
|
+
|
|
326
336
|
private val closedIndex: Int?
|
|
327
337
|
get() = detentSpecs.indexOfFirst { it.height == 0f }.takeIf { it >= 0 }
|
|
328
338
|
|
|
@@ -377,12 +387,13 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
|
|
|
377
387
|
|
|
378
388
|
private fun startChoreographer() {
|
|
379
389
|
if (choreographerCallback != null) return
|
|
380
|
-
val callback =
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
390
|
+
val callback =
|
|
391
|
+
object : Choreographer.FrameCallback {
|
|
392
|
+
override fun doFrame(frameTimeNanos: Long) {
|
|
393
|
+
emitPosition()
|
|
394
|
+
choreographerCallback?.let { Choreographer.getInstance().postFrameCallback(it) }
|
|
395
|
+
}
|
|
384
396
|
}
|
|
385
|
-
}
|
|
386
397
|
choreographerCallback = callback
|
|
387
398
|
Choreographer.getInstance().postFrameCallback(callback)
|
|
388
399
|
}
|
|
@@ -407,25 +418,29 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
|
|
|
407
418
|
activeAnimationEmitsSettle = emitSettle
|
|
408
419
|
activeAnimation?.cancel()
|
|
409
420
|
|
|
410
|
-
val spring =
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
421
|
+
val spring =
|
|
422
|
+
SpringAnimation(sheetContainer, DynamicAnimation.TRANSLATION_Y, targetTy).apply {
|
|
423
|
+
spring =
|
|
424
|
+
SpringForce(targetTy).apply {
|
|
425
|
+
dampingRatio = SpringForce.DAMPING_RATIO_NO_BOUNCY
|
|
426
|
+
stiffness = SpringForce.STIFFNESS_MEDIUM
|
|
427
|
+
}
|
|
428
|
+
setMinValue(minDetentTranslationY)
|
|
429
|
+
setMaxValue(maxDetentTranslationY)
|
|
430
|
+
setStartVelocity(velocity)
|
|
431
|
+
addEndListener { _, canceled, _, _ ->
|
|
432
|
+
if (canceled) {
|
|
433
|
+
return@addEndListener
|
|
434
|
+
}
|
|
435
|
+
stopChoreographer()
|
|
436
|
+
emitPosition()
|
|
437
|
+
activeAnimation = null
|
|
438
|
+
activeAnimationEmitsSettle = false
|
|
439
|
+
updateInteractionState()
|
|
440
|
+
if (emitIndexChange) listener?.onIndexChange(index)
|
|
441
|
+
if (emitSettle) listener?.onSettle(index)
|
|
419
442
|
}
|
|
420
|
-
stopChoreographer()
|
|
421
|
-
emitPosition()
|
|
422
|
-
activeAnimation = null
|
|
423
|
-
activeAnimationEmitsSettle = false
|
|
424
|
-
updateInteractionState()
|
|
425
|
-
if (emitIndexChange) listener?.onIndexChange(index)
|
|
426
|
-
if (emitSettle) listener?.onSettle(index)
|
|
427
443
|
}
|
|
428
|
-
}
|
|
429
444
|
|
|
430
445
|
activeAnimation = spring
|
|
431
446
|
startChoreographer()
|
|
@@ -440,11 +455,13 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
|
|
|
440
455
|
|
|
441
456
|
if (velocity < -flickThreshold) {
|
|
442
457
|
return draggable.firstOrNull { it.value.height > currentHeight }?.index
|
|
443
|
-
?: draggable.lastOrNull()?.index
|
|
458
|
+
?: draggable.lastOrNull()?.index
|
|
459
|
+
?: targetIndex
|
|
444
460
|
}
|
|
445
461
|
if (velocity > flickThreshold) {
|
|
446
462
|
return draggable.lastOrNull { it.value.height < currentHeight }?.index
|
|
447
|
-
?: draggable.firstOrNull()?.index
|
|
463
|
+
?: draggable.firstOrNull()?.index
|
|
464
|
+
?: targetIndex
|
|
448
465
|
}
|
|
449
466
|
|
|
450
467
|
return draggable.minByOrNull { abs(it.value.height - currentHeight) }?.index ?: targetIndex
|
|
@@ -459,7 +476,9 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
|
|
|
459
476
|
initialTouchX = ev.x
|
|
460
477
|
initialTouchY = ev.y
|
|
461
478
|
lastTouchY = ev.y
|
|
479
|
+
activePointerId = ev.getPointerId(0)
|
|
462
480
|
scrimPressed = true
|
|
481
|
+
scrimTouchActive = true
|
|
463
482
|
return true
|
|
464
483
|
}
|
|
465
484
|
return false
|
|
@@ -503,18 +522,20 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
|
|
|
503
522
|
}
|
|
504
523
|
}
|
|
505
524
|
}
|
|
506
|
-
MotionEvent.ACTION_UP,
|
|
525
|
+
MotionEvent.ACTION_UP,
|
|
526
|
+
MotionEvent.ACTION_CANCEL -> {
|
|
507
527
|
initialTouchX = 0f
|
|
508
528
|
initialTouchY = 0f
|
|
509
529
|
activePointerId = MotionEvent.INVALID_POINTER_ID
|
|
510
530
|
scrimPressed = false
|
|
531
|
+
scrimTouchActive = false
|
|
511
532
|
}
|
|
512
533
|
}
|
|
513
534
|
return false
|
|
514
535
|
}
|
|
515
536
|
|
|
516
537
|
override fun onTouchEvent(event: MotionEvent): Boolean {
|
|
517
|
-
if (
|
|
538
|
+
if (scrimTouchActive) {
|
|
518
539
|
when (event.actionMasked) {
|
|
519
540
|
MotionEvent.ACTION_MOVE -> {
|
|
520
541
|
val sheetTop = sheetContainer.top + sheetContainer.translationY
|
|
@@ -525,14 +546,22 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
|
|
|
525
546
|
}
|
|
526
547
|
MotionEvent.ACTION_UP -> {
|
|
527
548
|
val closeIndex = closedIndex
|
|
549
|
+
val shouldDismiss = scrimPressed && isScrimVisible()
|
|
528
550
|
scrimPressed = false
|
|
529
|
-
|
|
551
|
+
scrimTouchActive = false
|
|
552
|
+
activePointerId = MotionEvent.INVALID_POINTER_ID
|
|
553
|
+
if (shouldDismiss && closeIndex != null) {
|
|
530
554
|
snapToIndex(closeIndex, 0f)
|
|
531
555
|
}
|
|
532
556
|
return true
|
|
533
557
|
}
|
|
534
558
|
MotionEvent.ACTION_CANCEL -> {
|
|
535
559
|
scrimPressed = false
|
|
560
|
+
scrimTouchActive = false
|
|
561
|
+
activePointerId = MotionEvent.INVALID_POINTER_ID
|
|
562
|
+
return true
|
|
563
|
+
}
|
|
564
|
+
MotionEvent.ACTION_POINTER_UP -> {
|
|
536
565
|
return true
|
|
537
566
|
}
|
|
538
567
|
}
|
|
@@ -553,15 +582,17 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
|
|
|
553
582
|
emitPosition()
|
|
554
583
|
return true
|
|
555
584
|
}
|
|
556
|
-
MotionEvent.ACTION_UP,
|
|
585
|
+
MotionEvent.ACTION_UP,
|
|
586
|
+
MotionEvent.ACTION_CANCEL -> {
|
|
557
587
|
isPanning = false
|
|
558
588
|
activePointerId = MotionEvent.INVALID_POINTER_ID
|
|
559
|
-
val velocity =
|
|
560
|
-
tracker
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
589
|
+
val velocity =
|
|
590
|
+
velocityTracker?.let { tracker ->
|
|
591
|
+
tracker.computeCurrentVelocity(1000)
|
|
592
|
+
val v = tracker.yVelocity
|
|
593
|
+
tracker.recycle()
|
|
594
|
+
v
|
|
595
|
+
} ?: 0f
|
|
565
596
|
velocityTracker = null
|
|
566
597
|
val maxHeight = detentSpecs.maxOfOrNull { it.height } ?: resolvedMaxDetentHeight()
|
|
567
598
|
val currentHeight = maxHeight - sheetContainer.translationY
|
|
@@ -616,9 +647,9 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
|
|
|
616
647
|
val containerY = initialTouchY - sheetContainer.top - sheetContainer.translationY
|
|
617
648
|
if (
|
|
618
649
|
containerX < 0f ||
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
650
|
+
containerX >= sheetContainer.width ||
|
|
651
|
+
containerY < 0f ||
|
|
652
|
+
containerY >= sheetContainer.height
|
|
622
653
|
) {
|
|
623
654
|
return null
|
|
624
655
|
}
|
|
@@ -636,7 +667,9 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
|
|
|
636
667
|
if (childX < 0f || childX >= child.width || childY < 0f || childY >= child.height) {
|
|
637
668
|
continue
|
|
638
669
|
}
|
|
639
|
-
findScrollableAtPoint(child, childX, childY)?.let {
|
|
670
|
+
findScrollableAtPoint(child, childX, childY)?.let {
|
|
671
|
+
return it
|
|
672
|
+
}
|
|
640
673
|
}
|
|
641
674
|
}
|
|
642
675
|
|
|
@@ -680,6 +713,7 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
|
|
|
680
713
|
lastTouchY = 0f
|
|
681
714
|
activePointerId = MotionEvent.INVALID_POINTER_ID
|
|
682
715
|
scrimPressed = false
|
|
716
|
+
scrimTouchActive = false
|
|
683
717
|
sheetContainer.translationY = 0f
|
|
684
718
|
scrimProgress = 0f
|
|
685
719
|
sheetContainer.removeAllViews()
|
|
@@ -696,15 +730,16 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
|
|
|
696
730
|
|
|
697
731
|
// When settled at the closed detent, dynamic content updates can briefly
|
|
698
732
|
// produce stale non-zero positions. Keep scrim hidden in this state.
|
|
699
|
-
if (
|
|
733
|
+
if (
|
|
734
|
+
closedIndex != null && targetIndex == closedIndex && activeAnimation == null && !isPanning
|
|
735
|
+
) {
|
|
700
736
|
scrimProgress = 0f
|
|
701
737
|
invalidate()
|
|
702
738
|
return
|
|
703
739
|
}
|
|
704
740
|
|
|
705
741
|
val threshold = firstNonZeroDetentHeight
|
|
706
|
-
scrimProgress =
|
|
707
|
-
if (threshold <= 0f) 0f else (position / threshold).coerceIn(0f, 1f)
|
|
742
|
+
scrimProgress = if (threshold <= 0f) 0f else (position / threshold).coerceIn(0f, 1f)
|
|
708
743
|
invalidate()
|
|
709
744
|
}
|
|
710
745
|
|
package/android/src/main/java/com/swmansion/reactnativebottomsheet/BottomSheetViewManager.kt
CHANGED
|
@@ -14,8 +14,7 @@ import com.facebook.react.viewmanagers.BottomSheetViewManagerInterface
|
|
|
14
14
|
|
|
15
15
|
@ReactModule(name = BottomSheetViewManager.NAME)
|
|
16
16
|
class BottomSheetViewManager :
|
|
17
|
-
ViewGroupManager<BottomSheetView>(),
|
|
18
|
-
BottomSheetViewManagerInterface<BottomSheetView> {
|
|
17
|
+
ViewGroupManager<BottomSheetView>(), BottomSheetViewManagerInterface<BottomSheetView> {
|
|
19
18
|
|
|
20
19
|
companion object {
|
|
21
20
|
const val NAME = "BottomSheetView"
|
|
@@ -29,37 +28,37 @@ class BottomSheetViewManager :
|
|
|
29
28
|
|
|
30
29
|
override fun createViewInstance(context: ThemedReactContext): BottomSheetView {
|
|
31
30
|
val view = BottomSheetView(context)
|
|
32
|
-
view.listener =
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
view.listener =
|
|
32
|
+
object : BottomSheetViewListener {
|
|
33
|
+
override fun onIndexChange(index: Int) {
|
|
34
|
+
val event =
|
|
35
|
+
com.facebook.react.bridge.Arguments.createMap().apply { putInt("index", index) }
|
|
36
|
+
val reactContext = view.context as? ThemedReactContext ?: return
|
|
37
|
+
reactContext
|
|
38
|
+
.getJSModule(com.facebook.react.uimanager.events.RCTEventEmitter::class.java)
|
|
39
|
+
.receiveEvent(view.id, "topIndexChange", event)
|
|
36
40
|
}
|
|
37
|
-
val reactContext = view.context as? ThemedReactContext ?: return
|
|
38
|
-
reactContext
|
|
39
|
-
.getJSModule(com.facebook.react.uimanager.events.RCTEventEmitter::class.java)
|
|
40
|
-
.receiveEvent(view.id, "topIndexChange", event)
|
|
41
|
-
}
|
|
42
41
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
override fun onSettle(index: Int) {
|
|
43
|
+
val event =
|
|
44
|
+
com.facebook.react.bridge.Arguments.createMap().apply { putInt("index", index) }
|
|
45
|
+
val reactContext = view.context as? ThemedReactContext ?: return
|
|
46
|
+
reactContext
|
|
47
|
+
.getJSModule(com.facebook.react.uimanager.events.RCTEventEmitter::class.java)
|
|
48
|
+
.receiveEvent(view.id, "topSettle", event)
|
|
46
49
|
}
|
|
47
|
-
val reactContext = view.context as? ThemedReactContext ?: return
|
|
48
|
-
reactContext
|
|
49
|
-
.getJSModule(com.facebook.react.uimanager.events.RCTEventEmitter::class.java)
|
|
50
|
-
.receiveEvent(view.id, "topSettle", event)
|
|
51
|
-
}
|
|
52
50
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
override fun onPositionChange(position: Double) {
|
|
52
|
+
val event =
|
|
53
|
+
com.facebook.react.bridge.Arguments.createMap().apply {
|
|
54
|
+
putDouble("position", position)
|
|
55
|
+
}
|
|
56
|
+
val reactContext = view.context as? ThemedReactContext ?: return
|
|
57
|
+
reactContext
|
|
58
|
+
.getJSModule(com.facebook.react.uimanager.events.RCTEventEmitter::class.java)
|
|
59
|
+
.receiveEvent(view.id, "topPositionChange", event)
|
|
56
60
|
}
|
|
57
|
-
val reactContext = view.context as? ThemedReactContext ?: return
|
|
58
|
-
reactContext
|
|
59
|
-
.getJSModule(com.facebook.react.uimanager.events.RCTEventEmitter::class.java)
|
|
60
|
-
.receiveEvent(view.id, "topPositionChange", event)
|
|
61
61
|
}
|
|
62
|
-
}
|
|
63
62
|
return view
|
|
64
63
|
}
|
|
65
64
|
|
|
@@ -69,7 +68,8 @@ class BottomSheetViewManager :
|
|
|
69
68
|
|
|
70
69
|
override fun getChildCount(parent: BottomSheetView): Int = parent.sheetChildCount
|
|
71
70
|
|
|
72
|
-
override fun getChildAt(parent: BottomSheetView, index: Int): View? =
|
|
71
|
+
override fun getChildAt(parent: BottomSheetView, index: Int): View? =
|
|
72
|
+
parent.getSheetChildAt(index)
|
|
73
73
|
|
|
74
74
|
override fun removeViewAt(parent: BottomSheetView, index: Int) {
|
|
75
75
|
parent.removeSheetChildAt(index)
|
|
@@ -28,12 +28,15 @@ public final class RNSBottomSheetHostingView: UIView {
|
|
|
28
28
|
public var modal: Bool = false {
|
|
29
29
|
didSet { updateScrim() }
|
|
30
30
|
}
|
|
31
|
+
|
|
31
32
|
public var scrimColor: UIColor? = .clear {
|
|
32
33
|
didSet { scrimView.backgroundColor = scrimColor }
|
|
33
34
|
}
|
|
35
|
+
|
|
34
36
|
public var maxDetentHeight: CGFloat = .nan {
|
|
35
37
|
didSet { refreshDetentsFromLayout() }
|
|
36
38
|
}
|
|
39
|
+
|
|
37
40
|
public var disableScrollableNegotiation: Bool = false
|
|
38
41
|
|
|
39
42
|
private var rawDetentSpecs: [RawDetentSpec] = []
|
|
@@ -59,7 +62,7 @@ public final class RNSBottomSheetHostingView: UIView {
|
|
|
59
62
|
private var isContentInteractionDisabled = false
|
|
60
63
|
private weak var contentHeightMarker: UIView?
|
|
61
64
|
|
|
62
|
-
public
|
|
65
|
+
override public init(frame: CGRect) {
|
|
63
66
|
super.init(frame: frame)
|
|
64
67
|
backgroundColor = .clear
|
|
65
68
|
clipsToBounds = false
|
|
@@ -84,19 +87,20 @@ public final class RNSBottomSheetHostingView: UIView {
|
|
|
84
87
|
sheetContainer.addGestureRecognizer(panGesture)
|
|
85
88
|
}
|
|
86
89
|
|
|
87
|
-
|
|
90
|
+
@available(*, unavailable)
|
|
91
|
+
public required init?(coder _: NSCoder) {
|
|
88
92
|
fatalError("init(coder:) has not been implemented")
|
|
89
93
|
}
|
|
90
94
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
95
|
+
/// RCTSurfaceTouchHandler dispatches touch events to JS independently of the
|
|
96
|
+
/// pan gesture (it fires in touchesBegan: regardless of its recognizer state).
|
|
97
|
+
/// We cache it here and toggle isEnabled in handlePan(.began) to force a
|
|
98
|
+
/// touchesCancelled dispatch to JS, preventing Pressable from firing onPress
|
|
99
|
+
/// during a sheet drag. This is the iOS equivalent of Android's
|
|
100
|
+
/// NativeGestureUtil.notifyNativeGestureStarted.
|
|
97
101
|
private weak var surfaceTouchHandler: UIGestureRecognizer?
|
|
98
102
|
|
|
99
|
-
public
|
|
103
|
+
override public func didMoveToWindow() {
|
|
100
104
|
super.didMoveToWindow()
|
|
101
105
|
surfaceTouchHandler = nil
|
|
102
106
|
guard window != nil else { return }
|
|
@@ -112,7 +116,7 @@ public final class RNSBottomSheetHostingView: UIView {
|
|
|
112
116
|
}
|
|
113
117
|
}
|
|
114
118
|
|
|
115
|
-
public
|
|
119
|
+
override public func layoutSubviews() {
|
|
116
120
|
super.layoutSubviews()
|
|
117
121
|
guard bounds.width > 0, bounds.height > 0 else { return }
|
|
118
122
|
|
|
@@ -152,7 +156,7 @@ public final class RNSBottomSheetHostingView: UIView {
|
|
|
152
156
|
return sheetContainer.frame
|
|
153
157
|
}
|
|
154
158
|
|
|
155
|
-
public
|
|
159
|
+
override public func point(inside point: CGPoint, with _: UIEvent?) -> Bool {
|
|
156
160
|
if presentedSheetFrame.contains(point) {
|
|
157
161
|
return true
|
|
158
162
|
}
|
|
@@ -160,10 +164,10 @@ public final class RNSBottomSheetHostingView: UIView {
|
|
|
160
164
|
return isScrimVisible && bounds.contains(point)
|
|
161
165
|
}
|
|
162
166
|
|
|
163
|
-
public
|
|
167
|
+
override public func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
|
164
168
|
guard self.point(inside: point, with: event) else { return nil }
|
|
165
169
|
|
|
166
|
-
if isScrimVisible
|
|
170
|
+
if isScrimVisible, !presentedSheetFrame.contains(point) {
|
|
167
171
|
let scrimPoint = convert(point, to: scrimView)
|
|
168
172
|
return scrimView.hitTest(scrimPoint, with: event)
|
|
169
173
|
}
|
|
@@ -475,7 +479,7 @@ public final class RNSBottomSheetHostingView: UIView {
|
|
|
475
479
|
return nil
|
|
476
480
|
}
|
|
477
481
|
|
|
478
|
-
public
|
|
482
|
+
override public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
|
|
479
483
|
guard gestureRecognizer === panGesture else { return true }
|
|
480
484
|
|
|
481
485
|
let velocity = panGesture.velocity(in: self)
|
|
@@ -552,7 +556,7 @@ public final class RNSBottomSheetHostingView: UIView {
|
|
|
552
556
|
return
|
|
553
557
|
}
|
|
554
558
|
|
|
555
|
-
if hasLaidOut
|
|
559
|
+
if hasLaidOut, !isPanning {
|
|
556
560
|
targetIndex = max(0, min(detentSpecs.count - 1, targetIndex))
|
|
557
561
|
|
|
558
562
|
if let animator = activeAnimator {
|
|
@@ -606,8 +610,8 @@ extension RNSBottomSheetHostingView: UIGestureRecognizerDelegate {
|
|
|
606
610
|
}
|
|
607
611
|
|
|
608
612
|
public func gestureRecognizer(
|
|
609
|
-
_
|
|
610
|
-
shouldRecognizeSimultaneouslyWith
|
|
613
|
+
_: UIGestureRecognizer,
|
|
614
|
+
shouldRecognizeSimultaneouslyWith _: UIGestureRecognizer
|
|
611
615
|
) -> Bool {
|
|
612
616
|
return false
|
|
613
617
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@swmansion/react-native-bottom-sheet",
|
|
3
|
-
"version": "0.9.0
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Provides bottom-sheet components for React Native.",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"types": "./lib/typescript/src/index.d.ts",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"scripts": {
|
|
36
36
|
"example": "yarn workspace @swmansion/react-native-bottom-sheet-example",
|
|
37
37
|
"clean": "del-cli lib",
|
|
38
|
-
"prepare": "bob build",
|
|
38
|
+
"prepare": "lefthook install && bob build",
|
|
39
39
|
"typecheck": "tsc",
|
|
40
40
|
"lint": "eslint \"**/*.{js,ts,tsx}\""
|
|
41
41
|
},
|
|
@@ -69,6 +69,7 @@
|
|
|
69
69
|
"eslint": "9.39.2",
|
|
70
70
|
"eslint-config-prettier": "10.1.8",
|
|
71
71
|
"eslint-plugin-prettier": "5.5.5",
|
|
72
|
+
"lefthook": "2.1.6",
|
|
72
73
|
"prettier": "2.8.8",
|
|
73
74
|
"react": "19.1.0",
|
|
74
75
|
"react-native": "0.81.5",
|