@lodev09/react-native-true-sheet 2.0.6 → 4.0.0-beta.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 +36 -8
- package/RNTrueSheet.podspec +20 -0
- package/android/build.gradle +26 -14
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContainerView.kt +108 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContainerViewManager.kt +21 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentView.kt +46 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentViewManager.kt +21 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetFooterView.kt +47 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetFooterViewManager.kt +21 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetModule.kt +165 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetPackage.kt +36 -4
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +257 -303
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewController.kt +855 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt +104 -82
- package/android/src/main/java/com/lodev09/truesheet/events/DetentChangeEvent.kt +26 -0
- package/android/src/main/java/com/lodev09/truesheet/events/DidDismissEvent.kt +20 -0
- package/android/src/main/java/com/lodev09/truesheet/events/DidPresentEvent.kt +26 -0
- package/android/src/main/java/com/lodev09/truesheet/events/DragBeginEvent.kt +26 -0
- package/android/src/main/java/com/lodev09/truesheet/events/DragChangeEvent.kt +26 -0
- package/android/src/main/java/com/lodev09/truesheet/events/DragEndEvent.kt +26 -0
- package/android/src/main/java/com/lodev09/truesheet/events/MountEvent.kt +20 -0
- package/android/src/main/java/com/lodev09/truesheet/events/PositionChangeEvent.kt +32 -0
- package/android/src/main/java/com/lodev09/truesheet/events/SizeChangeEvent.kt +27 -0
- package/android/src/main/java/com/lodev09/truesheet/events/WillDismissEvent.kt +20 -0
- package/android/src/main/java/com/lodev09/truesheet/events/WillPresentEvent.kt +26 -0
- package/android/src/main/java/com/lodev09/truesheet/{core/Utils.kt → utils/ScreenUtils.kt} +47 -17
- package/android/src/main/res/values/styles.xml +8 -0
- package/ios/TrueSheetComponentDescriptor.h +24 -0
- package/ios/TrueSheetContainerView.h +47 -0
- package/ios/TrueSheetContainerView.mm +117 -0
- package/ios/TrueSheetContentView.h +37 -0
- package/ios/TrueSheetContentView.mm +114 -0
- package/ios/TrueSheetFooterView.h +27 -0
- package/ios/TrueSheetFooterView.mm +101 -0
- package/ios/TrueSheetModule.h +44 -0
- package/ios/TrueSheetModule.mm +133 -0
- package/ios/TrueSheetView.h +53 -0
- package/ios/TrueSheetView.mm +433 -0
- package/ios/TrueSheetViewController.h +53 -0
- package/ios/TrueSheetViewController.mm +649 -0
- package/ios/events/OnDetentChangeEvent.h +28 -0
- package/ios/events/OnDetentChangeEvent.mm +30 -0
- package/ios/events/OnDidDismissEvent.h +26 -0
- package/ios/events/OnDidDismissEvent.mm +25 -0
- package/ios/events/OnDidPresentEvent.h +28 -0
- package/ios/events/OnDidPresentEvent.mm +30 -0
- package/ios/events/OnDragBeginEvent.h +28 -0
- package/ios/events/OnDragBeginEvent.mm +30 -0
- package/ios/events/OnDragChangeEvent.h +28 -0
- package/ios/events/OnDragChangeEvent.mm +30 -0
- package/ios/events/OnDragEndEvent.h +28 -0
- package/ios/events/OnDragEndEvent.mm +30 -0
- package/ios/events/OnMountEvent.h +26 -0
- package/ios/events/OnMountEvent.mm +25 -0
- package/ios/events/OnPositionChangeEvent.h +29 -0
- package/ios/events/OnPositionChangeEvent.mm +32 -0
- package/ios/events/OnSizeChangeEvent.h +28 -0
- package/ios/events/OnSizeChangeEvent.mm +30 -0
- package/ios/events/OnWillDismissEvent.h +26 -0
- package/ios/events/OnWillDismissEvent.mm +25 -0
- package/ios/events/OnWillPresentEvent.h +28 -0
- package/ios/events/OnWillPresentEvent.mm +30 -0
- package/ios/utils/GestureUtil.h +25 -0
- package/ios/utils/GestureUtil.mm +26 -0
- package/ios/utils/LayoutUtil.h +44 -0
- package/ios/utils/LayoutUtil.mm +50 -0
- package/ios/utils/WindowUtil.h +27 -0
- package/ios/utils/WindowUtil.mm +42 -0
- package/lib/module/TrueSheet.js +231 -135
- package/lib/module/TrueSheet.js.map +1 -1
- package/lib/module/TrueSheetGrabber.js +16 -14
- package/lib/module/TrueSheetGrabber.js.map +1 -1
- package/lib/module/fabric/TrueSheetContainerViewNativeComponent.ts +8 -0
- package/lib/module/fabric/TrueSheetContentViewNativeComponent.ts +8 -0
- package/lib/module/fabric/TrueSheetFooterViewNativeComponent.ts +8 -0
- package/lib/module/fabric/TrueSheetViewNativeComponent.ts +63 -0
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/reanimated/ReanimatedTrueSheet.js +87 -0
- package/lib/module/reanimated/ReanimatedTrueSheet.js.map +1 -0
- package/lib/module/reanimated/ReanimatedTrueSheetProvider.js +72 -0
- package/lib/module/reanimated/ReanimatedTrueSheetProvider.js.map +1 -0
- package/lib/module/reanimated/index.js +6 -0
- package/lib/module/reanimated/index.js.map +1 -0
- package/lib/module/reanimated/useReanimatedPositionChangeHandler.js +19 -0
- package/lib/module/reanimated/useReanimatedPositionChangeHandler.js.map +1 -0
- package/lib/module/specs/NativeTrueSheetModule.js +12 -0
- package/lib/module/specs/NativeTrueSheetModule.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/TrueSheet.d.ts +79 -0
- package/lib/typescript/src/TrueSheet.d.ts.map +1 -0
- package/lib/typescript/src/TrueSheet.types.d.ts +260 -0
- package/lib/typescript/src/TrueSheet.types.d.ts.map +1 -0
- package/lib/typescript/{commonjs/src → src}/TrueSheetGrabber.d.ts +1 -1
- package/lib/typescript/src/TrueSheetGrabber.d.ts.map +1 -0
- package/lib/typescript/src/fabric/TrueSheetContainerViewNativeComponent.d.ts +6 -0
- package/lib/typescript/src/fabric/TrueSheetContainerViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/fabric/TrueSheetContentViewNativeComponent.d.ts +6 -0
- package/lib/typescript/src/fabric/TrueSheetContentViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/fabric/TrueSheetFooterViewNativeComponent.d.ts +6 -0
- package/lib/typescript/src/fabric/TrueSheetFooterViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts +44 -0
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/{commonjs/src → src}/index.d.ts +1 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/reanimated/ReanimatedTrueSheet.d.ts +43 -0
- package/lib/typescript/src/reanimated/ReanimatedTrueSheet.d.ts.map +1 -0
- package/lib/typescript/src/reanimated/ReanimatedTrueSheetProvider.d.ts +57 -0
- package/lib/typescript/src/reanimated/ReanimatedTrueSheetProvider.d.ts.map +1 -0
- package/lib/typescript/src/reanimated/index.d.ts +4 -0
- package/lib/typescript/src/reanimated/index.d.ts.map +1 -0
- package/lib/typescript/src/reanimated/useReanimatedPositionChangeHandler.d.ts +6 -0
- package/lib/typescript/src/reanimated/useReanimatedPositionChangeHandler.d.ts.map +1 -0
- package/lib/typescript/src/specs/NativeTrueSheetModule.d.ts +34 -0
- package/lib/typescript/src/specs/NativeTrueSheetModule.d.ts.map +1 -0
- package/package.json +104 -75
- package/react-native.config.js +17 -0
- package/src/TrueSheet.tsx +285 -188
- package/src/TrueSheet.types.ts +119 -106
- package/src/TrueSheetGrabber.tsx +29 -28
- package/src/__mocks__/index.js +60 -12
- package/src/fabric/TrueSheetContainerViewNativeComponent.ts +8 -0
- package/src/fabric/TrueSheetContentViewNativeComponent.ts +8 -0
- package/src/fabric/TrueSheetFooterViewNativeComponent.ts +8 -0
- package/src/fabric/TrueSheetViewNativeComponent.ts +63 -0
- package/src/index.ts +4 -3
- package/src/reanimated/ReanimatedTrueSheet.tsx +95 -0
- package/src/reanimated/ReanimatedTrueSheetProvider.tsx +92 -0
- package/src/reanimated/index.ts +3 -0
- package/src/reanimated/useReanimatedPositionChangeHandler.ts +26 -0
- package/src/specs/NativeTrueSheetModule.ts +38 -0
- package/TrueSheet.podspec +0 -49
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetDialog.kt +0 -413
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetEvent.kt +0 -22
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewModule.kt +0 -63
- package/android/src/main/java/com/lodev09/truesheet/core/KeyboardManager.kt +0 -58
- package/android/src/main/java/com/lodev09/truesheet/core/RootSheetView.kt +0 -102
- package/ios/Extensions/UIBlurEffect+withTint.swift +0 -62
- package/ios/Extensions/UIView+pinTo.swift +0 -74
- package/ios/Extensions/UIViewController+detentForSize.swift +0 -134
- package/ios/TrueSheet-Bridging-Header.h +0 -14
- package/ios/TrueSheetEvent.swift +0 -48
- package/ios/TrueSheetView.swift +0 -467
- package/ios/TrueSheetViewController.swift +0 -275
- package/ios/TrueSheetViewManager.m +0 -53
- package/ios/TrueSheetViewManager.swift +0 -48
- package/ios/Utils/Logger.swift +0 -39
- package/ios/Utils/Promise.swift +0 -25
- package/lib/commonjs/TrueSheet.js +0 -258
- package/lib/commonjs/TrueSheet.js.map +0 -1
- package/lib/commonjs/TrueSheet.types.js +0 -6
- package/lib/commonjs/TrueSheet.types.js.map +0 -1
- package/lib/commonjs/TrueSheetFooter.js +0 -19
- package/lib/commonjs/TrueSheetFooter.js.map +0 -1
- package/lib/commonjs/TrueSheetGrabber.js +0 -54
- package/lib/commonjs/TrueSheetGrabber.js.map +0 -1
- package/lib/commonjs/TrueSheetModule.js +0 -19
- package/lib/commonjs/TrueSheetModule.js.map +0 -1
- package/lib/commonjs/__mocks__/index.js +0 -52
- package/lib/commonjs/__mocks__/index.js.map +0 -1
- package/lib/commonjs/index.js +0 -39
- package/lib/commonjs/index.js.map +0 -1
- package/lib/module/TrueSheetFooter.js +0 -14
- package/lib/module/TrueSheetFooter.js.map +0 -1
- package/lib/module/TrueSheetModule.js +0 -15
- package/lib/module/TrueSheetModule.js.map +0 -1
- package/lib/module/__mocks__/index.js +0 -21
- package/lib/module/__mocks__/index.js.map +0 -1
- package/lib/typescript/commonjs/package.json +0 -1
- package/lib/typescript/commonjs/src/TrueSheet.d.ts +0 -70
- package/lib/typescript/commonjs/src/TrueSheet.d.ts.map +0 -1
- package/lib/typescript/commonjs/src/TrueSheet.types.d.ts +0 -241
- package/lib/typescript/commonjs/src/TrueSheet.types.d.ts.map +0 -1
- package/lib/typescript/commonjs/src/TrueSheetFooter.d.ts +0 -7
- package/lib/typescript/commonjs/src/TrueSheetFooter.d.ts.map +0 -1
- package/lib/typescript/commonjs/src/TrueSheetGrabber.d.ts.map +0 -1
- package/lib/typescript/commonjs/src/TrueSheetModule.d.ts +0 -2
- package/lib/typescript/commonjs/src/TrueSheetModule.d.ts.map +0 -1
- package/lib/typescript/commonjs/src/index.d.ts.map +0 -1
- package/lib/typescript/module/src/TrueSheet.d.ts +0 -70
- package/lib/typescript/module/src/TrueSheet.d.ts.map +0 -1
- package/lib/typescript/module/src/TrueSheet.types.d.ts +0 -241
- package/lib/typescript/module/src/TrueSheet.types.d.ts.map +0 -1
- package/lib/typescript/module/src/TrueSheetFooter.d.ts +0 -7
- package/lib/typescript/module/src/TrueSheetFooter.d.ts.map +0 -1
- package/lib/typescript/module/src/TrueSheetGrabber.d.ts +0 -39
- package/lib/typescript/module/src/TrueSheetGrabber.d.ts.map +0 -1
- package/lib/typescript/module/src/TrueSheetModule.d.ts +0 -2
- package/lib/typescript/module/src/TrueSheetModule.d.ts.map +0 -1
- package/lib/typescript/module/src/index.d.ts +0 -4
- package/lib/typescript/module/src/index.d.ts.map +0 -1
- package/src/TrueSheetFooter.tsx +0 -17
- package/src/TrueSheetModule.ts +0 -19
- /package/lib/{typescript/module → module}/package.json +0 -0
package/README.md
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# React Native True Sheet
|
|
2
2
|
|
|
3
3
|
[](https://github.com/lodev09/react-native-true-sheet/actions/workflows/ci.yml)
|
|
4
|
-
[](https://codeclimate.com/github/lodev09/react-native-true-sheet/maintainability)
|
|
5
4
|
[](https://www.npmjs.com/package/@lodev09/react-native-true-sheet)
|
|
6
5
|
|
|
7
6
|
The true native bottom sheet experience for your React Native Apps. 💩
|
|
@@ -10,14 +9,24 @@ The true native bottom sheet experience for your React Native Apps. 💩
|
|
|
10
9
|
|
|
11
10
|
## Features
|
|
12
11
|
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
12
|
+
* ⚡ **Powered by Fabric** - Built on React Native's new architecture for maximum performance
|
|
13
|
+
* 🎯 **Type-safe** - Full TypeScript support with Codegen-generated native interfaces
|
|
14
|
+
* 🚀 **Blazing fast** - Direct C++ communication, no bridge overhead
|
|
15
|
+
* 🎨 **Native** - Implemented in the native realm
|
|
16
|
+
* 🔄 **Imperative API** - Asynchronus `ref` [methods](https://sheet.lodev09.com/reference/methods#ref-methods)
|
|
17
17
|
|
|
18
18
|
## Installation
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
> [!IMPORTANT]
|
|
21
|
+
> **Version 3.0+ requires React Native's New Architecture (Fabric)**
|
|
22
|
+
> For the old architecture, use version 2.x. See the [Migration Guide (v2 → v3)](https://sheet.lodev09.com/migration) for upgrading.
|
|
23
|
+
|
|
24
|
+
### Prerequisites
|
|
25
|
+
|
|
26
|
+
- React Native >= 0.81
|
|
27
|
+
- New Architecture enabled (`RCT_NEW_ARCH_ENABLED=1` for iOS, `newArchEnabled=true` for Android)
|
|
28
|
+
|
|
29
|
+
### Install
|
|
21
30
|
|
|
22
31
|
```sh
|
|
23
32
|
yarn add @lodev09/react-native-true-sheet
|
|
@@ -26,18 +35,25 @@ yarn add @lodev09/react-native-true-sheet
|
|
|
26
35
|
npm i @lodev09/react-native-true-sheet
|
|
27
36
|
```
|
|
28
37
|
|
|
29
|
-
|
|
38
|
+
### iOS Setup
|
|
30
39
|
|
|
31
40
|
```sh
|
|
32
41
|
cd ios && pod install
|
|
33
42
|
```
|
|
34
43
|
|
|
44
|
+
> **Note:** If you need old architecture support, use version 2.x:
|
|
45
|
+
> ```sh
|
|
46
|
+
> yarn add @lodev09/react-native-true-sheet@^2.0.0
|
|
47
|
+
> ```
|
|
48
|
+
|
|
35
49
|
## Documentation
|
|
36
50
|
|
|
37
51
|
- [Example](example)
|
|
38
52
|
- [Guides](https://sheet.lodev09.com/category/guides)
|
|
39
53
|
- [Reference](https://sheet.lodev09.com/category/reference)
|
|
54
|
+
- [Migration Guide (v2 → v3)](https://sheet.lodev09.com/migration)
|
|
40
55
|
- [Troubleshooting](https://sheet.lodev09.com/troubleshooting)
|
|
56
|
+
- [Testing with Jest](https://sheet.lodev09.com/guides/jest)
|
|
41
57
|
|
|
42
58
|
## Usage
|
|
43
59
|
|
|
@@ -64,7 +80,7 @@ export const App = () => {
|
|
|
64
80
|
<Button onPress={present} title="Present" />
|
|
65
81
|
<TrueSheet
|
|
66
82
|
ref={sheet}
|
|
67
|
-
|
|
83
|
+
detents={['auto', 1]}
|
|
68
84
|
cornerRadius={24}
|
|
69
85
|
>
|
|
70
86
|
<Button onPress={dismiss} title="Dismiss" />
|
|
@@ -74,6 +90,18 @@ export const App = () => {
|
|
|
74
90
|
}
|
|
75
91
|
```
|
|
76
92
|
|
|
93
|
+
## Testing
|
|
94
|
+
|
|
95
|
+
TrueSheet includes built-in Jest mocks for easy testing. Simply mock the package in your tests:
|
|
96
|
+
|
|
97
|
+
```tsx
|
|
98
|
+
jest.mock('@lodev09/react-native-true-sheet');
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
All methods (`present`, `dismiss`, `resize`) are mocked as Jest functions, allowing you to test your components without native dependencies.
|
|
102
|
+
|
|
103
|
+
**[Full Testing Guide](https://sheet.lodev09.com/guides/jest)**
|
|
104
|
+
|
|
77
105
|
## Contributing
|
|
78
106
|
|
|
79
107
|
See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = "RNTrueSheet"
|
|
7
|
+
s.version = package["version"]
|
|
8
|
+
s.summary = package["description"]
|
|
9
|
+
s.homepage = package["homepage"]
|
|
10
|
+
s.license = package["license"]
|
|
11
|
+
s.authors = package["author"]
|
|
12
|
+
|
|
13
|
+
s.platforms = { :ios => min_ios_version_supported }
|
|
14
|
+
s.source = { :git => "https://github.com/lodev09/react-native-true-sheet.git", :tag => "#{s.version}" }
|
|
15
|
+
|
|
16
|
+
s.source_files = "ios/**/*.{h,m,mm,swift,cpp}"
|
|
17
|
+
s.private_header_files = "ios/**/*.h"
|
|
18
|
+
|
|
19
|
+
install_modules_dependencies(s)
|
|
20
|
+
end
|
package/android/build.gradle
CHANGED
|
@@ -16,24 +16,19 @@ buildscript {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
def isNewArchitectureEnabled() {
|
|
20
|
-
return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
|
|
21
|
-
}
|
|
22
|
-
|
|
23
19
|
apply plugin: "com.android.library"
|
|
24
20
|
apply plugin: "kotlin-android"
|
|
25
|
-
|
|
26
|
-
// TODO:
|
|
27
|
-
// When running example, comment this block!
|
|
28
|
-
// Not sure what's going on but we are getting multiple definition error when this is enabled.
|
|
29
|
-
if (isNewArchitectureEnabled()) {
|
|
30
|
-
apply plugin: "com.facebook.react"
|
|
31
|
-
}
|
|
21
|
+
apply plugin: "com.facebook.react"
|
|
32
22
|
|
|
33
23
|
def getExtOrIntegerDefault(name) {
|
|
34
24
|
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["TrueSheet_" + name]).toInteger()
|
|
35
25
|
}
|
|
36
26
|
|
|
27
|
+
def getEdgeToEdgeEnabled() {
|
|
28
|
+
def edgeToEdge = project.findProperty("edgeToEdgeEnabled")
|
|
29
|
+
return edgeToEdge != null ? edgeToEdge.toBoolean() : false
|
|
30
|
+
}
|
|
31
|
+
|
|
37
32
|
def supportsNamespace() {
|
|
38
33
|
def parsed = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')
|
|
39
34
|
def major = parsed[0].toInteger()
|
|
@@ -59,7 +54,7 @@ android {
|
|
|
59
54
|
defaultConfig {
|
|
60
55
|
minSdkVersion getExtOrIntegerDefault("minSdkVersion")
|
|
61
56
|
targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
|
|
62
|
-
|
|
57
|
+
buildConfigField "boolean", "EDGE_TO_EDGE_ENABLED", "${getEdgeToEdgeEnabled()}"
|
|
63
58
|
}
|
|
64
59
|
|
|
65
60
|
buildTypes {
|
|
@@ -73,8 +68,25 @@ android {
|
|
|
73
68
|
}
|
|
74
69
|
|
|
75
70
|
compileOptions {
|
|
76
|
-
sourceCompatibility JavaVersion.
|
|
77
|
-
targetCompatibility JavaVersion.
|
|
71
|
+
sourceCompatibility JavaVersion.VERSION_17
|
|
72
|
+
targetCompatibility JavaVersion.VERSION_17
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
kotlinOptions {
|
|
76
|
+
jvmTarget = "17"
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
buildFeatures {
|
|
80
|
+
buildConfig = true
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
sourceSets {
|
|
84
|
+
main {
|
|
85
|
+
java.srcDirs += [
|
|
86
|
+
"generated/java",
|
|
87
|
+
"generated/jni"
|
|
88
|
+
]
|
|
89
|
+
}
|
|
78
90
|
}
|
|
79
91
|
}
|
|
80
92
|
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
package com.lodev09.truesheet
|
|
2
|
+
|
|
3
|
+
import android.annotation.SuppressLint
|
|
4
|
+
import android.view.View
|
|
5
|
+
import androidx.core.view.isNotEmpty
|
|
6
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
7
|
+
import com.facebook.react.views.view.ReactViewGroup
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Delegate interface for container view changes
|
|
11
|
+
*/
|
|
12
|
+
interface TrueSheetContainerViewDelegate {
|
|
13
|
+
fun containerViewContentDidChangeSize(width: Int, height: Int)
|
|
14
|
+
fun containerViewFooterDidChangeSize(width: Int, height: Int)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Container view that manages the bottom sheet content and holds content and footer views.
|
|
19
|
+
* Simplified to be a lightweight content manager - events are now handled via dialog delegate.
|
|
20
|
+
*/
|
|
21
|
+
@SuppressLint("ViewConstructor")
|
|
22
|
+
class TrueSheetContainerView(private val reactContext: ThemedReactContext) :
|
|
23
|
+
ReactViewGroup(reactContext),
|
|
24
|
+
TrueSheetContentViewDelegate,
|
|
25
|
+
TrueSheetFooterViewDelegate {
|
|
26
|
+
|
|
27
|
+
var delegate: TrueSheetContainerViewDelegate? = null
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Reference to content view (first child)
|
|
31
|
+
*/
|
|
32
|
+
val contentView: TrueSheetContentView?
|
|
33
|
+
get() = if (isNotEmpty() && getChildAt(0) is TrueSheetContentView) {
|
|
34
|
+
getChildAt(0) as TrueSheetContentView
|
|
35
|
+
} else {
|
|
36
|
+
null
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Reference to footer view (second child)
|
|
41
|
+
*/
|
|
42
|
+
val footerView: TrueSheetFooterView?
|
|
43
|
+
get() = if (childCount > 1 && getChildAt(1) is TrueSheetFooterView) {
|
|
44
|
+
getChildAt(1) as TrueSheetFooterView
|
|
45
|
+
} else {
|
|
46
|
+
null
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* The content view height
|
|
51
|
+
*/
|
|
52
|
+
val contentHeight: Int
|
|
53
|
+
get() = contentView?.height ?: 0
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* The footer view height
|
|
57
|
+
*/
|
|
58
|
+
val footerHeight: Int
|
|
59
|
+
get() = footerView?.height ?: 0
|
|
60
|
+
|
|
61
|
+
init {
|
|
62
|
+
// Container should not clip children to allow footer to position absolutely
|
|
63
|
+
clipChildren = false
|
|
64
|
+
clipToPadding = false
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
override fun addView(child: View?, index: Int) {
|
|
68
|
+
super.addView(child, index)
|
|
69
|
+
|
|
70
|
+
// Set up delegate when content view is added
|
|
71
|
+
if (child is TrueSheetContentView) {
|
|
72
|
+
child.delegate = this
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Set up delegate when footer view is added
|
|
76
|
+
if (child is TrueSheetFooterView) {
|
|
77
|
+
child.delegate = this
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
override fun removeView(view: View?) {
|
|
82
|
+
// Clean up delegate when content view is removed
|
|
83
|
+
if (view is TrueSheetContentView) {
|
|
84
|
+
view.delegate = null
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Clean up delegate when footer view is removed
|
|
88
|
+
if (view is TrueSheetFooterView) {
|
|
89
|
+
view.delegate = null
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
super.removeView(view)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// ==================== TrueSheetContentViewDelegate Implementation ====================
|
|
96
|
+
|
|
97
|
+
override fun contentViewDidChangeSize(width: Int, height: Int) {
|
|
98
|
+
// Forward content size changes to controller for sheet resizing
|
|
99
|
+
delegate?.containerViewContentDidChangeSize(width, height)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// ==================== TrueSheetFooterViewDelegate Implementation ====================
|
|
103
|
+
|
|
104
|
+
override fun footerViewDidChangeSize(width: Int, height: Int) {
|
|
105
|
+
// Forward footer size changes to host view for repositioning
|
|
106
|
+
delegate?.containerViewFooterDidChangeSize(width, height)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
package com.lodev09.truesheet
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.module.annotations.ReactModule
|
|
4
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
5
|
+
import com.facebook.react.uimanager.ViewGroupManager
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* ViewManager for TrueSheetContainerView
|
|
9
|
+
* Container that holds content and footer views
|
|
10
|
+
*/
|
|
11
|
+
@ReactModule(name = TrueSheetContainerViewManager.REACT_CLASS)
|
|
12
|
+
class TrueSheetContainerViewManager : ViewGroupManager<TrueSheetContainerView>() {
|
|
13
|
+
|
|
14
|
+
override fun getName(): String = REACT_CLASS
|
|
15
|
+
|
|
16
|
+
override fun createViewInstance(reactContext: ThemedReactContext): TrueSheetContainerView = TrueSheetContainerView(reactContext)
|
|
17
|
+
|
|
18
|
+
companion object {
|
|
19
|
+
const val REACT_CLASS = "TrueSheetContainerView"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
package com.lodev09.truesheet
|
|
2
|
+
|
|
3
|
+
import android.annotation.SuppressLint
|
|
4
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
5
|
+
import com.facebook.react.views.view.ReactViewGroup
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Delegate interface for content view size changes
|
|
9
|
+
*/
|
|
10
|
+
interface TrueSheetContentViewDelegate {
|
|
11
|
+
fun contentViewDidChangeSize(width: Int, height: Int)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Content view that holds the main sheet content
|
|
16
|
+
* This is the first child of TrueSheetContainerView
|
|
17
|
+
*/
|
|
18
|
+
@SuppressLint("ViewConstructor")
|
|
19
|
+
class TrueSheetContentView(context: ThemedReactContext) : ReactViewGroup(context) {
|
|
20
|
+
var delegate: TrueSheetContentViewDelegate? = null
|
|
21
|
+
|
|
22
|
+
private var lastWidth = 0
|
|
23
|
+
private var lastHeight = 0
|
|
24
|
+
|
|
25
|
+
override fun onLayout(
|
|
26
|
+
changed: Boolean,
|
|
27
|
+
left: Int,
|
|
28
|
+
top: Int,
|
|
29
|
+
right: Int,
|
|
30
|
+
bottom: Int
|
|
31
|
+
) {
|
|
32
|
+
super.onLayout(changed, left, top, right, bottom)
|
|
33
|
+
|
|
34
|
+
// Notify delegate when content size changes
|
|
35
|
+
val newWidth = right - left
|
|
36
|
+
val newHeight = bottom - top
|
|
37
|
+
|
|
38
|
+
if (newWidth != lastWidth || newHeight != lastHeight) {
|
|
39
|
+
lastWidth = newWidth
|
|
40
|
+
lastHeight = newHeight
|
|
41
|
+
|
|
42
|
+
// Notify delegate of size change
|
|
43
|
+
delegate?.contentViewDidChangeSize(newWidth, newHeight)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
package com.lodev09.truesheet
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.module.annotations.ReactModule
|
|
4
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
5
|
+
import com.facebook.react.uimanager.ViewGroupManager
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* ViewManager for TrueSheetContentView
|
|
9
|
+
* Manages the main content area of the sheet
|
|
10
|
+
*/
|
|
11
|
+
@ReactModule(name = TrueSheetContentViewManager.REACT_CLASS)
|
|
12
|
+
class TrueSheetContentViewManager : ViewGroupManager<TrueSheetContentView>() {
|
|
13
|
+
|
|
14
|
+
override fun getName(): String = REACT_CLASS
|
|
15
|
+
|
|
16
|
+
override fun createViewInstance(reactContext: ThemedReactContext): TrueSheetContentView = TrueSheetContentView(reactContext)
|
|
17
|
+
|
|
18
|
+
companion object {
|
|
19
|
+
const val REACT_CLASS = "TrueSheetContentView"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
package com.lodev09.truesheet
|
|
2
|
+
|
|
3
|
+
import android.annotation.SuppressLint
|
|
4
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
5
|
+
import com.facebook.react.views.view.ReactViewGroup
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Delegate interface for footer view size changes
|
|
9
|
+
*/
|
|
10
|
+
interface TrueSheetFooterViewDelegate {
|
|
11
|
+
fun footerViewDidChangeSize(width: Int, height: Int)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Footer view that holds the footer content
|
|
16
|
+
* This is the second child of TrueSheetContainerView
|
|
17
|
+
* Positioned absolutely at the bottom of the sheet
|
|
18
|
+
*/
|
|
19
|
+
@SuppressLint("ViewConstructor")
|
|
20
|
+
class TrueSheetFooterView(context: ThemedReactContext) : ReactViewGroup(context) {
|
|
21
|
+
var delegate: TrueSheetFooterViewDelegate? = null
|
|
22
|
+
|
|
23
|
+
private var lastWidth = 0
|
|
24
|
+
private var lastHeight = 0
|
|
25
|
+
|
|
26
|
+
override fun onLayout(
|
|
27
|
+
changed: Boolean,
|
|
28
|
+
left: Int,
|
|
29
|
+
top: Int,
|
|
30
|
+
right: Int,
|
|
31
|
+
bottom: Int
|
|
32
|
+
) {
|
|
33
|
+
super.onLayout(changed, left, top, right, bottom)
|
|
34
|
+
|
|
35
|
+
// Notify delegate when footer size changes
|
|
36
|
+
val newWidth = right - left
|
|
37
|
+
val newHeight = bottom - top
|
|
38
|
+
|
|
39
|
+
if (newWidth != lastWidth || newHeight != lastHeight) {
|
|
40
|
+
lastWidth = newWidth
|
|
41
|
+
lastHeight = newHeight
|
|
42
|
+
|
|
43
|
+
// Notify delegate of size change
|
|
44
|
+
delegate?.footerViewDidChangeSize(newWidth, newHeight)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
package com.lodev09.truesheet
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.module.annotations.ReactModule
|
|
4
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
5
|
+
import com.facebook.react.uimanager.ViewGroupManager
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* ViewManager for TrueSheetFooterView
|
|
9
|
+
* Manages the footer area of the sheet
|
|
10
|
+
*/
|
|
11
|
+
@ReactModule(name = TrueSheetFooterViewManager.REACT_CLASS)
|
|
12
|
+
class TrueSheetFooterViewManager : ViewGroupManager<TrueSheetFooterView>() {
|
|
13
|
+
|
|
14
|
+
override fun getName(): String = REACT_CLASS
|
|
15
|
+
|
|
16
|
+
override fun createViewInstance(reactContext: ThemedReactContext): TrueSheetFooterView = TrueSheetFooterView(reactContext)
|
|
17
|
+
|
|
18
|
+
companion object {
|
|
19
|
+
const val REACT_CLASS = "TrueSheetFooterView"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
package com.lodev09.truesheet
|
|
2
|
+
|
|
3
|
+
import android.os.Handler
|
|
4
|
+
import android.os.Looper
|
|
5
|
+
import com.facebook.react.bridge.Promise
|
|
6
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
7
|
+
import com.facebook.react.bridge.ReactMethod
|
|
8
|
+
import com.facebook.react.module.annotations.ReactModule
|
|
9
|
+
import com.facebook.react.turbomodule.core.interfaces.TurboModule
|
|
10
|
+
import com.facebook.react.uimanager.UIManagerHelper
|
|
11
|
+
import java.util.concurrent.ConcurrentHashMap
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* TurboModule for TrueSheet imperative API
|
|
15
|
+
* Provides promise-based async operations using view references
|
|
16
|
+
*/
|
|
17
|
+
@ReactModule(name = TrueSheetModule.NAME)
|
|
18
|
+
class TrueSheetModule(reactContext: ReactApplicationContext) :
|
|
19
|
+
com.facebook.react.bridge.ReactContextBaseJavaModule(reactContext),
|
|
20
|
+
TurboModule {
|
|
21
|
+
|
|
22
|
+
override fun getName(): String = NAME
|
|
23
|
+
|
|
24
|
+
override fun initialize() {
|
|
25
|
+
super.initialize()
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
override fun invalidate() {
|
|
29
|
+
super.invalidate()
|
|
30
|
+
// Clear all registered views on module invalidation
|
|
31
|
+
synchronized(viewRegistry) {
|
|
32
|
+
viewRegistry.clear()
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Present a sheet by reference
|
|
38
|
+
*
|
|
39
|
+
* @param viewTag Native view tag of the sheet component
|
|
40
|
+
* @param index Detent index to present at
|
|
41
|
+
* @param promise Promise that resolves when sheet is fully presented
|
|
42
|
+
* @throws VIEW_NOT_FOUND if the view with the given tag is not found
|
|
43
|
+
* @throws INVALID_VIEW_TYPE if the view is not a TrueSheetView
|
|
44
|
+
* @throws OPERATION_FAILED if the operation fails for any other reason
|
|
45
|
+
*/
|
|
46
|
+
@ReactMethod
|
|
47
|
+
fun presentByRef(viewTag: Double, index: Double, promise: Promise) {
|
|
48
|
+
val tag = viewTag.toInt()
|
|
49
|
+
val detentIndex = index.toInt()
|
|
50
|
+
|
|
51
|
+
withTrueSheetView(tag, promise) { view ->
|
|
52
|
+
view.present(detentIndex) {
|
|
53
|
+
promise.resolve(null)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Dismiss a sheet by reference
|
|
60
|
+
*
|
|
61
|
+
* @param viewTag Native view tag of the sheet component
|
|
62
|
+
* @param promise Promise that resolves when sheet is fully dismissed
|
|
63
|
+
* @throws VIEW_NOT_FOUND if the view with the given tag is not found
|
|
64
|
+
* @throws INVALID_VIEW_TYPE if the view is not a TrueSheetView
|
|
65
|
+
* @throws OPERATION_FAILED if the operation fails for any other reason
|
|
66
|
+
*/
|
|
67
|
+
@ReactMethod
|
|
68
|
+
fun dismissByRef(viewTag: Double, promise: Promise) {
|
|
69
|
+
val tag = viewTag.toInt()
|
|
70
|
+
|
|
71
|
+
withTrueSheetView(tag, promise) { view ->
|
|
72
|
+
view.dismiss {
|
|
73
|
+
promise.resolve(null)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Resize a sheet to a different index by reference
|
|
80
|
+
*
|
|
81
|
+
* @param viewTag Native view tag of the sheet component
|
|
82
|
+
* @param index New detent index
|
|
83
|
+
* @param promise Promise that resolves when resize is complete
|
|
84
|
+
* @throws VIEW_NOT_FOUND if the view with the given tag is not found
|
|
85
|
+
* @throws INVALID_VIEW_TYPE if the view is not a TrueSheetView
|
|
86
|
+
* @throws OPERATION_FAILED if the operation fails for any other reason
|
|
87
|
+
*/
|
|
88
|
+
@ReactMethod
|
|
89
|
+
fun resizeByRef(viewTag: Double, index: Double, promise: Promise) {
|
|
90
|
+
// Resize is just an alias for present
|
|
91
|
+
presentByRef(viewTag, index, promise)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Helper method to get TrueSheetView by tag and execute closure
|
|
96
|
+
*/
|
|
97
|
+
private fun withTrueSheetView(tag: Int, promise: Promise, closure: (view: TrueSheetView) -> Unit) {
|
|
98
|
+
Handler(Looper.getMainLooper()).post {
|
|
99
|
+
try {
|
|
100
|
+
// First try to get from registry (faster)
|
|
101
|
+
val view = getSheetByTag(tag)
|
|
102
|
+
|
|
103
|
+
if (view != null) {
|
|
104
|
+
closure(view)
|
|
105
|
+
} else {
|
|
106
|
+
// Fallback to UIManager resolution
|
|
107
|
+
val manager = UIManagerHelper.getUIManagerForReactTag(reactApplicationContext, tag)
|
|
108
|
+
val resolvedView = manager?.resolveView(tag)
|
|
109
|
+
|
|
110
|
+
if (resolvedView == null) {
|
|
111
|
+
promise.reject("VIEW_NOT_FOUND", "TrueSheetView with tag $tag not found")
|
|
112
|
+
return@post
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (resolvedView is TrueSheetView) {
|
|
116
|
+
closure(resolvedView)
|
|
117
|
+
} else {
|
|
118
|
+
promise.reject(
|
|
119
|
+
"INVALID_VIEW_TYPE",
|
|
120
|
+
"View with tag $tag is not a TrueSheetView (got ${resolvedView::class.simpleName})"
|
|
121
|
+
)
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
} catch (e: Exception) {
|
|
125
|
+
promise.reject("OPERATION_FAILED", "Failed to execute operation: ${e.message}", e)
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
companion object {
|
|
131
|
+
const val NAME = "TrueSheetModule"
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Registry to keep track of TrueSheetView instances by their view tag
|
|
135
|
+
* This provides fast lookup for ref-based operations
|
|
136
|
+
*/
|
|
137
|
+
private val viewRegistry = ConcurrentHashMap<Int, TrueSheetView>()
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Register a TrueSheetView instance
|
|
141
|
+
* Called automatically by TrueSheetView during initialization
|
|
142
|
+
*/
|
|
143
|
+
@JvmStatic
|
|
144
|
+
fun registerView(view: TrueSheetView, tag: Int) {
|
|
145
|
+
viewRegistry[tag] = view
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Unregister a TrueSheetView instance
|
|
150
|
+
* Called automatically by TrueSheetView during cleanup
|
|
151
|
+
*/
|
|
152
|
+
@JvmStatic
|
|
153
|
+
fun unregisterView(tag: Int) {
|
|
154
|
+
viewRegistry.remove(tag)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Get a TrueSheetView by its tag
|
|
159
|
+
* @param tag - The React native tag of the view
|
|
160
|
+
* @return The TrueSheetView instance, or null if not found
|
|
161
|
+
*/
|
|
162
|
+
@JvmStatic
|
|
163
|
+
fun getSheetByTag(tag: Int): TrueSheetView? = viewRegistry[tag]
|
|
164
|
+
}
|
|
165
|
+
}
|
|
@@ -1,12 +1,44 @@
|
|
|
1
1
|
package com.lodev09.truesheet
|
|
2
2
|
|
|
3
|
-
import com.facebook.react.
|
|
3
|
+
import com.facebook.react.TurboReactPackage
|
|
4
4
|
import com.facebook.react.bridge.NativeModule
|
|
5
5
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
+
import com.facebook.react.module.model.ReactModuleInfo
|
|
7
|
+
import com.facebook.react.module.model.ReactModuleInfoProvider
|
|
6
8
|
import com.facebook.react.uimanager.ViewManager
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
/**
|
|
11
|
+
* TrueSheet package for Fabric architecture
|
|
12
|
+
* Registers all view managers and the TurboModule
|
|
13
|
+
*/
|
|
14
|
+
class TrueSheetPackage : TurboReactPackage() {
|
|
10
15
|
|
|
11
|
-
override fun
|
|
16
|
+
override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? =
|
|
17
|
+
when (name) {
|
|
18
|
+
TrueSheetModule.NAME -> TrueSheetModule(reactContext)
|
|
19
|
+
else -> null
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
override fun getReactModuleInfoProvider(): ReactModuleInfoProvider =
|
|
23
|
+
ReactModuleInfoProvider {
|
|
24
|
+
mapOf(
|
|
25
|
+
TrueSheetModule.NAME to ReactModuleInfo(
|
|
26
|
+
TrueSheetModule.NAME,
|
|
27
|
+
TrueSheetModule::class.java.name,
|
|
28
|
+
false, // canOverrideExistingModule
|
|
29
|
+
false, // needsEagerInit
|
|
30
|
+
true, // hasConstants
|
|
31
|
+
false, // isCxxModule
|
|
32
|
+
true // isTurboModule
|
|
33
|
+
)
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> =
|
|
38
|
+
listOf(
|
|
39
|
+
TrueSheetViewManager(),
|
|
40
|
+
TrueSheetContainerViewManager(),
|
|
41
|
+
TrueSheetContentViewManager(),
|
|
42
|
+
TrueSheetFooterViewManager()
|
|
43
|
+
)
|
|
12
44
|
}
|