react-native-keyboard-controller 1.13.4 → 1.14.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 +1 -0
- package/android/src/fabric/java/com/reactnativekeyboardcontroller/KeyboardControllerModule.kt +5 -3
- package/android/src/fabric/java/com/reactnativekeyboardcontroller/KeyboardControllerViewManager.kt +19 -20
- package/android/src/fabric/java/com/reactnativekeyboardcontroller/KeyboardGestureAreaViewManager.kt +22 -12
- package/android/src/fabric/java/com/reactnativekeyboardcontroller/OverKeyboardViewManager.kt +40 -0
- package/android/src/fabric/java/com/reactnativekeyboardcontroller/StatusBarManagerCompatModule.kt +7 -3
- package/android/src/main/java/com/reactnativekeyboardcontroller/KeyboardControllerPackage.kt +33 -27
- package/android/src/main/java/com/reactnativekeyboardcontroller/events/FocusedInputLayoutChangedEvent.kt +16 -15
- package/android/src/main/java/com/reactnativekeyboardcontroller/events/FocusedInputSelectionChangedEvent.kt +25 -24
- package/android/src/main/java/com/reactnativekeyboardcontroller/events/FocusedInputTextChangedEvent.kt +4 -3
- package/android/src/main/java/com/reactnativekeyboardcontroller/events/KeyboardTransitionEvent.kt +7 -6
- package/android/src/main/java/com/reactnativekeyboardcontroller/extensions/Context.kt +38 -0
- package/android/src/main/java/com/reactnativekeyboardcontroller/extensions/EditText.kt +78 -58
- package/android/src/main/java/com/reactnativekeyboardcontroller/extensions/ReactContext.kt +9 -4
- package/android/src/main/java/com/reactnativekeyboardcontroller/extensions/ThemedReactContext.kt +10 -3
- package/android/src/main/java/com/reactnativekeyboardcontroller/extensions/View.kt +10 -8
- package/android/src/main/java/com/reactnativekeyboardcontroller/interactive/KeyboardAnimationController.kt +65 -60
- package/android/src/main/java/com/reactnativekeyboardcontroller/interactive/interpolators/Interpolator.kt +6 -1
- package/android/src/main/java/com/reactnativekeyboardcontroller/interactive/interpolators/IosInterpolator.kt +4 -2
- package/android/src/main/java/com/reactnativekeyboardcontroller/interactive/interpolators/LinearInterpolator.kt +1 -3
- package/android/src/main/java/com/reactnativekeyboardcontroller/listeners/FocusedInputObserver.kt +62 -58
- package/android/src/main/java/com/reactnativekeyboardcontroller/listeners/KeyboardAnimationCallback.kt +47 -41
- package/android/src/main/java/com/reactnativekeyboardcontroller/listeners/WindowDimensionListener.kt +13 -7
- package/android/src/main/java/com/reactnativekeyboardcontroller/log/Logger.kt +10 -2
- package/android/src/main/java/com/reactnativekeyboardcontroller/managers/KeyboardControllerViewManagerImpl.kt +35 -24
- package/android/src/main/java/com/reactnativekeyboardcontroller/managers/KeyboardGestureAreaViewManagerImpl.kt +21 -8
- package/android/src/main/java/com/reactnativekeyboardcontroller/managers/OverKeyboardViewManagerImpl.kt +27 -0
- package/android/src/main/java/com/reactnativekeyboardcontroller/modal/ModalAttachedWatcher.kt +14 -12
- package/android/src/main/java/com/reactnativekeyboardcontroller/modules/KeyboardControllerModuleImpl.kt +8 -8
- package/android/src/main/java/com/reactnativekeyboardcontroller/modules/StatusBarManagerCompatModuleImpl.kt +7 -2
- package/android/src/main/java/com/reactnativekeyboardcontroller/traversal/FocusedInputHolder.kt +1 -3
- package/android/src/main/java/com/reactnativekeyboardcontroller/traversal/ViewHierarchyNavigator.kt +19 -13
- package/android/src/main/java/com/reactnativekeyboardcontroller/ui/FrameScheduler.kt +11 -8
- package/android/src/main/java/com/reactnativekeyboardcontroller/views/EdgeToEdgeReactViewGroup.kt +22 -17
- package/android/src/main/java/com/reactnativekeyboardcontroller/views/KeyboardGestureAreaReactViewGroup.kt +23 -14
- package/android/src/main/java/com/reactnativekeyboardcontroller/views/overlay/OverKeyboardHostShadowNode.kt +30 -0
- package/android/src/main/java/com/reactnativekeyboardcontroller/views/overlay/OverKeyboardViewGroup.kt +185 -0
- package/android/src/paper/java/com/reactnativekeyboardcontroller/KeyboardControllerModule.kt +3 -1
- package/android/src/paper/java/com/reactnativekeyboardcontroller/KeyboardControllerViewManager.kt +19 -10
- package/android/src/paper/java/com/reactnativekeyboardcontroller/KeyboardGestureAreaViewManager.kt +21 -8
- package/android/src/paper/java/com/reactnativekeyboardcontroller/OverKeyboardViewManager.kt +33 -0
- package/android/src/paper/java/com/reactnativekeyboardcontroller/StatusBarManagerCompatModule.kt +7 -3
- package/android/src/test/java/com/reactnativekeyboardcontroller/traversal/ViewHierarchyNavigatorTest.kt +30 -21
- package/ios/KeyboardController-Bridging-Header.h +1 -0
- package/ios/extensions/UIResponder.swift +0 -3
- package/ios/extensions/UIWindow.swift +48 -0
- package/ios/views/OverKeyboardViewManager.h +29 -0
- package/ios/views/OverKeyboardViewManager.mm +220 -0
- package/jest/index.js +1 -0
- package/lib/commonjs/bindings.js +2 -1
- package/lib/commonjs/bindings.js.map +1 -1
- package/lib/commonjs/bindings.native.js +2 -1
- package/lib/commonjs/bindings.native.js.map +1 -1
- package/lib/commonjs/components/KeyboardAwareScrollView/index.js +2 -1
- package/lib/commonjs/components/KeyboardAwareScrollView/index.js.map +1 -1
- package/lib/commonjs/components/KeyboardToolbar/index.js +5 -3
- package/lib/commonjs/components/KeyboardToolbar/index.js.map +1 -1
- package/lib/commonjs/index.js +9 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/specs/OverKeyboardViewNativeComponent.js +10 -0
- package/lib/commonjs/specs/OverKeyboardViewNativeComponent.js.map +1 -0
- package/lib/commonjs/types.js.map +1 -1
- package/lib/commonjs/views/OverKeyboardView/index.js +43 -0
- package/lib/commonjs/views/OverKeyboardView/index.js.map +1 -0
- package/lib/commonjs/views/index.js +14 -0
- package/lib/commonjs/views/index.js.map +1 -0
- package/lib/module/bindings.js +1 -0
- package/lib/module/bindings.js.map +1 -1
- package/lib/module/bindings.native.js +1 -0
- package/lib/module/bindings.native.js.map +1 -1
- package/lib/module/components/KeyboardAwareScrollView/index.js +2 -1
- package/lib/module/components/KeyboardAwareScrollView/index.js.map +1 -1
- package/lib/module/components/KeyboardToolbar/index.js +5 -3
- package/lib/module/components/KeyboardToolbar/index.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/specs/OverKeyboardViewNativeComponent.js +3 -0
- package/lib/module/specs/OverKeyboardViewNativeComponent.js.map +1 -0
- package/lib/module/types.js.map +1 -1
- package/lib/module/views/OverKeyboardView/index.js +35 -0
- package/lib/module/views/OverKeyboardView/index.js.map +1 -0
- package/lib/module/views/index.js +2 -0
- package/lib/module/views/index.js.map +1 -0
- package/lib/typescript/bindings.d.ts +2 -1
- package/lib/typescript/bindings.native.d.ts +2 -1
- package/lib/typescript/components/KeyboardAwareScrollView/index.d.ts +4 -0
- package/lib/typescript/components/KeyboardToolbar/index.d.ts +2 -2
- package/lib/typescript/index.d.ts +1 -0
- package/lib/typescript/specs/OverKeyboardViewNativeComponent.d.ts +7 -0
- package/lib/typescript/types.d.ts +4 -1
- package/lib/typescript/views/OverKeyboardView/index.d.ts +5 -0
- package/lib/typescript/views/index.d.ts +1 -0
- package/package.json +8 -3
- package/src/bindings.native.ts +3 -0
- package/src/bindings.ts +3 -0
- package/src/components/KeyboardAwareScrollView/index.tsx +5 -2
- package/src/components/KeyboardToolbar/index.tsx +7 -3
- package/src/index.ts +1 -0
- package/src/specs/OverKeyboardViewNativeComponent.ts +12 -0
- package/src/types.ts +4 -0
- package/src/views/OverKeyboardView/index.tsx +43 -0
- package/src/views/index.ts +1 -0
- package/ios/.clang-format +0 -90
- package/ios/.swiftformat +0 -5
- package/ios/.swiftlint.yml +0 -14
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
package com.reactnativekeyboardcontroller.views.overlay
|
|
2
|
+
|
|
3
|
+
import android.annotation.SuppressLint
|
|
4
|
+
import android.content.Context
|
|
5
|
+
import android.graphics.PixelFormat
|
|
6
|
+
import android.view.MotionEvent
|
|
7
|
+
import android.view.View
|
|
8
|
+
import android.view.WindowManager
|
|
9
|
+
import com.facebook.react.bridge.UiThreadUtil
|
|
10
|
+
import com.facebook.react.config.ReactFeatureFlags
|
|
11
|
+
import com.facebook.react.uimanager.JSPointerDispatcher
|
|
12
|
+
import com.facebook.react.uimanager.JSTouchDispatcher
|
|
13
|
+
import com.facebook.react.uimanager.RootView
|
|
14
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
15
|
+
import com.facebook.react.uimanager.UIManagerHelper
|
|
16
|
+
import com.facebook.react.uimanager.events.EventDispatcher
|
|
17
|
+
import com.facebook.react.views.view.ReactViewGroup
|
|
18
|
+
|
|
19
|
+
@SuppressLint("ViewConstructor")
|
|
20
|
+
class OverKeyboardHostView(
|
|
21
|
+
private val reactContext: ThemedReactContext,
|
|
22
|
+
) : ReactViewGroup(reactContext) {
|
|
23
|
+
private val dispatcher = UIManagerHelper.getEventDispatcherForReactTag(reactContext, this.id)
|
|
24
|
+
private var windowManager: WindowManager = reactContext.getSystemService(Context.WINDOW_SERVICE) as WindowManager
|
|
25
|
+
private var hostView: OverKeyboardRootViewGroup = OverKeyboardRootViewGroup(reactContext)
|
|
26
|
+
|
|
27
|
+
init {
|
|
28
|
+
hostView.eventDispatcher = dispatcher
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// region life cycles
|
|
32
|
+
override fun onDetachedFromWindow() {
|
|
33
|
+
super.onDetachedFromWindow()
|
|
34
|
+
|
|
35
|
+
hide()
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
override fun addView(
|
|
39
|
+
child: View?,
|
|
40
|
+
index: Int,
|
|
41
|
+
) {
|
|
42
|
+
UiThreadUtil.assertOnUiThread()
|
|
43
|
+
hostView.addView(child, index)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
override fun getChildCount(): Int = hostView.childCount
|
|
47
|
+
|
|
48
|
+
override fun getChildAt(index: Int): View? = hostView.getChildAt(index)
|
|
49
|
+
|
|
50
|
+
override fun removeView(child: View?) {
|
|
51
|
+
UiThreadUtil.assertOnUiThread()
|
|
52
|
+
|
|
53
|
+
if (child != null) {
|
|
54
|
+
hostView.removeView(child)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
override fun removeViewAt(index: Int) {
|
|
59
|
+
UiThreadUtil.assertOnUiThread()
|
|
60
|
+
val child = getChildAt(index)
|
|
61
|
+
hostView.removeView(child)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
override fun onLayout(
|
|
65
|
+
changed: Boolean,
|
|
66
|
+
l: Int,
|
|
67
|
+
t: Int,
|
|
68
|
+
r: Int,
|
|
69
|
+
b: Int,
|
|
70
|
+
) {
|
|
71
|
+
// Do nothing as we are laid out by UIManager
|
|
72
|
+
}
|
|
73
|
+
// endregion
|
|
74
|
+
|
|
75
|
+
fun show() {
|
|
76
|
+
val layoutParams =
|
|
77
|
+
WindowManager.LayoutParams(
|
|
78
|
+
WindowManager.LayoutParams.MATCH_PARENT,
|
|
79
|
+
WindowManager.LayoutParams.MATCH_PARENT,
|
|
80
|
+
// This type ensures it floats over other application windows but under system windows
|
|
81
|
+
WindowManager.LayoutParams.TYPE_APPLICATION_PANEL,
|
|
82
|
+
// Ensures touches outside the view pass through to other windows
|
|
83
|
+
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
|
|
84
|
+
PixelFormat.TRANSLUCENT,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
windowManager.addView(hostView, layoutParams)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
fun hide() {
|
|
91
|
+
if (hostView.isAttached) {
|
|
92
|
+
windowManager.removeView(hostView)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
@SuppressLint("ViewConstructor")
|
|
98
|
+
class OverKeyboardRootViewGroup(
|
|
99
|
+
private val reactContext: ThemedReactContext,
|
|
100
|
+
) : ReactViewGroup(reactContext),
|
|
101
|
+
RootView {
|
|
102
|
+
private val jsTouchDispatcher: JSTouchDispatcher = JSTouchDispatcher(this)
|
|
103
|
+
private var jsPointerDispatcher: JSPointerDispatcher? = null
|
|
104
|
+
internal var eventDispatcher: EventDispatcher? = null
|
|
105
|
+
internal var isAttached = false
|
|
106
|
+
|
|
107
|
+
init {
|
|
108
|
+
if (ReactFeatureFlags.dispatchPointerEvents) {
|
|
109
|
+
jsPointerDispatcher = JSPointerDispatcher(this)
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// region life cycles
|
|
114
|
+
override fun onAttachedToWindow() {
|
|
115
|
+
super.onAttachedToWindow()
|
|
116
|
+
isAttached = true
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
override fun onDetachedFromWindow() {
|
|
120
|
+
super.onDetachedFromWindow()
|
|
121
|
+
isAttached = false
|
|
122
|
+
}
|
|
123
|
+
// endregion
|
|
124
|
+
|
|
125
|
+
// region Touch events handling
|
|
126
|
+
override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
|
|
127
|
+
eventDispatcher?.let { eventDispatcher ->
|
|
128
|
+
jsTouchDispatcher.handleTouchEvent(event, eventDispatcher)
|
|
129
|
+
jsPointerDispatcher?.handleMotionEvent(event, eventDispatcher, true)
|
|
130
|
+
}
|
|
131
|
+
return super.onInterceptTouchEvent(event)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
@SuppressLint("ClickableViewAccessibility")
|
|
135
|
+
override fun onTouchEvent(event: MotionEvent): Boolean {
|
|
136
|
+
eventDispatcher?.let { eventDispatcher ->
|
|
137
|
+
jsTouchDispatcher.handleTouchEvent(event, eventDispatcher)
|
|
138
|
+
jsPointerDispatcher?.handleMotionEvent(event, eventDispatcher, false)
|
|
139
|
+
}
|
|
140
|
+
super.onTouchEvent(event)
|
|
141
|
+
// In case when there is no children interested in handling touch event, we return true from
|
|
142
|
+
// the root view in order to receive subsequent events related to that gesture
|
|
143
|
+
return true
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
override fun onInterceptHoverEvent(event: MotionEvent): Boolean {
|
|
147
|
+
eventDispatcher?.let { jsPointerDispatcher?.handleMotionEvent(event, it, true) }
|
|
148
|
+
return super.onHoverEvent(event)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
override fun onHoverEvent(event: MotionEvent): Boolean {
|
|
152
|
+
eventDispatcher?.let { jsPointerDispatcher?.handleMotionEvent(event, it, false) }
|
|
153
|
+
return super.onHoverEvent(event)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
override fun requestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {
|
|
157
|
+
// No-op - override in order to still receive events to onInterceptTouchEvent
|
|
158
|
+
// even when some other view disallow that
|
|
159
|
+
}
|
|
160
|
+
// endregion
|
|
161
|
+
|
|
162
|
+
// region RootView methods
|
|
163
|
+
override fun onChildStartedNativeGesture(
|
|
164
|
+
childView: View,
|
|
165
|
+
ev: MotionEvent,
|
|
166
|
+
) {
|
|
167
|
+
eventDispatcher?.let { eventDispatcher ->
|
|
168
|
+
jsTouchDispatcher.onChildStartedNativeGesture(ev, eventDispatcher)
|
|
169
|
+
jsPointerDispatcher?.onChildStartedNativeGesture(childView, ev, eventDispatcher)
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
override fun onChildEndedNativeGesture(
|
|
174
|
+
childView: View,
|
|
175
|
+
ev: MotionEvent,
|
|
176
|
+
) {
|
|
177
|
+
eventDispatcher?.let { jsTouchDispatcher.onChildEndedNativeGesture(ev, it) }
|
|
178
|
+
jsPointerDispatcher?.onChildEndedNativeGesture()
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
override fun handleException(t: Throwable) {
|
|
182
|
+
reactContext.reactApplicationContext.handleException(RuntimeException(t))
|
|
183
|
+
}
|
|
184
|
+
// endregion
|
|
185
|
+
}
|
package/android/src/paper/java/com/reactnativekeyboardcontroller/KeyboardControllerModule.kt
CHANGED
|
@@ -5,7 +5,9 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule
|
|
|
5
5
|
import com.facebook.react.bridge.ReactMethod
|
|
6
6
|
import com.reactnativekeyboardcontroller.modules.KeyboardControllerModuleImpl
|
|
7
7
|
|
|
8
|
-
class KeyboardControllerModule(
|
|
8
|
+
class KeyboardControllerModule(
|
|
9
|
+
mReactContext: ReactApplicationContext,
|
|
10
|
+
) : ReactContextBaseJavaModule(mReactContext) {
|
|
9
11
|
private val module = KeyboardControllerModuleImpl(mReactContext)
|
|
10
12
|
|
|
11
13
|
override fun getName(): String = KeyboardControllerModuleImpl.NAME
|
package/android/src/paper/java/com/reactnativekeyboardcontroller/KeyboardControllerViewManager.kt
CHANGED
|
@@ -7,31 +7,40 @@ import com.facebook.react.views.view.ReactViewManager
|
|
|
7
7
|
import com.reactnativekeyboardcontroller.managers.KeyboardControllerViewManagerImpl
|
|
8
8
|
import com.reactnativekeyboardcontroller.views.EdgeToEdgeReactViewGroup
|
|
9
9
|
|
|
10
|
-
class KeyboardControllerViewManager(
|
|
10
|
+
class KeyboardControllerViewManager(
|
|
11
|
+
mReactContext: ReactApplicationContext,
|
|
12
|
+
) : ReactViewManager() {
|
|
11
13
|
private val manager = KeyboardControllerViewManagerImpl(mReactContext)
|
|
12
14
|
|
|
13
15
|
override fun getName(): String = KeyboardControllerViewManagerImpl.NAME
|
|
14
16
|
|
|
15
|
-
override fun createViewInstance(reactContext: ThemedReactContext): EdgeToEdgeReactViewGroup
|
|
16
|
-
|
|
17
|
-
}
|
|
17
|
+
override fun createViewInstance(reactContext: ThemedReactContext): EdgeToEdgeReactViewGroup =
|
|
18
|
+
manager.createViewInstance(reactContext)
|
|
18
19
|
|
|
19
20
|
@ReactProp(name = "enabled")
|
|
20
|
-
fun setEnabled(
|
|
21
|
+
fun setEnabled(
|
|
22
|
+
view: EdgeToEdgeReactViewGroup,
|
|
23
|
+
enabled: Boolean,
|
|
24
|
+
) {
|
|
21
25
|
manager.setEnabled(view, enabled)
|
|
22
26
|
}
|
|
23
27
|
|
|
24
28
|
@ReactProp(name = "statusBarTranslucent")
|
|
25
|
-
fun setStatusBarTranslucent(
|
|
29
|
+
fun setStatusBarTranslucent(
|
|
30
|
+
view: EdgeToEdgeReactViewGroup,
|
|
31
|
+
isStatusBarTranslucent: Boolean,
|
|
32
|
+
) {
|
|
26
33
|
manager.setStatusBarTranslucent(view, isStatusBarTranslucent)
|
|
27
34
|
}
|
|
28
35
|
|
|
29
36
|
@ReactProp(name = "navigationBarTranslucent")
|
|
30
|
-
fun setNavigationBarTranslucent(
|
|
37
|
+
fun setNavigationBarTranslucent(
|
|
38
|
+
view: EdgeToEdgeReactViewGroup,
|
|
39
|
+
isNavigationBarTranslucent: Boolean,
|
|
40
|
+
) {
|
|
31
41
|
manager.setNavigationBarTranslucent(view, isNavigationBarTranslucent)
|
|
32
42
|
}
|
|
33
43
|
|
|
34
|
-
override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any>
|
|
35
|
-
|
|
36
|
-
}
|
|
44
|
+
override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any> =
|
|
45
|
+
manager.getExportedCustomDirectEventTypeConstants()
|
|
37
46
|
}
|
package/android/src/paper/java/com/reactnativekeyboardcontroller/KeyboardGestureAreaViewManager.kt
CHANGED
|
@@ -7,32 +7,45 @@ import com.facebook.react.views.view.ReactViewManager
|
|
|
7
7
|
import com.reactnativekeyboardcontroller.managers.KeyboardGestureAreaViewManagerImpl
|
|
8
8
|
import com.reactnativekeyboardcontroller.views.KeyboardGestureAreaReactViewGroup
|
|
9
9
|
|
|
10
|
-
class KeyboardGestureAreaViewManager(
|
|
10
|
+
class KeyboardGestureAreaViewManager(
|
|
11
|
+
mReactContext: ReactApplicationContext,
|
|
12
|
+
) : ReactViewManager() {
|
|
11
13
|
private val manager = KeyboardGestureAreaViewManagerImpl(mReactContext)
|
|
12
14
|
|
|
13
15
|
override fun getName(): String = KeyboardGestureAreaViewManagerImpl.NAME
|
|
14
16
|
|
|
15
|
-
override fun createViewInstance(reactContext: ThemedReactContext): KeyboardGestureAreaReactViewGroup
|
|
16
|
-
|
|
17
|
-
}
|
|
17
|
+
override fun createViewInstance(reactContext: ThemedReactContext): KeyboardGestureAreaReactViewGroup =
|
|
18
|
+
manager.createViewInstance(reactContext)
|
|
18
19
|
|
|
19
20
|
@ReactProp(name = "offset")
|
|
20
|
-
fun setInterpolator(
|
|
21
|
+
fun setInterpolator(
|
|
22
|
+
view: KeyboardGestureAreaReactViewGroup,
|
|
23
|
+
offset: Double,
|
|
24
|
+
) {
|
|
21
25
|
manager.setOffset(view, offset)
|
|
22
26
|
}
|
|
23
27
|
|
|
24
28
|
@ReactProp(name = "interpolator")
|
|
25
|
-
fun setInterpolator(
|
|
29
|
+
fun setInterpolator(
|
|
30
|
+
view: KeyboardGestureAreaReactViewGroup,
|
|
31
|
+
interpolator: String,
|
|
32
|
+
) {
|
|
26
33
|
manager.setInterpolator(view, interpolator)
|
|
27
34
|
}
|
|
28
35
|
|
|
29
36
|
@ReactProp(name = "showOnSwipeUp")
|
|
30
|
-
fun setScrollKeyboardOnScreenWhenNotVisible(
|
|
37
|
+
fun setScrollKeyboardOnScreenWhenNotVisible(
|
|
38
|
+
view: KeyboardGestureAreaReactViewGroup,
|
|
39
|
+
value: Boolean,
|
|
40
|
+
) {
|
|
31
41
|
manager.setScrollKeyboardOnScreenWhenNotVisible(view, value)
|
|
32
42
|
}
|
|
33
43
|
|
|
34
44
|
@ReactProp(name = "enableSwipeToDismiss")
|
|
35
|
-
fun setScrollKeyboardOffScreenWhenVisible(
|
|
45
|
+
fun setScrollKeyboardOffScreenWhenVisible(
|
|
46
|
+
view: KeyboardGestureAreaReactViewGroup,
|
|
47
|
+
value: Boolean,
|
|
48
|
+
) {
|
|
36
49
|
manager.setScrollKeyboardOffScreenWhenVisible(view, value)
|
|
37
50
|
}
|
|
38
51
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
package com.reactnativekeyboardcontroller
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
4
|
+
import com.facebook.react.uimanager.LayoutShadowNode
|
|
5
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
6
|
+
import com.facebook.react.uimanager.ViewGroupManager
|
|
7
|
+
import com.facebook.react.uimanager.annotations.ReactProp
|
|
8
|
+
import com.reactnativekeyboardcontroller.managers.OverKeyboardViewManagerImpl
|
|
9
|
+
import com.reactnativekeyboardcontroller.views.overlay.OverKeyboardHostShadowNode
|
|
10
|
+
import com.reactnativekeyboardcontroller.views.overlay.OverKeyboardHostView
|
|
11
|
+
|
|
12
|
+
class OverKeyboardViewManager(
|
|
13
|
+
mReactContext: ReactApplicationContext,
|
|
14
|
+
) : ViewGroupManager<OverKeyboardHostView>() {
|
|
15
|
+
private val manager = OverKeyboardViewManagerImpl(mReactContext)
|
|
16
|
+
|
|
17
|
+
override fun getName(): String = OverKeyboardViewManagerImpl.NAME
|
|
18
|
+
|
|
19
|
+
override fun createViewInstance(reactContext: ThemedReactContext): OverKeyboardHostView =
|
|
20
|
+
manager.createViewInstance(reactContext)
|
|
21
|
+
|
|
22
|
+
override fun createShadowNodeInstance(): LayoutShadowNode = OverKeyboardHostShadowNode()
|
|
23
|
+
|
|
24
|
+
override fun getShadowNodeClass(): Class<out LayoutShadowNode> = OverKeyboardHostShadowNode::class.java
|
|
25
|
+
|
|
26
|
+
@ReactProp(name = "visible")
|
|
27
|
+
fun setVisible(
|
|
28
|
+
view: OverKeyboardHostView,
|
|
29
|
+
value: Boolean,
|
|
30
|
+
) {
|
|
31
|
+
manager.setVisible(view, value)
|
|
32
|
+
}
|
|
33
|
+
}
|
package/android/src/paper/java/com/reactnativekeyboardcontroller/StatusBarManagerCompatModule.kt
CHANGED
|
@@ -7,8 +7,9 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule
|
|
|
7
7
|
import com.facebook.react.bridge.ReactMethod
|
|
8
8
|
import com.reactnativekeyboardcontroller.modules.StatusBarManagerCompatModuleImpl
|
|
9
9
|
|
|
10
|
-
class StatusBarManagerCompatModule(
|
|
11
|
-
|
|
10
|
+
class StatusBarManagerCompatModule(
|
|
11
|
+
mReactContext: ReactApplicationContext,
|
|
12
|
+
) : ReactContextBaseJavaModule(mReactContext) {
|
|
12
13
|
private val module = StatusBarManagerCompatModuleImpl(mReactContext)
|
|
13
14
|
|
|
14
15
|
override fun getName(): String = StatusBarManagerCompatModuleImpl.NAME
|
|
@@ -20,7 +21,10 @@ class StatusBarManagerCompatModule(mReactContext: ReactApplicationContext) :
|
|
|
20
21
|
|
|
21
22
|
@ReactMethod
|
|
22
23
|
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
|
23
|
-
private fun setColor(
|
|
24
|
+
private fun setColor(
|
|
25
|
+
color: Int,
|
|
26
|
+
animated: Boolean,
|
|
27
|
+
) {
|
|
24
28
|
module.setColor(color, animated)
|
|
25
29
|
}
|
|
26
30
|
|
|
@@ -36,8 +36,16 @@ class ViewHierarchyNavigatorTest {
|
|
|
36
36
|
|
|
37
37
|
editText1 = EditText(context).apply { id = 1 }
|
|
38
38
|
editText2 = EditText(context).apply { id = 2 }
|
|
39
|
-
editText3 =
|
|
40
|
-
|
|
39
|
+
editText3 =
|
|
40
|
+
EditText(context).apply {
|
|
41
|
+
id = 3
|
|
42
|
+
isEnabled = false
|
|
43
|
+
}
|
|
44
|
+
editText4 =
|
|
45
|
+
EditText(context).apply {
|
|
46
|
+
id = 4
|
|
47
|
+
isEnabled = false
|
|
48
|
+
}
|
|
41
49
|
editText5 = EditText(context).apply { id = 5 }
|
|
42
50
|
editText6 = EditText(context).apply { id = 6 }
|
|
43
51
|
editText7 = EditText(context).apply { id = 7 }
|
|
@@ -48,25 +56,26 @@ class ViewHierarchyNavigatorTest {
|
|
|
48
56
|
editText12 = EditText(context).apply { id = 12 }
|
|
49
57
|
editText13 = EditText(context).apply { id = 13 }
|
|
50
58
|
|
|
51
|
-
layout =
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
59
|
+
layout =
|
|
60
|
+
LinearLayout(context).apply {
|
|
61
|
+
addView(editText1)
|
|
62
|
+
addView(editText2)
|
|
63
|
+
addView(editText3)
|
|
64
|
+
addView(editText4)
|
|
65
|
+
addView(
|
|
66
|
+
LinearLayout(context).apply {
|
|
67
|
+
addView(editText5)
|
|
68
|
+
addView(editText6)
|
|
69
|
+
addView(editText7)
|
|
70
|
+
},
|
|
71
|
+
)
|
|
72
|
+
addView(editText8)
|
|
73
|
+
addView(editText9)
|
|
74
|
+
addView(editText10)
|
|
75
|
+
addView(editText11)
|
|
76
|
+
addView(editText12)
|
|
77
|
+
addView(editText13)
|
|
78
|
+
}
|
|
70
79
|
}
|
|
71
80
|
|
|
72
81
|
@Test
|
|
@@ -56,10 +56,7 @@ public extension Optional where Wrapped: UIResponder {
|
|
|
56
56
|
!(currentView is UITextView),
|
|
57
57
|
scrollView.frame.width >= scrollView.contentSize.width,
|
|
58
58
|
scrollView.isScrollEnabled
|
|
59
|
-
// it was fixed in swiftlint https://github.com/realm/SwiftLint/issues/3756 but a new release is not available yet
|
|
60
|
-
// swiftlint:disable all
|
|
61
59
|
{
|
|
62
|
-
// swiftlint:enable all
|
|
63
60
|
return scrollView.reactViewTag
|
|
64
61
|
}
|
|
65
62
|
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
//
|
|
2
|
+
// UIWindow.swift
|
|
3
|
+
// react-native-keyboard-controller
|
|
4
|
+
//
|
|
5
|
+
// Created by Kiryl Ziusko on 12/09/2024.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
import ObjectiveC
|
|
10
|
+
import UIKit
|
|
11
|
+
|
|
12
|
+
@objc
|
|
13
|
+
public extension UIWindow {
|
|
14
|
+
static let sharedKeyboardWindowObserver = KeyboardWindowObserver()
|
|
15
|
+
|
|
16
|
+
class KeyboardWindowObserver: NSObject {
|
|
17
|
+
private weak var keyboardWindow: UIWindow?
|
|
18
|
+
|
|
19
|
+
override init() {
|
|
20
|
+
super.init()
|
|
21
|
+
NotificationCenter.default.addObserver(
|
|
22
|
+
self,
|
|
23
|
+
selector: #selector(windowDidBecomeVisible(_:)),
|
|
24
|
+
name: UIWindow.didBecomeVisibleNotification,
|
|
25
|
+
object: nil
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@objc private func windowDidBecomeVisible(_ notification: Notification) {
|
|
30
|
+
guard let window = notification.object as? UIWindow else { return }
|
|
31
|
+
|
|
32
|
+
// Check if the window is of UIRemoteKeyboardWindow class
|
|
33
|
+
let type = String(describing: window)
|
|
34
|
+
if type.range(of: "UIRemoteKeyboardWindow") != nil {
|
|
35
|
+
keyboardWindow = window
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
func getTopWindow() -> UIWindow? {
|
|
40
|
+
// Return the keyboard window if it's available, otherwise return the last window
|
|
41
|
+
return keyboardWindow ?? UIApplication.shared.windows.last
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
static var topWindow: UIWindow? {
|
|
46
|
+
return sharedKeyboardWindowObserver.getTopWindow()
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//
|
|
2
|
+
// OverKeyboardViewManager.h
|
|
3
|
+
// KeyboardController
|
|
4
|
+
//
|
|
5
|
+
// Created by Kiryl Ziusko on 17.09.24.
|
|
6
|
+
// Copyright © 2024 Facebook. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
9
|
+
#import <React/RCTViewComponentView.h>
|
|
10
|
+
#else
|
|
11
|
+
#import <React/RCTBridge.h>
|
|
12
|
+
#endif
|
|
13
|
+
#import <React/RCTViewManager.h>
|
|
14
|
+
#import <UIKit/UIKit.h>
|
|
15
|
+
|
|
16
|
+
@interface OverKeyboardViewManager : RCTViewManager
|
|
17
|
+
@end
|
|
18
|
+
|
|
19
|
+
@interface OverKeyboardView :
|
|
20
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
21
|
+
RCTViewComponentView
|
|
22
|
+
#else
|
|
23
|
+
UIView
|
|
24
|
+
|
|
25
|
+
- (instancetype)initWithBridge:(RCTBridge *)bridge;
|
|
26
|
+
|
|
27
|
+
#endif
|
|
28
|
+
@property (nonatomic, assign) BOOL visible;
|
|
29
|
+
@end
|