@swmansion/react-native-bottom-sheet 0.10.0-next.3 → 0.10.0-next.4
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.
|
@@ -85,6 +85,7 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
|
|
|
85
85
|
private var scrimColor = Color.TRANSPARENT
|
|
86
86
|
private var scrimProgress = 0f
|
|
87
87
|
private var suppressScrimForClosingTarget = false
|
|
88
|
+
private var scrimPinnedFull = false
|
|
88
89
|
private var maxDetentHeight = Float.NaN
|
|
89
90
|
private var contentHeightMarker: View? = null
|
|
90
91
|
|
|
@@ -294,6 +295,13 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
|
|
|
294
295
|
}
|
|
295
296
|
|
|
296
297
|
val previousMaxHeight = detentSpecs.maxOfOrNull { it.height } ?: resolvedMaxDetentHeight()
|
|
298
|
+
// Whether the scrim is currently fully opaque, i.e. the sheet is settled at
|
|
299
|
+
// or above the first non-zero detent. If so, a detent resize must not dip
|
|
300
|
+
// the scrim while the sheet re-anchors to the new geometry.
|
|
301
|
+
val wasScrimFull =
|
|
302
|
+
modal &&
|
|
303
|
+
firstNonZeroDetentHeight > 0f &&
|
|
304
|
+
currentSheetHeight() + 0.5f >= firstNonZeroDetentHeight
|
|
297
305
|
detentSpecs = resolvedDetents
|
|
298
306
|
if (width > 0 && height > 0 && detentSpecs.isNotEmpty()) {
|
|
299
307
|
layoutSheetContainer(width, height)
|
|
@@ -317,8 +325,15 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
|
|
|
317
325
|
// sheet surface keeps the same on-screen height across the resize.
|
|
318
326
|
val visibleHeight = previousMaxHeight - currentTy
|
|
319
327
|
sheetContainer.translationY = (newMaxHeight - visibleHeight).coerceIn(0f, newMaxHeight)
|
|
328
|
+
scrimPinnedFull = scrimPinnedFull || wasScrimFull
|
|
320
329
|
emitPosition()
|
|
321
|
-
snapToIndex(
|
|
330
|
+
snapToIndex(
|
|
331
|
+
targetIndex,
|
|
332
|
+
0f,
|
|
333
|
+
emitIndexChange = false,
|
|
334
|
+
emitSettle = shouldEmitSettle,
|
|
335
|
+
preserveScrimPin = true,
|
|
336
|
+
)
|
|
322
337
|
} else {
|
|
323
338
|
val currentVisibleHeight = previousMaxHeight - sheetContainer.translationY
|
|
324
339
|
val targetHeight = detentSpecs.getOrNull(targetIndex)?.height ?: 0f
|
|
@@ -332,8 +347,15 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
|
|
|
332
347
|
// up to the taller detent.
|
|
333
348
|
sheetContainer.translationY =
|
|
334
349
|
(newMaxHeight - currentVisibleHeight).coerceIn(0f, newMaxHeight)
|
|
350
|
+
scrimPinnedFull = scrimPinnedFull || wasScrimFull
|
|
335
351
|
emitPosition()
|
|
336
|
-
snapToIndex(
|
|
352
|
+
snapToIndex(
|
|
353
|
+
targetIndex,
|
|
354
|
+
0f,
|
|
355
|
+
emitIndexChange = false,
|
|
356
|
+
emitSettle = false,
|
|
357
|
+
preserveScrimPin = true,
|
|
358
|
+
)
|
|
337
359
|
}
|
|
338
360
|
}
|
|
339
361
|
}
|
|
@@ -474,12 +496,16 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
|
|
|
474
496
|
velocity: Float,
|
|
475
497
|
emitIndexChange: Boolean = true,
|
|
476
498
|
emitSettle: Boolean = true,
|
|
499
|
+
preserveScrimPin: Boolean = false,
|
|
477
500
|
) {
|
|
478
501
|
if (index < 0 || index >= detentSpecs.size) return
|
|
479
502
|
targetIndex = index
|
|
480
503
|
if (!isTargetingClosedDetent) {
|
|
481
504
|
suppressScrimForClosingTarget = false
|
|
482
505
|
}
|
|
506
|
+
if (!preserveScrimPin) {
|
|
507
|
+
scrimPinnedFull = false
|
|
508
|
+
}
|
|
483
509
|
|
|
484
510
|
val targetTy = translationY(index)
|
|
485
511
|
val currentTy = sheetContainer.translationY
|
|
@@ -504,6 +530,7 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
|
|
|
504
530
|
activeAnimation = null
|
|
505
531
|
activeAnimationEmitsSettle = false
|
|
506
532
|
suppressScrimForClosingTarget = false
|
|
533
|
+
scrimPinnedFull = false
|
|
507
534
|
if (closedIndex == index) {
|
|
508
535
|
sheetContainer.translationY = translationY(index)
|
|
509
536
|
hideScrim()
|
|
@@ -693,6 +720,7 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
|
|
|
693
720
|
|
|
694
721
|
private fun beginPan(event: MotionEvent) {
|
|
695
722
|
isPanning = true
|
|
723
|
+
scrimPinnedFull = false
|
|
696
724
|
panStartingIndex = targetIndex
|
|
697
725
|
activePointerId = event.getPointerId(0)
|
|
698
726
|
lastTouchY = event.y
|
|
@@ -818,6 +846,15 @@ class BottomSheetView(context: Context) : ReactViewGroup(context) {
|
|
|
818
846
|
return
|
|
819
847
|
}
|
|
820
848
|
|
|
849
|
+
// While the sheet is fully open and only its content/detent geometry is
|
|
850
|
+
// resizing, the position momentarily lags the grown detent height. Keep the
|
|
851
|
+
// scrim at full opacity instead of dipping it until the re-anchor settles.
|
|
852
|
+
if (scrimPinnedFull) {
|
|
853
|
+
scrimProgress = 1f
|
|
854
|
+
invalidate()
|
|
855
|
+
return
|
|
856
|
+
}
|
|
857
|
+
|
|
821
858
|
val threshold = firstNonZeroDetentHeight
|
|
822
859
|
scrimProgress = if (threshold <= 0f) 0f else (position / threshold).coerceIn(0f, 1f)
|
|
823
860
|
invalidate()
|
|
@@ -55,6 +55,7 @@ public final class RNSBottomSheetHostingView: UIView {
|
|
|
55
55
|
private var panGesture: UIPanGestureRecognizer!
|
|
56
56
|
private var activeAnimator: UIViewPropertyAnimator?
|
|
57
57
|
private var activeAnimatorEmitsSettle = false
|
|
58
|
+
private var scrimPinnedFull = false
|
|
58
59
|
private var displayLink: CADisplayLink?
|
|
59
60
|
private var pendingIndex: Int?
|
|
60
61
|
private var hasLaidOut = false
|
|
@@ -364,10 +365,14 @@ public final class RNSBottomSheetHostingView: UIView {
|
|
|
364
365
|
_ index: Int,
|
|
365
366
|
velocity: CGFloat,
|
|
366
367
|
emitIndexChange: Bool = true,
|
|
367
|
-
emitSettle: Bool = true
|
|
368
|
+
emitSettle: Bool = true,
|
|
369
|
+
preserveScrimPin: Bool = false
|
|
368
370
|
) {
|
|
369
371
|
guard index >= 0, index < detentSpecs.count else { return }
|
|
370
372
|
targetIndex = index
|
|
373
|
+
if !preserveScrimPin {
|
|
374
|
+
scrimPinnedFull = false
|
|
375
|
+
}
|
|
371
376
|
|
|
372
377
|
let currentTy = sheetContainer.transform.ty
|
|
373
378
|
let targetTy = translationY(for: index)
|
|
@@ -391,6 +396,7 @@ public final class RNSBottomSheetHostingView: UIView {
|
|
|
391
396
|
self.emitPosition()
|
|
392
397
|
self.activeAnimator = nil
|
|
393
398
|
self.activeAnimatorEmitsSettle = false
|
|
399
|
+
self.scrimPinnedFull = false
|
|
394
400
|
self.setContentInteractionEnabled(true)
|
|
395
401
|
self.updateInteractionState()
|
|
396
402
|
if emitIndexChange {
|
|
@@ -411,6 +417,7 @@ public final class RNSBottomSheetHostingView: UIView {
|
|
|
411
417
|
switch gesture.state {
|
|
412
418
|
case .began:
|
|
413
419
|
isPanning = true
|
|
420
|
+
scrimPinnedFull = false
|
|
414
421
|
panStartingIndex = targetIndex
|
|
415
422
|
sheetContainer.endEditing(true)
|
|
416
423
|
setContentInteractionEnabled(false)
|
|
@@ -609,6 +616,12 @@ public final class RNSBottomSheetHostingView: UIView {
|
|
|
609
616
|
}
|
|
610
617
|
|
|
611
618
|
let previousMaxHeight = maximumResolvedDetentHeight ?? resolvedMaxDetentHeight
|
|
619
|
+
// Whether the scrim is currently fully opaque, i.e. the sheet is settled at
|
|
620
|
+
// or above the first non-zero detent. If so, a detent resize must not dip
|
|
621
|
+
// the scrim while the sheet re-anchors to the new geometry.
|
|
622
|
+
let wasScrimFull = modal
|
|
623
|
+
&& firstNonZeroDetentHeight > 0
|
|
624
|
+
&& currentSheetHeight + 0.5 >= firstNonZeroDetentHeight
|
|
612
625
|
detentSpecs = resolvedDetents
|
|
613
626
|
|
|
614
627
|
guard bounds.width > 0, bounds.height > 0, !detentSpecs.isEmpty else {
|
|
@@ -632,8 +645,15 @@ public final class RNSBottomSheetHostingView: UIView {
|
|
|
632
645
|
let visibleHeight = previousMaxHeight - visualTy
|
|
633
646
|
let reanchoredTy = min(max(newMaxHeight - visibleHeight, 0), newMaxHeight)
|
|
634
647
|
sheetContainer.transform = CGAffineTransform(translationX: 0, y: reanchoredTy)
|
|
648
|
+
scrimPinnedFull = scrimPinnedFull || wasScrimFull
|
|
635
649
|
emitPosition()
|
|
636
|
-
snapToIndex(
|
|
650
|
+
snapToIndex(
|
|
651
|
+
targetIndex,
|
|
652
|
+
velocity: 0,
|
|
653
|
+
emitIndexChange: false,
|
|
654
|
+
emitSettle: shouldEmitSettle,
|
|
655
|
+
preserveScrimPin: true
|
|
656
|
+
)
|
|
637
657
|
} else {
|
|
638
658
|
let currentVisibleHeight = previousMaxHeight - currentTranslationY
|
|
639
659
|
let targetHeight = detent(at: targetIndex).height
|
|
@@ -647,8 +667,15 @@ public final class RNSBottomSheetHostingView: UIView {
|
|
|
647
667
|
// up to the taller detent.
|
|
648
668
|
let startTy = min(max(newMaxHeight - currentVisibleHeight, 0), newMaxHeight)
|
|
649
669
|
sheetContainer.transform = CGAffineTransform(translationX: 0, y: startTy)
|
|
670
|
+
scrimPinnedFull = scrimPinnedFull || wasScrimFull
|
|
650
671
|
emitPosition()
|
|
651
|
-
snapToIndex(
|
|
672
|
+
snapToIndex(
|
|
673
|
+
targetIndex,
|
|
674
|
+
velocity: 0,
|
|
675
|
+
emitIndexChange: false,
|
|
676
|
+
emitSettle: false,
|
|
677
|
+
preserveScrimPin: true
|
|
678
|
+
)
|
|
652
679
|
}
|
|
653
680
|
}
|
|
654
681
|
}
|
|
@@ -786,6 +813,15 @@ private extension RNSBottomSheetHostingView {
|
|
|
786
813
|
return
|
|
787
814
|
}
|
|
788
815
|
|
|
816
|
+
// While the sheet is fully open and only its content/detent geometry is
|
|
817
|
+
// resizing, the position momentarily lags the grown detent height. Keep the
|
|
818
|
+
// scrim at full opacity instead of dipping it until the re-anchor settles.
|
|
819
|
+
if scrimPinnedFull {
|
|
820
|
+
scrimView.alpha = 1
|
|
821
|
+
scrimView.isHidden = false
|
|
822
|
+
return
|
|
823
|
+
}
|
|
824
|
+
|
|
789
825
|
let threshold = firstNonZeroDetentHeight
|
|
790
826
|
let progress: CGFloat
|
|
791
827
|
if threshold <= 0 {
|
package/package.json
CHANGED