@lodev09/react-native-true-sheet 3.0.0-beta.0 → 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.
Files changed (59) hide show
  1. package/README.md +7 -21
  2. package/RNTrueSheet.podspec +5 -1
  3. package/android/src/main/java/com/lodev09/truesheet/TrueSheetContainerView.kt +58 -60
  4. package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentView.kt +10 -18
  5. package/android/src/main/java/com/lodev09/truesheet/TrueSheetFooterView.kt +76 -20
  6. package/android/src/main/java/com/lodev09/truesheet/TrueSheetHeaderView.kt +38 -0
  7. package/android/src/main/java/com/lodev09/truesheet/TrueSheetHeaderViewManager.kt +21 -0
  8. package/android/src/main/java/com/lodev09/truesheet/TrueSheetPackage.kt +1 -0
  9. package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +104 -146
  10. package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewController.kt +315 -403
  11. package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt +24 -11
  12. package/android/src/main/java/com/lodev09/truesheet/core/RNScreensFragmentObserver.kt +116 -0
  13. package/android/src/main/java/com/lodev09/truesheet/utils/ScreenUtils.kt +33 -5
  14. package/android/src/main/jni/CMakeLists.txt +87 -0
  15. package/android/src/main/jni/TrueSheetSpec.h +17 -0
  16. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewComponentDescriptor.h +24 -0
  17. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.cpp +46 -0
  18. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.h +28 -0
  19. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewState.cpp +11 -0
  20. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewState.h +42 -0
  21. package/ios/TrueSheetContainerView.h +23 -0
  22. package/ios/TrueSheetContainerView.mm +80 -13
  23. package/ios/TrueSheetContentView.h +9 -1
  24. package/ios/TrueSheetContentView.mm +102 -24
  25. package/ios/TrueSheetFooterView.mm +2 -2
  26. package/ios/TrueSheetHeaderView.h +29 -0
  27. package/ios/TrueSheetHeaderView.mm +60 -0
  28. package/ios/TrueSheetView.h +0 -16
  29. package/ios/TrueSheetView.mm +208 -190
  30. package/ios/TrueSheetViewController.h +17 -4
  31. package/ios/TrueSheetViewController.mm +197 -266
  32. package/ios/utils/ConversionUtil.h +24 -0
  33. package/ios/utils/ConversionUtil.mm +50 -0
  34. package/ios/utils/LayoutUtil.h +11 -1
  35. package/ios/utils/LayoutUtil.mm +32 -1
  36. package/lib/module/TrueSheet.js +30 -33
  37. package/lib/module/TrueSheet.js.map +1 -1
  38. package/lib/module/fabric/TrueSheetContainerViewNativeComponent.ts +1 -1
  39. package/lib/module/fabric/TrueSheetHeaderViewNativeComponent.ts +8 -0
  40. package/lib/module/fabric/TrueSheetViewNativeComponent.ts +6 -8
  41. package/lib/typescript/src/TrueSheet.d.ts +0 -3
  42. package/lib/typescript/src/TrueSheet.d.ts.map +1 -1
  43. package/lib/typescript/src/TrueSheet.types.d.ts +30 -43
  44. package/lib/typescript/src/TrueSheet.types.d.ts.map +1 -1
  45. package/lib/typescript/src/fabric/TrueSheetContainerViewNativeComponent.d.ts.map +1 -1
  46. package/lib/typescript/src/fabric/TrueSheetHeaderViewNativeComponent.d.ts +6 -0
  47. package/lib/typescript/src/fabric/TrueSheetHeaderViewNativeComponent.d.ts.map +1 -0
  48. package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts +3 -6
  49. package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts.map +1 -1
  50. package/package.json +9 -5
  51. package/react-native.config.js +5 -2
  52. package/src/TrueSheet.tsx +34 -31
  53. package/src/TrueSheet.types.ts +47 -61
  54. package/src/fabric/TrueSheetContainerViewNativeComponent.ts +1 -1
  55. package/src/fabric/TrueSheetHeaderViewNativeComponent.ts +8 -0
  56. package/src/fabric/TrueSheetViewNativeComponent.ts +6 -8
  57. package/android/src/main/java/com/lodev09/truesheet/events/SizeChangeEvent.kt +0 -27
  58. package/ios/events/OnSizeChangeEvent.h +0 -28
  59. package/ios/events/OnSizeChangeEvent.mm +0 -30
