@swmansion/react-native-bottom-sheet 0.9.0-next.2 → 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.
Files changed (31) hide show
  1. package/android/src/main/java/com/swmansion/reactnativebottomsheet/BottomSheetView.kt +118 -65
  2. package/android/src/main/java/com/swmansion/reactnativebottomsheet/BottomSheetViewManager.kt +33 -28
  3. package/ios/BottomSheetComponentView.mm +4 -0
  4. package/ios/BottomSheetContentView.h +1 -0
  5. package/ios/BottomSheetContentView.mm +10 -0
  6. package/ios/RNSBottomSheetHostingView.swift +49 -32
  7. package/lib/module/BottomSheet.js +8 -0
  8. package/lib/module/BottomSheet.js.map +1 -1
  9. package/lib/module/BottomSheetNativeComponent.ts +1 -0
  10. package/lib/module/BottomSheetProvider.js +2 -0
  11. package/lib/module/BottomSheetProvider.js.map +1 -1
  12. package/lib/module/ModalBottomSheet.js +3 -0
  13. package/lib/module/ModalBottomSheet.js.map +1 -1
  14. package/lib/module/bottomSheetUtils.js +5 -0
  15. package/lib/module/bottomSheetUtils.js.map +1 -1
  16. package/lib/typescript/src/BottomSheet.d.ts +21 -1
  17. package/lib/typescript/src/BottomSheet.d.ts.map +1 -1
  18. package/lib/typescript/src/BottomSheetNativeComponent.d.ts +1 -0
  19. package/lib/typescript/src/BottomSheetNativeComponent.d.ts.map +1 -1
  20. package/lib/typescript/src/BottomSheetProvider.d.ts +1 -0
  21. package/lib/typescript/src/BottomSheetProvider.d.ts.map +1 -1
  22. package/lib/typescript/src/ModalBottomSheet.d.ts +2 -0
  23. package/lib/typescript/src/ModalBottomSheet.d.ts.map +1 -1
  24. package/lib/typescript/src/bottomSheetUtils.d.ts +3 -0
  25. package/lib/typescript/src/bottomSheetUtils.d.ts.map +1 -1
  26. package/package.json +3 -2
  27. package/src/BottomSheet.tsx +22 -0
  28. package/src/BottomSheetNativeComponent.ts +1 -0
  29. package/src/BottomSheetProvider.tsx +1 -0
  30. package/src/ModalBottomSheet.tsx +2 -0
  31. package/src/bottomSheetUtils.ts +3 -0
@@ -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,8 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
54
57
  updateInteractionState()
55
58
  updateScrim()
56
59
  }
60
+
61
+ var disableScrollableNegotiation: Boolean = false
57
62
  private var pendingIndex: Int? = null
58
63
  private var hasLaidOut = false
59
64
  private var isPanning = false
@@ -75,15 +80,14 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
75
80
  private var lastTouchY = 0f
76
81
  private var activePointerId = MotionEvent.INVALID_POINTER_ID
77
82
  private var scrimPressed = false
83
+ private var scrimTouchActive = false
78
84
  private var scrimColor = Color.TRANSPARENT
79
85
  private var scrimProgress = 0f
80
86
  private var maxDetentHeight = Float.NaN
81
87
  private var contentHeightMarker: View? = null
82
88
 
83
89
  private val contentHeightMarkerLayoutListener =
84
- View.OnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
85
- refreshDetentsFromLayout()
86
- }
90
+ View.OnLayoutChangeListener { _, _, _, _, _, _, _, _, _ -> refreshDetentsFromLayout() }
87
91
 
88
92
  init {
89
93
  clipChildren = false
@@ -197,16 +201,17 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
197
201
  // MARK: - Prop setters
198
202
 
199
203
  fun setDetents(raw: List<Map<String, Any>>) {
200
- rawDetentSpecs = raw.mapNotNull { dict ->
201
- val value = (dict["value"] as? Number)?.toDouble() ?: return@mapNotNull null
202
- val kind =
203
- when ((dict["kind"] as? String)?.lowercase()) {
204
- "content" -> DetentKind.CONTENT
205
- else -> DetentKind.POINTS
206
- }
207
- val programmatic = dict["programmatic"] as? Boolean ?: false
208
- RawDetentSpec(value = (value * density).toFloat(), kind = kind, programmatic = programmatic)
209
- }
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
+ }
210
215
  refreshDetentsFromLayout()
211
216
  }
212
217
 
@@ -322,6 +327,12 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
322
327
  return maxHeight - snapHeight
323
328
  }
324
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
+
325
336
  private val closedIndex: Int?
326
337
  get() = detentSpecs.indexOfFirst { it.height == 0f }.takeIf { it >= 0 }
327
338
 
@@ -376,12 +387,13 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
376
387
 
377
388
  private fun startChoreographer() {
378
389
  if (choreographerCallback != null) return
379
- val callback = object : Choreographer.FrameCallback {
380
- override fun doFrame(frameTimeNanos: Long) {
381
- emitPosition()
382
- choreographerCallback?.let { Choreographer.getInstance().postFrameCallback(it) }
390
+ val callback =
391
+ object : Choreographer.FrameCallback {
392
+ override fun doFrame(frameTimeNanos: Long) {
393
+ emitPosition()
394
+ choreographerCallback?.let { Choreographer.getInstance().postFrameCallback(it) }
395
+ }
383
396
  }
384
- }
385
397
  choreographerCallback = callback
386
398
  Choreographer.getInstance().postFrameCallback(callback)
387
399
  }
@@ -406,25 +418,29 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
406
418
  activeAnimationEmitsSettle = emitSettle
407
419
  activeAnimation?.cancel()
408
420
 
409
- val spring = SpringAnimation(sheetContainer, DynamicAnimation.TRANSLATION_Y, targetTy).apply {
410
- spring = SpringForce(targetTy).apply {
411
- dampingRatio = SpringForce.DAMPING_RATIO_NO_BOUNCY
412
- stiffness = SpringForce.STIFFNESS_MEDIUM
413
- }
414
- setStartVelocity(velocity)
415
- addEndListener { _, canceled, _, _ ->
416
- if (canceled) {
417
- return@addEndListener
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)
418
442
  }
419
- stopChoreographer()
420
- emitPosition()
421
- activeAnimation = null
422
- activeAnimationEmitsSettle = false
423
- updateInteractionState()
424
- if (emitIndexChange) listener?.onIndexChange(index)
425
- if (emitSettle) listener?.onSettle(index)
426
443
  }
427
- }
428
444
 
