react-native-nitro-modal 0.3.1-rc → 0.3.4-rc

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 (50) hide show
  1. package/README.md +4 -1
  2. package/android/src/main/java/com/margelo/nitro/nitromodal/BottomSheetPresenter.kt +29 -15
  3. package/android/src/main/java/com/margelo/nitro/nitromodal/HybridNitroModal.kt +5 -0
  4. package/android/src/main/java/com/margelo/nitro/nitromodal/ModalConfig.kt +3 -0
  5. package/android/src/main/java/com/margelo/nitro/nitromodal/PopupPresenter.kt +6 -0
  6. package/ios/HybridNitroModal.swift +4 -0
  7. package/ios/ModalConfig.swift +3 -0
  8. package/ios/PopupViewController.swift +2 -0
  9. package/ios/SheetView.swift +56 -21
  10. package/lib/module/NitroModal.js +4 -0
  11. package/lib/module/NitroModal.js.map +1 -1
  12. package/lib/module/NitroModalView.web.js +24 -8
  13. package/lib/module/NitroModalView.web.js.map +1 -1
  14. package/lib/module/web/ModalConfig.js +2 -0
  15. package/lib/module/web/ModalConfig.js.map +1 -1
  16. package/lib/module/web/ModalPresenter.js +5 -0
  17. package/lib/module/web/ModalPresenter.js.map +1 -1
  18. package/lib/module/web/SheetPresenter.js +50 -11
  19. package/lib/module/web/SheetPresenter.js.map +1 -1
  20. package/lib/typescript/src/NitroModal.d.ts +8 -1
  21. package/lib/typescript/src/NitroModal.d.ts.map +1 -1
  22. package/lib/typescript/src/NitroModal.nitro.d.ts +4 -0
  23. package/lib/typescript/src/NitroModal.nitro.d.ts.map +1 -1
  24. package/lib/typescript/src/NitroModalView.web.d.ts.map +1 -1
  25. package/lib/typescript/src/web/ModalConfig.d.ts +4 -0
  26. package/lib/typescript/src/web/ModalConfig.d.ts.map +1 -1
  27. package/lib/typescript/src/web/ModalPresenter.d.ts +3 -1
  28. package/lib/typescript/src/web/ModalPresenter.d.ts.map +1 -1
  29. package/lib/typescript/src/web/SheetPresenter.d.ts +14 -2
  30. package/lib/typescript/src/web/SheetPresenter.d.ts.map +1 -1
  31. package/nitrogen/generated/android/c++/JHybridNitroModalSpec.cpp +18 -0
  32. package/nitrogen/generated/android/c++/JHybridNitroModalSpec.hpp +4 -0
  33. package/nitrogen/generated/android/c++/views/JHybridNitroModalStateUpdater.cpp +10 -0
  34. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromodal/HybridNitroModalSpec.kt +12 -0
  35. package/nitrogen/generated/ios/c++/HybridNitroModalSpecSwift.hpp +13 -0
  36. package/nitrogen/generated/ios/c++/views/HybridNitroModalComponent.mm +12 -0
  37. package/nitrogen/generated/ios/swift/HybridNitroModalSpec.swift +2 -0
  38. package/nitrogen/generated/ios/swift/HybridNitroModalSpec_cxx.swift +35 -0
  39. package/nitrogen/generated/shared/c++/HybridNitroModalSpec.cpp +4 -0
  40. package/nitrogen/generated/shared/c++/HybridNitroModalSpec.hpp +4 -0
  41. package/nitrogen/generated/shared/c++/views/HybridNitroModalComponent.cpp +4 -0
  42. package/nitrogen/generated/shared/c++/views/HybridNitroModalComponent.hpp +6 -0
  43. package/nitrogen/generated/shared/json/NitroModalConfig.json +2 -0
  44. package/package.json +1 -1
  45. package/src/NitroModal.nitro.ts +4 -0
  46. package/src/NitroModal.tsx +11 -0
  47. package/src/NitroModalView.web.tsx +16 -3
  48. package/src/web/ModalConfig.ts +9 -0
  49. package/src/web/ModalPresenter.ts +9 -1
  50. package/src/web/SheetPresenter.ts +39 -13
package/README.md CHANGED
@@ -142,8 +142,9 @@ A sheet hands drags off to the scroll view under the finger:
142
142
 
143
143
  - Dragging up expands the sheet first, then scrolls the content.
144
144
  - Dragging down scrolls the content back to its top. Once the content has scrolled during a drag, that drag never moves the sheet; the next drag collapses it.
145
+ - A sheet that can't be swiped away (inline, or `dismissOnSwipe={false}`) and has no `onPullToRefresh` stops at its lowest detent. Dragging down further pulls the scrollable content instead, so a `RefreshControl` on it works, with its indicator inside the sheet (iOS and Android).
145
146
  - With `onPullToRefresh` set, a drag that starts with the sheet resting on its lowest detent can pull it further down. Letting go past the threshold calls `onPullToRefresh` (with haptic feedback when it is crossed). This needs a sheet that can't be swiped away: inline, or `dismissOnSwipe={false}`.
146
- - With `refreshing` set too, an activity indicator shows in the gap the pull uncovers, and the sheet stays pulled down while `refreshing` is `true`, like `RefreshControl`. Set it to `true` in `onPullToRefresh` and back to `false` when the refresh is done. Setting it to `true` yourself shows the indicator without a pull.
147
+ - With `refreshing` set too, the sheet stays on its lowest detent and its content moves down inside it, uncovering an activity indicator at the top of the sheet. The content stays pulled down while `refreshing` is `true`, like `RefreshControl`. Set it to `true` in `onPullToRefresh` and back to `false` when the refresh is done. Setting it to `true` yourself shows the indicator without a pull.
147
148
 
148
149
  On Android, scrollable content takes part through nested scrolling, so set `nestedScrollEnabled` on it.
149
150
 
@@ -216,6 +217,8 @@ const sheet = useRef<NitroModalRef>(null);
216
217
  | `dismissOnBackButton` | `boolean` | `true` | The Android back button/gesture (Escape on web) closes the modal. |
