@lodev09/react-native-true-sheet 0.4.5 → 0.5.1

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/README.md CHANGED
@@ -4,11 +4,13 @@
4
4
  ![GitHub Release](https://img.shields.io/github/v/release/lodev09/react-native-true-sheet)
5
5
  ![NPM Downloads](https://img.shields.io/npm/dw/%40lodev09%2Freact-native-true-sheet)
6
6
 
7
- The true native bottom sheet.
7
+ The true native bottom sheet 💩
8
+
9
+ ![Preview](preview.gif)
8
10
 
9
11
  ## Features
10
12
  * ✅ Implemented on the native realm.
11
- * ✅ **_NOT_** your pure JS, (re)animated View.
13
+ * ✅ **_NOT_** your pure JS, (re)animated View. But might integrate in the future 👀
12
14
  * ✅ Clean, fast and lightweight.
13
15
  * ✅ Handles your Sscrolling needs, easy.
14
16
  * ✅ Asynchronus `ref` methods.
@@ -35,7 +37,11 @@ const openSheet = () => {
35
37
  return (
36
38
  <View>
37
39
  <Button onPress={openSheet} title="Open Sheet" />
38
- <TrueSheet sizes={['auto', 'large']} ref={sheet}>
40
+ <TrueSheet
41
+ ref={sheet}
42
+ sizes={['auto', 'large']}
43
+ cornerRadius={24}
44
+ >
39
45
  // ...
40
46
  </TrueSheet>
41
47
  </View>
@@ -43,7 +49,138 @@ return (
43
49
  ```
44
50
 
45
51
  ## Options
46
- > TODO - laters
52
+
53
+ Extended from `ViewProps`
54
+
55
+ | Prop | Type | Default | Description | 🍎 | 🤖 |
56
+ | - | - | - | - | - | - |
57
+ | sizes | [`SheetSize`](#sheetsize) | `['medium', 'large']` | The sizes you want the Sheet to support. Maximum of _**3 sizes**_ only! **_collapsed_**, **_half-expanded_** and **_expanded_**. Example: `size={['auto', '60%', 'large']}`| ✅ | ✅ |
58
+ | backgroundColor | `ColorValue` | - | Main sheet background color. | ✅ | ✅ |
59
+ | cornerRadius | `number` | - | The sheet corner radius. | ✅ | ✅ |
60
+ | maxHeight | `number` | - | Overrides `large` or `100%` height. | ✅ | ✅ |
61
+ | FooterComponent | `ReactNode` | - | A component that floats at the bottom of the Sheet. | ✅ | ✅ |
62
+ | grabber | `boolean` | - | Shows native grabber (or handle) on IOS. | ✅ | |
63
+ | blurStyle | [`BlurStyle`](#blurstyle) | - | The blur effect style on iOS. Overrides `backgroundColor` if set. Example: `light`, `dark`, etc. | ✅ | |
64
+ | scrollRef | `RefObject<...>` | - | The main scrollable ref that Sheet should handle on IOS. | ✅ | |
65
+
66
+ ## Methods
67
+
68
+ ```ts
69
+ const sheet = useRef<TrueSheet>(null)
70
+
71
+ const open = () => {
72
+ // Presents 80%
73
+ sheet.current?.present(1)
74
+ }
75
+
76
+ const dismiss = () => {
77
+ sheet.current?.dismiss()
78
+ }
79
+
80
+ return (
81
+ <View>
82
+ <Button onPress={open} title="Open" />
83
+ <Button onPress={dismiss} title="Dimiss" />
84
+ <TrueSheet sizes={['auto', '80%']} ref={sheet}>
85
+ // ...
86
+ </TrueSheet>
87
+ </View>
88
+ )
89
+ ```
90
+
91
+ | Name | Parameters | Description |
92
+ | - | - | - |
93
+ | present | `index: number = 0` | Present the modal sheet at size index. See `sizes` prop. |
94
+ | dismiss | - | Dismisses the Sheet. |
95
+
96
+ ## Events
97
+
98
+ ```ts
99
+ const handleSizeChange = (info: SizeInfo) => {
100
+ console.log(info)
101
+ }
102
+
103
+ return (
104
+ <TrueSheet onSizeChange={handleSizeChange} sizes={['auto', '80%']} ref={sheet}>
105
+ // ...
106
+ </TrueSheet>
107
+ )
108
+ ```
109
+
110
+ | Name | Parameters | Description |
111
+ | - | - | - |
112
+ | onPresent | - | Called when the Sheet has been presented. Comes with the size index and value. |
113
+ | onDismiss | - | Called when the Sheet has been dismissed. |
114
+ | onSizeChange | [`SizeInfo`](#sizeinfo) | Called when the size of the sheet has changed. Either by dragging or programatically. |
115
+
116
+ ## Types
117
+
118
+ ### `SheetSize`
119
+
120
+ ```ts
121
+ <TrueSheet sizes={['auto', '80%', 'large']}>
122
+ // ...
123
+ </TrueSheet>
124
+ ```
125
+
126
+ | Value | Description | 🍎 | 🤖 |
127
+ | - | - | - | - |
128
+ | `large` | Translates to 100% | ✅ | ✅ |
129
+ | `medium` | Translates to 50% | **_15+_** | ✅ |
130
+ | `auto` | Auto resize based on content height. | **_16+_** | ✅ |
131
+ | `number` | Fixed height | **_16+_** | ✅ |
132
+ | `${number}%` | Fixed height in % | **_16+_** | ✅ |
133
+ | `small` | Translates to 25% | **_16+_** | ✅ |
134
+
135
+ ### `BlurStyle`
136
+
137
+ Blur style mapped to native values in IOS.
138
+
139
+ ```ts
140
+ <TrueSheet blurStyle="dark">
141
+ // ...
142
+ </TrueSheet>
143
+ ```
144
+
145
+ | Value |
146
+ | - |
147
+ | `"light"` |
148
+ | `"dark"` |
149
+ | `"default"` |
150
+ | `"extraLight"` |
151
+ | `"regular"` |
152
+ | `"prominent"` |
153
+ | `"systemUltraThinMaterial"` |
154
+ | `"systemThinMaterial"` |
155
+ | `"systemMaterial"` |
156
+ | `"systemThickMaterial"` |
157
+ | `"systemChromeMaterial"` |
158
+ | `"systemUltraThinMaterialLight"` |
159
+ | `"systemThinMaterialLight"` |
160
+ | `"systemMaterialLight"` |
161
+ | `"systemThickMaterialLight"` |
162
+ | `"systemChromeMaterialLight"` |
163
+ | `"systemUltraThinMaterialDark"` |
164
+ | `"systemThinMaterialDark"` |
165
+ | `"systemMaterialDark"` |
166
+ | `"systemThickMaterialDark"` |
167
+ | `"systemChromeMaterialDark"` |
168
+
169
+ ### `SizeInfo`
170
+
171
+ `Object` that comes with some events.
172
+
173
+ ```ts
174
+ {
175
+ index: 1,
176
+ value: 69
177
+ }
178
+ ```
179
+
180
+ | Property | Type | Description |
181
+ | - | - | - |
182
+ | index | `number` | The size index from the provided sizes. See `sizes` prop. |
183
+ | value | `number` | The actual height value of the size. |
47
184
 
48
185
  ## Contributing
49
186
 
@@ -1,6 +1,7 @@
1
1
  package com.lodev09.truesheet
2
2
 
3
3
  import android.content.Context
4
+ import android.graphics.Color
4
5
  import android.view.View
5
6
  import android.view.ViewGroup
6
7
  import android.view.ViewStructure
@@ -17,8 +18,8 @@ import com.google.android.material.bottomsheet.BottomSheetDialog
17
18
  import com.lodev09.truesheet.core.DismissEvent
18
19
  import com.lodev09.truesheet.core.PresentEvent
19
20
  import com.lodev09.truesheet.core.RootViewGroup
20
- import com.lodev09.truesheet.core.SheetBehavior
21
21
  import com.lodev09.truesheet.core.SizeChangeEvent
22
+ import com.lodev09.truesheet.core.TrueSheetBehavior
22
23
  import com.lodev09.truesheet.core.Utils
23
24
 
24
25
  class TrueSheetView(context: Context) :
@@ -32,14 +33,16 @@ class TrueSheetView(context: Context) :
32
33
  private val surfaceId: Int
33
34
  get() = UIManagerHelper.getSurfaceId(this)
34
35
 
35
- private var sizeIndex: Int = 0
36
- private var sizes: Array<Any> = arrayOf("medium", "large")
36
+ private var activeIndex: Int = 0
37
37
 
38
38
  private var presentPromise: (() -> Unit)? = null
39
39
  private var dismissPromise: (() -> Unit)? = null
40
40
 
41
41
  private val sheetDialog: BottomSheetDialog
42
- private val sheetLayout: LinearLayout
42
+ private val sheetBehavior: TrueSheetBehavior
43
+ private val sheetView: ViewGroup
44
+
45
+ // React root view placeholder
43
46
  private val sheetRootView: RootViewGroup
44
47
 
45
48
  // 1st child of the container view
@@ -48,8 +51,6 @@ class TrueSheetView(context: Context) :
48
51
  // 2nd child of the container view
49
52
  private var footerView: ViewGroup? = null
50
53
 
51
- private var sheetBehavior: SheetBehavior<ViewGroup>
52
-
53
54
  init {
54
55
  reactContext.addLifecycleEventListener(this)
55
56
  eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag(reactContext, id)
@@ -58,58 +59,27 @@ class TrueSheetView(context: Context) :
58
59
  sheetRootView.eventDispatcher = eventDispatcher
59
60
 
60
61
  sheetDialog = BottomSheetDialog(context)
61
- sheetBehavior = SheetBehavior()
62
- sheetLayout = LinearLayout(context)
63
-
64
- // Configure Sheet events
65
- sheetBehavior.apply {
66
-
67
- // Set our default max height
68
- maxSheetSize = Utils.maxSize(context)
69
-
70
- addBottomSheetCallback(
71
- object : BottomSheetBehavior.BottomSheetCallback() {
72
- override fun onSlide(sheetView: View, slideOffset: Float) {
73
- footerView?.let {
74
- it.y = (sheetView.height - sheetView.top - it.height).toFloat()
75
- }
76
- }
77
-
78
- override fun onStateChanged(view: View, newState: Int) {
79
- val sizeInfo = getSizeInfoForState(sizes.size, newState)
80
- if (sizeInfo != null && sizeInfo.index != sizeIndex) {
81
- sizeIndex = sizeInfo.index
82
-
83
- // dispatch onSizeChange event
84
- eventDispatcher?.dispatchEvent(SizeChangeEvent(surfaceId, id, sizeInfo))
85
- }
62
+ sheetBehavior = TrueSheetBehavior()
86
63
 
87
- when (newState) {
88
- BottomSheetBehavior.STATE_HIDDEN -> sheetDialog.dismiss()
89
- else -> {}
90
- }
91
- }
92
- }
93
- )
94
- }
95
-
96
- // Configure the sheet layout
97
- sheetLayout.apply {
64
+ // Configure the sheet layout view
65
+ LinearLayout(context).apply {
98
66
  addView(sheetRootView)
99
67
  sheetDialog.setContentView(this)
100
68
 
101
- val layoutParent = parent as ViewGroup
102
- (layoutParent.layoutParams as CoordinatorLayout.LayoutParams).behavior = sheetBehavior
69
+ sheetView = parent as ViewGroup
70
+ sheetView.setBackgroundColor(Color.TRANSPARENT)
71
+
72
+ // Assign our main BottomSheetBehavior
73
+ val sheetViewParams = sheetView.layoutParams as CoordinatorLayout.LayoutParams
74
+ sheetViewParams.behavior = sheetBehavior
103
75
  }
104
76
 
105
77
  // Configure Sheet Dialog
106
78
  sheetDialog.apply {
107
79
  setOnShowListener {
108
-
109
80
  // Initialize footer y
110
81
  UiThreadUtil.runOnUiThread {
111
82
  footerView?.let {
112
- val sheetView = sheetLayout.parent as ViewGroup
113
83
  it.y = (sheetView.height - sheetView.top - it.height).toFloat()
114
84
  }
115
85
  }
@@ -118,7 +88,7 @@ class TrueSheetView(context: Context) :
118
88
  presentPromise = null
119
89
 
120
90
  // dispatch onPresent event
121
- eventDispatcher?.dispatchEvent(PresentEvent(surfaceId, id))
91
+ eventDispatcher?.dispatchEvent(PresentEvent(surfaceId, id, sheetBehavior.getSizeInfoForIndex(activeIndex)))
122
92
  }
123
93
 
124
94
  setOnDismissListener {
@@ -129,6 +99,37 @@ class TrueSheetView(context: Context) :
129
99
  eventDispatcher?.dispatchEvent(DismissEvent(surfaceId, id))
130
100
  }
131
101
  }
102
+
103
+ // Configure Sheet events
104
+ sheetBehavior.apply {
105
+
106
+ // Set our default max height
107
+ maxSheetSize = Utils.maxSize(context)
108
+
109
+ addBottomSheetCallback(
110
+ object : BottomSheetBehavior.BottomSheetCallback() {
111
+ override fun onSlide(sheetView: View, slideOffset: Float) {
112
+ footerView?.let {
113
+ it.y = (sheetView.height - sheetView.top - it.height).toFloat()
114
+ }
115
+ }
116
+
117
+ override fun onStateChanged(view: View, newState: Int) {
118
+ val sizeInfo = getSizeInfoForState(newState)
119
+ if (sizeInfo != null && sizeInfo.index != activeIndex) {
120
+ activeIndex = sizeInfo.index
121
+
122
+ // dispatch onSizeChange event
123
+ eventDispatcher?.dispatchEvent(SizeChangeEvent(surfaceId, id, sizeInfo))
124
+ }
125
+
126
+ if (newState == BottomSheetBehavior.STATE_HIDDEN) {
127
+ sheetDialog.dismiss()
128
+ }
129
+ }
130
+ }
131
+ )
132
+ }
132
133
  }
133
134
 
134
135
  override fun dispatchProvideStructure(structure: ViewStructure) {
@@ -211,21 +212,24 @@ class TrueSheetView(context: Context) :
211
212
 
212
213
  fun setMaxHeight(height: Int) {
213
214
  sheetBehavior.maxSheetHeight = height
214
- sheetBehavior.configure(sizes)
215
+ sheetBehavior.configure()
215
216
  }
216
217
 
217
218
  fun setSizes(newSizes: Array<Any>) {
218
- sizes = newSizes
219
- sheetBehavior.configure(sizes)
219
+ sheetBehavior.sizes = newSizes
220
+ sheetBehavior.configure()
220
221
  }
221
222
 
222
223
  fun present(index: Int, promiseCallback: () -> Unit) {
223
- sheetBehavior.setStateForSizeIndex(sizes.size, index)
224
-
225
224
  if (sheetDialog.isShowing) {
225
+ sheetBehavior.setStateForSizeIndex(index)
226
226
  promiseCallback()
227
227
  } else {
228
- sheetBehavior.configure(sizes)
228
+ sheetBehavior.configure()
229
+
230
+ activeIndex = index
231
+ sheetBehavior.setStateForSizeIndex(index)
232
+
229
233
  presentPromise = promiseCallback
230
234
  sheetDialog.show()
231
235
  }
@@ -5,10 +5,16 @@ import com.facebook.react.bridge.WritableMap
5
5
  import com.facebook.react.uimanager.events.Event
6
6
 
7
7
  // onPresent
8
- class PresentEvent(surfaceId: Int, viewId: Int) : Event<PresentEvent>(surfaceId, viewId) {
8
+ class PresentEvent(surfaceId: Int, viewId: Int, private val sizeInfo: SizeInfo) : Event<PresentEvent>(surfaceId, viewId) {
9
9
  override fun getEventName() = EVENT_NAME
10
10
 
11
- override fun getEventData(): WritableMap = Arguments.createMap()
11
+ override fun getEventData(): WritableMap {
12
+ val data = Arguments.createMap()
13
+ data.putInt("index", sizeInfo.index)
14
+ data.putDouble("value", sizeInfo.value.toDouble())
15
+
16
+ return data
17
+ }
12
18
 
13
19
  companion object {
14
20
  const val EVENT_NAME = "present"
@@ -9,14 +9,16 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior
9
9
 
10
10
  data class SizeInfo(val index: Int, val value: Float)
11
11
 
12
- class SheetBehavior<T : ViewGroup> : BottomSheetBehavior<T>() {
12
+ class TrueSheetBehavior : BottomSheetBehavior<ViewGroup>() {
13
13
  var maxSheetSize: Point = Point()
14
14
  var maxSheetHeight: Int? = null
15
15
 
16
16
  var contentView: ViewGroup? = null
17
17
  var footerView: ViewGroup? = null
18
18
 
19
- override fun onInterceptTouchEvent(parent: CoordinatorLayout, child: T, event: MotionEvent): Boolean {
19
+ var sizes: Array<Any> = arrayOf("medium", "large")
20
+
21
+ override fun onInterceptTouchEvent(parent: CoordinatorLayout, child: ViewGroup, event: MotionEvent): Boolean {
20
22
  contentView?.let {
21
23
  val isDownEvent = (event.actionMasked == MotionEvent.ACTION_DOWN)
22
24
  val expanded = state == STATE_EXPANDED
@@ -54,7 +56,7 @@ class SheetBehavior<T : ViewGroup> : BottomSheetBehavior<T>() {
54
56
  event.action == MotionEvent.ACTION_CANCEL
55
57
  }
56
58
 
57
- fun getSizeHeight(size: Any, contentHeight: Int): Int {
59
+ private fun getSizeHeight(size: Any, contentHeight: Int): Int {
58
60
  val height =
59
61
  when (size) {
60
62
  is Double -> Utils.toPixel(size)
@@ -97,7 +99,7 @@ class SheetBehavior<T : ViewGroup> : BottomSheetBehavior<T>() {
97
99
  return minOf(height, maxSheetHeight ?: maxSheetSize.y)
98
100
  }
99
101
 
100
- fun configure(sizes: Array<Any>) {
102
+ fun configure() {
101
103
  var contentHeight = 0
102
104
 
103
105
  contentView?.let { contentHeight = it.height }
@@ -132,8 +134,32 @@ class SheetBehavior<T : ViewGroup> : BottomSheetBehavior<T>() {
132
134
  }
133
135
  }
134
136
 
135
- fun getSizeInfoForState(sizeCount: Int, state: Int): SizeInfo? =
136
- when (sizeCount) {
137
+ fun getStateForIndex(index: Int) =
138
+ when (sizes.size) {
139
+ 1 -> STATE_EXPANDED
140
+
141
+ 2 -> {
142
+ when (index) {
143
+ 0 -> STATE_COLLAPSED
144
+ 1 -> STATE_EXPANDED
145
+ else -> STATE_HIDDEN
146
+ }
147
+ }
148
+
149
+ 3 -> {
150
+ when (index) {
151
+ 0 -> STATE_COLLAPSED
152
+ 1 -> STATE_HALF_EXPANDED
153
+ 2 -> STATE_EXPANDED
154
+ else -> STATE_HIDDEN
155
+ }
156
+ }
157
+
158
+ else -> STATE_HIDDEN
159
+ }
160
+
161
+ fun getSizeInfoForState(state: Int): SizeInfo? =
162
+ when (sizes.size) {
137
163
  1 -> {
138
164
  when (state) {
139
165
  STATE_EXPANDED -> SizeInfo(0, Utils.toDIP(maxHeight))
@@ -167,29 +193,9 @@ class SheetBehavior<T : ViewGroup> : BottomSheetBehavior<T>() {
167
193
  else -> null
168
194
  }
169
195
 
170
- fun setStateForSizeIndex(sizeCount: Int, index: Int) {
171
- state =
172
- when (sizeCount) {
173
- 1 -> STATE_EXPANDED
174
-
175
- 2 -> {
176
- when (index) {
177
- 0 -> STATE_COLLAPSED
178
- 1 -> STATE_EXPANDED
179
- else -> STATE_HIDDEN
180
- }
181
- }
182
-
183
- 3 -> {
184
- when (index) {
185
- 0 -> STATE_COLLAPSED
186
- 1 -> STATE_HALF_EXPANDED
187
- 2 -> STATE_EXPANDED
188
- else -> STATE_HIDDEN
189
- }
190
- }
196
+ fun getSizeInfoForIndex(index: Int) = getSizeInfoForState(getStateForIndex(index)) ?: SizeInfo(0, 0f)
191
197
 
192
- else -> STATE_HIDDEN
193
- }
198
+ fun setStateForSizeIndex(index: Int) {
199
+ state = getStateForIndex(index)
194
200
  }
195
201
  }
@@ -0,0 +1,62 @@
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
+ extension UIBlurEffect {
10
+ convenience init(with style: String) {
11
+ var blurStyle: Style
12
+
13
+ switch style {
14
+ case "default":
15
+ blurStyle = .regular
16
+ case "extraLight":
17
+ blurStyle = .extraLight
18
+ case "light":
19
+ blurStyle = .light
20
+ case "regular":
21
+ blurStyle = .regular
22
+ case "dark":
23
+ blurStyle = .dark
24
+ case "prominent":
25
+ blurStyle = .prominent
26
+ case "systemUltraThinMaterial":
27
+ blurStyle = .systemUltraThinMaterial
28
+ case "systemThinMaterial":
29
+ blurStyle = .systemThinMaterial
30
+ case "systemMaterial":
31
+ blurStyle = .systemMaterial
32
+ case "systemThickMaterial":
33
+ blurStyle = .systemThickMaterial
34
+ case "systemChromeMaterial":
35
+ blurStyle = .systemChromeMaterial
36
+ case "systemUltraThinMaterialLight":
37
+ blurStyle = .systemUltraThinMaterialLight
38
+ case "systemThickMaterialLight":
39
+ blurStyle = .systemThickMaterialLight
40
+ case "systemThinMaterialLight":
41
+ blurStyle = .systemThinMaterialLight
42
+ case "systemMaterialLight":
43
+ blurStyle = .systemMaterialLight
44
+ case "systemChromeMaterialLight":
45
+ blurStyle = .systemChromeMaterialLight
46
+ case "systemUltraThinMaterialDark":
47
+ blurStyle = .systemUltraThinMaterialDark
48
+ case "systemThinMaterialDark":
49
+ blurStyle = .systemThinMaterialDark
50
+ case "systemMaterialDark":
51
+ blurStyle = .systemMaterialDark
52
+ case "systemThickMaterialDark":
53
+ blurStyle = .systemThickMaterialDark
54
+ case "systemChromeMaterialDark":
55
+ blurStyle = .systemChromeMaterialDark
56
+ default:
57
+ blurStyle = .light
58
+ }
59
+
60
+ self.init(style: blurStyle)
61
+ }
62
+ }
@@ -57,11 +57,12 @@ class TrueSheetView: UIView, RCTInvalidating, TrueSheetViewControllerDelegate {
57
57
  self.bridge = bridge
58
58
 
59
59
  viewController = TrueSheetViewController()
60
+ viewController.view.autoresizingMask = [.flexibleHeight, .flexibleWidth]
61
+
60
62
  touchHandler = RCTTouchHandler(bridge: bridge)
61
63
 
62
64
  super.init(frame: .zero)
63
65
 
64
- viewController.view.autoresizingMask = [.flexibleHeight, .flexibleWidth]
65
66
  viewController.delegate = self
66
67
  }
67
68
 
@@ -78,10 +79,10 @@ class TrueSheetView: UIView, RCTInvalidating, TrueSheetViewControllerDelegate {
78
79
  return
79
80
  }
80
81
 
81
- viewController.view.insertSubview(subview, at: 0)
82
+ viewController.view.addSubview(subview)
82
83
 
83
84
  containerView = subview
84
- touchHandler.attach(to: subview)
85
+ touchHandler.attach(to: containerView)
85
86
  }
86
87
 
87
88
  override func removeReactSubview(_ subview: UIView!) {
@@ -141,10 +142,10 @@ class TrueSheetView: UIView, RCTInvalidating, TrueSheetViewControllerDelegate {
141
142
  onDismiss?(nil)
142
143
  }
143
144
 
144
- func viewControllerSheetDidChangeSize(_ value: CGFloat, at index: Int) {
145
- if index != activeIndex {
146
- activeIndex = index
147
- onSizeChange?(["index": index, "value": value])
145
+ func viewControllerSheetDidChangeSize(_ sizeInfo: SizeInfo) {
146
+ if sizeInfo.index != activeIndex {
147
+ activeIndex = sizeInfo.index
148
+ onSizeChange?(sizeInfoData(from: sizeInfo))
148
149
  }
149
150
  }
150
151
 
@@ -162,6 +163,31 @@ class TrueSheetView: UIView, RCTInvalidating, TrueSheetViewControllerDelegate {
162
163
  configureSheetIfPresented()
163
164
  }
164
165
 
166
+ @objc
167
+ func setBlurStyle(_ style: NSString?) {
168
+ guard let style else {
169
+ viewController.setBlurStyle(nil)
170
+ return
171
+ }
172
+
173
+ viewController.setBlurStyle(style as String)
174
+ }
175
+
176
+ @objc
177
+ func setGrabber(_ visible: Bool) {
178
+ viewController.grabber = visible
179
+ }
180
+
181
+ @objc
182
+ func setCornerRadius(_ radius: NSNumber?) {
183
+ guard let radius else {
184
+ viewController.cornerRadius = nil
185
+ return
186
+ }
187
+
188
+ viewController.cornerRadius = CGFloat(radius.floatValue)
189
+ }
190
+
165
191
  @objc
166
192
  func setScrollableHandle(_ tag: NSNumber?) {
167
193
  let view = bridge.uiManager.view(forReactTag: tag) as? RCTScrollView
@@ -174,6 +200,14 @@ class TrueSheetView: UIView, RCTInvalidating, TrueSheetViewControllerDelegate {
174
200
 
175
201
  // MARK: - Methods
176
202
 
203
+ private func sizeInfoData(from sizeInfo: SizeInfo?) -> [String: Any] {
204
+ guard let sizeInfo else {
205
+ return ["index": 0, "value": 0.0]
206
+ }
207
+
208
+ return ["index": sizeInfo.index, "value": sizeInfo.value]
209
+ }
210
+
177
211
  func configureSheetIfPresented() {
178
212
  // Resize sheet
179
213
  if #available(iOS 15.0, *), isPresented {
@@ -231,12 +265,8 @@ class TrueSheetView: UIView, RCTInvalidating, TrueSheetViewControllerDelegate {
231
265
 
232
266
  if #available(iOS 15.0, *) {
233
267
  viewController.configureSheet(at: index, with: contentHeight) {
234
- if self.isPresented {
235
- // Notify when size is changed programatically
236
- let info = self.viewController.detentValues.first(where: { $0.value.index == index })
237
- if let sizeValue = info?.value.value {
238
- self.viewControllerSheetDidChangeSize(sizeValue, at: index)
239
- }
268
+ if self.isPresented, let sizeInfo = self.viewController.selectedSizeInfo {
269
+ self.viewControllerSheetDidChangeSize(sizeInfo)
240
270
  }
241
271
  }
242
272
  }
@@ -249,8 +279,14 @@ class TrueSheetView: UIView, RCTInvalidating, TrueSheetViewControllerDelegate {
249
279
 
250
280
  rvc.present(viewController, animated: true) {
251
281
  self.isPresented = true
252
- self.onPresent?(nil)
253
282
 
283
+ var data = ["index": 0, "value": 0.0]
284
+
285
+ if #available(iOS 15.0, *), let sizeInfo = self.viewController.selectedSizeInfo {
286
+ data = self.sizeInfoData(from: sizeInfo)
287
+ }
288
+
289
+ self.onPresent?(data)
254
290
  promise.resolve(nil)
255
291
  }
256
292
  }