429
445
  activeAnimation = spring
430
446
  startChoreographer()
@@ -439,11 +455,13 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
439
455
 
440
456
  if (velocity < -flickThreshold) {
441
457
  return draggable.firstOrNull { it.value.height > currentHeight }?.index
442
- ?: draggable.lastOrNull()?.index ?: targetIndex
458
+ ?: draggable.lastOrNull()?.index
459
+ ?: targetIndex
443
460
  }
444
461
  if (velocity > flickThreshold) {
445
462
  return draggable.lastOrNull { it.value.height < currentHeight }?.index
446
- ?: draggable.firstOrNull()?.index ?: targetIndex
463
+ ?: draggable.firstOrNull()?.index
464
+ ?: targetIndex
447
465
  }
448
466
 
449
467
  return draggable.minByOrNull { abs(it.value.height - currentHeight) }?.index ?: targetIndex
@@ -458,7 +476,9 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
458
476
  initialTouchX = ev.x
459
477
  initialTouchY = ev.y
460
478
  lastTouchY = ev.y
479
+ activePointerId = ev.getPointerId(0)
461
480
  scrimPressed = true
481
+ scrimTouchActive = true
462
482
  return true
463
483
  }
464
484
  return false
@@ -481,6 +501,9 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
481
501
  val dy = y - initialTouchY
482
502
 
483
503
  if (abs(dy) > touchSlop && abs(dy) > abs(dx) && draggableMinTy < draggableMaxTy) {
504
+ if (disableScrollableNegotiation && findScrollableAtTouch() != null) {
505
+ return false
506
+ }
484
507
  if (!isAtMaxDraggable) {
485
508
  lastTouchY = y
486
509
  requestDisallowInterceptTouchEvent(false)
@@ -499,18 +522,20 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
499
522
  }
500
523
  }
501
524
  }
502
- MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
525
+ MotionEvent.ACTION_UP,
526
+ MotionEvent.ACTION_CANCEL -> {
503
527
  initialTouchX = 0f
504
528
  initialTouchY = 0f
505
529
  activePointerId = MotionEvent.INVALID_POINTER_ID
506
530
  scrimPressed = false
531
+ scrimTouchActive = false
507
532
  }
508
533
  }
509
534
  return false
510
535
  }
511
536
 
