@lodev09/react-native-true-sheet 3.0.0-beta.1 → 3.0.0-beta.10
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 +7 -21
- package/RNTrueSheet.podspec +5 -1
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContainerView.kt +58 -60
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentView.kt +10 -18
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetFooterView.kt +76 -20
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetHeaderView.kt +38 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetHeaderViewManager.kt +21 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetPackage.kt +1 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +104 -146
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewController.kt +315 -403
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt +24 -11
- package/android/src/main/java/com/lodev09/truesheet/core/RNScreensFragmentObserver.kt +116 -0
- package/android/src/main/java/com/lodev09/truesheet/utils/ScreenUtils.kt +33 -5
- package/android/src/main/jni/CMakeLists.txt +87 -0
- package/android/src/main/jni/TrueSheetSpec.h +17 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewComponentDescriptor.h +24 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.cpp +46 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.h +28 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewState.cpp +11 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewState.h +42 -0
- package/ios/TrueSheetContainerView.h +23 -0
- package/ios/TrueSheetContainerView.mm +80 -13
- package/ios/TrueSheetContentView.h +9 -1
- package/ios/TrueSheetContentView.mm +102 -24
- package/ios/TrueSheetFooterView.mm +2 -2
- package/ios/TrueSheetHeaderView.h +29 -0
- package/ios/TrueSheetHeaderView.mm +60 -0
- package/ios/TrueSheetView.h +0 -16
- package/ios/TrueSheetView.mm +208 -194
- package/ios/TrueSheetViewController.h +4 -3
- package/ios/TrueSheetViewController.mm +180 -272
- package/ios/utils/ConversionUtil.h +24 -0
- package/ios/utils/ConversionUtil.mm +50 -0
- package/ios/utils/LayoutUtil.h +11 -1
- package/ios/utils/LayoutUtil.mm +32 -1
- package/lib/module/TrueSheet.js +30 -33
- package/lib/module/TrueSheet.js.map +1 -1
- package/lib/module/fabric/TrueSheetContainerViewNativeComponent.ts +1 -1
- package/lib/module/fabric/TrueSheetHeaderViewNativeComponent.ts +8 -0
- package/lib/module/fabric/TrueSheetViewNativeComponent.ts +6 -8
- package/lib/typescript/src/TrueSheet.d.ts +0 -3
- package/lib/typescript/src/TrueSheet.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheet.types.d.ts +30 -43
- package/lib/typescript/src/TrueSheet.types.d.ts.map +1 -1
- package/lib/typescript/src/fabric/TrueSheetContainerViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/fabric/TrueSheetHeaderViewNativeComponent.d.ts +6 -0
- package/lib/typescript/src/fabric/TrueSheetHeaderViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts +3 -6
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts.map +1 -1
- package/package.json +9 -5
- package/react-native.config.js +5 -2
- package/src/TrueSheet.tsx +34 -31
- package/src/TrueSheet.types.ts +47 -61
- package/src/fabric/TrueSheetContainerViewNativeComponent.ts +1 -1
- package/src/fabric/TrueSheetHeaderViewNativeComponent.ts +8 -0
- package/src/fabric/TrueSheetViewNativeComponent.ts +6 -8
- package/android/src/main/java/com/lodev09/truesheet/events/SizeChangeEvent.kt +0 -27
- package/ios/events/OnSizeChangeEvent.h +0 -28
- package/ios/events/OnSizeChangeEvent.mm +0 -30
|
@@ -6,6 +6,9 @@ import android.view.ViewStructure
|
|
|
6
6
|
import android.view.accessibility.AccessibilityEvent
|
|
7
7
|
import androidx.annotation.UiThread
|
|
8
8
|
import com.facebook.react.bridge.LifecycleEventListener
|
|
9
|
+
import com.facebook.react.bridge.WritableNativeMap
|
|
10
|
+
import com.facebook.react.uimanager.PixelUtil.pxToDp
|
|
11
|
+
import com.facebook.react.uimanager.StateWrapper
|
|
9
12
|
import com.facebook.react.uimanager.ThemedReactContext
|
|
10
13
|
import com.facebook.react.uimanager.UIManagerHelper
|
|
11
14
|
import com.facebook.react.uimanager.events.EventDispatcher
|
|
@@ -18,13 +21,12 @@ import com.lodev09.truesheet.events.DragChangeEvent
|
|
|
18
21
|
import com.lodev09.truesheet.events.DragEndEvent
|
|
19
22
|
import com.lodev09.truesheet.events.MountEvent
|
|
20
23
|
import com.lodev09.truesheet.events.PositionChangeEvent
|
|
21
|
-
import com.lodev09.truesheet.events.SizeChangeEvent
|
|
22
24
|
import com.lodev09.truesheet.events.WillDismissEvent
|
|
23
25
|
import com.lodev09.truesheet.events.WillPresentEvent
|
|
24
26
|
|
|
25
27
|
/**
|
|
26
|
-
* Main TrueSheet host view.
|
|
27
|
-
*
|
|
28
|
+
* Main TrueSheet host view that manages the sheet dialog and dispatches events to JavaScript.
|
|
29
|
+
* This view is hidden (GONE) and delegates all rendering to TrueSheetViewController in a dialog window.
|
|
28
30
|
*/
|
|
29
31
|
@SuppressLint("ViewConstructor")
|
|
30
32
|
class TrueSheetView(private val reactContext: ThemedReactContext) :
|
|
@@ -33,14 +35,8 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
|
|
|
33
35
|
TrueSheetViewControllerDelegate,
|
|
34
36
|
TrueSheetContainerViewDelegate {
|
|
35
37
|
|
|
36
|
-
/**
|
|
37
|
-
* The TrueSheetViewController instance that acts as both root view and controller
|
|
38
|
-
*/
|
|
39
38
|
private val viewController: TrueSheetViewController = TrueSheetViewController(reactContext)
|
|
40
39
|
|
|
41
|
-
/**
|
|
42
|
-
* Gets the container view (first child of view controller)
|
|
43
|
-
*/
|
|
44
40
|
private val containerView: TrueSheetContainerView?
|
|
45
41
|
get() = viewController.getChildAt(0) as? TrueSheetContainerView
|
|
46
42
|
|
|
@@ -49,19 +45,28 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
|
|
|
49
45
|
var initialDetentIndex: Int = -1
|
|
50
46
|
var initialDetentAnimated: Boolean = true
|
|
51
47
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
48
|
+
var stateWrapper: StateWrapper? = null
|
|
49
|
+
set(value) {
|
|
50
|
+
// Immediately update state with screen width during first state update
|
|
51
|
+
// This ensures we have initial width for content layout before presenting
|
|
52
|
+
if (field == null && value != null) {
|
|
53
|
+
updateState(viewController.screenWidth, 0)
|
|
54
|
+
}
|
|
55
|
+
field = value
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Track last dimensions to avoid unnecessary state updates
|
|
59
|
+
private var lastContainerWidth: Int = 0
|
|
60
|
+
private var lastContainerHeight: Int = 0
|
|
61
|
+
|
|
62
|
+
// Flag to prevent multiple pending sheet updates
|
|
63
|
+
private var isSheetUpdatePending: Boolean = false
|
|
56
64
|
|
|
57
65
|
init {
|
|
58
66
|
reactContext.addLifecycleEventListener(this)
|
|
59
|
-
|
|
60
|
-
// Set delegates
|
|
61
67
|
viewController.delegate = this
|
|
62
68
|
|
|
63
|
-
// Hide the host view
|
|
64
|
-
// The actual content is shown in a dialog window
|
|
69
|
+
// Hide the host view - actual content is rendered in the dialog window
|
|
65
70
|
visibility = GONE
|
|
66
71
|
}
|
|
67
72
|
|
|
@@ -81,102 +86,66 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
|
|
|
81
86
|
|
|
82
87
|
override fun setId(id: Int) {
|
|
83
88
|
super.setId(id)
|
|
84
|
-
|
|
85
89
|
viewController.id = id
|
|
86
90
|
TrueSheetModule.registerView(this, id)
|
|
87
91
|
}
|
|
88
92
|
|
|
89
|
-
override fun onAttachedToWindow() {
|
|
90
|
-
super.onAttachedToWindow()
|
|
91
|
-
}
|
|
92
|
-
|
|
93
93
|
override fun onDetachedFromWindow() {
|
|
94
94
|
super.onDetachedFromWindow()
|
|
95
|
-
onDropInstance()
|
|
96
95
|
|
|
97
|
-
|
|
96
|
+
// Don't unregister if we have active modals - we need the view for recovery
|
|
97
|
+
if (viewController.hasActiveModals()) {
|
|
98
|
+
return
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
onDropInstance()
|
|
98
102
|
}
|
|
99
103
|
|
|
100
104
|
/**
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
* if the changed properties can be applied directly to the Dialog or require the recreation of a
|
|
104
|
-
* new Dialog.
|
|
105
|
+
* Called by the manager after all properties are set.
|
|
106
|
+
* Reconfigures the sheet if it's currently presented.
|
|
105
107
|
*/
|
|
106
|
-
fun
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
// Create dialog if not created yet
|
|
112
|
-
if (!viewController.isPresented) {
|
|
113
|
-
viewController.createDialog()
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
post {
|
|
117
|
-
present(initialDetentIndex, initialDetentAnimated) { }
|
|
118
|
-
}
|
|
119
|
-
} else if (viewController.isPresented) {
|
|
120
|
-
viewController.setupSheetDetents()
|
|
108
|
+
fun finalizeUpdates() {
|
|
109
|
+
if (viewController.isPresented) {
|
|
110
|
+
viewController.setupBackground()
|
|
111
|
+
viewController.setupGrabber()
|
|
112
|
+
updateSheetIfNeeded()
|
|
121
113
|
viewController.setStateForDetentIndex(viewController.currentDetentIndex)
|
|
122
|
-
viewController.positionFooter()
|
|
123
114
|
}
|
|
124
115
|
}
|
|
125
116
|
|
|
126
117
|
// ==================== View Management ====================
|
|
127
118
|
|
|
128
119
|
override fun addView(child: View?, index: Int) {
|
|
129
|
-
// Add the child to our ViewController
|
|
130
|
-
// This is the TrueSheetContainerView
|
|
131
120
|
viewController.addView(child, index)
|
|
132
121
|
|
|
133
|
-
// Create dialog and dispatch mount event when TrueSheetContainerView is added
|
|
134
122
|
if (child is TrueSheetContainerView) {
|
|
135
|
-
// Set up container delegate to listen for content size changes
|
|
136
123
|
child.delegate = this
|
|
124
|
+
viewController.createDialog()
|
|
137
125
|
|
|
138
|
-
//
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
viewController.contentHeight = contentHeight
|
|
126
|
+
// Present at initial detent after layout pass when content height is available
|
|
127
|
+
if (initialDetentIndex >= 0) {
|
|
128
|
+
post { present(initialDetentIndex, initialDetentAnimated) { } }
|
|
142
129
|
}
|
|
143
130
|
|
|
144
|
-
// Create the dialog now that the container is mounted
|
|
145
|
-
viewController.createDialog()
|
|
146
|
-
|
|
147
131
|
val surfaceId = UIManagerHelper.getSurfaceId(this)
|
|
148
|
-
eventDispatcher?.dispatchEvent(
|
|
149
|
-
MountEvent(surfaceId, id)
|
|
150
|
-
)
|
|
132
|
+
eventDispatcher?.dispatchEvent(MountEvent(surfaceId, id))
|
|
151
133
|
}
|
|
152
134
|
}
|
|
153
135
|
|
|
154
136
|
override fun getChildCount(): Int = viewController.childCount
|
|
155
137
|
override fun getChildAt(index: Int): View? = viewController.getChildAt(index)
|
|
156
138
|
|
|
157
|
-
override fun removeView(child: View?) {
|
|
158
|
-
if (child != null) {
|
|
159
|
-
// Clean up container delegate
|
|
160
|
-
if (child is TrueSheetContainerView) {
|
|
161
|
-
child.delegate = null
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
viewController.removeView(child)
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
139
|
override fun removeViewAt(index: Int) {
|
|
169
140
|
val child = getChildAt(index)
|
|
141
|
+
if (child is TrueSheetContainerView) {
|
|
142
|
+
child.delegate = null
|
|
143
|
+
}
|
|
170
144
|
viewController.removeView(child)
|
|
171
145
|
}
|
|
172
146
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
// Those will be handled by the mHostView which lives in the dialog
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
// Explicitly override this to prevent accessibility events being passed down to children
|
|
179
|
-
// Those will be handled by the mHostView which lives in the dialog
|
|
147
|
+
// Accessibility events are handled by the dialog's host view
|
|
148
|
+
override fun addChildrenForAccessibility(outChildren: ArrayList<View>) {}
|
|
180
149
|
override fun dispatchPopulateAccessibilityEvent(event: AccessibilityEvent): Boolean = false
|
|
181
150
|
|
|
182
151
|
fun onDropInstance() {
|
|
@@ -190,7 +159,7 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
|
|
|
190
159
|
}
|
|
191
160
|
|
|
192
161
|
override fun onHostResume() {
|
|
193
|
-
|
|
162
|
+
finalizeUpdates()
|
|
194
163
|
}
|
|
195
164
|
|
|
196
165
|
override fun onHostPause() {
|
|
@@ -204,71 +173,59 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
|
|
|
204
173
|
|
|
205
174
|
override fun viewControllerWillPresent(index: Int, position: Float) {
|
|
206
175
|
val surfaceId = UIManagerHelper.getSurfaceId(this)
|
|
207
|
-
eventDispatcher?.dispatchEvent(
|
|
208
|
-
WillPresentEvent(surfaceId, id, index, position)
|
|
209
|
-
)
|
|
176
|
+
eventDispatcher?.dispatchEvent(WillPresentEvent(surfaceId, id, index, position))
|
|
210
177
|
}
|
|
211
178
|
|
|
212
179
|
override fun viewControllerDidPresent(index: Int, position: Float) {
|
|
213
180
|
val surfaceId = UIManagerHelper.getSurfaceId(this)
|
|
214
|
-
eventDispatcher?.dispatchEvent(
|
|
215
|
-
DidPresentEvent(surfaceId, id, index, position)
|
|
216
|
-
)
|
|
181
|
+
eventDispatcher?.dispatchEvent(DidPresentEvent(surfaceId, id, index, position))
|
|
217
182
|
|
|
218
|
-
//
|
|
183
|
+
// Enable touch event dispatching to React Native
|
|
219
184
|
viewController.eventDispatcher = eventDispatcher
|
|
185
|
+
containerView?.footerView?.eventDispatcher = eventDispatcher
|
|
220
186
|
}
|
|
221
187
|
|
|
222
188
|
override fun viewControllerWillDismiss() {
|
|
223
189
|
val surfaceId = UIManagerHelper.getSurfaceId(this)
|
|
224
|
-
eventDispatcher?.dispatchEvent(
|
|
225
|
-
WillDismissEvent(surfaceId, id)
|
|
226
|
-
)
|
|
190
|
+
eventDispatcher?.dispatchEvent(WillDismissEvent(surfaceId, id))
|
|
227
191
|
|
|
228
|
-
//
|
|
192
|
+
// Disable touch event dispatching
|
|
229
193
|
viewController.eventDispatcher = null
|
|
194
|
+
containerView?.footerView?.eventDispatcher = null
|
|
230
195
|
}
|
|
231
196
|
|
|
232
197
|
override fun viewControllerDidDismiss() {
|
|
233
198
|
val surfaceId = UIManagerHelper.getSurfaceId(this)
|
|
234
|
-
eventDispatcher?.dispatchEvent(
|
|
235
|
-
DidDismissEvent(surfaceId, id)
|
|
236
|
-
)
|
|
199
|
+
eventDispatcher?.dispatchEvent(DidDismissEvent(surfaceId, id))
|
|
237
200
|
}
|
|
238
201
|
|
|
239
202
|
override fun viewControllerDidChangeDetent(index: Int, position: Float) {
|
|
240
203
|
val surfaceId = UIManagerHelper.getSurfaceId(this)
|
|
241
|
-
eventDispatcher?.dispatchEvent(
|
|
242
|
-
DetentChangeEvent(surfaceId, id, index, position)
|
|
243
|
-
)
|
|
204
|
+
eventDispatcher?.dispatchEvent(DetentChangeEvent(surfaceId, id, index, position))
|
|
244
205
|
}
|
|
245
206
|
|
|
246
207
|
override fun viewControllerDidDragBegin(index: Int, position: Float) {
|
|
247
208
|
val surfaceId = UIManagerHelper.getSurfaceId(this)
|
|
248
|
-
eventDispatcher?.dispatchEvent(
|
|
249
|
-
DragBeginEvent(surfaceId, id, index, position)
|
|
250
|
-
)
|
|
209
|
+
eventDispatcher?.dispatchEvent(DragBeginEvent(surfaceId, id, index, position))
|
|
251
210
|
}
|
|
252
211
|
|
|
253
212
|
override fun viewControllerDidDragChange(index: Int, position: Float) {
|
|
254
213
|
val surfaceId = UIManagerHelper.getSurfaceId(this)
|
|
255
|
-
eventDispatcher?.dispatchEvent(
|
|
256
|
-
DragChangeEvent(surfaceId, id, index, position)
|
|
257
|
-
)
|
|
214
|
+
eventDispatcher?.dispatchEvent(DragChangeEvent(surfaceId, id, index, position))
|
|
258
215
|
}
|
|
259
216
|
|
|
260
217
|
override fun viewControllerDidDragEnd(index: Int, position: Float) {
|
|
261
218
|
val surfaceId = UIManagerHelper.getSurfaceId(this)
|
|
262
|
-
eventDispatcher?.dispatchEvent(
|
|
263
|
-
DragEndEvent(surfaceId, id, index, position)
|
|
264
|
-
)
|
|
219
|
+
eventDispatcher?.dispatchEvent(DragEndEvent(surfaceId, id, index, position))
|
|
265
220
|
}
|
|
266
221
|
|
|
267
222
|
override fun viewControllerDidChangePosition(index: Int, position: Float, transitioning: Boolean) {
|
|
268
223
|
val surfaceId = UIManagerHelper.getSurfaceId(this)
|
|
269
|
-
eventDispatcher?.dispatchEvent(
|
|
270
|
-
|
|
271
|
-
|
|
224
|
+
eventDispatcher?.dispatchEvent(PositionChangeEvent(surfaceId, id, index, position, transitioning))
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
override fun viewControllerDidChangeSize(width: Int, height: Int) {
|
|
228
|
+
updateState(width, height)
|
|
272
229
|
}
|
|
273
230
|
|
|
274
231
|
// ==================== Property Setters (forward to controller) ====================
|
|
@@ -286,24 +243,22 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
|
|
|
286
243
|
}
|
|
287
244
|
}
|
|
288
245
|
|
|
289
|
-
fun
|
|
290
|
-
if (viewController.
|
|
291
|
-
viewController.
|
|
246
|
+
fun setDimmedDetentIndex(index: Int) {
|
|
247
|
+
if (viewController.dimmedDetentIndex == index) return
|
|
248
|
+
viewController.dimmedDetentIndex = index
|
|
292
249
|
if (viewController.isPresented) {
|
|
293
250
|
viewController.setupDimmedBackground(viewController.currentDetentIndex)
|
|
294
251
|
}
|
|
295
252
|
}
|
|
296
253
|
|
|
297
254
|
fun setCornerRadius(radius: Float) {
|
|
298
|
-
if (viewController.
|
|
299
|
-
viewController.
|
|
300
|
-
viewController.setupBackground()
|
|
255
|
+
if (viewController.sheetCornerRadius == radius) return
|
|
256
|
+
viewController.sheetCornerRadius = radius
|
|
301
257
|
}
|
|
302
258
|
|
|
303
259
|
fun setSheetBackgroundColor(color: Int) {
|
|
304
260
|
if (viewController.sheetBackgroundColor == color) return
|
|
305
261
|
viewController.sheetBackgroundColor = color
|
|
306
|
-
viewController.setupBackground()
|
|
307
262
|
}
|
|
308
263
|
|
|
309
264
|
fun setSoftInputMode(mode: Int) {
|
|
@@ -314,7 +269,9 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
|
|
|
314
269
|
viewController.dismissible = dismissible
|
|
315
270
|
}
|
|
316
271
|
|
|
317
|
-
fun setGrabber(grabber: Boolean) {
|
|
272
|
+
fun setGrabber(grabber: Boolean) {
|
|
273
|
+
viewController.grabber = grabber
|
|
274
|
+
}
|
|
318
275
|
|
|
319
276
|
fun setDetents(newDetents: MutableList<Double>) {
|
|
320
277
|
viewController.detents = newDetents
|
|
@@ -326,61 +283,62 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
|
|
|
326
283
|
viewController.edgeToEdgeFullScreen = edgeToEdgeFullScreen
|
|
327
284
|
}
|
|
328
285
|
|
|
286
|
+
// ==================== State Management ====================
|
|
287
|
+
|
|
329
288
|
/**
|
|
330
|
-
*
|
|
331
|
-
*
|
|
332
|
-
* @param detentIndex The detent index to present at
|
|
333
|
-
* @param animated Whether to animate the presentation
|
|
334
|
-
* @param promiseCallback Callback invoked when presentation completes
|
|
289
|
+
* Updates the Fabric state with container dimensions for Yoga layout.
|
|
335
290
|
*/
|
|
291
|
+
fun updateState(width: Int, height: Int) {
|
|
292
|
+
if (width == lastContainerWidth && height == lastContainerHeight) return
|
|
293
|
+
|
|
294
|
+
lastContainerWidth = width
|
|
295
|
+
lastContainerHeight = height
|
|
296
|
+
|
|
297
|
+
val sw = stateWrapper ?: return
|
|
298
|
+
val newStateData = WritableNativeMap()
|
|
299
|
+
newStateData.putDouble("containerWidth", width.toFloat().pxToDp().toDouble())
|
|
300
|
+
newStateData.putDouble("containerHeight", height.toFloat().pxToDp().toDouble())
|
|
301
|
+
sw.updateState(newStateData)
|
|
302
|
+
}
|
|
303
|
+
|
|
336
304
|
@UiThread
|
|
337
305
|
fun present(detentIndex: Int, animated: Boolean = true, promiseCallback: () -> Unit) {
|
|
338
306
|
viewController.presentPromise = promiseCallback
|
|
339
307
|
viewController.present(detentIndex, animated)
|
|
340
308
|
}
|
|
341
309
|
|
|
342
|
-
/**
|
|
343
|
-
* Dismisses the sheet.
|
|
344
|
-
*
|
|
345
|
-
* @param promiseCallback Callback invoked when dismissal completes
|
|
346
|
-
*/
|
|
347
310
|
@UiThread
|
|
348
311
|
fun dismiss(promiseCallback: () -> Unit) {
|
|
349
312
|
viewController.dismissPromise = promiseCallback
|
|
350
313
|
viewController.dismiss()
|
|
351
314
|
}
|
|
352
315
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
)
|
|
316
|
+
/**
|
|
317
|
+
* Debounced sheet update to handle rapid content/header size changes.
|
|
318
|
+
* Uses post to ensure all layout passes complete before reconfiguring.
|
|
319
|
+
*/
|
|
320
|
+
fun updateSheetIfNeeded() {
|
|
321
|
+
if (!viewController.isPresented || isSheetUpdatePending) return
|
|
322
|
+
|
|
323
|
+
isSheetUpdatePending = true
|
|
324
|
+
viewController.post {
|
|
325
|
+
isSheetUpdatePending = false
|
|
326
|
+
viewController.setupSheetDetents()
|
|
327
|
+
viewController.positionFooter()
|
|
328
|
+
}
|
|
359
329
|
}
|
|
360
330
|
|
|
361
331
|
// ==================== TrueSheetContainerViewDelegate Implementation ====================
|
|
362
332
|
|
|
363
333
|
override fun containerViewContentDidChangeSize(width: Int, height: Int) {
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
val contentHeight = if (containerHeight > 0) minOf(height, containerHeight) else height
|
|
367
|
-
|
|
368
|
-
viewController.contentHeight = contentHeight
|
|
369
|
-
|
|
370
|
-
// Update detents if sheet is already presented
|
|
371
|
-
if (viewController.isPresented) {
|
|
372
|
-
// Reconfigure sheet detents with new content height
|
|
373
|
-
viewController.setupSheetDetents()
|
|
334
|
+
updateSheetIfNeeded()
|
|
335
|
+
}
|
|
374
336
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
viewController.positionFooter()
|
|
378
|
-
}
|
|
379
|
-
}
|
|
337
|
+
override fun containerViewHeaderDidChangeSize(width: Int, height: Int) {
|
|
338
|
+
updateSheetIfNeeded()
|
|
380
339
|
}
|
|
381
340
|
|
|
382
341
|
override fun containerViewFooterDidChangeSize(width: Int, height: Int) {
|
|
383
|
-
// Reposition footer when its size changes
|
|
384
342
|
if (viewController.isPresented) {
|
|
385
343
|
viewController.positionFooter()
|
|
386
344
|
}
|