@lodev09/react-native-true-sheet 0.4.5 → 0.5.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/README.md +141 -4
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +57 -53
- package/android/src/main/java/com/lodev09/truesheet/core/Events.kt +8 -2
- package/android/src/main/java/com/lodev09/truesheet/core/{SheetBehavior.kt → TrueSheetBehavior.kt} +35 -29
- package/ios/Extensions/UIBlurEffect+withStyle.swift +62 -0
- package/ios/TrueSheetView.swift +48 -13
- package/ios/TrueSheetViewController.swift +51 -6
- package/ios/TrueSheetViewManager.m +3 -0
- package/lib/commonjs/TrueSheet.js +41 -14
- package/lib/commonjs/TrueSheet.js.map +1 -1
- package/lib/module/TrueSheet.js +41 -14
- package/lib/module/TrueSheet.js.map +1 -1
- package/lib/typescript/src/TrueSheet.d.ts +1 -1
- package/lib/typescript/src/TrueSheet.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +44 -14
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/package.json +5 -2
- package/src/TrueSheet.tsx +48 -20
- package/src/types.ts +70 -15
package/README.md
CHANGED
|
@@ -4,11 +4,13 @@
|
|
|
4
4
|

|
|
5
5
|

|
|
6
6
|
|
|
7
|
-
The true native bottom sheet
|
|
7
|
+
The true native bottom sheet 💩
|
|
8
|
+
|
|
9
|
+

