react-native-keyboard-controller 1.21.4 → 1.21.5

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.
@@ -2,6 +2,7 @@ package com.reactnativekeyboardcontroller.extensions
2
2
 
3
3
  import android.view.View
4
4
  import android.view.ViewGroup
5
+ import android.view.WindowManager
5
6
  import com.facebook.react.bridge.ReactContext
6
7
  import com.facebook.react.uimanager.UIManagerHelper
7
8
  import com.facebook.react.uimanager.common.UIManagerType
@@ -28,3 +29,12 @@ val ReactContext.content: ViewGroup?
28
29
  this.currentActivity?.window?.decorView?.rootView?.findViewById(
29
30
  androidx.appcompat.R.id.action_bar_root,
30
31
  )
32
+
33
+ val ReactContext.windowSoftInputMode: Int
34
+ get() =
35
+ this
36
+ .currentActivity
37
+ ?.window
38
+ ?.attributes
39
+ ?.softInputMode
40
+ ?: WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED
@@ -4,9 +4,7 @@ import android.annotation.SuppressLint
4
4
  import android.graphics.Rect
5
5
  import android.os.Build
6
6
  import android.view.View
7
- import androidx.core.graphics.Insets
8
7
  import androidx.core.view.ViewCompat
9
- import androidx.core.view.WindowInsetsCompat
10
8
  import com.reactnativekeyboardcontroller.log.Logger
11
9
 
12
10
  /**
@@ -61,41 +59,3 @@ val View.screenLocation get(): IntArray {
61
59
 
62
60
  return point
63
61
  }
64
-
65
- /**
66
- * Safely replaces status bar insets so that when we edge-to-edge mode gets disabled/enabled
67
- * the app content is not jumping/resizing a window.
68
- * */
69
- @Suppress("DEPRECATION")
70
- fun View.replaceStatusBarInsets(
71
- insets: WindowInsetsCompat,
72
- isStatusBarTranslucent: Boolean,
73
- active: Boolean,
74
- ): WindowInsetsCompat {
75
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
76
- val sysBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
77
- val navBars = insets.getInsets(WindowInsetsCompat.Type.navigationBars())
78
- val ime = insets.getInsets(WindowInsetsCompat.Type.ime())
79
- val adjustedTop = if (isStatusBarTranslucent) 0 else sysBars.top
80
- // pick bottom: use IME if present, otherwise nav bar bottom (respect translucency)
81
- val bottomFromImeOrNav = if (ime.bottom > 0) ime.bottom else navBars.bottom
82
- val adjustedInsets =
83
- WindowInsetsCompat
84
- .Builder(insets)
85
- .setInsets(
86
- WindowInsetsCompat.Type.systemBars(),
87
- Insets.of(sysBars.left, adjustedTop, sysBars.right, if (active) sysBars.bottom else bottomFromImeOrNav),
88
- ).build()
89
-
90
- return ViewCompat.onApplyWindowInsets(this, adjustedInsets)
91
- } else {
92
- val defaultInsets = ViewCompat.onApplyWindowInsets(this, insets)
93
-
94
- return defaultInsets.replaceSystemWindowInsets(
95
- defaultInsets.systemWindowInsetLeft,
96
- if (isStatusBarTranslucent) 0 else defaultInsets.systemWindowInsetTop,
97
- defaultInsets.systemWindowInsetRight,
98
- defaultInsets.systemWindowInsetBottom,
99
- )
100
- }
101
- }
@@ -3,7 +3,6 @@ package com.reactnativekeyboardcontroller.modules
3
3
  import android.content.Context
4
4
  import android.os.Build
5
5
  import android.view.View
6
- import android.view.WindowManager
7
6
  import android.view.inputmethod.InputMethodManager
8
7
  import com.facebook.react.bridge.Arguments
9
8
  import com.facebook.react.bridge.Promise
@@ -12,6 +11,7 @@ import com.facebook.react.bridge.UiThreadUtil
12
11
  import com.reactnativekeyboardcontroller.extensions.dp
13
12
  import com.reactnativekeyboardcontroller.extensions.screenLocation
14
13
  import com.reactnativekeyboardcontroller.extensions.uiManager
14
+ import com.reactnativekeyboardcontroller.extensions.windowSoftInputMode
15
15
  import com.reactnativekeyboardcontroller.interactive.KeyboardAnimationController
16
16
  import com.reactnativekeyboardcontroller.traversal.FocusedInputHolder
17
17
  import com.reactnativekeyboardcontroller.traversal.ViewHierarchyNavigator