package/README.md CHANGED
@@ -5,21 +5,22 @@
5
5
 
6
6
  The true native bottom sheet experience for your React Native Apps. 💩
7
7
 
8
- <img alt="React Native True Sheet - IOS" src="docs/static/img/preview.gif" width="300" height="600" /><img alt="React Native True Sheet - Android" src="docs/static/img/preview-2.gif" width="300" height="600" />
8
+ <img alt="React Native True Sheet - IOS" src="docs/static/img/preview-ios.gif" width="300" height="600" /><img alt="React Native True Sheet - Android" src="docs/static/img/preview-android.gif" width="300" height="600" />
9
9
 
10
10
  ## Features
11
11
 
12
12
  * ⚡ **Powered by Fabric** - Built on React Native's new architecture for maximum performance
13
+ * 🚀 **Native** - Implemented in the native realm
13
14
  * 🎯 **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)
15
+ * **Accessible** - Native accessibility and screen reader support out of the box
16
+ * 🔄 **Imperative API** - Asynchronus `ref` [Methods](https://sheet.lodev09.com/reference/methods#ref-methods)
17
+ * 🪟 **Liquid Glass** - iOS 26+ Liquid Glass support out of the box. Featured in [Expo Blog](https://expo.dev/blog/how-to-create-apple-maps-style-liquid-glass-sheets)
17
18
 
18
19
  ## Installation
19
20
 
20
21
  > [!IMPORTANT]
21
22
  > **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
+ > For the old architecture, use version 2.x. See the [Migration Guide](https://sheet.lodev09.com/migration) for upgrading.
23
24
 
24
25
  ### Prerequisites
25
26
 
@@ -31,27 +32,13 @@ The true native bottom sheet experience for your React Native Apps. 💩
31
32
  ```sh
32
33
  yarn add @lodev09/react-native-true-sheet
33
34
  ```
34
- ```sh
35
- npm i @lodev09/react-native-true-sheet
36
- ```
37
-
38
- ### iOS Setup
39
-
40
- ```sh
41
- cd ios && pod install
42
- ```
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
36
  ## Documentation
50
37
 
51
38
  - [Example](example)
52
39
  - [Guides](https://sheet.lodev09.com/category/guides)
53
40
  - [Reference](https://sheet.lodev09.com/category/reference)
54
- - [Migration Guide (v2 → v3)](https://sheet.lodev09.com/migration)
41
+ - [Migrating to v3](https://sheet.lodev09.com/migration)
55
42
  - [Troubleshooting](https://sheet.lodev09.com/troubleshooting)
56
43
  - [Testing with Jest](https://sheet.lodev09.com/guides/jest)
57
44
 
@@ -81,7 +68,6 @@ export const App = () => {
81
68
  <TrueSheet
82
69
  ref={sheet}
83
70
  detents={['auto', 1]}
84
- cornerRadius={24}
85
71
  >
86
72
  <Button onPress={dismiss} title="Dismiss" />
87
73
  </TrueSheet>
@@ -13,8 +13,12 @@ Pod::Spec.new do |s|
13
13
  s.platforms = { :ios => min_ios_version_supported }
14
14
  s.source = { :git => "https://github.com/lodev09/react-native-true-sheet.git", :tag => "#{s.version}" }
15
15
 
16
- s.source_files = "ios/**/*.{h,m,mm,swift,cpp}"
16
+ s.source_files = "ios/**/*.{h,m,mm,swift,cpp}", "common/cpp/**/*.{cpp,h}"
17
17
  s.private_header_files = "ios/**/*.h"
18
18
 
19
+ s.pod_target_xcconfig = {
20
+ "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/common/cpp\""
21
+ }
22
+
19
23
  install_modules_dependencies(s)
20
24
  end
@@ -2,64 +2,38 @@ package com.lodev09.truesheet
2
2
 
3
3
  import android.annotation.SuppressLint
4
4
  import android.view.View
5
- import androidx.core.view.isNotEmpty
6
5
  import com.facebook.react.uimanager.ThemedReactContext
7
6
  import com.facebook.react.views.view.ReactViewGroup
8
7
 
9
- /**
10
- * Delegate interface for container view changes
11
- */
12
8
  interface TrueSheetContainerViewDelegate {
13
9
  fun containerViewContentDidChangeSize(width: Int, height: Int)
10
+ fun containerViewHeaderDidChangeSize(width: Int, height: Int)
14
11
  fun containerViewFooterDidChangeSize(width: Int, height: Int)
15
12
  }
16
13
 
17
14
  /**
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.
15
+ * Container view that manages the sheet's content, header, and footer views.
16
+ * Size changes are forwarded to the delegate for sheet reconfiguration.
20
17
  */
21
18
  @SuppressLint("ViewConstructor")
22
- class TrueSheetContainerView(private val reactContext: ThemedReactContext) :
19
+ class TrueSheetContainerView(reactContext: ThemedReactContext) :
23
20
  ReactViewGroup(reactContext),
24
21
  TrueSheetContentViewDelegate,
22
+ TrueSheetHeaderViewDelegate,
25
23
  TrueSheetFooterViewDelegate {
26
24
 
27
25
  var delegate: TrueSheetContainerViewDelegate? = null
28
26
 
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
- }
27
+ var contentView: TrueSheetContentView? = null
28
+ var headerView: TrueSheetHeaderView? = null
29
+ var footerView: TrueSheetFooterView? = null
38
30
 
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
31
+ var contentHeight: Int = 0
32
+ var headerHeight: Int = 0
33
+ var footerHeight: Int = 0
60
34
 
61
35
  init {
62
- // Container should not clip children to allow footer to position absolutely
36
+ // Allow footer to position outside container bounds
63
37
  clipChildren = false
64
38
  clipToPadding = false
65
39
  }
@@ -67,42 +41,66 @@ class TrueSheetContainerView(private val reactContext: ThemedReactContext) :
67
41
  override fun addView(child: View?, index: Int) {
68
42
  super.addView(child, index)
69
43
 
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
44
+ when (child) {
45
+ is TrueSheetContentView -> {
46
+ child.delegate = this
47
+ contentView = child
48
+ }
49
+
50
+ is TrueSheetHeaderView -> {
51
+ child.delegate = this
52
+ headerView = child
53
+ }
54
+
55
+ is TrueSheetFooterView -> {
56
+ child.delegate = this
57
+ footerView = child
58
+ }
78
59
  }
79
60
  }
80
61
 
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
62
+ override fun removeViewAt(index: Int) {
63
+ when (val view = getChildAt(index)) {
64
+ is TrueSheetContentView -> {
65
+ view.delegate = null
66
+ contentView = null
67
+ contentViewDidChangeSize(0, 0)
68
+ }
69
+
70
+ is TrueSheetHeaderView -> {
71
+ view.delegate = null
72
+ headerView = null
73
+ headerViewDidChangeSize(0, 0)
74
+ }
75
+
76
+ is TrueSheetFooterView -> {
77
+ view.delegate = null
78
+ footerView = null
79
+ footerViewDidChangeSize(0, 0)
80
+ }
90
81
  }
91
82
 
92
- super.removeView(view)
83
+ super.removeViewAt(index)
93
84
  }
94
85
 
95
- // ==================== TrueSheetContentViewDelegate Implementation ====================
86
+ // ==================== Delegate Implementations ====================
96
87
 
97
88
  override fun contentViewDidChangeSize(width: Int, height: Int) {
98
- // Forward content size changes to controller for sheet resizing
89
+ contentHeight = height
99
90
  delegate?.containerViewContentDidChangeSize(width, height)
100
91
  }
101
92
 
102
- // ==================== TrueSheetFooterViewDelegate Implementation ====================
93
+ override fun headerViewDidChangeSize(width: Int, height: Int) {
94
+ headerHeight = height
95
+ delegate?.containerViewHeaderDidChangeSize(width, height)
96
+ }
103
97
 
104
98
  override fun footerViewDidChangeSize(width: Int, height: Int) {
105
- // Forward footer size changes to host view for repositioning
99
+ footerHeight = height
106
100
  delegate?.containerViewFooterDidChangeSize(width, height)
107
101
  }
102
+
103
+ companion object {
104
+ const val TAG_NAME = "TrueSheet"
105
+ }
108
106
  }
@@ -22,25 +22,17 @@ class TrueSheetContentView(context: ThemedReactContext) : ReactViewGroup(context
22
22
  private var lastWidth = 0
23
23
  private var lastHeight = 0
24
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)
25
+ override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
26
+ super.onSizeChanged(w, h, oldw, oldh)
33
27
 
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)
28
+ if (w != lastWidth || h != lastHeight) {
29
+ lastWidth = w
30
+ lastHeight = h
31
+ delegate?.contentViewDidChangeSize(w, h)
44
32
  }
45
33
  }
34
+
35
+ companion object {
36
+ const val TAG_NAME = "TrueSheet"
37
+ }
46
38
  }
@@ -1,7 +1,13 @@
1
1
  package com.lodev09.truesheet
2
2
 
3
3
  import android.annotation.SuppressLint
4
+ import android.view.MotionEvent
5
+ import android.view.View
6
+ import com.facebook.react.uimanager.JSPointerDispatcher
7
+ import com.facebook.react.uimanager.JSTouchDispatcher
8
+ import com.facebook.react.uimanager.RootView
4
9
  import com.facebook.react.uimanager.ThemedReactContext
10
+ import com.facebook.react.uimanager.events.EventDispatcher
5
11
  import com.facebook.react.views.view.ReactViewGroup
6
12
 
7
13
  /**
@@ -15,33 +21,83 @@ interface TrueSheetFooterViewDelegate {
15
21
  * Footer view that holds the footer content
16
22
  * This is the second child of TrueSheetContainerView
17
23
  * Positioned absolutely at the bottom of the sheet
24
+ *
25
+ * Implements RootView to handle touch events when positioned outside parent bounds.
18
26
  */
19
27
  @SuppressLint("ViewConstructor")
20
- class TrueSheetFooterView(context: ThemedReactContext) : ReactViewGroup(context) {
28
+ class TrueSheetFooterView(private val reactContext: ThemedReactContext) :
29
+ ReactViewGroup(reactContext),
30
+ RootView {
31
+
21
32
  var delegate: TrueSheetFooterViewDelegate? = null
33
+ var eventDispatcher: EventDispatcher? = null
22
34
 
23
35
  private var lastWidth = 0
24
36
  private var lastHeight = 0
25
37
 
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)
38
+ private val jsTouchDispatcher = JSTouchDispatcher(this)
39
+ private var jsPointerDispatcher: JSPointerDispatcher? = null
40
+
41
+ init {
42
+ jsPointerDispatcher = JSPointerDispatcher(this)
43
+ }
44
+
45
+ override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
46
+ super.onSizeChanged(w, h, oldw, oldh)
47
+
48
+ if (w != lastWidth || h != lastHeight) {
49
+ lastWidth = w
50
+ lastHeight = h
51
+ delegate?.footerViewDidChangeSize(w, h)
45
52
  }
46
53
  }
54
+
55
+ // ==================== RootView Implementation ====================
56
+
57
+ override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
58
+ eventDispatcher?.let { dispatcher ->
59
+ jsTouchDispatcher.handleTouchEvent(event, dispatcher, reactContext)
60
+ jsPointerDispatcher?.handleMotionEvent(event, dispatcher, true)
61
+ }
62
+ return super.onInterceptTouchEvent(event)
63
+ }
64
+
65
+ override fun onTouchEvent(event: MotionEvent): Boolean {
66
+ eventDispatcher?.let { dispatcher ->
67
+ jsTouchDispatcher.handleTouchEvent(event, dispatcher, reactContext)
68
+ jsPointerDispatcher?.handleMotionEvent(event, dispatcher, false)
69
+ }
70
+ super.onTouchEvent(event)
71
+ return true
72
+ }
73
+
74
+ override fun onInterceptHoverEvent(event: MotionEvent): Boolean {
75
+ eventDispatcher?.let { jsPointerDispatcher?.handleMotionEvent(event, it, true) }
76
+ return super.onHoverEvent(event)
77
+ }
78
+
79
+ override fun onHoverEvent(event: MotionEvent): Boolean {
80
+ eventDispatcher?.let { jsPointerDispatcher?.handleMotionEvent(event, it, false) }
81
+ return super.onHoverEvent(event)
82
+ }
83
+
84
+ override fun onChildStartedNativeGesture(childView: View?, ev: MotionEvent) {
85
+ eventDispatcher?.let { dispatcher ->
86
+ jsTouchDispatcher.onChildStartedNativeGesture(ev, dispatcher)
87
+ jsPointerDispatcher?.onChildStartedNativeGesture(childView, ev, dispatcher)
88
+ }
89
+ }
90
+
91
+ override fun onChildEndedNativeGesture(childView: View, ev: MotionEvent) {
92
+ eventDispatcher?.let { jsTouchDispatcher.onChildEndedNativeGesture(ev, it) }
93
+ jsPointerDispatcher?.onChildEndedNativeGesture()
94
+ }
95
+
96
+ override fun handleException(t: Throwable) {
97
+ reactContext.reactApplicationContext.handleException(RuntimeException(t))
98
+ }
99
+
100
+ companion object {
101
+ const val TAG_NAME = "TrueSheet"
102
+ }
47
103
  }
@@ -0,0 +1,38 @@
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 header view size changes
9
+ */
10
+ interface TrueSheetHeaderViewDelegate {
11
+ fun headerViewDidChangeSize(width: Int, height: Int)
12
+ }
13
+
14
+ /**
15
+ * Header view that holds the header content
16
+ * Positioned at the top of the sheet content area
17
+ */
18
+ @SuppressLint("ViewConstructor")
19
+ class TrueSheetHeaderView(context: ThemedReactContext) : ReactViewGroup(context) {
20
+ var delegate: TrueSheetHeaderViewDelegate? = null
21
+
22
+ private var lastWidth = 0
23
+ private var lastHeight = 0
24
+
25
+ override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
26
+ super.onSizeChanged(w, h, oldw, oldh)
27
+
28
+ if (w != lastWidth || h != lastHeight) {
29
+ lastWidth = w
30
+ lastHeight = h
31
+ delegate?.headerViewDidChangeSize(w, h)
32
+ }
33
+ }
34
+
35
+ companion object {
36
+ const val TAG_NAME = "TrueSheet"
37
+ }
38
+ }
@@ -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 TrueSheetHeaderView
9
+ * Manages the header area of the sheet
10
+ */
11
+ @ReactModule(name = TrueSheetHeaderViewManager.REACT_CLASS)
12
+ class TrueSheetHeaderViewManager : ViewGroupManager<TrueSheetHeaderView>() {
13
+
14
+ override fun getName(): String = REACT_CLASS
15
+
16
+ override fun createViewInstance(reactContext: ThemedReactContext): TrueSheetHeaderView = TrueSheetHeaderView(reactContext)
17
+
18
+ companion object {
19
+ const val REACT_CLASS = "TrueSheetHeaderView"
20
+ }
21
+ }
@@ -39,6 +39,7 @@ class TrueSheetPackage : TurboReactPackage() {
39
39
  TrueSheetViewManager(),
40
40
  TrueSheetContainerViewManager(),
41
41
  TrueSheetContentViewManager(),
42
+ TrueSheetHeaderViewManager(),
42
43
  TrueSheetFooterViewManager()
43
44
  )
44
45
  }