512
537
  override fun onTouchEvent(event: MotionEvent): Boolean {
513
- if (scrimPressed) {
538
+ if (scrimTouchActive) {
514
539
  when (event.actionMasked) {
515
540
  MotionEvent.ACTION_MOVE -> {
516
541
  val sheetTop = sheetContainer.top + sheetContainer.translationY
@@ -521,14 +546,22 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
521
546
  }
522
547
  MotionEvent.ACTION_UP -> {
523
548
  val closeIndex = closedIndex
549
+ val shouldDismiss = scrimPressed && isScrimVisible()
524
550
  scrimPressed = false
525
- if (closeIndex != null && isScrimVisible()) {
551
+ scrimTouchActive = false
552
+ activePointerId = MotionEvent.INVALID_POINTER_ID
553
+ if (shouldDismiss && closeIndex != null) {
526
554
  snapToIndex(closeIndex, 0f)
527
555
  }
528
556
  return true
529
557
  }
530
558
  MotionEvent.ACTION_CANCEL -> {
531
559
  scrimPressed = false
560
+ scrimTouchActive = false
561
+ activePointerId = MotionEvent.INVALID_POINTER_ID
562
+ return true
563
+ }
564
+ MotionEvent.ACTION_POINTER_UP -> {
532
565
  return true
533
566
  }
534
567
  }
@@ -549,15 +582,17 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
549
582
  emitPosition()
550
583
  return true
551
584
  }
552
- MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
585
+ MotionEvent.ACTION_UP,
586
+ MotionEvent.ACTION_CANCEL -> {
553
587
  isPanning = false
554
588
  activePointerId = MotionEvent.INVALID_POINTER_ID
555
- val velocity = velocityTracker?.let { tracker ->
556
- tracker.computeCurrentVelocity(1000)
557
- val v = tracker.yVelocity
558
- tracker.recycle()
559
- v
560
- } ?: 0f
589
+ val velocity =
590
+ velocityTracker?.let { tracker ->
591
+ tracker.computeCurrentVelocity(1000)
592
+ val v = tracker.yVelocity
593
+ tracker.recycle()
594
+ v
595
+ } ?: 0f
561
596
  velocityTracker = null
562
597
  val maxHeight = detentSpecs.maxOfOrNull { it.height } ?: resolvedMaxDetentHeight()
563
598
  val currentHeight = maxHeight - sheetContainer.translationY
@@ -602,29 +637,45 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
602
637
  // could never collapse by dragging down when a ScrollView is at the top.
603
638
 
604
639
  private fun isScrollViewAtTop(): Boolean {
605
- val scrollView = findScrollView(sheetContainer) ?: return true
606
- if (!isTouchInsideView(scrollView)) return true
640
+ val scrollView = findScrollableAtTouch() ?: return true
607
641
  val inverted = isViewInverted(scrollView)
608
642
  return if (inverted) !scrollView.canScrollVertically(1) else !scrollView.canScrollVertically(-1)
609
643
  }
610
644
 
611
- private fun isTouchInsideView(target: View): Boolean {
612
- val rect = android.graphics.Rect()
613
- if (!target.getGlobalVisibleRect(rect)) return false
614
- val myLocation = IntArray(2)
615
- getLocationOnScreen(myLocation)
616
- val touchScreenX = (myLocation[0] + initialTouchX).toInt()
617
- val touchScreenY = (myLocation[1] + initialTouchY).toInt()
618
- return rect.contains(touchScreenX, touchScreenY)
645
+ private fun findScrollableAtTouch(): View? {
646
+ val containerX = initialTouchX - sheetContainer.left - sheetContainer.translationX
647
+ val containerY = initialTouchY - sheetContainer.top - sheetContainer.translationY
648
+ if (
649
+ containerX < 0f ||
650
+ containerX >= sheetContainer.width ||
651
+ containerY < 0f ||
652
+ containerY >= sheetContainer.height
653
+ ) {
654
+ return null
655
+ }
656
+ return findScrollableAtPoint(sheetContainer, containerX, containerY)
619
657
  }
620
658
 
621
- private fun findScrollView(view: View): View? {
622
- if (view.canScrollVertically(1) || view.canScrollVertically(-1)) return view
659
+ private fun findScrollableAtPoint(view: View, x: Float, y: Float): View? {
660
+ if (!view.isShown) return null
661
+
623
662
  if (view is ViewGroup) {
624
- for (i in 0 until view.childCount) {
625
- findScrollView(view.getChildAt(i))?.let { return it }
663
+ for (i in view.childCount - 1 downTo 0) {
664
+ val child = view.getChildAt(i)
665
+ val childX = x - child.left - child.translationX
666
+ val childY = y - child.top - child.translationY
667
+ if (childX < 0f || childX >= child.width || childY < 0f || childY >= child.height) {
668
+ continue
669
+ }
670
+ findScrollableAtPoint(child, childX, childY)?.let {
671
+ return it
672
+ }
626
673
  }
627
674
  }
675
+
676
+ if (view.canScrollVertically(1) || view.canScrollVertically(-1)) {
677
+ return view
678
+ }
628
679
  return null
629
680
  }
630
681
 
@@ -662,6 +713,7 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
662
713
  lastTouchY = 0f
663
714
  activePointerId = MotionEvent.INVALID_POINTER_ID
664
715
  scrimPressed = false
716
+ scrimTouchActive = false
665
717
  sheetContainer.translationY = 0f
666
718
  scrimProgress = 0f
667
719
  sheetContainer.removeAllViews()
@@ -678,15 +730,16 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
678
730
 
679
731
  // When settled at the closed detent, dynamic content updates can briefly
680
732
  // produce stale non-zero positions. Keep scrim hidden in this state.
681
- if (closedIndex != null && targetIndex == closedIndex && activeAnimation == null && !isPanning) {
733
+ if (
734
+ closedIndex != null && targetIndex == closedIndex && activeAnimation == null && !isPanning
735
+ ) {
682
736
  scrimProgress = 0f
683
737
  invalidate()
684
738
  return
685
739
  }
686
740
 
687
741
  val threshold = firstNonZeroDetentHeight
688
- scrimProgress =
689
- if (threshold <= 0f) 0f else (position / threshold).coerceIn(0f, 1f)
742
+ scrimProgress = if (threshold <= 0f) 0f else (position / threshold).coerceIn(0f, 1f)
690
743
  invalidate()
691
744
  }
692
745
 
@@ -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 = object : BottomSheetViewListener {
33
- override fun onIndexChange(index: Int) {
34
- val event = com.facebook.react.bridge.Arguments.createMap().apply {
35
- putInt("index", index)
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
- override fun onSettle(index: Int) {
44
- val event = com.facebook.react.bridge.Arguments.createMap().apply {
45
- putInt("index", index)
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
- override fun onPositionChange(position: Double) {
54
- val event = com.facebook.react.bridge.Arguments.createMap().apply {
55
- putDouble("position", position)
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? = parent.getSheetChildAt(index)
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)
@@ -131,6 +131,11 @@ class BottomSheetViewManager :
131
131
  view.modal = modal
132
132
  }
133
133
 
134
+ @ReactProp(name = "disableScrollableNegotiation")
135
+ override fun setDisableScrollableNegotiation(view: BottomSheetView, value: Boolean) {
136
+ view.disableScrollableNegotiation = value
137
+ }
138
+
134
139
  @ReactProp(name = "scrimColor", customType = "Color")
135
140
  override fun setScrimColor(view: BottomSheetView, scrimColor: Int?) {
136
141
  view.setScrimColor(scrimColor)
@@ -76,6 +76,10 @@ using namespace facebook::react;
76
76
  _sheetView.modal = newViewProps.modal;
77
77
  }
78
78
 
79
+ if (newViewProps.disableScrollableNegotiation != oldViewProps.disableScrollableNegotiation) {
80
+ _sheetView.disableScrollableNegotiation = newViewProps.disableScrollableNegotiation;
81
+ }
82
+
79
83
  if (newViewProps.scrimColor != oldViewProps.scrimColor) {
80
84
  [_sheetView setScrimColor:RCTUIColorFromSharedColor(newViewProps.scrimColor)];
81
85
  }
@@ -15,6 +15,7 @@ NS_ASSUME_NONNULL_BEGIN
15
15
  @property (nonatomic, weak, nullable) id<BottomSheetContentViewDelegate> delegate;
16
16
  @property (nonatomic) BOOL animateIn;
17
17
  @property (nonatomic) BOOL modal;
18
+ @property (nonatomic) BOOL disableScrollableNegotiation;
18
19
  @property (nonatomic, readonly) UIView *sheetContainer;
19
20
 
20
21
  - (void)setDetents:(NSArray<NSDictionary *> *)raw;
@@ -40,6 +40,16 @@
40
40
  return _impl.sheetContainer;
41
41
  }
42
42
 
43
+ - (BOOL)disableScrollableNegotiation
44
+ {
45
+ return _impl.disableScrollableNegotiation;
46
+ }
47
+
48
+ - (void)setDisableScrollableNegotiation:(BOOL)disableScrollableNegotiation
49
+ {
50
+ _impl.disableScrollableNegotiation = disableScrollableNegotiation;
51
+ }
52
+
43
53
  - (BOOL)modal
44
54
  {
45
55
  return _impl.modal;
@@ -28,13 +28,17 @@ 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
  }
37
39
 
40
+ public var disableScrollableNegotiation: Bool = false
41
+
38
42
  private var rawDetentSpecs: [RawDetentSpec] = []
39
43
  private var detentSpecs: [DetentSpec] = [] {
40
44
  didSet {
@@ -58,7 +62,7 @@ public final class RNSBottomSheetHostingView: UIView {
58
62
  private var isContentInteractionDisabled = false
59
63
  private weak var contentHeightMarker: UIView?
60
64
 
61
- public override init(frame: CGRect) {
65
+ override public init(frame: CGRect) {
62
66
  super.init(frame: frame)
63
67
  backgroundColor = .clear
64
68
  clipsToBounds = false
@@ -83,19 +87,20 @@ public final class RNSBottomSheetHostingView: UIView {
83
87
  sheetContainer.addGestureRecognizer(panGesture)
84
88
  }
85
89
 
86
- public required init?(coder: NSCoder) {
90
+ @available(*, unavailable)
91
+ public required init?(coder _: NSCoder) {
87
92
  fatalError("init(coder:) has not been implemented")
88
93
  }
89
94
 
90
- // RCTSurfaceTouchHandler dispatches touch events to JS independently of the
91
- // pan gesture (it fires in touchesBegan: regardless of its recognizer state).
92
- // We cache it here and toggle isEnabled in handlePan(.began) to force a
93
- // touchesCancelled dispatch to JS, preventing Pressable from firing onPress
94
- // during a sheet drag. This is the iOS equivalent of Android's
95
- // NativeGestureUtil.notifyNativeGestureStarted.
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.
96
101
  private weak var surfaceTouchHandler: UIGestureRecognizer?
97
102
 
98
- public override func didMoveToWindow() {
103
+ override public func didMoveToWindow() {
99
104
  super.didMoveToWindow()
100
105
  surfaceTouchHandler = nil
101
106
  guard window != nil else { return }
@@ -111,7 +116,7 @@ public final class RNSBottomSheetHostingView: UIView {
111
116
  }
112
117
  }
113
118
 
114
- public override func layoutSubviews() {
119
+ override public func layoutSubviews() {
115
120
  super.layoutSubviews()
116
121
  guard bounds.width > 0, bounds.height > 0 else { return }
117
122
 
@@ -151,7 +156,7 @@ public final class RNSBottomSheetHostingView: UIView {
151
156
  return sheetContainer.frame
152
157
  }
153
158
 
154
- public override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
159
+ override public func point(inside point: CGPoint, with _: UIEvent?) -> Bool {
155
160
  if presentedSheetFrame.contains(point) {
156
161
  return true
157
162
  }
@@ -159,10 +164,10 @@ public final class RNSBottomSheetHostingView: UIView {
159
164
  return isScrimVisible && bounds.contains(point)
160
165
  }
161
166
 
162
- public override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
167
+ override public func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
163
168
  guard self.point(inside: point, with: event) else { return nil }
164
169
 
165
- if isScrimVisible && !presentedSheetFrame.contains(point) {
170
+ if isScrimVisible, !presentedSheetFrame.contains(point) {
166
171
  let scrimPoint = convert(point, to: scrimView)
167
172
  return scrimView.hitTest(scrimPoint, with: event)
168
173
  }
@@ -449,18 +454,6 @@ public final class RNSBottomSheetHostingView: UIView {
449
454
  return scrollView.alwaysBounceVertical || scrollView.contentSize.height > visibleHeight
450
455
  }
451
456
 
452
- private func firstScrollView(in view: UIView) -> UIScrollView? {
453
- for subview in view.subviews {
454
- if let scrollView = subview as? UIScrollView, isVerticallyScrollable(scrollView) {
455
- return scrollView
456
- }
457
- if let found = firstScrollView(in: subview) {
458
- return found
459
- }
460
- }
461
- return nil
462
- }
463
-
464
457
  private func isViewInverted(_ view: UIView) -> Bool {
465
458
  var current: UIView? = view
466
459
  while let v = current, v !== sheetContainer {
@@ -470,7 +463,23 @@ public final class RNSBottomSheetHostingView: UIView {
470
463
  return false
471
464
  }
472
465
 
473
- public override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
466
+ private func scrollView(containing location: CGPoint, in view: UIView) -> UIScrollView? {
467
+ for subview in view.subviews.reversed() {
468
+ let locationInSubview = view.convert(location, to: subview)
469
+ guard subview.bounds.contains(locationInSubview) else { continue }
470
+
471
+ if let found = scrollView(containing: locationInSubview, in: subview) {
472
+ return found
473
+ }
474
+
475
+ if let scrollView = subview as? UIScrollView, isVerticallyScrollable(scrollView) {
476
+ return scrollView
477
+ }
478
+ }
479
+ return nil
480
+ }
481
+
482
+ override public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
474
483
  guard gestureRecognizer === panGesture else { return true }
475
484
 
476
485
  let velocity = panGesture.velocity(in: self)
@@ -479,6 +488,13 @@ public final class RNSBottomSheetHostingView: UIView {
479
488
  let draggable = detentSpecs.enumerated().filter { !$0.element.programmatic }
480
489
  guard draggable.count > 1 else { return false }
481
490
 
491
+ if disableScrollableNegotiation {
492
+ let locationInContainer = panGesture.location(in: sheetContainer)
493
+ if scrollView(containing: locationInContainer, in: sheetContainer) != nil {
494
+ return false
495
+ }
496
+ }
497
+
482
498
  let maxDraggableIndex = draggable.last?.offset ?? 0
483
499
  // Below max: allow drag in either direction to reach other detents.
484
500
  guard targetIndex >= maxDraggableIndex else { return true }
@@ -488,9 +504,10 @@ public final class RNSBottomSheetHostingView: UIView {
488
504
  return false
489
505
  }
490
506
 
491
- guard let scrollView = firstScrollView(in: sheetContainer) else { return true }
492
- let locationInScroll = panGesture.location(in: scrollView)
493
- guard scrollView.bounds.contains(locationInScroll) else { return true }
507
+ let locationInContainer = panGesture.location(in: sheetContainer)
508
+ guard let scrollView = scrollView(containing: locationInContainer, in: sheetContainer) else {
509
+ return true
510
+ }
494
511
  let inverted = isViewInverted(scrollView)
495
512
  if inverted {
496
513
  let maxOffsetY = scrollView.contentSize.height - scrollView.bounds.height + scrollView.adjustedContentInset.bottom
@@ -539,7 +556,7 @@ public final class RNSBottomSheetHostingView: UIView {
539
556
  return
540
557
  }
541
558
 
542
- if hasLaidOut && !isPanning {
559
+ if hasLaidOut, !isPanning {
543
560
  targetIndex = max(0, min(detentSpecs.count - 1, targetIndex))
544
561
 
545
562
  if let animator = activeAnimator {
@@ -593,8 +610,8 @@ extension RNSBottomSheetHostingView: UIGestureRecognizerDelegate {
593
610
  }
594
611
 
595
612
  public func gestureRecognizer(
596
- _ gestureRecognizer: UIGestureRecognizer,
597
- shouldRecognizeSimultaneouslyWith other: UIGestureRecognizer
613
+ _: UIGestureRecognizer,
614
+ shouldRecognizeSimultaneouslyWith _: UIGestureRecognizer
598
615
  ) -> Bool {
599
616
  return false
600
617
  }
@@ -6,6 +6,12 @@ import BottomSheetNativeComponent from './BottomSheetNativeComponent';
6
6
  import { Portal } from "./BottomSheetProvider.js";
7
7
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
8
  export { programmatic } from "./bottomSheetUtils.js";
9
+
10
+ /**
11
+ * Props for the inline bottom-sheet component.
12
+ */
13
+
14
+ /** Native bottom sheet that renders inline within the current screen layout. */
9
15
  export const BottomSheet = ({
10
16
  children,
11
17
  style,
@@ -16,6 +22,7 @@ export const BottomSheet = ({
16
22
  onSettle,
17
23
  onPositionChange,
18
24
  modal = false,
25
+ disableScrollableNegotiation = false,
19
26
  scrimColor
20
27
  }) => {
21
28
  const {
@@ -75,6 +82,7 @@ export const BottomSheet = ({
75
82
  index: index,
76
83
  animateIn: animateIn,
77
84
  modal: modal,
85
+ disableScrollableNegotiation: disableScrollableNegotiation,
78
86
  scrimColor: scrimColor,
79
87
  onIndexChange: handleIndexChange,
80
88
  onSettle: handleSettle,
@@ -1 +1 @@
1
- {"version":3,"names":["StyleSheet","View","useWindowDimensions","useSafeAreaInsets","BottomSheetNativeComponent","Portal","jsx","_jsx","jsxs","_jsxs","programmatic","BottomSheet","children","style","detents","index","animateIn","onIndexChange","onSettle","onPositionChange","modal","scrimColor","height","windowHeight","insets","maxHeight","top","nativeDetents","map","detent","isDetentProgrammatic","value","resolveDetentValue","kind","Math","max","min","clampedIndex","length","selectedDetentValue","isCollapsed","handleIndexChange","event","nativeEvent","handleSettle","handlePositionChange","position","sheet","absoluteFill","pointerEvents","left","right","bottom","maxDetentHeight","collapsable","flex"],"sourceRoot":"../../src","sources":["BottomSheet.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["StyleSheet","View","useWindowDimensions","useSafeAreaInsets","BottomSheetNativeComponent","Portal","jsx","_jsx","jsxs","_jsxs","programmatic","BottomSheet","children","style","detents","index","animateIn","onIndexChange","onSettle","onPositionChange","modal","disableScrollableNegotiation","scrimColor","height","windowHeight","insets","maxHeight","top","nativeDetents","map","detent","isDetentProgrammatic","value","resolveDetentValue","kind","Math","max","min","clampedIndex","length","selectedDetentValue","isCollapsed","handleIndexChange","event","nativeEvent","handleSettle","handlePositionChange","position","sheet","absoluteFill","pointerEvents","left","right","bottom","maxDetentHeight","collapsable","flex"],"sourceRoot":"../../src","sources":["BottomSheet.tsx"],"mappings":"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","ignoreList":[]}
@@ -17,6 +17,7 @@ export interface NativeProps extends ViewProps {
17
17
  index: CodegenTypes.Int32;
18
18
  animateIn: boolean;
19
19
  modal: boolean;
20
+ disableScrollableNegotiation?: boolean;
20
21
  scrimColor?: ColorValue;
21
22
  onIndexChange?: CodegenTypes.DirectEventHandler<
22
23
  Readonly<{ index: CodegenTypes.Int32 }>
@@ -16,6 +16,8 @@ const PortalHost = () => {
16
16
  children: element
17
17
  }, key));
18
18
  };
19
+
20
+ /** Provides the portal host required for modal bottom sheets. */
19
21
  export const BottomSheetProvider = ({
20
22
  children
21
23
  }) => {
@@ -1 +1 @@
1
- {"version":3,"names":["createContext","useContext","useEffect","useId","useReducer","useState","StyleSheet","View","jsx","_jsx","jsxs","_jsxs","PortalContext","PortalHost","context","forceRender","x","subscribe","Array","from","getPortals","entries","map","key","element","style","absoluteFill","pointerEvents","children","BottomSheetProvider","portals","Map","subscribers","Set","notify","forEach","subscriber","addPortal","set","removePortal","delete","callback","add","Provider","value","Portal","Error","id"],"sourceRoot":"../../src","sources":["BottomSheetProvider.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["createContext","useContext","useEffect","useId","useReducer","useState","StyleSheet","View","jsx","_jsx","jsxs","_jsxs","PortalContext","PortalHost","context","forceRender","x","subscribe","Array","from","getPortals","entries","map","key","element","style","absoluteFill","pointerEvents","children","BottomSheetProvider","portals","Map","subscribers","Set","notify","forEach","subscriber","addPortal","set","removePortal","delete","callback","add","Provider","value","Portal","Error","id"],"sourceRoot":"../../src","sources":["BottomSheetProvider.tsx"],"mappings":"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","ignoreList":[]}
@@ -1,7 +1,10 @@
1
1
  "use strict";
2
2
 
3
3
  import { BottomSheet } from "./BottomSheet.js";
4
+
5
+ /** Props for the modal bottom-sheet variant rendered through the provider portal. */
4
6
  import { jsx as _jsx } from "react/jsx-runtime";
7
+ /** Bottom sheet presented above the current UI with a scrim. */
5
8
  export const ModalBottomSheet = props => /*#__PURE__*/_jsx(BottomSheet, {
6
9
  ...props,
7
10
  modal: true
@@ -1 +1 @@
1
- {"version":3,"names":["BottomSheet","jsx","_jsx","ModalBottomSheet","props","modal"],"sourceRoot":"../../src","sources":["ModalBottomSheet.tsx"],"mappings":";;AAAA,SAASA,WAAW,QAA+B,kBAAe;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAKnE,OAAO,MAAMC,gBAAgB,GAAIC,KAA4B,iBAC3DF,IAAA,CAACF,WAAW;EAAA,GAAKI,KAAK;EAAEC,KAAK;AAAA,CAAE,CAChC","ignoreList":[]}
1
+ {"version":3,"names":["BottomSheet","jsx","_jsx","ModalBottomSheet","props","modal"],"sourceRoot":"../../src","sources":["ModalBottomSheet.tsx"],"mappings":";;AAAA,SAASA,WAAW,QAA+B,kBAAe;;AAElE;AAAA,SAAAC,GAAA,IAAAC,IAAA;AAIA;AACA,OAAO,MAAMC,gBAAgB,GAAIC,KAA4B,iBAC3DF,IAAA,CAACF,WAAW;EAAA,GAAKI,KAAK;EAAEC,KAAK;AAAA,CAAE,CAChC","ignoreList":[]}
@@ -1,5 +1,10 @@
1
1
  "use strict";
2
2
 
3
+ /** A detent value in points, or `'content'` to size to the measured content height. */
4
+
5
+ /** A draggable detent or an object form that can mark a detent as programmatic-only. */
6
+
7
+ /** Marks a detent as reachable only via controlled `index` updates, not dragging. */
3
8
  export const programmatic = value => ({
4
9
  value,
5
10
  programmatic: true
@@ -1 +1 @@
1
- {"version":3,"names":["programmatic","value","detentValue","detent","isDetentProgrammatic","VELOCITY_THRESHOLD","findSnapTarget","currentTranslate","velocityY","currentIndex","allPositions","draggablePositions","filter","position","isDraggable","effectivePositions","length","targetIndex","minDistance","Infinity","distance","Math","abs","translateY","index","lowerPosition","sort","a","b","undefined","upperPosition","resolveDetent","contentHeight","maxHeight","detentValueInput","min","Error","clampIndex","detentCount","max"],"sourceRoot":"../../src","sources":["bottomSheetUtils.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["programmatic","value","detentValue","detent","isDetentProgrammatic","VELOCITY_THRESHOLD","findSnapTarget","currentTranslate","velocityY","currentIndex","allPositions","draggablePositions","filter","position","isDraggable","effectivePositions","length","targetIndex","minDistance","Infinity","distance","Math","abs","translateY","index","lowerPosition","sort","a","b","undefined","upperPosition","resolveDetent","contentHeight","maxHeight","detentValueInput","min","Error","clampIndex","detentCount","max"],"sourceRoot":"../../src","sources":["bottomSheetUtils.ts"],"mappings":"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","ignoreList":[]}
@@ -3,17 +3,37 @@ import type { StyleProp, ViewStyle } from 'react-native';
3
3
  import { type Detent } from './bottomSheetUtils';
4
4
  export type { Detent, DetentValue } from './bottomSheetUtils';
5
5
  export { programmatic } from './bottomSheetUtils';
6
+ /**
7
+ * Props for the inline bottom-sheet component.
8
+ */
6
9
  export interface BottomSheetProps {
10
+ /** Sheet contents, including any background or scrollable content. */
7
11
  children: ReactNode;
12
+ /** Additional style applied to the native sheet host view. */
8
13
  style?: StyleProp<ViewStyle>;
14
+ /** Snap points for the sheet. Defaults to `[0, 'content']`. */
9
15
  detents?: Detent[];
16
+ /** Zero-based index into `detents`. */
10
17
  index: number;
18
+ /** Whether the sheet should animate in on first layout. */
11
19
  animateIn?: boolean;
20
+ /** Called after a user-driven snap changes the active index. */
12
21
  onIndexChange?: (index: number) => void;
22
+ /** Called when a snap animation settles, including programmatic changes. */
13
23
  onSettle?: (index: number) => void;
24
+ /** Called as the sheet position changes, in points from the bottom. */
14
25
  onPositionChange?: (position: number) => void;
26
+ /** Internal flag used by `ModalBottomSheet`. */
15
27
  modal?: boolean;
28
+ /**
29
+ * Escape hatch that disables sheet/list gesture negotiation.
30
+ * If a gesture starts inside a nested scrollable, that scrollable keeps it
31
+ * even when it cannot scroll any further.
32
+ */
33
+ disableScrollableNegotiation?: boolean;
34
+ /** Scrim color used by `ModalBottomSheet`. */
16
35
  scrimColor?: string;
17
36
  }
18
- export declare const BottomSheet: ({ children, style, detents, index, animateIn, onIndexChange, onSettle, onPositionChange, modal, scrimColor, }: BottomSheetProps) => import("react/jsx-runtime").JSX.Element;
37
+ /** Native bottom sheet that renders inline within the current screen layout. */
38
+ export declare const BottomSheet: ({ children, style, detents, index, animateIn, onIndexChange, onSettle, onPositionChange, modal, disableScrollableNegotiation, scrimColor, }: BottomSheetProps) => import("react/jsx-runtime").JSX.Element;
19
39
  //# sourceMappingURL=BottomSheet.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"BottomSheet.d.ts","sourceRoot":"","sources":["../../../src/BottomSheet.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAMzD,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,WAAW,GAAI,+GAWzB,gBAAgB,4CAuFlB,CAAC"}
1
+ {"version":3,"file":"BottomSheet.d.ts","sourceRoot":"","sources":["../../../src/BottomSheet.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAMzD,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,sEAAsE;IACtE,QAAQ,EAAE,SAAS,CAAC;IACpB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gEAAgE;IAChE,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,uEAAuE;IACvE,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,gDAAgD;IAChD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,gFAAgF;AAChF,eAAO,MAAM,WAAW,GAAI,6IAYzB,gBAAgB,4CAwFlB,CAAC"}
@@ -10,6 +10,7 @@ export interface NativeProps extends ViewProps {
10
10
  index: CodegenTypes.Int32;
11
11
  animateIn: boolean;
12
12
  modal: boolean;
13
+ disableScrollableNegotiation?: boolean;
13
14
  scrimColor?: ColorValue;
14
15
  onIndexChange?: CodegenTypes.DirectEventHandler<Readonly<{
15
16
  index: CodegenTypes.Int32;
@@ -1 +1 @@
1
- {"version":3,"file":"BottomSheetNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/BottomSheetNativeComponent.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAEtB,KAAK,YAAY,GAAG,QAAQ,CAAC;IAC3B,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,OAAO,CAAC;CACvB,CAAC,CAAC;AAEH,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC5C,OAAO,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IACrC,eAAe,EAAE,YAAY,CAAC,MAAM,CAAC;IACrC,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,aAAa,CAAC,EAAE,YAAY,CAAC,kBAAkB,CAC7C,QAAQ,CAAC;QAAE,KAAK,EAAE,YAAY,CAAC,KAAK,CAAA;KAAE,CAAC,CACxC,CAAC;IACF,QAAQ,CAAC,EAAE,YAAY,CAAC,kBAAkB,CACxC,QAAQ,CAAC;QAAE,KAAK,EAAE,YAAY,CAAC,KAAK,CAAA;KAAE,CAAC,CACxC,CAAC;IACF,gBAAgB,CAAC,EAAE,YAAY,CAAC,kBAAkB,CAChD,QAAQ,CAAC;QAAE,QAAQ,EAAE,YAAY,CAAC,MAAM,CAAA;KAAE,CAAC,CAC5C,CAAC;CACH;;AAED,wBAAsE"}
1
+ {"version":3,"file":"BottomSheetNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/BottomSheetNativeComponent.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAEtB,KAAK,YAAY,GAAG,QAAQ,CAAC;IAC3B,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,OAAO,CAAC;CACvB,CAAC,CAAC;AAEH,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC5C,OAAO,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IACrC,eAAe,EAAE,YAAY,CAAC,MAAM,CAAC;IACrC,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;IACf,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,aAAa,CAAC,EAAE,YAAY,CAAC,kBAAkB,CAC7C,QAAQ,CAAC;QAAE,KAAK,EAAE,YAAY,CAAC,KAAK,CAAA;KAAE,CAAC,CACxC,CAAC;IACF,QAAQ,CAAC,EAAE,YAAY,CAAC,kBAAkB,CACxC,QAAQ,CAAC;QAAE,KAAK,EAAE,YAAY,CAAC,KAAK,CAAA;KAAE,CAAC,CACxC,CAAC;IACF,gBAAgB,CAAC,EAAE,YAAY,CAAC,kBAAkB,CAChD,QAAQ,CAAC;QAAE,QAAQ,EAAE,YAAY,CAAC,MAAM,CAAA;KAAE,CAAC,CAC5C,CAAC;CACH;;AAED,wBAAsE"}
@@ -1,4 +1,5 @@
1
1
  import type { ReactNode } from 'react';
2
+ /** Provides the portal host required for modal bottom sheets. */
2
3
  export declare const BottomSheetProvider: ({ children }: {
3
4
  children: ReactNode;
4
5
  }) => import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"BottomSheetProvider.d.ts","sourceRoot":"","sources":["../../../src/BottomSheetProvider.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AA0BvC,eAAO,MAAM,mBAAmB,GAAI,cAAc;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,4CAgCxE,CAAC;AAEF,eAAO,MAAM,MAAM,GAAI,cAAc;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,SAkB3D,CAAC"}
1
+ {"version":3,"file":"BottomSheetProvider.d.ts","sourceRoot":"","sources":["../../../src/BottomSheetProvider.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AA0BvC,iEAAiE;AACjE,eAAO,MAAM,mBAAmB,GAAI,cAAc;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,4CAgCxE,CAAC;AAEF,eAAO,MAAM,MAAM,GAAI,cAAc;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,SAkB3D,CAAC"}
@@ -1,5 +1,7 @@
1
1
  import { type BottomSheetProps } from './BottomSheet';
2
+ /** Props for the modal bottom-sheet variant rendered through the provider portal. */
2
3
  export interface ModalBottomSheetProps extends Omit<BottomSheetProps, 'modal'> {
3
4
  }
5
+ /** Bottom sheet presented above the current UI with a scrim. */
4
6
  export declare const ModalBottomSheet: (props: ModalBottomSheetProps) => import("react/jsx-runtime").JSX.Element;
5
7
  //# sourceMappingURL=ModalBottomSheet.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ModalBottomSheet.d.ts","sourceRoot":"","sources":["../../../src/ModalBottomSheet.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEnE,MAAM,WAAW,qBACf,SAAQ,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC;CAAG;AAE5C,eAAO,MAAM,gBAAgB,GAAI,OAAO,qBAAqB,4CAE5D,CAAC"}
1
+ {"version":3,"file":"ModalBottomSheet.d.ts","sourceRoot":"","sources":["../../../src/ModalBottomSheet.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEnE,qFAAqF;AACrF,MAAM,WAAW,qBACf,SAAQ,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC;CAAG;AAE5C,gEAAgE;AAChE,eAAO,MAAM,gBAAgB,GAAI,OAAO,qBAAqB,4CAE5D,CAAC"}
@@ -1,8 +1,11 @@
1
+ /** A detent value in points, or `'content'` to size to the measured content height. */
1
2
  export type DetentValue = number | 'content';
3
+ /** A draggable detent or an object form that can mark a detent as programmatic-only. */
2
4
  export type Detent = DetentValue | {
3
5
  value: DetentValue;
4
6
  programmatic?: boolean;
5
7
  };
8
+ /** Marks a detent as reachable only via controlled `index` updates, not dragging. */
6
9
  export declare const programmatic: (value: DetentValue) => Detent;
7
10
  export declare const detentValue: (detent: Detent) => DetentValue;
8
11
  export declare const isDetentProgrammatic: (detent: Detent) => boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"bottomSheetUtils.d.ts","sourceRoot":"","sources":["../../../src/bottomSheetUtils.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,SAAS,CAAC;AAE7C,MAAM,MAAM,MAAM,GACd,WAAW,GACX;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEnD,eAAO,MAAM,YAAY,GAAI,OAAO,WAAW,KAAG,MAGhD,CAAC;AAEH,eAAO,MAAM,WAAW,GAAI,QAAQ,MAAM,KAAG,WAG5C,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,QAAQ,MAAM,KAAG,OAKrD,CAAC;AAIF,eAAO,MAAM,cAAc,GACzB,kBAAkB,MAAM,EACxB,WAAW,MAAM,EACjB,cAAc,MAAM,EACpB,cAAc;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,EAAE,WAiC5E,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,QAAQ,MAAM,EACd,eAAe,MAAM,EACrB,WAAW,MAAM,WAQlB,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,EAAE,aAAa,MAAM,WAG5D,CAAC"}
1
+ {"version":3,"file":"bottomSheetUtils.d.ts","sourceRoot":"","sources":["../../../src/bottomSheetUtils.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,SAAS,CAAC;AAE7C,wFAAwF;AACxF,MAAM,MAAM,MAAM,GACd,WAAW,GACX;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEnD,qFAAqF;AACrF,eAAO,MAAM,YAAY,GAAI,OAAO,WAAW,KAAG,MAGhD,CAAC;AAEH,eAAO,MAAM,WAAW,GAAI,QAAQ,MAAM,KAAG,WAG5C,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,QAAQ,MAAM,KAAG,OAKrD,CAAC;AAIF,eAAO,MAAM,cAAc,GACzB,kBAAkB,MAAM,EACxB,WAAW,MAAM,EACjB,cAAc,MAAM,EACpB,cAAc;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,EAAE,WAiC5E,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,QAAQ,MAAM,EACd,eAAe,MAAM,EACrB,WAAW,MAAM,WAQlB,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,EAAE,aAAa,MAAM,WAG5D,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swmansion/react-native-bottom-sheet",
3
- "version": "0.9.0-next.2",
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",
@@ -9,19 +9,39 @@ import { type Detent } from './bottomSheetUtils';
9
9
  export type { Detent, DetentValue } from './bottomSheetUtils';
10
10
  export { programmatic } from './bottomSheetUtils';
11
11
 
12
+ /**
13
+ * Props for the inline bottom-sheet component.
14
+ */
12
15
  export interface BottomSheetProps {
16
+ /** Sheet contents, including any background or scrollable content. */
13
17
  children: ReactNode;
18
+ /** Additional style applied to the native sheet host view. */
14
19
  style?: StyleProp<ViewStyle>;
20
+ /** Snap points for the sheet. Defaults to `[0, 'content']`. */
15
21
  detents?: Detent[];
22
+ /** Zero-based index into `detents`. */
16
23
  index: number;
24
+ /** Whether the sheet should animate in on first layout. */
17
25
  animateIn?: boolean;
26
+ /** Called after a user-driven snap changes the active index. */
18
27
  onIndexChange?: (index: number) => void;
28
+ /** Called when a snap animation settles, including programmatic changes. */
19
29
  onSettle?: (index: number) => void;
30
+ /** Called as the sheet position changes, in points from the bottom. */
20
31
  onPositionChange?: (position: number) => void;
32
+ /** Internal flag used by `ModalBottomSheet`. */
21
33
  modal?: boolean;
34
+ /**
35
+ * Escape hatch that disables sheet/list gesture negotiation.
36
+ * If a gesture starts inside a nested scrollable, that scrollable keeps it
37
+ * even when it cannot scroll any further.
38
+ */
39
+ disableScrollableNegotiation?: boolean;
40
+ /** Scrim color used by `ModalBottomSheet`. */
22
41
  scrimColor?: string;
23
42
  }
24
43
 
44
+ /** Native bottom sheet that renders inline within the current screen layout. */
25
45
  export const BottomSheet = ({
26
46
  children,
27
47
  style,
@@ -32,6 +52,7 @@ export const BottomSheet = ({
32
52
  onSettle,
33
53
  onPositionChange,
34
54
  modal = false,
55
+ disableScrollableNegotiation = false,
35
56
  scrimColor,
36
57
  }: BottomSheetProps) => {
37
58
  const { height: windowHeight } = useWindowDimensions();
@@ -101,6 +122,7 @@ export const BottomSheet = ({
101
122
  index={index}
102
123
  animateIn={animateIn}
103
124
  modal={modal}
125
+ disableScrollableNegotiation={disableScrollableNegotiation}
104
126
  scrimColor={scrimColor}
105
127
  onIndexChange={handleIndexChange}
106
128
  onSettle={handleSettle}
@@ -17,6 +17,7 @@ export interface NativeProps extends ViewProps {
17
17
  index: CodegenTypes.Int32;
18
18
  animateIn: boolean;
19
19
  modal: boolean;
20
+ disableScrollableNegotiation?: boolean;
20
21
  scrimColor?: ColorValue;
21
22
  onIndexChange?: CodegenTypes.DirectEventHandler<
22
23
  Readonly<{ index: CodegenTypes.Int32 }>
@@ -32,6 +32,7 @@ const PortalHost = () => {
32
32
  ));
33
33
  };
34
34
 
35
+ /** Provides the portal host required for modal bottom sheets. */
35
36
  export const BottomSheetProvider = ({ children }: { children: ReactNode }) => {
36
37
  const [context] = useState<PortalContextType>(() => {
37
38
  const portals = new Map<string, ReactNode>();
@@ -1,8 +1,10 @@
1
1
  import { BottomSheet, type BottomSheetProps } from './BottomSheet';
2
2
 
3
+ /** Props for the modal bottom-sheet variant rendered through the provider portal. */
3
4
  export interface ModalBottomSheetProps
4
5
  extends Omit<BottomSheetProps, 'modal'> {}
5
6
 
7
+ /** Bottom sheet presented above the current UI with a scrim. */
6
8
  export const ModalBottomSheet = (props: ModalBottomSheetProps) => (
7
9
  <BottomSheet {...props} modal />
8
10
  );
@@ -1,9 +1,12 @@
1
+ /** A detent value in points, or `'content'` to size to the measured content height. */
1
2
  export type DetentValue = number | 'content';
2
3
 
4
+ /** A draggable detent or an object form that can mark a detent as programmatic-only. */
3
5
  export type Detent =
4
6
  | DetentValue
5
7
  | { value: DetentValue; programmatic?: boolean };
6
8
 
9
+ /** Marks a detent as reachable only via controlled `index` updates, not dragging. */
7
10
  export const programmatic = (value: DetentValue): Detent => ({
8
11
  value,
9
12
  programmatic: true,