@lodev09/react-native-true-sheet 3.5.7 → 3.6.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.
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +4 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewController.kt +19 -4
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt +7 -2
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetBottomSheetView.kt +8 -0
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetKeyboardObserver.kt +5 -4
- package/android/src/main/java/com/lodev09/truesheet/utils/KeyboardUtils.kt +29 -0
- package/ios/TrueSheetView.mm +1 -1
- package/ios/TrueSheetViewController.h +1 -1
- package/ios/TrueSheetViewController.mm +67 -45
- package/ios/core/TrueSheetBlurView.h +1 -1
- package/ios/core/TrueSheetBlurView.mm +2 -39
- package/ios/utils/BlurUtil.h +23 -0
- package/ios/utils/BlurUtil.mm +53 -0
- package/lib/module/TrueSheet.js +6 -4
- package/lib/module/TrueSheet.js.map +1 -1
- package/lib/module/TrueSheet.web.js +28 -6
- package/lib/module/TrueSheet.web.js.map +1 -1
- package/lib/module/fabric/TrueSheetViewNativeComponent.ts +2 -1
- package/lib/typescript/src/TrueSheet.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheet.types.d.ts +21 -5
- package/lib/typescript/src/TrueSheet.types.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheet.web.d.ts.map +1 -1
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts +2 -1
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/navigation/types.d.ts +1 -1
- package/lib/typescript/src/navigation/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/TrueSheet.tsx +6 -4
- package/src/TrueSheet.types.ts +30 -5
- package/src/TrueSheet.web.tsx +34 -5
- package/src/fabric/TrueSheetViewNativeComponent.ts +2 -1
- package/src/navigation/types.ts +1 -1
|
@@ -222,6 +222,10 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
|
|
|
222
222
|
viewController.grabberOptions = options
|
|
223
223
|
}
|
|
224
224
|
|
|
225
|
+
fun setSheetElevation(elevation: Float) {
|
|
226
|
+
viewController.sheetElevation = elevation
|
|
227
|
+
}
|
|
228
|
+
|
|
225
229
|
fun setDetents(newDetents: MutableList<Double>) {
|
|
226
230
|
viewController.detents = newDetents
|
|
227
231
|
}
|
|
@@ -35,6 +35,7 @@ import com.lodev09.truesheet.core.TrueSheetDimViewDelegate
|
|
|
35
35
|
import com.lodev09.truesheet.core.TrueSheetKeyboardObserver
|
|
36
36
|
import com.lodev09.truesheet.core.TrueSheetKeyboardObserverDelegate
|
|
37
37
|
import com.lodev09.truesheet.core.TrueSheetStackManager
|
|
38
|
+
import com.lodev09.truesheet.utils.KeyboardUtils
|
|
38
39
|
import com.lodev09.truesheet.utils.ScreenUtils
|
|
39
40
|
|
|
40
41
|
// =============================================================================
|
|
@@ -177,6 +178,12 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
177
178
|
if (isPresented) sheetView?.setupBackground()
|
|
178
179
|
}
|
|
179
180
|
|
|
181
|
+
override var sheetElevation: Float = -1f
|
|
182
|
+
set(value) {
|
|
183
|
+
field = value
|
|
184
|
+
if (isPresented) sheetView?.setupElevation()
|
|
185
|
+
}
|
|
186
|
+
|
|
180
187
|
var dismissible: Boolean = true
|
|
181
188
|
set(value) {
|
|
182
189
|
field = value
|
|
@@ -318,8 +325,10 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
318
325
|
isPresented = false
|
|
319
326
|
isSheetVisible = false
|
|
320
327
|
wasHiddenByModal = false
|
|
328
|
+
isKeyboardTransitioning = false
|
|
321
329
|
isPresentAnimating = false
|
|
322
330
|
lastEmittedPositionPx = -1
|
|
331
|
+
detentIndexBeforeKeyboard = -1
|
|
323
332
|
shouldAnimatePresent = true
|
|
324
333
|
}
|
|
325
334
|
|
|
@@ -407,6 +416,7 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
407
416
|
if (newState == BottomSheetBehavior.STATE_HIDDEN) {
|
|
408
417
|
if (isDismissing) return
|
|
409
418
|
isDismissing = true
|
|
419
|
+
dismissKeyboard()
|
|
410
420
|
emitWillDismissEvents()
|
|
411
421
|
finishDismiss()
|
|
412
422
|
return
|
|
@@ -471,8 +481,6 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
471
481
|
delegate?.viewControllerDidDragEnd(detentInfo.index, detentInfo.position, detent)
|
|
472
482
|
|
|
473
483
|
if (detentInfo.index != currentDetentIndex) {
|
|
474
|
-
presentPromise?.invoke()
|
|
475
|
-
presentPromise = null
|
|
476
484
|
currentDetentIndex = detentInfo.index
|
|
477
485
|
setupDimmedBackground(detentInfo.index)
|
|
478
486
|
delegate?.viewControllerDidChangeDetent(detentInfo.index, detentInfo.position, detent)
|
|
@@ -645,6 +653,7 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
645
653
|
setupDimmedBackground(currentDetentIndex)
|
|
646
654
|
setupKeyboardObserver()
|
|
647
655
|
sheet.setupBackground()
|
|
656
|
+
sheet.setupElevation()
|
|
648
657
|
sheet.setupGrabber()
|
|
649
658
|
|
|
650
659
|
if (shouldAnimatePresent) {
|
|
@@ -665,6 +674,7 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
665
674
|
if (isDismissing) return
|
|
666
675
|
|
|
667
676
|
isDismissing = true
|
|
677
|
+
dismissKeyboard()
|
|
668
678
|
emitWillDismissEvents()
|
|
669
679
|
|
|
670
680
|
if (animated) {
|
|
@@ -675,6 +685,10 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
675
685
|
}
|
|
676
686
|
}
|
|
677
687
|
|
|
688
|
+
private fun dismissKeyboard() {
|
|
689
|
+
KeyboardUtils.dismiss(reactContext)
|
|
690
|
+
}
|
|
691
|
+
|
|
678
692
|
private fun dismissOrCollapseToLowest() {
|
|
679
693
|
if (dismissible) {
|
|
680
694
|
dismiss(animated = true)
|
|
@@ -845,7 +859,8 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
845
859
|
|
|
846
860
|
fun updateDimAmount(sheetTop: Int? = null, animated: Boolean = false) {
|
|
847
861
|
if (!dimmed) return
|
|
848
|
-
val
|
|
862
|
+
val keyboardOffset = if (isDismissing) 0 else currentKeyboardInset
|
|
863
|
+
val top = (sheetTop ?: sheetView?.top ?: return) + keyboardOffset
|
|
849
864
|
|
|
850
865
|
if (animated) {
|
|
851
866
|
val targetAlpha = dimView?.calculateAlpha(
|
|
@@ -912,7 +927,7 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
|
|
|
912
927
|
override fun keyboardWillHide() {
|
|
913
928
|
if (!shouldHandleKeyboard()) return
|
|
914
929
|
setupSheetDetents()
|
|
915
|
-
if (detentIndexBeforeKeyboard >= 0) {
|
|
930
|
+
if (!isDismissing && detentIndexBeforeKeyboard >= 0) {
|
|
916
931
|
setStateForDetentIndex(detentIndexBeforeKeyboard)
|
|
917
932
|
detentIndexBeforeKeyboard = -1
|
|
918
933
|
}
|
|
@@ -173,8 +173,8 @@ class TrueSheetViewManager :
|
|
|
173
173
|
}
|
|
174
174
|
}
|
|
175
175
|
|
|
176
|
-
@ReactProp(name = "
|
|
177
|
-
override fun
|
|
176
|
+
@ReactProp(name = "backgroundBlur")
|
|
177
|
+
override fun setBackgroundBlur(view: TrueSheetView, tint: String?) {
|
|
178
178
|
// iOS-specific prop - no-op on Android
|
|
179
179
|
}
|
|
180
180
|
|
|
@@ -198,6 +198,11 @@ class TrueSheetViewManager :
|
|
|
198
198
|
// iOS-specific prop - no-op on Android
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
+
@ReactProp(name = "elevation", defaultDouble = -1.0)
|
|
202
|
+
override fun setElevation(view: TrueSheetView, elevation: Double) {
|
|
203
|
+
view.setSheetElevation(elevation.toFloat())
|
|
204
|
+
}
|
|
205
|
+
|
|
201
206
|
companion object {
|
|
202
207
|
const val REACT_CLASS = "TrueSheetView"
|
|
203
208
|
const val TAG_NAME = "TrueSheet"
|
|
@@ -18,6 +18,7 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior
|
|
|
18
18
|
interface TrueSheetBottomSheetViewDelegate {
|
|
19
19
|
val isTopmostSheet: Boolean
|
|
20
20
|
val sheetCornerRadius: Float
|
|
21
|
+
val sheetElevation: Float
|
|
21
22
|
val sheetBackgroundColor: Int?
|
|
22
23
|
val grabber: Boolean
|
|
23
24
|
val grabberOptions: GrabberOptions?
|
|
@@ -37,6 +38,7 @@ class TrueSheetBottomSheetView(private val reactContext: ThemedReactContext) : F
|
|
|
37
38
|
private const val GRABBER_TAG = "TrueSheetGrabber"
|
|
38
39
|
private const val DEFAULT_CORNER_RADIUS = 16f // dp
|
|
39
40
|
private const val DEFAULT_MAX_WIDTH = 640 // dp
|
|
41
|
+
private const val DEFAULT_ELEVATION = 4f // dp
|
|
40
42
|
}
|
|
41
43
|
|
|
42
44
|
// =============================================================================
|
|
@@ -138,6 +140,12 @@ class TrueSheetBottomSheetView(private val reactContext: ThemedReactContext) : F
|
|
|
138
140
|
}
|
|
139
141
|
}
|
|
140
142
|
|
|
143
|
+
fun setupElevation() {
|
|
144
|
+
val value = delegate?.sheetElevation ?: DEFAULT_ELEVATION
|
|
145
|
+
val effectiveElevation = if (value < 0) DEFAULT_ELEVATION else value
|
|
146
|
+
elevation = effectiveElevation.dpToPx()
|
|
147
|
+
}
|
|
148
|
+
|
|
141
149
|
// =============================================================================
|
|
142
150
|
// MARK: - Grabber
|
|
143
151
|
// =============================================================================
|
|
@@ -8,6 +8,7 @@ import androidx.core.view.ViewCompat
|
|
|
8
8
|
import androidx.core.view.WindowInsetsAnimationCompat
|
|
9
9
|
import androidx.core.view.WindowInsetsCompat
|
|
10
10
|
import com.facebook.react.uimanager.ThemedReactContext
|
|
11
|
+
import com.lodev09.truesheet.utils.KeyboardUtils
|
|
11
12
|
|
|
12
13
|
interface TrueSheetKeyboardObserverDelegate {
|
|
13
14
|
fun keyboardWillShow(height: Int)
|
|
@@ -59,7 +60,7 @@ class TrueSheetKeyboardObserver(private val targetView: View, private val reactC
|
|
|
59
60
|
}
|
|
60
61
|
}
|
|
61
62
|
|
|
62
|
-
private fun getKeyboardHeight(
|
|
63
|
+
private fun getKeyboardHeight(): Int = KeyboardUtils.getKeyboardHeight(targetView)
|
|
63
64
|
|
|
64
65
|
private fun setupAnimationCallback() {
|
|
65
66
|
ViewCompat.setWindowInsetsAnimationCallback(
|
|
@@ -69,14 +70,14 @@ class TrueSheetKeyboardObserver(private val targetView: View, private val reactC
|
|
|
69
70
|
private var endHeight = 0
|
|
70
71
|
|
|
71
72
|
override fun onPrepare(animation: WindowInsetsAnimationCompat) {
|
|
72
|
-
startHeight = getKeyboardHeight(
|
|
73
|
+
startHeight = getKeyboardHeight()
|
|
73
74
|
}
|
|
74
75
|
|
|
75
76
|
override fun onStart(
|
|
76
77
|
animation: WindowInsetsAnimationCompat,
|
|
77
78
|
bounds: WindowInsetsAnimationCompat.BoundsCompat
|
|
78
79
|
): WindowInsetsAnimationCompat.BoundsCompat {
|
|
79
|
-
endHeight = getKeyboardHeight(
|
|
80
|
+
endHeight = getKeyboardHeight()
|
|
80
81
|
targetHeight = endHeight
|
|
81
82
|
isHiding = endHeight < startHeight
|
|
82
83
|
if (endHeight > startHeight) {
|
|
@@ -99,7 +100,7 @@ class TrueSheetKeyboardObserver(private val targetView: View, private val reactC
|
|
|
99
100
|
}
|
|
100
101
|
|
|
101
102
|
override fun onEnd(animation: WindowInsetsAnimationCompat) {
|
|
102
|
-
val finalHeight = getKeyboardHeight(
|
|
103
|
+
val finalHeight = getKeyboardHeight()
|
|
103
104
|
updateHeight(startHeight, finalHeight, 1f)
|
|
104
105
|
if (isHiding) {
|
|
105
106
|
delegate?.keyboardDidHide()
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
package com.lodev09.truesheet.utils
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.view.View
|
|
5
|
+
import android.view.inputmethod.InputMethodManager
|
|
6
|
+
import androidx.core.view.ViewCompat
|
|
7
|
+
import androidx.core.view.WindowInsetsCompat
|
|
8
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
9
|
+
|
|
10
|
+
object KeyboardUtils {
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Dismisses the soft keyboard if currently shown.
|
|
14
|
+
*/
|
|
15
|
+
fun dismiss(reactContext: ThemedReactContext) {
|
|
16
|
+
val imm = reactContext.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager
|
|
17
|
+
reactContext.currentActivity?.currentFocus?.let { focusedView ->
|
|
18
|
+
imm?.hideSoftInputFromWindow(focusedView.windowToken, 0)
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Gets the current keyboard height from window insets.
|
|
24
|
+
*/
|
|
25
|
+
fun getKeyboardHeight(view: View): Int {
|
|
26
|
+
val insets = ViewCompat.getRootWindowInsets(view)
|
|
27
|
+
return insets?.getInsets(WindowInsetsCompat.Type.ime())?.bottom ?: 0
|
|
28
|
+
}
|
|
29
|
+
}
|
package/ios/TrueSheetView.mm
CHANGED
|
@@ -134,7 +134,7 @@ using namespace facebook::react;
|
|
|
134
134
|
_controller.backgroundColor = RCTUIColorFromSharedColor(newProps.backgroundColor);
|
|
135
135
|
|
|
136
136
|
// Blur tint
|
|
137
|
-
_controller.
|
|
137
|
+
_controller.backgroundBlur = !newProps.backgroundBlur.empty() ? RCTNSStringFromString(newProps.backgroundBlur) : nil;
|
|
138
138
|
|
|
139
139
|
// Blur options
|
|
140
140
|
const auto &blurOpts = newProps.blurOptions;
|
|
@@ -61,7 +61,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
61
61
|
@property (nonatomic, assign) BOOL draggable;
|
|
62
62
|
@property (nonatomic, assign) BOOL dimmed;
|
|
63
63
|
@property (nonatomic, strong, nullable) NSNumber *dimmedDetentIndex;
|
|
64
|
-
@property (nonatomic, copy, nullable) NSString *
|
|
64
|
+
@property (nonatomic, copy, nullable) NSString *backgroundBlur;
|
|
65
65
|
@property (nonatomic, strong, nullable) NSNumber *blurIntensity;
|
|
66
66
|
@property (nonatomic, assign) BOOL blurInteraction;
|
|
67
67
|
@property (nonatomic, assign) BOOL pageSizing;
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
#import "core/TrueSheetBlurView.h"
|
|
12
12
|
#import "core/TrueSheetDetentCalculator.h"
|
|
13
13
|
#import "core/TrueSheetGrabberView.h"
|
|
14
|
+
#import "utils/BlurUtil.h"
|
|
14
15
|
#import "utils/GestureUtil.h"
|
|
15
16
|
#import "utils/WindowUtil.h"
|
|
16
17
|
|
|
@@ -77,6 +78,10 @@
|
|
|
77
78
|
|
|
78
79
|
#pragma mark - Computed Properties
|
|
79
80
|
|
|
81
|
+
- (UISheetPresentationController *)sheet {
|
|
82
|
+
return self.sheetPresentationController;
|
|
83
|
+
}
|
|
84
|
+
|
|
80
85
|
- (BOOL)isTopmostPresentedController {
|
|
81
86
|
if (!self.isViewLoaded || self.view.window == nil) {
|
|
82
87
|
return NO;
|
|
@@ -85,7 +90,7 @@
|
|
|
85
90
|
}
|
|
86
91
|
|
|
87
92
|
- (UIView *)presentedView {
|
|
88
|
-
return self.
|
|
93
|
+
return self.sheet.presentedView;
|
|
89
94
|
}
|
|
90
95
|
|
|
91
96
|
- (CGFloat)currentPosition {
|
|
@@ -119,7 +124,7 @@
|
|
|
119
124
|
}
|
|
120
125
|
|
|
121
126
|
- (NSInteger)currentDetentIndex {
|
|
122
|
-
UISheetPresentationController *sheet = self.
|
|
127
|
+
UISheetPresentationController *sheet = self.sheet;
|
|
123
128
|
if (!sheet)
|
|
124
129
|
return -1;
|
|
125
130
|
|
|
@@ -134,7 +139,6 @@
|
|
|
134
139
|
return i;
|
|
135
140
|
}
|
|
136
141
|
} else {
|
|
137
|
-
// iOS 15 only supports medium/large system detents
|
|
138
142
|
if ([selectedIdentifier isEqualToString:UISheetPresentationControllerDetentIdentifierMedium]) {
|
|
139
143
|
return 0;
|
|
140
144
|
} else if ([selectedIdentifier isEqualToString:UISheetPresentationControllerDetentIdentifierLarge]) {
|
|
@@ -491,7 +495,7 @@
|
|
|
491
495
|
#pragma mark - Sheet Configuration
|
|
492
496
|
|
|
493
497
|
- (void)setupSheetDetentsForSizeChange {
|
|
494
|
-
[self.
|
|
498
|
+
[self.sheet animateChanges:^{
|
|
495
499
|
_pendingContentSizeChange = YES;
|
|
496
500
|
[self setupSheetDetents];
|
|
497
501
|
}];
|
|
@@ -503,7 +507,7 @@
|
|
|
503
507
|
}
|
|
504
508
|
|
|
505
509
|
- (void)setupSheetDetents {
|
|
506
|
-
UISheetPresentationController *sheet = self.
|
|
510
|
+
UISheetPresentationController *sheet = self.sheet;
|
|
507
511
|
if (!sheet) {
|
|
508
512
|
RCTLogError(@"TrueSheet: sheetPresentationController is nil in setupSheetDetents");
|
|
509
513
|
return;
|
|
@@ -593,7 +597,7 @@
|
|
|
593
597
|
}
|
|
594
598
|
|
|
595
599
|
- (UISheetPresentationControllerDetentIdentifier)detentIdentifierForIndex:(NSInteger)index {
|
|
596
|
-
UISheetPresentationController *sheet = self.
|
|
600
|
+
UISheetPresentationController *sheet = self.sheet;
|
|
597
601
|
if (!sheet) {
|
|
598
602
|
RCTLogError(@"TrueSheet: sheetPresentationController is nil in detentIdentifierForIndex");
|
|
599
603
|
return UISheetPresentationControllerDetentIdentifierMedium;
|
|
@@ -615,8 +619,7 @@
|
|
|
615
619
|
}
|
|
616
620
|
|
|
617
621
|
- (void)applyActiveDetent {
|
|
618
|
-
|
|
619
|
-
if (!sheet) {
|
|
622
|
+
if (!self.sheet) {
|
|
620
623
|
RCTLogError(@"TrueSheet: sheetPresentationController is nil in applyActiveDetent");
|
|
621
624
|
return;
|
|
622
625
|
}
|
|
@@ -638,7 +641,7 @@
|
|
|
638
641
|
|
|
639
642
|
UISheetPresentationControllerDetentIdentifier identifier = [self detentIdentifierForIndex:clampedIndex];
|
|
640
643
|
if (identifier) {
|
|
641
|
-
sheet.selectedDetentIdentifier = identifier;
|
|
644
|
+
self.sheet.selectedDetentIdentifier = identifier;
|
|
642
645
|
}
|
|
643
646
|
}
|
|
644
647
|
|
|
@@ -657,62 +660,55 @@
|
|
|
657
660
|
[self applyActiveDetent];
|
|
658
661
|
}
|
|
659
662
|
|
|
660
|
-
- (void)
|
|
661
|
-
|
|
662
|
-
if (
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
sheet.delegate = self;
|
|
669
|
-
|
|
670
|
-
if (@available(iOS 17.0, *)) {
|
|
671
|
-
sheet.prefersPageSizing = self.pageSizing;
|
|
672
|
-
}
|
|
673
|
-
|
|
674
|
-
sheet.prefersEdgeAttachedInCompactHeight = YES;
|
|
675
|
-
|
|
676
|
-
// When draggable is disabled, prevent scrolling from expanding the sheet
|
|
677
|
-
sheet.prefersScrollingExpandsWhenScrolledToEdge = self.draggable;
|
|
678
|
-
|
|
679
|
-
if (self.cornerRadius) {
|
|
680
|
-
sheet.preferredCornerRadius = [self.cornerRadius floatValue];
|
|
681
|
-
} else {
|
|
682
|
-
sheet.preferredCornerRadius = UISheetPresentationControllerAutomaticDimension;
|
|
663
|
+
- (void)setupBackground {
|
|
664
|
+
// iOS 26.1+: use native backgroundEffect when only backgroundBlur is set (no backgroundColor)
|
|
665
|
+
if (@available(iOS 26.1, *)) {
|
|
666
|
+
if (!self.backgroundColor && self.backgroundBlur && self.backgroundBlur.length > 0) {
|
|
667
|
+
UIBlurEffectStyle style = [BlurUtil blurEffectStyleFromString:self.backgroundBlur];
|
|
668
|
+
self.sheet.backgroundEffect = [UIBlurEffect effectWithStyle:style];
|
|
669
|
+
return;
|
|
670
|
+
}
|
|
683
671
|
}
|
|
684
672
|
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
NSString *effectiveBlurTint = self.blurTint;
|
|
673
|
+
NSString *effectiveBackgroundBlur = self.backgroundBlur;
|
|
688
674
|
if (@available(iOS 26.0, *)) {
|
|
689
|
-
// iOS 26+ has
|
|
690
|
-
} else if ((!
|
|
691
|
-
|
|
675
|
+
// iOS 26+ has default liquid glass effect
|
|
676
|
+
} else if ((!effectiveBackgroundBlur || effectiveBackgroundBlur.length == 0) && !self.backgroundColor) {
|
|
677
|
+
effectiveBackgroundBlur = @"system-material";
|
|
692
678
|
}
|
|
693
679
|
|
|
694
|
-
BOOL
|
|
680
|
+
BOOL blurChanged = ![_blurView.backgroundBlur isEqualToString:effectiveBackgroundBlur];
|
|
695
681
|
|
|
696
|
-
if (_blurView &&
|
|
682
|
+
if (_blurView && blurChanged) {
|
|
697
683
|
[_blurView removeFromSuperview];
|
|
698
684
|
_blurView = nil;
|
|
699
685
|
}
|
|
700
686
|
|
|
701
|
-
if (
|
|
687
|
+
if (effectiveBackgroundBlur && effectiveBackgroundBlur.length > 0) {
|
|
702
688
|
if (!_blurView) {
|
|
703
689
|
_blurView = [[TrueSheetBlurView alloc] init];
|
|
704
690
|
[_blurView addToView:self.view];
|
|
705
691
|
}
|
|
706
|
-
_blurView.
|
|
692
|
+
_blurView.backgroundBlur = effectiveBackgroundBlur;
|
|
707
693
|
_blurView.blurIntensity = self.blurIntensity;
|
|
708
694
|
_blurView.blurInteraction = self.blurInteraction;
|
|
709
695
|
[_blurView applyBlurEffect];
|
|
710
696
|
}
|
|
711
697
|
|
|
698
|
+
if (@available(iOS 26.1, *)) {
|
|
699
|
+
if (self.backgroundColor) {
|
|
700
|
+
self.sheet.backgroundEffect = [UIColorEffect effectWithColor:self.backgroundColor];
|
|
701
|
+
}
|
|
702
|
+
} else {
|
|
703
|
+
self.view.backgroundColor = self.backgroundColor;
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
- (void)setupGrabber {
|
|
712
708
|
BOOL showGrabber = self.grabber && self.draggable;
|
|
713
709
|
|
|
714
710
|
if (self.grabberOptions) {
|
|
715
|
-
sheet.prefersGrabberVisible = NO;
|
|
711
|
+
self.sheet.prefersGrabberVisible = NO;
|
|
716
712
|
|
|
717
713
|
NSDictionary *options = self.grabberOptions;
|
|
718
714
|
_grabberView.grabberWidth = options[@"width"];
|
|
@@ -724,14 +720,40 @@
|
|
|
724
720
|
[_grabberView applyConfiguration];
|
|
725
721
|
_grabberView.hidden = !showGrabber;
|
|
726
722
|
|
|
727
|
-
// Ensure grabber is above container/header views
|
|
728
723
|
[self.view bringSubviewToFront:_grabberView];
|
|
729
724
|
} else {
|
|
730
|
-
sheet.prefersGrabberVisible = showGrabber;
|
|
725
|
+
self.sheet.prefersGrabberVisible = showGrabber;
|
|
731
726
|
_grabberView.hidden = YES;
|
|
732
727
|
}
|
|
733
728
|
}
|
|
734
729
|
|
|
730
|
+
- (void)setupSheetProps {
|
|
731
|
+
UISheetPresentationController *sheet = self.sheet;
|
|
732
|
+
if (!sheet) {
|
|
733
|
+
RCTLogWarn(
|
|
734
|
+
@"TrueSheet: No sheet presentation controller available. Ensure the view controller is presented modally.");
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
sheet.delegate = self;
|
|
739
|
+
|
|
740
|
+
if (@available(iOS 17.0, *)) {
|
|
741
|
+
sheet.prefersPageSizing = self.pageSizing;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
sheet.prefersEdgeAttachedInCompactHeight = YES;
|
|
745
|
+
sheet.prefersScrollingExpandsWhenScrolledToEdge = self.draggable;
|
|
746
|
+
|
|
747
|
+
if (self.cornerRadius) {
|
|
748
|
+
sheet.preferredCornerRadius = [self.cornerRadius floatValue];
|
|
749
|
+
} else {
|
|
750
|
+
sheet.preferredCornerRadius = UISheetPresentationControllerAutomaticDimension;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
[self setupBackground];
|
|
754
|
+
[self setupGrabber];
|
|
755
|
+
}
|
|
756
|
+
|
|
735
757
|
#pragma mark - UISheetPresentationControllerDelegate
|
|
736
758
|
|
|
737
759
|
- (void)sheetPresentationControllerDidChangeSelectedDetentIdentifier:
|
|
@@ -12,7 +12,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
12
12
|
|
|
13
13
|
@interface TrueSheetBlurView : UIVisualEffectView
|
|
14
14
|
|
|
15
|
-
@property (nonatomic, copy, nullable) NSString *
|
|
15
|
+
@property (nonatomic, copy, nullable) NSString *backgroundBlur;
|
|
16
16
|
@property (nonatomic, strong, nullable) NSNumber *blurIntensity;
|
|
17
17
|
@property (nonatomic, assign) BOOL blurInteraction;
|
|
18
18
|
|
|
@@ -7,49 +7,12 @@
|
|
|
7
7
|
//
|
|
8
8
|
|
|
9
9
|
#import "TrueSheetBlurView.h"
|
|
10
|
+
#import "BlurUtil.h"
|
|
10
11
|
|
|
11
12
|
@implementation TrueSheetBlurView {
|
|
12
13
|
UIViewPropertyAnimator *_blurAnimator;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
#pragma mark - Private
|
|
16
|
-
|
|
17
|
-
+ (UIBlurEffectStyle)blurEffectStyleFromString:(NSString *)tintString {
|
|
18
|
-
static NSDictionary<NSString *, NSNumber *> *styleMap = nil;
|
|
19
|
-
static dispatch_once_t onceToken;
|
|
20
|
-
dispatch_once(&onceToken, ^{
|
|
21
|
-
styleMap = @{
|
|
22
|
-
@"dark" : @(UIBlurEffectStyleDark),
|
|
23
|
-
@"light" : @(UIBlurEffectStyleLight),
|
|
24
|
-
@"extra-light" : @(UIBlurEffectStyleExtraLight),
|
|
25
|
-
@"regular" : @(UIBlurEffectStyleRegular),
|
|
26
|
-
@"prominent" : @(UIBlurEffectStyleProminent),
|
|
27
|
-
@"system-ultra-thin-material" : @(UIBlurEffectStyleSystemUltraThinMaterial),
|
|
28
|
-
@"system-thin-material" : @(UIBlurEffectStyleSystemThinMaterial),
|
|
29
|
-
@"system-material" : @(UIBlurEffectStyleSystemMaterial),
|
|
30
|
-
@"system-thick-material" : @(UIBlurEffectStyleSystemThickMaterial),
|
|
31
|
-
@"system-chrome-material" : @(UIBlurEffectStyleSystemChromeMaterial),
|
|
32
|
-
@"system-ultra-thin-material-light" : @(UIBlurEffectStyleSystemUltraThinMaterialLight),
|
|
33
|
-
@"system-thin-material-light" : @(UIBlurEffectStyleSystemThinMaterialLight),
|
|
34
|
-
@"system-material-light" : @(UIBlurEffectStyleSystemMaterialLight),
|
|
35
|
-
@"system-thick-material-light" : @(UIBlurEffectStyleSystemThickMaterialLight),
|
|
36
|
-
@"system-chrome-material-light" : @(UIBlurEffectStyleSystemChromeMaterialLight),
|
|
37
|
-
@"system-ultra-thin-material-dark" : @(UIBlurEffectStyleSystemUltraThinMaterialDark),
|
|
38
|
-
@"system-thin-material-dark" : @(UIBlurEffectStyleSystemThinMaterialDark),
|
|
39
|
-
@"system-material-dark" : @(UIBlurEffectStyleSystemMaterialDark),
|
|
40
|
-
@"system-thick-material-dark" : @(UIBlurEffectStyleSystemThickMaterialDark),
|
|
41
|
-
@"system-chrome-material-dark" : @(UIBlurEffectStyleSystemChromeMaterialDark),
|
|
42
|
-
};
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
NSNumber *style = styleMap[tintString];
|
|
46
|
-
if (style) {
|
|
47
|
-
return (UIBlurEffectStyle)[style integerValue];
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return UIBlurEffectStyleLight;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
16
|
#pragma mark - Initialization
|
|
54
17
|
|
|
55
18
|
- (instancetype)init {
|
|
@@ -76,7 +39,7 @@
|
|
|
76
39
|
|
|
77
40
|
// Create animator only once
|
|
78
41
|
if (!_blurAnimator) {
|
|
79
|
-
UIBlurEffectStyle style = [
|
|
42
|
+
UIBlurEffectStyle style = [BlurUtil blurEffectStyleFromString:self.backgroundBlur];
|
|
80
43
|
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:style];
|
|
81
44
|
|
|
82
45
|
__weak __typeof(self) weakSelf = self;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Created by Jovanni Lo (@lodev09)
|
|
3
|
+
// Copyright (c) 2024-present. All rights reserved.
|
|
4
|
+
//
|
|
5
|
+
// This source code is licensed under the MIT license found in the
|
|
6
|
+
// LICENSE file in the root directory of this source tree.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
10
|
+
|
|
11
|
+
#import <UIKit/UIKit.h>
|
|
12
|
+
|
|
13
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
14
|
+
|
|
15
|
+
@interface BlurUtil : NSObject
|
|
16
|
+
|
|
17
|
+
+ (UIBlurEffectStyle)blurEffectStyleFromString:(NSString *)tintString;
|
|
18
|
+
|
|
19
|
+
@end
|
|
20
|
+
|
|
21
|
+
NS_ASSUME_NONNULL_END
|
|
22
|
+
|
|
23
|
+
#endif
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Created by Jovanni Lo (@lodev09)
|
|
3
|
+
// Copyright (c) 2024-present. All rights reserved.
|
|
4
|
+
//
|
|
5
|
+
// This source code is licensed under the MIT license found in the
|
|
6
|
+
// LICENSE file in the root directory of this source tree.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
10
|
+
|
|
11
|
+
#import "BlurUtil.h"
|
|
12
|
+
|
|
13
|
+
@implementation BlurUtil
|
|
14
|
+
|
|
15
|
+
+ (UIBlurEffectStyle)blurEffectStyleFromString:(NSString *)tintString {
|
|
16
|
+
static NSDictionary<NSString *, NSNumber *> *styleMap = nil;
|
|
17
|
+
static dispatch_once_t onceToken;
|
|
18
|
+
dispatch_once(&onceToken, ^{
|
|
19
|
+
styleMap = @{
|
|
20
|
+
@"dark" : @(UIBlurEffectStyleDark),
|
|
21
|
+
@"light" : @(UIBlurEffectStyleLight),
|
|
22
|
+
@"extra-light" : @(UIBlurEffectStyleExtraLight),
|
|
23
|
+
@"regular" : @(UIBlurEffectStyleRegular),
|
|
24
|
+
@"prominent" : @(UIBlurEffectStyleProminent),
|
|
25
|
+
@"system-ultra-thin-material" : @(UIBlurEffectStyleSystemUltraThinMaterial),
|
|
26
|
+
@"system-thin-material" : @(UIBlurEffectStyleSystemThinMaterial),
|
|
27
|
+
@"system-material" : @(UIBlurEffectStyleSystemMaterial),
|
|
28
|
+
@"system-thick-material" : @(UIBlurEffectStyleSystemThickMaterial),
|
|
29
|
+
@"system-chrome-material" : @(UIBlurEffectStyleSystemChromeMaterial),
|
|
30
|
+
@"system-ultra-thin-material-light" : @(UIBlurEffectStyleSystemUltraThinMaterialLight),
|
|
31
|
+
@"system-thin-material-light" : @(UIBlurEffectStyleSystemThinMaterialLight),
|
|
32
|
+
@"system-material-light" : @(UIBlurEffectStyleSystemMaterialLight),
|
|
33
|
+
@"system-thick-material-light" : @(UIBlurEffectStyleSystemThickMaterialLight),
|
|
34
|
+
@"system-chrome-material-light" : @(UIBlurEffectStyleSystemChromeMaterialLight),
|
|
35
|
+
@"system-ultra-thin-material-dark" : @(UIBlurEffectStyleSystemUltraThinMaterialDark),
|
|
36
|
+
@"system-thin-material-dark" : @(UIBlurEffectStyleSystemThinMaterialDark),
|
|
37
|
+
@"system-material-dark" : @(UIBlurEffectStyleSystemMaterialDark),
|
|
38
|
+
@"system-thick-material-dark" : @(UIBlurEffectStyleSystemThickMaterialDark),
|
|
39
|
+
@"system-chrome-material-dark" : @(UIBlurEffectStyleSystemChromeMaterialDark),
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
NSNumber *style = styleMap[tintString];
|
|
44
|
+
if (style) {
|
|
45
|
+
return (UIBlurEffectStyle)[style integerValue];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return UIBlurEffectStyleLight;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@end
|
|
52
|
+
|
|
53
|
+
#endif
|
package/lib/module/TrueSheet.js
CHANGED
|
@@ -260,7 +260,7 @@ export class TrueSheet extends PureComponent {
|
|
|
260
260
|
initialDetentIndex = -1,
|
|
261
261
|
initialDetentAnimated = true,
|
|
262
262
|
dimmedDetentIndex,
|
|
263
|
-
|
|
263
|
+
backgroundBlur,
|
|
264
264
|
blurOptions,
|
|
265
265
|
cornerRadius,
|
|
266
266
|
maxHeight,
|
|
@@ -269,7 +269,9 @@ export class TrueSheet extends PureComponent {
|
|
|
269
269
|
children,
|
|
270
270
|
style,
|
|
271
271
|
header,
|
|
272
|
+
headerStyle,
|
|
272
273
|
footer,
|
|
274
|
+
footerStyle,
|
|
273
275
|
insetAdjustment = 'automatic',
|
|
274
276
|
...rest
|
|
275
277
|
} = this.props;
|
|
@@ -295,7 +297,7 @@ export class TrueSheet extends PureComponent {
|
|
|
295
297
|
ref: this.nativeRef,
|
|
296
298
|
style: styles.sheetView,
|
|
297
299
|
detents: resolvedDetents,
|
|
298
|
-
|
|
300
|
+
backgroundBlur: backgroundBlur,
|
|
299
301
|
blurOptions: blurOptions,
|
|
300
302
|
backgroundColor: backgroundColor,
|
|
301
303
|
cornerRadius: cornerRadius,
|
|
@@ -332,13 +334,13 @@ export class TrueSheet extends PureComponent {
|
|
|
332
334
|
children: this.state.shouldRenderNativeView && /*#__PURE__*/_jsxs(TrueSheetContainerViewNativeComponent, {
|
|
333
335
|
style: containerStyle,
|
|
334
336
|
children: [header && /*#__PURE__*/_jsx(TrueSheetHeaderViewNativeComponent, {
|
|
335
|
-
style: styles.header,
|
|
337
|
+
style: [styles.header, headerStyle],
|
|
336
338
|
children: /*#__PURE__*/isValidElement(header) ? header : /*#__PURE__*/createElement(header)
|
|
337
339
|
}), /*#__PURE__*/_jsx(TrueSheetContentViewNativeComponent, {
|
|
338
340
|
style: [style, contentStyle],
|
|
339
341
|
children: children
|
|
340
342
|
}), footer && /*#__PURE__*/_jsx(TrueSheetFooterViewNativeComponent, {
|
|
341
|
-
style: styles.footer,
|
|
343
|
+
style: [styles.footer, footerStyle],
|
|
342
344
|
children: /*#__PURE__*/isValidElement(footer) ? footer : /*#__PURE__*/createElement(footer)
|
|
343
345
|
})]
|
|
344
346
|
})
|