@@ -21,7 +21,7 @@ class KeyboardControllerModuleImpl(
21
21
  ) {
22
22
  private val uiManager = mReactContext.uiManager
23
23
  private val controller = KeyboardAnimationController()
24
- private val mDefaultMode: Int = getCurrentMode()
24
+ private val mDefaultMode: Int = mReactContext.windowSoftInputMode
25
25
 
26
26
  // region Module methods
27
27
  fun setInputMode(mode: Int) {
@@ -108,19 +108,11 @@ class KeyboardControllerModuleImpl(
108
108
  // region Helpers
109
109
  private fun setSoftInputMode(mode: Int) {
110
110
  UiThreadUtil.runOnUiThread {
111
- if (getCurrentMode() != mode) {
111
+ if (mReactContext.windowSoftInputMode != mode) {
112
112
  mReactContext.currentActivity?.window?.setSoftInputMode(mode)
113
113
  }
114
114
  }
115
115
  }
116
-
117
- private fun getCurrentMode(): Int =
118
- mReactContext
119
- .currentActivity
120
- ?.window
121
- ?.attributes
122
- ?.softInputMode
123
- ?: WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED
124
116
  // endregion
125
117
 
126
118
  // region Module constants
@@ -5,6 +5,7 @@ import android.content.res.Configuration
5
5
  import android.os.Handler
6
6
  import android.os.Looper
7
7
  import android.view.WindowManager
8
+ import android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
8
9
  import android.widget.FrameLayout
9
10
  import androidx.core.view.ViewCompat
10
11
  import androidx.core.view.WindowCompat
@@ -14,14 +15,15 @@ import com.facebook.react.uimanager.ThemedReactContext
14
15
  import com.facebook.react.views.view.ReactViewGroup
15
16
  import com.reactnativekeyboardcontroller.extensions.content
16
17
  import com.reactnativekeyboardcontroller.extensions.removeSelf
17
- import com.reactnativekeyboardcontroller.extensions.replaceStatusBarInsets
18
18
  import com.reactnativekeyboardcontroller.extensions.requestApplyInsetsWhenAttached
19
19
  import com.reactnativekeyboardcontroller.extensions.rootView
20
+ import com.reactnativekeyboardcontroller.extensions.windowSoftInputMode
20
21
  import com.reactnativekeyboardcontroller.listeners.KeyboardAnimationCallback
21
22
  import com.reactnativekeyboardcontroller.listeners.KeyboardAnimationCallbackConfig
22
23
  import com.reactnativekeyboardcontroller.log.Logger
23
24
  import com.reactnativekeyboardcontroller.modal.ModalAttachedWatcher
24
25
  import java.lang.ref.WeakReference
26
+ import kotlin.math.max
25
27
 
26
28
  private val TAG = EdgeToEdgeReactViewGroup::class.qualifiedName
27
29
 
@@ -44,7 +46,6 @@ class EdgeToEdgeReactViewGroup(
44
46
  private var isStatusBarTranslucent = false
45
47
  private var isNavigationBarTranslucent = false
46
48
  private var isPreservingEdgeToEdge = false
47
- private var isEdgeToEdge = false
48
49
  var active: Boolean = false
49
50
  set(value) {
50
51
  field = value
@@ -110,47 +111,43 @@ class EdgeToEdgeReactViewGroup(
110
111
  FrameLayout.LayoutParams.MATCH_PARENT,
111
112
  )
112
113
 
113
- val shouldApplyZeroPaddingTop = !active || this.isStatusBarTranslucent
114
- val shouldApplyZeroPaddingBottom = !active || this.isNavigationBarTranslucent
114
+ val shouldApplyBottomPadding =
115
+ !active && reactContext.windowSoftInputMode == SOFT_INPUT_ADJUST_RESIZE && !isPreservingEdgeToEdge
115
116
  val navBarInsets = insets.getInsets(WindowInsetsCompat.Type.navigationBars())
116
117
  val systemBarInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
118
+ val keyboardInsets =
119
+ if (!shouldApplyBottomPadding) 0 else insets.getInsets(WindowInsetsCompat.Type.ime()).bottom
117
120
 
118
121
  params.setMargins(
119
122
  navBarInsets.left,
120
- if (shouldApplyZeroPaddingTop) {
123
+ if (this.isStatusBarTranslucent) {
121
124
  0
122
125
  } else {
123
126
  systemBarInsets.top
124
127
  },
125
128
  navBarInsets.right,
126
- if (shouldApplyZeroPaddingBottom) {
127
- 0
129
+ if (this.isNavigationBarTranslucent) {
130
+ keyboardInsets
128
131
  } else {
129
- navBarInsets.bottom
132
+ max(navBarInsets.bottom, keyboardInsets)
130
133
  },
131
134
  )
132
135
  content?.layoutParams = params
133
136
 
134
- v.replaceStatusBarInsets(insets, this.isStatusBarTranslucent, active)
137
+ ViewCompat.onApplyWindowInsets(v, insets)
135
138
  }
136
139
  }
137
140
  }
138
141
 
139
142
  fun setEdgeToEdge() {
140
- val nextValue = active || isPreservingEdgeToEdge
141
-
142
- if (isEdgeToEdge != nextValue) {
143
- isEdgeToEdge = nextValue
144
-
145
- reactContext.currentActivity?.let {
146
- WindowCompat.setDecorFitsSystemWindows(
147
- it.window,
148
- !isEdgeToEdge,
149
- )
150
- }
151
- // unclear legacy flag if it was set earlier
152
- reactContext.currentActivity?.window?.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
143
+ reactContext.currentActivity?.let {
144
+ WindowCompat.setDecorFitsSystemWindows(
145
+ it.window,
146
+ false,
147
+ )
153
148
  }
149
+ // unclear legacy flag if it was set earlier
150
+ reactContext.currentActivity?.window?.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
154
151
  }
155
152
 
156
153
  private fun setupKeyboardCallbacks() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-keyboard-controller",
3
- "version": "1.21.4",
3
+ "version": "1.21.5",
4
4
  "description": "Keyboard manager which works in identical way on both iOS and Android",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",