217
218
  | `showGrabber` | `boolean` | `false` | Shows the drag handle on a bottom sheet. |
218
219
  | `cornerRadius` | `number` | platform default | Corner radius of the sheet/card. |
220
+ | `borderWidth` | `number` | `0` | Width of a border around the sheet/card, drawn above the content. |
221
+ | `borderColor` | `ColorValue` | `'transparent'` | Color of the border. |
219
222
  | `backgroundColor` | `ColorValue` | system surface | Background of the sheet/card. |
220
223
  | `keyboardBehavior` | `'pan' \| 'resize' \| 'none'` | `'pan'` | How the modal reacts to the software keyboard. |
221
224
  | `popupAnimation` | `'scale' \| 'fade' \| 'none'` | `'scale'` | Enter/exit transition of a popup. |
@@ -8,6 +8,7 @@ import android.content.res.ColorStateList
8
8
  import android.graphics.Color
9
9
  import android.graphics.Outline
10
10
  import android.graphics.drawable.GradientDrawable
11
+ import android.graphics.drawable.InsetDrawable
11
12
  import android.os.Build
12
13
  import android.view.Gravity
13
14
  import android.view.HapticFeedbackConstants
@@ -62,6 +63,8 @@ internal class BottomSheetPresenter(
62
63
  private val refreshIndicator = ProgressBar(activity)
63
64
  private val behavior = SheetBehavior()
64
65
  private val sheetBackground = GradientDrawable()
66
+ /** The border, as the sheet's foreground so the content can't cover it. */
67
+ private val sheetBorder = GradientDrawable()
65
68
  private var cornerRadiusPx = 0f
66
69
 
67
70
  /** Resting detents sorted by height; position i maps to [states][i]. */
@@ -133,18 +136,9 @@ internal class BottomSheetPresenter(
133
136
  layoutRefreshIndicator()
134
137
  }
135
138
 
136
- // Behind the sheet, which uncovers it as it's pulled down.
137
- refreshIndicator.isIndeterminate = true
138
- refreshIndicator.visibility = View.INVISIBLE
139
- refreshIndicator.importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
140
- coordinator.addView(
141
- refreshIndicator,
142
- CoordinatorLayout.LayoutParams(dp(REFRESH_INDICATOR_SIZE_DP), dp(REFRESH_INDICATOR_SIZE_DP)).apply {
143
- gravity = Gravity.TOP or Gravity.CENTER_HORIZONTAL
144
- },
145
- )
146
-
147
139
  sheet.background = sheetBackground
140
+ // Extends past the bottom edge so only the top and sides show.
141
+ sheet.foreground = InsetDrawable(sheetBorder, 0, 0, 0, -dp(BORDER_OVERHANG_DP))
148
142
  sheet.outlineProvider = object : ViewOutlineProvider() {
149
143
  override fun getOutline(view: View, outline: Outline) {
150
144
  // Extends past the bottom edge so only the top corners round. A round
@@ -155,6 +149,18 @@ internal class BottomSheetPresenter(
155
149
  }
156
150
  }
157
151
  sheet.clipToOutline = true
152
+ // Inside the sheet, behind the content, which uncovers it as it's pulled down.
153
+ refreshIndicator.isIndeterminate = true
154
+ refreshIndicator.visibility = View.INVISIBLE
155
+ refreshIndicator.importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
156
+ sheet.addView(
157
+ refreshIndicator,
158
+ FrameLayout.LayoutParams(
159
+ dp(REFRESH_INDICATOR_SIZE_DP),
160
+ dp(REFRESH_INDICATOR_SIZE_DP),
161
+ Gravity.TOP or Gravity.CENTER_HORIZONTAL,
162
+ ),
163
+ )
158
164
  sheet.addView(contentRoot, FrameLayout.LayoutParams(MATCH, MATCH))
159
165
  sheet.addView(
160
166
  grabber,
@@ -233,6 +239,7 @@ internal class BottomSheetPresenter(
233
239
  override fun onConfigChanged(previous: ModalConfig) {
234
240
  applyAppearance()
235
241
  if (previous.refreshing != config.refreshing) setRefreshing(config.refreshing ?: false)
242
+ applyTranslation()
236
243
  layoutRefreshIndicator()
237
244
  if (presented && !isDismissing) behavior.isHideable = config.dismissOnSwipe
238
245
  if (previous.detents != config.detents || previous.keyboardBehavior != config.keyboardBehavior) {
@@ -264,9 +271,11 @@ internal class BottomSheetPresenter(
264
271
  if (radius != cornerRadiusPx) {
265
272
  cornerRadiusPx = radius
266
273
  sheetBackground.cornerRadii = floatArrayOf(radius, radius, radius, radius, 0f, 0f, 0f, 0f)
274
+ sheetBorder.cornerRadii = sheetBackground.cornerRadii
267
275
  sheet.invalidateOutline()
268
276
  }
269
277
  sheetBackground.setColor(config.surfaceColor(activity))
278
+ sheetBorder.setStroke(ceil(activity.dpToPx(config.borderWidth)).toInt(), config.borderColor)
270
279
  grabber.visibility = if (config.grabberVisible) View.VISIBLE else View.GONE
271
280
  grabber.background = GradientDrawable().apply {
272
281
  cornerRadius = activity.dpToPx(2f)
@@ -386,7 +395,11 @@ internal class BottomSheetPresenter(
386
395
  val headroom = (sheet.top - systemInsets.top).coerceAtLeast(0)
387
396
  keyboardOverlap.coerceAtMost(headroom)
388
397
  }
389
- sheet.translationY = pullOffset - lift
398
+ // With a refresh indicator, the sheet stays on its lowest detent and the
399
+ // content moves down inside it, uncovering the indicator.
400
+ val pullsContent = config.refreshing != null
401
+ sheet.translationY = (if (pullsContent) 0f else pullOffset) - lift
402
+ contentRoot.translationY = if (pullsContent) pullOffset else 0f
390
403
  }
391
404
 
392
405
  private fun setPullOffset(offset: Float) {
@@ -419,12 +432,12 @@ internal class BottomSheetPresenter(
419
432
  }
420
433
 
421
434
  /**
422
- * Centered in the gap a pull uncovers below the lowest detent, fading in
423
- * as the pull nears the threshold.
435
+ * Centered in the gap a pull uncovers above the content, fading in as the
436
+ * pull nears the threshold.
424
437
  */
425
438
  private fun layoutRefreshIndicator() {
426
439
  val size = refreshIndicator.layoutParams?.height ?: return
427
- refreshIndicator.translationY = sheet.top + sheet.translationY - (refreshThreshold + size) / 2
440
+ refreshIndicator.translationY = (pullOffset - size) / 2
428
441
  val progress = if (config.refreshing == null || isDismissing) 0f else (pullOffset / refreshThreshold).coerceIn(0f, 1f)
429
442
  refreshIndicator.alpha = progress
430
443
  // Hidden, the indeterminate animation stops.
@@ -636,6 +649,7 @@ internal class BottomSheetPresenter(
636
649
  /** How far below its lowest detent the sheet must be pulled to refresh. */
637
650
  private const val REFRESH_THRESHOLD_DP = 56f
638
651
  private const val REFRESH_INDICATOR_SIZE_DP = 32f
652
+ private const val BORDER_OVERHANG_DP = 8f
639
653
  private const val PULL_RELEASE_DURATION = 300L
640
654
  private val THRESHOLD_FEEDBACK =
641
655
  if (Build.VERSION.SDK_INT >= 34) {
@@ -1,5 +1,6 @@
1
1
  package com.margelo.nitro.nitromodal
2
2
 
3
+ import android.graphics.Color
3
4
  import android.os.Handler
4
5
  import android.os.Looper
5
6
  import android.view.WindowManager
@@ -48,6 +49,8 @@ class HybridNitroModal(private val reactContext: ThemedReactContext) :
48
49
  override var dismissOnBackButton: Boolean = true
49
50
  override var grabberVisible: Boolean = false
50
51
  override var cornerRadius: Double = -1.0
52
+ override var borderWidth: Double = 0.0
53
+ override var borderColor: Double? = null
51
54
  override var contentBackgroundColor: Double? = null
52
55
  override var keyboardBehavior: KeyboardBehavior = KeyboardBehavior.PAN
53
56
  override var popupAnimation: PopupAnimation = PopupAnimation.SCALE
@@ -335,6 +338,8 @@ class HybridNitroModal(private val reactContext: ThemedReactContext) :
335
338
  dismissOnBackButton = dismissOnBackButton && !inline,
336
339
  grabberVisible = grabberVisible,
337
340
  cornerRadius = cornerRadius.takeIf { it >= 0 }?.toFloat(),
341
+ borderWidth = borderWidth.takeIf { it.isFinite() && it > 0 }?.toFloat() ?: 0f,
342
+ borderColor = borderColor?.toProcessedColor() ?: Color.TRANSPARENT,
338
343
  contentBackgroundColor = contentBackgroundColor?.toProcessedColor(),
339
344
  keyboardBehavior = keyboardBehavior,
340
345
  popupAnimation = popupAnimation,
@@ -44,6 +44,9 @@ internal data class ModalConfig(
44
44
  val grabberVisible: Boolean = false,
45
45
  /** dp, `null` uses the platform default. */
46
46
  val cornerRadius: Float? = null,
47
+ /** dp, drawn above the content around the sheet/card. */
48
+ val borderWidth: Float = 0f,
49
+ val borderColor: Int = Color.TRANSPARENT,
47
50
  /** `null` uses the system surface color. */
48
51
  val contentBackgroundColor: Int? = null,
49
52
  val keyboardBehavior: KeyboardBehavior = KeyboardBehavior.PAN,
@@ -12,6 +12,7 @@ import android.widget.FrameLayout
12
12
  import androidx.activity.BackEventCompat
13
13
  import androidx.core.graphics.Insets
14
14
  import com.facebook.react.uimanager.ThemedReactContext
15
+ import kotlin.math.ceil
15
16
 
16
17
  /**
17
18
  * `popup` mode: a centered card over the backdrop. Enter/exit are
@@ -33,12 +34,15 @@ internal class PopupPresenter(
33
34
  private val cardFrame = FrameLayout(activity)
34
35
  private val card = FrameLayout(activity)
35
36
  private val cardBackground = GradientDrawable()
37
+ /** The border, as the card's foreground so the content can't cover it. */
38
+ private val cardBorder = GradientDrawable()
36
39
  private var started = false
37
40
  private var backPreview = false
38
41
 
39
42
  override fun createLayout(): ViewGroup {
40
43
  root.addView(backdrop, FrameLayout.LayoutParams(MATCH, MATCH))
41
44
  card.background = cardBackground
45
+ card.foreground = cardBorder
42
46
  card.outlineProvider = ViewOutlineProvider.BACKGROUND
43
47
  card.clipToOutline = true
44
48
  card.addView(contentRoot, FrameLayout.LayoutParams(MATCH, MATCH))
@@ -166,6 +170,8 @@ internal class PopupPresenter(
166
170
  private fun applyAppearance() {
167
171
  cardBackground.cornerRadius = activity.dpToPx(config.cornerRadius ?: DEFAULT_CORNER_RADIUS_DP)
168
172
  cardBackground.setColor(config.surfaceColor(activity))
173
+ cardBorder.cornerRadius = cardBackground.cornerRadius
174
+ cardBorder.setStroke(ceil(activity.dpToPx(config.borderWidth)).toInt(), config.borderColor)
169
175
  }
170
176
 
171
177
  private fun updateCardSize() {
@@ -43,6 +43,8 @@ final class HybridNitroModal: HybridNitroModalSpec {
43
43
  var dismissOnBackButton = true
44
44
  var grabberVisible = false
45
45
  var cornerRadius: Double = -1
46
+ var borderWidth: Double = 0
47
+ var borderColor: Double?
46
48
  var contentBackgroundColor: Double?
47
49
  var keyboardBehavior: KeyboardBehavior = .pan
48
50
  var popupAnimation: PopupAnimation = .scale
@@ -325,6 +327,8 @@ final class HybridNitroModal: HybridNitroModalSpec {
325
327
  dismissOnSwipe: dismissOnSwipe && !inline,
326
328
  grabberVisible: grabberVisible,
327
329
  cornerRadius: cornerRadius >= 0 ? CGFloat(cornerRadius) : nil,
330
+ borderWidth: borderWidth.isFinite ? max(CGFloat(borderWidth), 0) : 0,
331
+ borderColor: borderColor.map(UIColor.init(processedColor:)) ?? .clear,
328
332
  contentBackgroundColor: contentBackgroundColor.map(UIColor.init(processedColor:)) ?? .systemBackground,
329
333
  keyboardBehavior: keyboardBehavior,
330
334
  popupAnimation: popupAnimation,
@@ -49,6 +49,9 @@ struct ModalConfig: Equatable {
49
49
  var grabberVisible = false
50
50
  /// `nil` uses the platform default.
51
51
  var cornerRadius: CGFloat?
52
+ /// Border around the sheet/card, drawn above the content.
53
+ var borderWidth: CGFloat = 0
54
+ var borderColor: UIColor = .clear
52
55
  var contentBackgroundColor: UIColor = .systemBackground
53
56
  var keyboardBehavior: KeyboardBehavior = .pan
54
57
  var popupAnimation: PopupAnimation = .scale
@@ -125,6 +125,8 @@ final class PopupViewController: UIViewController, ModalPresenting, UIViewContro
125
125
  backdrop.configure(color: config.backdropColor, opacity: config.backdropOpacity, blurRadius: config.backdropBlurRadius)
126
126
  card.backgroundColor = config.contentBackgroundColor
127
127
  card.layer.cornerRadius = config.cornerRadius ?? Self.defaultCornerRadius
128
+ card.layer.borderWidth = config.borderWidth
129
+ card.layer.borderColor = config.borderColor.cgColor
128
130
  }
129
131
 
130
132
  /// Area a card may occupy inside `bounds`, keeping clear of the safe area.
@@ -110,11 +110,11 @@ final class SheetView: UIView, UIGestureRecognizerDelegate {
110
110
  grabber.layer.cornerRadius = Self.grabberSize.height / 2
111
111
  sheetView.addSubview(grabber)
112
112
 
113
- // Behind the sheet, which uncovers it as it's pulled down.
113
+ // Inside the sheet, behind the content, which uncovers it as it's pulled down.
114
114
  refreshIndicator.hidesWhenStopped = false
115
115
  refreshIndicator.isUserInteractionEnabled = false
116
116
  refreshIndicator.alpha = 0
117
- addSubview(refreshIndicator)
117
+ sheetView.insertSubview(refreshIndicator, belowSubview: contentView)
118
118
  addSubview(sheetView)
119
119
 
120
120
  let pan = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)))
@@ -180,7 +180,7 @@ final class SheetView: UIView, UIGestureRecognizerDelegate {
180
180
 
181
181
  /// Slides the sheet in or out; a swipe dismissal keeps its release velocity.
182
182
  func animateTransition(toOffscreen offscreen: Bool, animated: Bool, duration: TimeInterval, completion: @escaping () -> Void) {
183
- let from = sheetView.frame.minY
183
+ let from = sheetView.frame.minY + contentView.frame.minY
184
184
  let velocity = offscreen ? releaseVelocity : 0
185
185
  releaseVelocity = 0
186
186
  isOffscreen = offscreen
@@ -262,32 +262,41 @@ final class SheetView: UIView, UIGestureRecognizerDelegate {
262
262
  return dragTop ?? settledTop(for: selectedIndex)
263
263
  }
264
264
 
265
+ /// With a refresh indicator, a pull below the lowest detent keeps the sheet
266
+ /// there and moves the content down inside it instead, uncovering the
267
+ /// indicator at the top of the sheet.
268
+ private var pullsContent: Bool {
269
+ config.refreshing != nil && config.pullToRefreshEnabled && !config.dismissOnSwipe
270
+ }
271
+
272
+ /// Splits a sheet top into where the sheet goes and how far its content is pulled down.
273
+ private func split(_ top: CGFloat) -> (sheetTop: CGFloat, pull: CGFloat) {
274
+ guard pullsContent, !isOffscreen, let lowest = detentTops.max(), top > lowest else { return (top, 0) }
275
+ return (lowest, top - lowest)
276
+ }
277
+
265
278
  private func layoutSheet() {
266
279
  let width = sheetWidth
267
- let top = currentTop
280
+ let (top, pull) = split(currentTop)
268
281
  backdrop.frame = bounds
269
282
  sheetView.frame = CGRect(x: (bounds.width - width) / 2, y: top, width: width, height: bounds.height + Self.overscroll)
270
- contentView.frame = CGRect(x: 0, y: 0, width: width, height: maximumDetentValue)
283
+ contentView.frame = CGRect(x: 0, y: pull, width: width, height: maximumDetentValue)
271
284
  grabber.frame = CGRect(
272
285
  origin: CGPoint(x: (width - Self.grabberSize.width) / 2, y: 5),
273
286
  size: Self.grabberSize
274
287
  )
275
288
  backdrop.alpha = backdropAlpha(forTop: top)
276
- layoutRefreshIndicator(sheetTop: top)
289
+ layoutRefreshIndicator(width: width, pull: pull)
277
290
  reportRestingTop()
278
291
  }
279
292
 
280
- /// Centered in the gap a pull uncovers below the lowest detent, fading in
281
- /// as the pull nears the threshold.
282
- private func layoutRefreshIndicator(sheetTop top: CGFloat) {
293
+ /// Centered in the gap a pull uncovers above the content, fading in as the
294
+ /// pull nears the threshold.
295
+ private func layoutRefreshIndicator(width: CGFloat, pull: CGFloat) {
283
296
  let size = refreshIndicator.intrinsicContentSize
284
297
  refreshIndicator.bounds = CGRect(origin: .zero, size: size)
285
- refreshIndicator.center = CGPoint(x: bounds.midX, y: top - Self.refreshThreshold / 2)
286
- guard config.refreshing != nil, !isOffscreen, let lowest = detentTops.max() else {
287
- refreshIndicator.alpha = 0
288
- return
289
- }
290
- let progress = min(max((top - lowest) / Self.refreshThreshold, 0), 1)
298
+ refreshIndicator.center = CGPoint(x: width / 2, y: pull / 2)
299
+ let progress = min(max(pull / Self.refreshThreshold, 0), 1)
291
300
  refreshIndicator.alpha = progress
292
301
  if progress > 0, !refreshIndicator.isAnimating {
293
302
  refreshIndicator.startAnimating()
@@ -321,6 +330,9 @@ final class SheetView: UIView, UIGestureRecognizerDelegate {
321
330
  backdrop.configure(color: config.backdropColor, opacity: config.backdropOpacity, blurRadius: config.backdropBlurRadius)
322
331
  sheetView.backgroundColor = config.contentBackgroundColor
323
332
  sheetView.layer.cornerRadius = config.cornerRadius ?? Self.defaultCornerRadius
333
+ // Drawn above the sublayers, so the content can't cover it.
334
+ sheetView.layer.borderWidth = config.borderWidth
335
+ sheetView.layer.borderColor = config.borderColor.cgColor
324
336
  grabber.isHidden = !config.grabberVisible
325
337
  refreshIndicator.color = config.refreshIndicatorColor
326
338
  }
@@ -425,9 +437,14 @@ final class SheetView: UIView, UIGestureRecognizerDelegate {
425
437
  switch pan.state {
426
438
  case .began:
427
439
  // Grab the sheet where it is, even mid-animation.
428
- let isSettled = sheetView.layer.animationKeys()?.isEmpty ?? true
429
- let top = sheetView.layer.presentation()?.frame.minY ?? sheetView.frame.minY
440
+ let isSettled = (sheetView.layer.animationKeys()?.isEmpty ?? true)
441
+ && (contentView.layer.animationKeys()?.isEmpty ?? true)
442
+ let sheetTop = sheetView.layer.presentation()?.frame.minY ?? sheetView.frame.minY
443
+ let pull = contentView.layer.presentation()?.frame.minY ?? contentView.frame.minY
444
+ let top = sheetTop + pull
430
445
  sheetView.layer.removeAllAnimations()
446
+ contentView.layer.removeAllAnimations()
447
+ refreshIndicator.layer.removeAllAnimations()
431
448
  backdrop.layer.removeAllAnimations()
432
449
  let translation = pan.translation(in: sheetView)
433
450
  let location = pan.location(in: sheetView)
@@ -449,17 +466,20 @@ final class SheetView: UIView, UIGestureRecognizerDelegate {
449
466
  layoutSheet()
450
467
 
451
468
  case .changed:
452
- guard var state = drag, let minTop = detentTops.min() else { return }
469
+ guard var state = drag, let minTop = detentTops.min(), let maxTop = settledTops.max() else { return }
453
470
  let translation = pan.translation(in: self).y
454
471
  let delta = translation - state.lastTranslation
455
472
  state.lastTranslation = translation
456
473
 
457
474
  if let scrollView = state.scrollView {
458
- // Up: expand the sheet before scrolling. Down: scroll back to the top
459
- // before collapsing the sheet, in a separate gesture.
475
+ // Up: expand the sheet before scrolling, once content pulled past its
476
+ // top is back. Down: scroll back to the top before collapsing the
477
+ // sheet, in a separate gesture. A sheet that stops at its lowest
478
+ // detent leaves the pull to the content there (bounce, RefreshControl).
460
479
  let drive = delta < 0
461
- ? state.rawTop > minTop + 0.5
480
+ ? state.rawTop > minTop + 0.5 && !scrollView.isPulledDown
462
481
  : !state.contentScrolled && scrollView.isScrolledToTop
482
+ && (canDragBelowLowestDetent || state.rawTop < maxTop - 0.5)
463
483
  if drive {
464
484
  state.rawTop = max(state.rawTop + delta, minTop)
465
485
  lockScroll(scrollView, at: delta < 0 ? lockedOffsetY : scrollView.topOffsetY)
@@ -475,6 +495,9 @@ final class SheetView: UIView, UIGestureRecognizerDelegate {
475
495
  state.rawTop += delta
476
496
  state.sheetDrove = true
477
497
  }
498
+ if !canDragBelowLowestDetent {
499
+ state.rawTop = min(state.rawTop, maxTop)
500
+ }
478
501
  let top = constrained(state.rawTop)
479
502
  if state.sheetDrove, isInline, !state.cancelledReactTouches {
480
503
  state.cancelledReactTouches = true
@@ -543,6 +566,13 @@ final class SheetView: UIView, UIGestureRecognizerDelegate {
543
566
  }
544
567
  }
545
568
 
569
+ /// Whether a drag can take the sheet below its lowest detent: to dismiss it
570
+ /// or to pull to refresh. Otherwise it stops there, like Android's
571
+ /// `BottomSheetBehavior`.
572
+ private var canDragBelowLowestDetent: Bool {
573
+ config.dismissOnSwipe || config.pullToRefreshEnabled
574
+ }
575
+
546
576
  /// Rubber-bands above the tallest detent, and below the lowest one when
547
577
  /// swiping cannot dismiss.
548
578
  private func constrained(_ top: CGFloat) -> CGFloat {
@@ -640,6 +670,11 @@ private extension UIScrollView {
640
670
  contentOffset.y <= topOffsetY + 0.5
641
671
  }
642
672
 
673
+ /// Pulled down past its top, bouncing or revealing a refresh control.
674
+ var isPulledDown: Bool {
675
+ contentOffset.y < topOffsetY - 0.5
676
+ }
677
+
643
678
  var canScrollVertically: Bool {
644
679
  alwaysBounceVertical
645
680
  || contentSize.height + adjustedContentInset.top + adjustedContentInset.bottom > bounds.height + 0.5
@@ -39,6 +39,8 @@ export function NitroModal({
39
39
  dismissOnBackButton = true,
40
40
  showGrabber = false,
41
41
  cornerRadius,
42
+ borderWidth = 0,
43
+ borderColor,
42
44
  backgroundColor,
43
45
  keyboardBehavior = 'pan',
44
46
  popupAnimation = 'scale',
@@ -197,6 +199,8 @@ export function NitroModal({
197
199
  dismissOnBackButton: dismissOnBackButton,
198
200
  grabberVisible: showGrabber,
199
201
  cornerRadius: cornerRadius ?? -1,
202
+ borderWidth: borderWidth,
203
+ borderColor: toNativeColor(borderColor),
200
204
  contentBackgroundColor: toNativeColor(backgroundColor),
201
205
  keyboardBehavior: keyboardBehavior,
202
206
  popupAnimation: popupAnimation,
@@ -1 +1 @@
1
- {"version":3,"names":["useEffect","useImperativeHandle","useLayoutEffect","useMemo","useRef","useState","processColor","StyleSheet","useWindowDimensions","View","callback","NitroModalView","jsx","_jsx","DEFAULT_DETENTS","BLACK","parseDetent","value","points","Number","isFinite","toNativeColor","color","undefined","processed","NitroModal","isOpen","mode","presentation","style","detents","initialDetentIndex","backdropColor","backdropOpacity","backdropBlur","dismissOnBackdropPress","dismissOnSwipe","dismissOnBackButton","showGrabber","cornerRadius","backgroundColor","keyboardBehavior","popupAnimation","contentContainerStyle","onPresent","onDismiss","onDetentChange","onBackdropPress","onBackButtonPress","onPullToRefresh","refreshing","refreshIndicatorColor","children","testID","ref","isControlled","isInline","internalOpen","setInternalOpen","open","sessionActive","setSessionActive","prevOpen","setPrevOpen","renderContent","area","setArea","restingTop","setRestingTop","isRefreshControlled","pullPending","setPullPending","hybridRef","latest","current","nativeCallbacks","instance","reason","index","onRestingTopChange","top","onContentAreaChange","next","width","height","present","console","warn","dismiss","snapToDetent","detentsKey","join","nativeDetents","Set","split","map","windowSize","contentArea","containerStyle","maxWidth","maxHeight","includes","absoluteFill","styles","host","pointerEvents","backdropBlurRadius","grabberVisible","contentBackgroundColor","pullToRefreshEnabled","collapsable","container","create","position","left"],"sourceRoot":"../../src","sources":["NitroModal.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["useEffect","useImperativeHandle","useLayoutEffect","useMemo","useRef","useState","processColor","StyleSheet","useWindowDimensions","View","callback","NitroModalView","jsx","_jsx","DEFAULT_DETENTS","BLACK","parseDetent","value","points","Number","isFinite","toNativeColor","color","undefined","processed","NitroModal","isOpen","mode","presentation","style","detents","initialDetentIndex","backdropColor","backdropOpacity","backdropBlur","dismissOnBackdropPress","dismissOnSwipe","dismissOnBackButton","showGrabber","cornerRadius","borderWidth","borderColor","backgroundColor","keyboardBehavior","popupAnimation","contentContainerStyle","onPresent","onDismiss","onDetentChange","onBackdropPress","onBackButtonPress","onPullToRefresh","refreshing","refreshIndicatorColor","children","testID","ref","isControlled","isInline","internalOpen","setInternalOpen","open","sessionActive","setSessionActive","prevOpen","setPrevOpen","renderContent","area","setArea","restingTop","setRestingTop","isRefreshControlled","pullPending","setPullPending","hybridRef","latest","current","nativeCallbacks","instance","reason","index","onRestingTopChange","top","onContentAreaChange","next","width","height","present","console","warn","dismiss","snapToDetent","detentsKey","join","nativeDetents","Set","split","map","windowSize","contentArea","containerStyle","maxWidth","maxHeight","includes","absoluteFill","styles","host","pointerEvents","backdropBlurRadius","grabberVisible","contentBackgroundColor","pullToRefreshEnabled","collapsable","container","create","position","left"],"sourceRoot":"../../src","sources":["NitroModal.tsx"],"mappings":"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","ignoreList":[]}
@@ -34,6 +34,7 @@ function WebNitroModalView(props) {
34
34
  const surface = useRef(null);
35
35
  const content = useRef(null);
36
36
  const grabber = useRef(null);
37
+ const border = useRef(null);
37
38
  const refreshIndicator = useRef(null);
38
39
  const refreshSpinner = useRef(null);
39
40
  useLayoutEffect(() => {
@@ -54,6 +55,7 @@ function WebNitroModalView(props) {
54
55
  surface: surface.current,
55
56
  content: content.current,
56
57
  grabber: grabber.current,
58
+ border: border.current,
57
59
  refreshIndicator: refreshIndicator.current,
58
60
  refreshSpinner: refreshSpinner.current
59
61
  });
@@ -84,18 +86,18 @@ function WebNitroModalView(props) {
84
86
  ref: backdrop,
85
87
  "aria-hidden": true,
86
88
  style: styles.backdrop
87
- }), /*#__PURE__*/_jsx("div", {
88
- ref: refreshIndicator,
89
- "aria-hidden": true,
90
- style: styles.refreshIndicator,
91
- children: /*#__PURE__*/_jsx("div", {
92
- ref: refreshSpinner,
93
- style: styles.refreshSpinner
94
- })
95
89
  }), /*#__PURE__*/_jsxs("div", {
96
90
  ref: surface,
97
91
  style: styles.surface,
98
92
  children: [/*#__PURE__*/_jsx("div", {
93
+ ref: refreshIndicator,
94
+ "aria-hidden": true,
95
+ style: styles.refreshIndicator,
96
+ children: /*#__PURE__*/_jsx("div", {
97
+ ref: refreshSpinner,
98
+ style: styles.refreshSpinner
99
+ })
100
+ }), /*#__PURE__*/_jsx("div", {
99
101
  ref: content,
100
102
  style: styles.content,
101
103
  children: children
@@ -103,6 +105,10 @@ function WebNitroModalView(props) {
103
105
  ref: grabber,
104
106
  "aria-hidden": true,
105
107
  style: styles.grabber
108
+ }), /*#__PURE__*/_jsx("div", {
109
+ ref: border,
110
+ "aria-hidden": true,
111
+ style: styles.border
106
112
  })]
107
113
  })]
108
114
  }) : null;
@@ -166,6 +172,16 @@ const styles = {
166
172
  backgroundColor: 'rgba(127, 127, 127, 0.4)',
167
173
  pointerEvents: 'none'
168
174
  },
175
+ // Sized by the presenter's border width; follows the surface's corners.
176
+ border: {
177
+ position: 'absolute',
178
+ inset: 0,
179
+ boxSizing: 'border-box',
180
+ borderStyle: 'solid',
181
+ borderWidth: 0,
182
+ borderRadius: 'inherit',
183
+ pointerEvents: 'none'
184
+ },
169
185
  refreshIndicator: {
170
186
  position: 'absolute',
171
187
  left: 0,
@@ -1 +1 @@
1
- {"version":3,"names":["useCallback","useLayoutEffect","useRef","useState","Modal","View","clipOverflow","REFRESH_INDICATOR_SIZE","ModalController","jsx","_jsx","jsxs","_jsxs","callback","func","WebNitroModalView","props","hybridRef","children","isInline","mode","mounted","setMounted","controller","overlay","backdrop","surface","content","grabber","refreshIndicator","refreshSpinner","attach","detach","methods","update","undefined","elementsDidMount","current","elementsWillUnmount","contentDidRender","hostRef","node","hostDidChange","HTMLElement","layer","ref","tabIndex","style","styles","inlineOverlay","overflow","pointerEvents","visible","transparent","animationType","onRequestClose","handleBackPress","position","inset","outline","touchAction","left","top","boxSizing","willChange","width","height","marginLeft","borderRadius","backgroundColor","opacity","border","borderTopColor","NitroModalView"],"sourceRoot":"../../src","sources":["NitroModalView.web.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["useCallback","useLayoutEffect","useRef","useState","Modal","View","clipOverflow","REFRESH_INDICATOR_SIZE","ModalController","jsx","_jsx","jsxs","_jsxs","callback","func","WebNitroModalView","props","hybridRef","children","isInline","mode","mounted","setMounted","controller","overlay","backdrop","surface","content","grabber","border","refreshIndicator","refreshSpinner","attach","detach","methods","update","undefined","elementsDidMount","current","elementsWillUnmount","contentDidRender","hostRef","node","hostDidChange","HTMLElement","layer","ref","tabIndex","style","styles","inlineOverlay","overflow","pointerEvents","visible","transparent","animationType","onRequestClose","handleBackPress","position","inset","outline","touchAction","left","top","boxSizing","willChange","width","height","marginLeft","borderRadius","backgroundColor","borderStyle","borderWidth","opacity","borderTopColor","NitroModalView"],"sourceRoot":"../../src","sources":["NitroModalView.web.tsx"],"mappings":"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","ignoreList":[]}
@@ -18,6 +18,8 @@ export function makeConfig(props) {
18
18
  dismissOnBackButton: props.dismissOnBackButton && !isInline,
19
19
  grabberVisible: props.grabberVisible,
20
20
  cornerRadius: props.cornerRadius >= 0 ? props.cornerRadius : null,
21
+ borderWidth: Number.isFinite(props.borderWidth) && props.borderWidth > 0 ? props.borderWidth : 0,
22
+ borderColor: props.borderColor ?? null,
21
23
  contentBackgroundColor: props.contentBackgroundColor ?? null,
22
24
  keyboardBehavior: props.keyboardBehavior,
23
25
  popupAnimation: props.popupAnimation,
@@ -1 +1 @@
1
- {"version":3,"names":["makeConfig","props","isInline","mode","detents","initialDetentIndex","Number","isFinite","Math","trunc","backdropColor","backdropOpacity","backdropBlurRadius","dismissOnBackdropPress","dismissOnSwipe","dismissOnBackButton","grabberVisible","cornerRadius","contentBackgroundColor","keyboardBehavior","popupAnimation","pullToRefreshEnabled","refreshing","refreshIndicatorColor","isSameConfig","a","b","Object","keys","every","key","join"],"sourceRoot":"../../../src","sources":["web/ModalConfig.ts"],"mappings":";;AAQA;;AA+BA,OAAO,SAASA,UAAUA,CAACC,KAAsB,EAAe;EAC9D;EACA,MAAMC,QAAQ,GAAGD,KAAK,CAACC,QAAQ,IAAID,KAAK,CAACE,IAAI,KAAK,aAAa;EAC/D,OAAO;IACLA,IAAI,EAAEF,KAAK,CAACE,IAAI;IAChBD,QAAQ;IACRE,OAAO,EAAEH,KAAK,CAACG,OAAO;IACtBC,kBAAkB,EAAEC,MAAM,CAACC,QAAQ,CAACN,KAAK,CAACI,kBAAkB,CAAC,GACzDG,IAAI,CAACC,KAAK,CAACR,KAAK,CAACI,kBAAkB,CAAC,GACpC,CAAC;IACLK,aAAa,EAAET,KAAK,CAACS,aAAa;IAClCC,eAAe,EAAEV,KAAK,CAACU,eAAe;IACtCC,kBAAkB,EAAEX,KAAK,CAACW,kBAAkB;IAC5CC,sBAAsB,EAAEZ,KAAK,CAACY,sBAAsB,IAAI,CAACX,QAAQ;IACjEY,cAAc,EAAEb,KAAK,CAACa,cAAc,IAAI,CAACZ,QAAQ;IACjDa,mBAAmB,EAAEd,KAAK,CAACc,mBAAmB,IAAI,CAACb,QAAQ;IAC3Dc,cAAc,EAAEf,KAAK,CAACe,cAAc;IACpCC,YAAY,EAAEhB,KAAK,CAACgB,YAAY,IAAI,CAAC,GAAGhB,KAAK,CAACgB,YAAY,GAAG,IAAI;IACjEC,sBAAsB,EAAEjB,KAAK,CAACiB,sBAAsB,IAAI,IAAI;IAC5DC,gBAAgB,EAAElB,KAAK,CAACkB,gBAAgB;IACxCC,cAAc,EAAEnB,KAAK,CAACmB,cAAc;IACpCC,oBAAoB,EAAEpB,KAAK,CAACoB,oBAAoB;IAChDC,UAAU,EAAErB,KAAK,CAACqB,UAAU,IAAI,IAAI;IACpCC,qBAAqB,EAAEtB,KAAK,CAACsB,qBAAqB,IAAI;EACxD,CAAC;AACH;AAEA,OAAO,SAASC,YAAYA,CAACC,CAAc,EAAEC,CAAc,EAAW;EACpE,OAAQC,MAAM,CAACC,IAAI,CAACH,CAAC,CAAC,CAA2BI,KAAK,CAAEC,GAAG,IACzDA,GAAG,KAAK,SAAS,GACbL,CAAC,CAACrB,OAAO,CAAC2B,IAAI,CAAC,CAAC,KAAKL,CAAC,CAACtB,OAAO,CAAC2B,IAAI,CAAC,CAAC,GACrCN,CAAC,CAACK,GAAG,CAAC,KAAKJ,CAAC,CAACI,GAAG,CACtB,CAAC;AACH","ignoreList":[]}
1
+ {"version":3,"names":["makeConfig","props","isInline","mode","detents","initialDetentIndex","Number","isFinite","Math","trunc","backdropColor","backdropOpacity","backdropBlurRadius","dismissOnBackdropPress","dismissOnSwipe","dismissOnBackButton","grabberVisible","cornerRadius","borderWidth","borderColor","contentBackgroundColor","keyboardBehavior","popupAnimation","pullToRefreshEnabled","refreshing","refreshIndicatorColor","isSameConfig","a","b","Object","keys","every","key","join"],"sourceRoot":"../../../src","sources":["web/ModalConfig.ts"],"mappings":";;AAQA;;AAmCA,OAAO,SAASA,UAAUA,CAACC,KAAsB,EAAe;EAC9D;EACA,MAAMC,QAAQ,GAAGD,KAAK,CAACC,QAAQ,IAAID,KAAK,CAACE,IAAI,KAAK,aAAa;EAC/D,OAAO;IACLA,IAAI,EAAEF,KAAK,CAACE,IAAI;IAChBD,QAAQ;IACRE,OAAO,EAAEH,KAAK,CAACG,OAAO;IACtBC,kBAAkB,EAAEC,MAAM,CAACC,QAAQ,CAACN,KAAK,CAACI,kBAAkB,CAAC,GACzDG,IAAI,CAACC,KAAK,CAACR,KAAK,CAACI,kBAAkB,CAAC,GACpC,CAAC;IACLK,aAAa,EAAET,KAAK,CAACS,aAAa;IAClCC,eAAe,EAAEV,KAAK,CAACU,eAAe;IACtCC,kBAAkB,EAAEX,KAAK,CAACW,kBAAkB;IAC5CC,sBAAsB,EAAEZ,KAAK,CAACY,sBAAsB,IAAI,CAACX,QAAQ;IACjEY,cAAc,EAAEb,KAAK,CAACa,cAAc,IAAI,CAACZ,QAAQ;IACjDa,mBAAmB,EAAEd,KAAK,CAACc,mBAAmB,IAAI,CAACb,QAAQ;IAC3Dc,cAAc,EAAEf,KAAK,CAACe,cAAc;IACpCC,YAAY,EAAEhB,KAAK,CAACgB,YAAY,IAAI,CAAC,GAAGhB,KAAK,CAACgB,YAAY,GAAG,IAAI;IACjEC,WAAW,EACTZ,MAAM,CAACC,QAAQ,CAACN,KAAK,CAACiB,WAAW,CAAC,IAAIjB,KAAK,CAACiB,WAAW,GAAG,CAAC,GACvDjB,KAAK,CAACiB,WAAW,GACjB,CAAC;IACPC,WAAW,EAAElB,KAAK,CAACkB,WAAW,IAAI,IAAI;IACtCC,sBAAsB,EAAEnB,KAAK,CAACmB,sBAAsB,IAAI,IAAI;IAC5DC,gBAAgB,EAAEpB,KAAK,CAACoB,gBAAgB;IACxCC,cAAc,EAAErB,KAAK,CAACqB,cAAc;IACpCC,oBAAoB,EAAEtB,KAAK,CAACsB,oBAAoB;IAChDC,UAAU,EAAEvB,KAAK,CAACuB,UAAU,IAAI,IAAI;IACpCC,qBAAqB,EAAExB,KAAK,CAACwB,qBAAqB,IAAI;EACxD,CAAC;AACH;AAEA,OAAO,SAASC,YAAYA,CAACC,CAAc,EAAEC,CAAc,EAAW;EACpE,OAAQC,MAAM,CAACC,IAAI,CAACH,CAAC,CAAC,CAA2BI,KAAK,CAAEC,GAAG,IACzDA,GAAG,KAAK,SAAS,GACbL,CAAC,CAACvB,OAAO,CAAC6B,IAAI,CAAC,CAAC,KAAKL,CAAC,CAACxB,OAAO,CAAC6B,IAAI,CAAC,CAAC,GACrCN,CAAC,CAACK,GAAG,CAAC,KAAKJ,CAAC,CAACI,GAAG,CACtB,CAAC;AACH","ignoreList":[]}
@@ -188,6 +188,11 @@ export class ModalPresenter {
188
188
  backdrop.style.setProperty('-webkit-backdrop-filter', blur);
189
189
  // `Canvas` follows the page's `color-scheme`, like a system background.
190
190
  surface.style.backgroundColor = config.contentBackgroundColor != null ? toCSSColor(config.contentBackgroundColor) : 'Canvas';
191
+ const {
192
+ border
193
+ } = this.elements;
194
+ border.style.borderWidth = `${config.borderWidth}px`;
195
+ border.style.borderColor = config.borderColor != null ? toCSSColor(config.borderColor) : 'transparent';
191
196
  }
192
197
 
193
198
  /** Inline, only the surface takes input; the rest reaches the page. */