|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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 =
|
|
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
|
-
|
|
88
|
-
|
|
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
|
-
|
|
102
|
-
(
|
|
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(
|
|
215
|
+
sheetBehavior.configure()
|
|
215
216
|
}
|
|
216
217
|
|
|
217
218
|
fun setSizes(newSizes: Array<Any>) {
|
|
218
|
-
sizes = newSizes
|
|
219
|
-
sheetBehavior.configure(
|
|
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(
|
|
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
|
|
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"
|
package/android/src/main/java/com/lodev09/truesheet/core/{SheetBehavior.kt → TrueSheetBehavior.kt}
RENAMED
|
@@ -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
|
|
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
|
-
|
|
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(
|
|
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
|
|
136
|
-
when (
|
|
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
|
|
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
|
-
|
|
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
|
+
}
|
package/ios/TrueSheetView.swift
CHANGED
|
@@ -61,7 +61,6 @@ class TrueSheetView: UIView, RCTInvalidating, TrueSheetViewControllerDelegate {
|
|
|
61
61
|
|
|
62
62
|
super.init(frame: .zero)
|
|
63
63
|
|
|
64
|
-
viewController.view.autoresizingMask = [.flexibleHeight, .flexibleWidth]
|
|
65
64
|
viewController.delegate = self
|
|
66
65
|
}
|
|
67
66
|
|
|
@@ -78,7 +77,8 @@ class TrueSheetView: UIView, RCTInvalidating, TrueSheetViewControllerDelegate {
|
|
|
78
77
|
return
|
|
79
78
|
}
|
|
80
79
|
|
|
81
|
-
viewController.view.insertSubview(subview, at: 0)
|
|
80
|
+
// viewController.view.insertSubview(subview, at: 0)
|
|
81
|
+
viewController.view.addSubview(subview)
|
|
82
82
|
|
|
83
83
|
containerView = subview
|
|
84
84
|
touchHandler.attach(to: subview)
|
|
@@ -141,10 +141,10 @@ class TrueSheetView: UIView, RCTInvalidating, TrueSheetViewControllerDelegate {
|
|
|
141
141
|
onDismiss?(nil)
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
-
func viewControllerSheetDidChangeSize(_
|
|
145
|
-
if index != activeIndex {
|
|
146
|
-
activeIndex = index
|
|
147
|
-
onSizeChange?(
|
|
144
|
+
func viewControllerSheetDidChangeSize(_ sizeInfo: SizeInfo) {
|
|
145
|
+
if sizeInfo.index != activeIndex {
|
|
146
|
+
activeIndex = sizeInfo.index
|
|
147
|
+
onSizeChange?(sizeInfoData(from: sizeInfo))
|
|
148
148
|
}
|
|
149
149
|
}
|
|
150
150
|
|
|
@@ -162,6 +162,31 @@ class TrueSheetView: UIView, RCTInvalidating, TrueSheetViewControllerDelegate {
|
|
|
162
162
|
configureSheetIfPresented()
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
+
@objc
|
|
166
|
+
func setBlurStyle(_ style: NSString?) {
|
|
167
|
+
guard let style else {
|
|
168
|
+
viewController.blurView.effect = nil
|
|
169
|
+
return
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
viewController.blurView.effect = UIBlurEffect(with: style as String)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
@objc
|
|
176
|
+
func setGrabber(_ visible: Bool) {
|
|
177
|
+
viewController.grabber = visible
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
@objc
|
|
181
|
+
func setCornerRadius(_ radius: NSNumber?) {
|
|
182
|
+
guard let radius else {
|
|
183
|
+
viewController.cornerRadius = nil
|
|
184
|
+
return
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
viewController.cornerRadius = CGFloat(radius.floatValue)
|
|
188
|
+
}
|
|
189
|
+
|
|
165
190
|
@objc
|
|
166
191
|
func setScrollableHandle(_ tag: NSNumber?) {
|
|
167
192
|
let view = bridge.uiManager.view(forReactTag: tag) as? RCTScrollView
|
|
@@ -174,6 +199,14 @@ class TrueSheetView: UIView, RCTInvalidating, TrueSheetViewControllerDelegate {
|
|
|
174
199
|
|
|
175
200
|
// MARK: - Methods
|
|
176
201
|
|
|
202
|
+
private func sizeInfoData(from sizeInfo: SizeInfo?) -> [String: Any] {
|
|
203
|
+
guard let sizeInfo else {
|
|
204
|
+
return ["index": 0, "value": 0.0]
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return ["index": sizeInfo.index, "value": sizeInfo.value]
|
|
208
|
+
}
|
|
209
|
+
|
|
177
210
|
func configureSheetIfPresented() {
|
|
178
211
|
// Resize sheet
|
|
179
212
|
if #available(iOS 15.0, *), isPresented {
|
|
@@ -231,12 +264,8 @@ class TrueSheetView: UIView, RCTInvalidating, TrueSheetViewControllerDelegate {
|
|
|
231
264
|
|
|
232
265
|
if #available(iOS 15.0, *) {
|
|
233
266
|
viewController.configureSheet(at: index, with: contentHeight) {
|
|
234
|
-
if self.isPresented {
|
|
235
|
-
|
|
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
|
-
}
|
|
267
|
+
if self.isPresented, let sizeInfo = self.viewController.selectedSizeInfo {
|
|
268
|
+
self.viewControllerSheetDidChangeSize(sizeInfo)
|
|
240
269
|
}
|
|
241
270
|
}
|
|
242
271
|
}
|
|
@@ -249,8 +278,14 @@ class TrueSheetView: UIView, RCTInvalidating, TrueSheetViewControllerDelegate {
|
|
|
249
278
|
|
|
250
279
|
rvc.present(viewController, animated: true) {
|
|
251
280
|
self.isPresented = true
|
|
252
|
-
self.onPresent?(nil)
|
|
253
281
|
|
|
282
|
+
var data = ["index": 0, "value": 0.0]
|
|
283
|
+
|
|
284
|
+
if #available(iOS 15.0, *), let sizeInfo = self.viewController.selectedSizeInfo {
|
|
285
|
+
data = self.sizeInfoData(from: sizeInfo)
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
self.onPresent?(data)
|
|
254
289
|
promise.resolve(nil)
|
|
255
290
|
}
|
|
256
291
|
}
|