react-native-keyboard-controller 1.5.1 → 1.5.3
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/android/build.gradle +1 -1
- package/android/gradle.properties +1 -0
- package/android/src/fabric/java/com/reactnativekeyboardcontroller/KeyboardControllerViewManager.kt +3 -2
- package/android/src/main/java/com/reactnativekeyboardcontroller/KeyboardAnimationCallback.kt +1 -1
- package/android/src/main/java/com/reactnativekeyboardcontroller/managers/KeyboardControllerViewManagerImpl.kt +6 -54
- package/android/src/main/java/com/reactnativekeyboardcontroller/views/EdgeToEdgeReactViewGroup.kt +66 -0
- package/android/src/paper/java/com/reactnativekeyboardcontroller/KeyboardControllerViewManager.kt +4 -4
- package/ios/KeyboardMovementObserver.swift +27 -4
- package/package.json +1 -1
package/android/build.gradle
CHANGED
|
@@ -42,7 +42,7 @@ if (isNewArchitectureEnabled()) {
|
|
|
42
42
|
android {
|
|
43
43
|
compileSdkVersion getExtOrIntegerDefault('compileSdkVersion')
|
|
44
44
|
defaultConfig {
|
|
45
|
-
minSdkVersion
|
|
45
|
+
minSdkVersion getExtOrIntegerDefault('minSdkVersion')
|
|
46
46
|
targetSdkVersion getExtOrIntegerDefault('targetSdkVersion')
|
|
47
47
|
versionCode 1
|
|
48
48
|
versionName "1.0"
|
package/android/src/fabric/java/com/reactnativekeyboardcontroller/KeyboardControllerViewManager.kt
CHANGED
|
@@ -9,6 +9,7 @@ import com.facebook.react.viewmanagers.KeyboardControllerViewManagerInterface
|
|
|
9
9
|
import com.facebook.react.views.view.ReactViewGroup
|
|
10
10
|
import com.facebook.react.views.view.ReactViewManager
|
|
11
11
|
import com.reactnativekeyboardcontroller.managers.KeyboardControllerViewManagerImpl
|
|
12
|
+
import com.reactnativekeyboardcontroller.views.EdgeToEdgeReactViewGroup
|
|
12
13
|
|
|
13
14
|
class KeyboardControllerViewManager(mReactContext: ReactApplicationContext) : ReactViewManager(), KeyboardControllerViewManagerInterface<ReactViewGroup> {
|
|
14
15
|
private val manager = KeyboardControllerViewManagerImpl(mReactContext)
|
|
@@ -26,12 +27,12 @@ class KeyboardControllerViewManager(mReactContext: ReactApplicationContext) : Re
|
|
|
26
27
|
|
|
27
28
|
@ReactProp(name = "statusBarTranslucent")
|
|
28
29
|
override fun setStatusBarTranslucent(view: ReactViewGroup, value: Boolean) {
|
|
29
|
-
return manager.setStatusBarTranslucent(view, value)
|
|
30
|
+
return manager.setStatusBarTranslucent(view as EdgeToEdgeReactViewGroup, value)
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
@ReactProp(name = "navigationBarTranslucent")
|
|
33
34
|
override fun setNavigationBarTranslucent(view: ReactViewGroup, value: Boolean) {
|
|
34
|
-
return manager.setNavigationBarTranslucent(view, value)
|
|
35
|
+
return manager.setNavigationBarTranslucent(view as EdgeToEdgeReactViewGroup, value)
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any> {
|
package/android/src/main/java/com/reactnativekeyboardcontroller/KeyboardAnimationCallback.kt
CHANGED
|
@@ -156,7 +156,7 @@ class KeyboardAnimationCallback(
|
|
|
156
156
|
// then we need to reset the state
|
|
157
157
|
InteractiveKeyboardProvider.shown = false
|
|
158
158
|
}
|
|
159
|
-
|
|
159
|
+
isKeyboardVisible = isKeyboardVisible || isKeyboardShown
|
|
160
160
|
|
|
161
161
|
this.emitEvent("KeyboardController::" + if (!isKeyboardVisible) "keyboardDidHide" else "keyboardDidShow", getEventParams(this.persistentKeyboardHeight))
|
|
162
162
|
this.sendEventToJS(KeyboardTransitionEvent(view.id, "topKeyboardMoveEnd", this.persistentKeyboardHeight, if (!isKeyboardVisible) 0.0 else 1.0))
|
|
@@ -1,69 +1,21 @@
|
|
|
1
1
|
package com.reactnativekeyboardcontroller.managers
|
|
2
2
|
|
|
3
|
-
import android.util.Log
|
|
4
|
-
import androidx.appcompat.widget.FitWindowsLinearLayout
|
|
5
|
-
import androidx.core.view.ViewCompat
|
|
6
|
-
import androidx.core.view.WindowInsetsAnimationCompat
|
|
7
|
-
import androidx.core.view.WindowInsetsCompat
|
|
8
3
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
9
4
|
import com.facebook.react.common.MapBuilder
|
|
10
5
|
import com.facebook.react.uimanager.ThemedReactContext
|
|
11
|
-
import com.facebook.react.views.view.ReactViewGroup
|
|
12
|
-
import com.reactnativekeyboardcontroller.KeyboardAnimationCallback
|
|
13
|
-
import com.reactnativekeyboardcontroller.R
|
|
14
|
-
import com.reactnativekeyboardcontroller.extensions.requestApplyInsetsWhenAttached
|
|
15
6
|
import com.reactnativekeyboardcontroller.views.EdgeToEdgeReactViewGroup
|
|
16
7
|
|
|
17
8
|
class KeyboardControllerViewManagerImpl(private val mReactContext: ReactApplicationContext) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
private var isNavigationBarTranslucent = false
|
|
21
|
-
|
|
22
|
-
fun createViewInstance(reactContext: ThemedReactContext): ReactViewGroup {
|
|
23
|
-
val view = EdgeToEdgeReactViewGroup(reactContext)
|
|
24
|
-
val activity = reactContext.currentActivity
|
|
25
|
-
|
|
26
|
-
if (activity == null) {
|
|
27
|
-
Log.w(TAG, "Can not setup keyboard animation listener, since `currentActivity` is null")
|
|
28
|
-
return view
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
val callback = KeyboardAnimationCallback(
|
|
32
|
-
view = view,
|
|
33
|
-
persistentInsetTypes = WindowInsetsCompat.Type.systemBars(),
|
|
34
|
-
deferredInsetTypes = WindowInsetsCompat.Type.ime(),
|
|
35
|
-
// We explicitly allow dispatch to continue down to binding.messageHolder's
|
|
36
|
-
// child views, so that step 2.5 below receives the call
|
|
37
|
-
dispatchMode = WindowInsetsAnimationCompat.Callback.DISPATCH_MODE_CONTINUE_ON_SUBTREE,
|
|
38
|
-
context = reactContext,
|
|
39
|
-
onApplyWindowInsetsListener = { v, insets ->
|
|
40
|
-
val content =
|
|
41
|
-
reactContext.currentActivity?.window?.decorView?.rootView?.findViewById<FitWindowsLinearLayout>(
|
|
42
|
-
R.id.action_bar_root,
|
|
43
|
-
)
|
|
44
|
-
content?.setPadding(
|
|
45
|
-
0,
|
|
46
|
-
if (this.isStatusBarTranslucent) 0 else insets?.getInsets(WindowInsetsCompat.Type.systemBars())?.top ?: 0,
|
|
47
|
-
0,
|
|
48
|
-
if (this.isNavigationBarTranslucent) 0 else insets?.getInsets(WindowInsetsCompat.Type.navigationBars())?.bottom ?: 0,
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
insets
|
|
52
|
-
},
|
|
53
|
-
)
|
|
54
|
-
ViewCompat.setWindowInsetsAnimationCallback(view, callback)
|
|
55
|
-
ViewCompat.setOnApplyWindowInsetsListener(view, callback)
|
|
56
|
-
view.requestApplyInsetsWhenAttached()
|
|
57
|
-
|
|
58
|
-
return view
|
|
9
|
+
fun createViewInstance(reactContext: ThemedReactContext): EdgeToEdgeReactViewGroup {
|
|
10
|
+
return EdgeToEdgeReactViewGroup(reactContext)
|
|
59
11
|
}
|
|
60
12
|
|
|
61
|
-
fun setStatusBarTranslucent(view:
|
|
62
|
-
|
|
13
|
+
fun setStatusBarTranslucent(view: EdgeToEdgeReactViewGroup, isStatusBarTranslucent: Boolean) {
|
|
14
|
+
view.setStatusBarTranslucent(isStatusBarTranslucent)
|
|
63
15
|
}
|
|
64
16
|
|
|
65
|
-
fun setNavigationBarTranslucent(view:
|
|
66
|
-
|
|
17
|
+
fun setNavigationBarTranslucent(view: EdgeToEdgeReactViewGroup, isNavigationBarTranslucent: Boolean) {
|
|
18
|
+
view.setNavigationBarTranslucent(isNavigationBarTranslucent)
|
|
67
19
|
}
|
|
68
20
|
|
|
69
21
|
fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any> {
|
package/android/src/main/java/com/reactnativekeyboardcontroller/views/EdgeToEdgeReactViewGroup.kt
CHANGED
|
@@ -1,12 +1,70 @@
|
|
|
1
1
|
package com.reactnativekeyboardcontroller.views
|
|
2
2
|
|
|
3
3
|
import android.annotation.SuppressLint
|
|
4
|
+
import android.util.Log
|
|
5
|
+
import androidx.appcompat.widget.FitWindowsLinearLayout
|
|
6
|
+
import androidx.core.view.ViewCompat
|
|
4
7
|
import androidx.core.view.WindowCompat
|
|
8
|
+
import androidx.core.view.WindowInsetsAnimationCompat
|
|
9
|
+
import androidx.core.view.WindowInsetsCompat
|
|
5
10
|
import com.facebook.react.uimanager.ThemedReactContext
|
|
6
11
|
import com.facebook.react.views.view.ReactViewGroup
|
|
12
|
+
import com.reactnativekeyboardcontroller.KeyboardAnimationCallback
|
|
13
|
+
import com.reactnativekeyboardcontroller.R
|
|
14
|
+
import com.reactnativekeyboardcontroller.extensions.requestApplyInsetsWhenAttached
|
|
7
15
|
|
|
8
16
|
@SuppressLint("ViewConstructor")
|
|
9
17
|
class EdgeToEdgeReactViewGroup(private val reactContext: ThemedReactContext) : ReactViewGroup(reactContext) {
|
|
18
|
+
private val TAG = EdgeToEdgeReactViewGroup::class.qualifiedName
|
|
19
|
+
private var isStatusBarTranslucent = false
|
|
20
|
+
private var isNavigationBarTranslucent = false
|
|
21
|
+
|
|
22
|
+
init {
|
|
23
|
+
val activity = reactContext.currentActivity
|
|
24
|
+
|
|
25
|
+
if (activity != null) {
|
|
26
|
+
|
|
27
|
+
val callback = KeyboardAnimationCallback(
|
|
28
|
+
view = this,
|
|
29
|
+
persistentInsetTypes = WindowInsetsCompat.Type.systemBars(),
|
|
30
|
+
deferredInsetTypes = WindowInsetsCompat.Type.ime(),
|
|
31
|
+
// We explicitly allow dispatch to continue down to binding.messageHolder's
|
|
32
|
+
// child views, so that step 2.5 below receives the call
|
|
33
|
+
dispatchMode = WindowInsetsAnimationCompat.Callback.DISPATCH_MODE_CONTINUE_ON_SUBTREE,
|
|
34
|
+
context = reactContext,
|
|
35
|
+
onApplyWindowInsetsListener = { v, insets ->
|
|
36
|
+
val content =
|
|
37
|
+
reactContext.currentActivity?.window?.decorView?.rootView?.findViewById<FitWindowsLinearLayout>(
|
|
38
|
+
R.id.action_bar_root,
|
|
39
|
+
)
|
|
40
|
+
content?.setPadding(
|
|
41
|
+
0,
|
|
42
|
+
if (this.isStatusBarTranslucent) {
|
|
43
|
+
0
|
|
44
|
+
} else {
|
|
45
|
+
insets?.getInsets(WindowInsetsCompat.Type.systemBars())?.top
|
|
46
|
+
?: 0
|
|
47
|
+
},
|
|
48
|
+
0,
|
|
49
|
+
if (this.isNavigationBarTranslucent) {
|
|
50
|
+
0
|
|
51
|
+
} else {
|
|
52
|
+
insets?.getInsets(WindowInsetsCompat.Type.navigationBars())?.bottom
|
|
53
|
+
?: 0
|
|
54
|
+
},
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
insets
|
|
58
|
+
},
|
|
59
|
+
)
|
|
60
|
+
ViewCompat.setWindowInsetsAnimationCallback(this, callback)
|
|
61
|
+
ViewCompat.setOnApplyWindowInsetsListener(this, callback)
|
|
62
|
+
this.requestApplyInsetsWhenAttached()
|
|
63
|
+
} else {
|
|
64
|
+
Log.w(TAG, "Can not setup keyboard animation listener, since `currentActivity` is null")
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
10
68
|
override fun onAttachedToWindow() {
|
|
11
69
|
super.onAttachedToWindow()
|
|
12
70
|
|
|
@@ -17,4 +75,12 @@ class EdgeToEdgeReactViewGroup(private val reactContext: ThemedReactContext) : R
|
|
|
17
75
|
)
|
|
18
76
|
}
|
|
19
77
|
}
|
|
78
|
+
|
|
79
|
+
fun setStatusBarTranslucent(isStatusBarTranslucent: Boolean) {
|
|
80
|
+
this.isStatusBarTranslucent = isStatusBarTranslucent
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
fun setNavigationBarTranslucent(isNavigationBarTranslucent: Boolean) {
|
|
84
|
+
this.isNavigationBarTranslucent = isNavigationBarTranslucent
|
|
85
|
+
}
|
|
20
86
|
}
|
package/android/src/paper/java/com/reactnativekeyboardcontroller/KeyboardControllerViewManager.kt
CHANGED
|
@@ -3,26 +3,26 @@ package com.reactnativekeyboardcontroller
|
|
|
3
3
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
4
4
|
import com.facebook.react.uimanager.ThemedReactContext
|
|
5
5
|
import com.facebook.react.uimanager.annotations.ReactProp
|
|
6
|
-
import com.facebook.react.views.view.ReactViewGroup
|
|
7
6
|
import com.facebook.react.views.view.ReactViewManager
|
|
8
7
|
import com.reactnativekeyboardcontroller.managers.KeyboardControllerViewManagerImpl
|
|
8
|
+
import com.reactnativekeyboardcontroller.views.EdgeToEdgeReactViewGroup
|
|
9
9
|
|
|
10
10
|
class KeyboardControllerViewManager(mReactContext: ReactApplicationContext) : ReactViewManager() {
|
|
11
11
|
private val manager = KeyboardControllerViewManagerImpl(mReactContext)
|
|
12
12
|
|
|
13
13
|
override fun getName(): String = KeyboardControllerViewManagerImpl.NAME
|
|
14
14
|
|
|
15
|
-
override fun createViewInstance(reactContext: ThemedReactContext):
|
|
15
|
+
override fun createViewInstance(reactContext: ThemedReactContext): EdgeToEdgeReactViewGroup {
|
|
16
16
|
return manager.createViewInstance(reactContext)
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
@ReactProp(name = "statusBarTranslucent")
|
|
20
|
-
fun setStatusBarTranslucent(view:
|
|
20
|
+
fun setStatusBarTranslucent(view: EdgeToEdgeReactViewGroup, isStatusBarTranslucent: Boolean) {
|
|
21
21
|
manager.setStatusBarTranslucent(view, isStatusBarTranslucent)
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
@ReactProp(name = "navigationBarTranslucent")
|
|
25
|
-
fun setNavigationBarTranslucent(view:
|
|
25
|
+
fun setNavigationBarTranslucent(view: EdgeToEdgeReactViewGroup, isNavigationBarTranslucent: Boolean) {
|
|
26
26
|
manager.setNavigationBarTranslucent(view, isNavigationBarTranslucent)
|
|
27
27
|
}
|
|
28
28
|
|
|
@@ -42,6 +42,7 @@ public class KeyboardMovementObserver: NSObject {
|
|
|
42
42
|
private var prevKeyboardPosition = 0.0
|
|
43
43
|
private var displayLink: CADisplayLink?
|
|
44
44
|
private var keyboardHeight: CGFloat = 0.0
|
|
45
|
+
private var hasKVObserver = false
|
|
45
46
|
|
|
46
47
|
@objc public init(
|
|
47
48
|
handler: @escaping (NSString, NSNumber, NSNumber) -> Void,
|
|
@@ -82,18 +83,40 @@ public class KeyboardMovementObserver: NSObject {
|
|
|
82
83
|
name: UIWindow.didBecomeVisibleNotification,
|
|
83
84
|
object: nil
|
|
84
85
|
)
|
|
86
|
+
NotificationCenter.default.addObserver(
|
|
87
|
+
self,
|
|
88
|
+
selector: #selector(windowDidBecomeHidden),
|
|
89
|
+
name: UIWindow.didBecomeHiddenNotification,
|
|
90
|
+
object: nil
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
@objc func windowDidBecomeHidden(_: Notification) {
|
|
95
|
+
removeKVObserver()
|
|
85
96
|
}
|
|
86
97
|
|
|
87
98
|
@objc func windowDidBecomeVisible(_: Notification) {
|
|
88
|
-
|
|
99
|
+
setupKVObserver()
|
|
100
|
+
}
|
|
89
101
|
|
|
90
|
-
|
|
102
|
+
private func setupKVObserver() {
|
|
103
|
+
if hasKVObserver {
|
|
91
104
|
return
|
|
92
105
|
}
|
|
93
106
|
|
|
94
|
-
|
|
107
|
+
if keyboardView != nil {
|
|
108
|
+
hasKVObserver = true
|
|
109
|
+
keyboardView?.addObserver(self, forKeyPath: "center", options: .new, context: nil)
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
private func removeKVObserver() {
|
|
114
|
+
if !hasKVObserver {
|
|
115
|
+
return
|
|
116
|
+
}
|
|
95
117
|
|
|
96
|
-
|
|
118
|
+
hasKVObserver = false
|
|
119
|
+
keyboardView?.removeObserver(self, forKeyPath: "center", context: nil)
|
|
97
120
|
}
|
|
98
121
|
|
|
99
122
|
// swiftlint:disable:next block_based_kvo
|
package/package.json
CHANGED