@momo-kits/calculator-keyboard 0.150.2-beta.21 → 0.150.2-beta.22

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 CHANGED
@@ -10,57 +10,15 @@ npm install react-native-calculator-keyboard
10
10
 
11
11
  ## Usage
12
12
 
13
+
13
14
  ```js
14
- import InputCalculator from '@momo-kits/calculator-keyboard';
15
+ import { CalculatorKeyboardView } from "react-native-calculator-keyboard";
15
16
 
16
17
  // ...
17
18
 
18
- <InputCalculator
19
- mode="NumDefault"
20
- customKeyText="Next"
21
- onCustomKeyEvent={() => console.log('Custom key pressed')}
22
- />;
23
- ```
24
-
25
- ## Requirements
26
-
27
- **React Native 0.80+** with **Fabric (New Architecture) enabled**.
28
-
29
- This library is **pure Fabric** implementation with:
30
-
31
- - ✅ Zero RCTBridge dependencies
32
- - ✅ Native C++ ComponentView on iOS
33
- - ✅ Fabric ViewManager with codegen delegates on Android
34
- - ✅ All Props, Events, Commands auto-generated by codegen
35
- - ❌ No Paper (old architecture) support
36
-
37
- ### Android Setup
38
-
39
- Add to your `gradle.properties`:
40
-
41
- ```properties
42
- newArchEnabled=true
43
- ```
44
-
45
- Then rebuild:
46
-
47
- ```bash
48
- cd android && ./gradlew clean && cd ..
49
- npx react-native run-android
50
- ```
51
-
52
- ### iOS Setup
53
-
54
- **Required**: Set the environment variable before installing pods:
55
-
56
- ```bash
57
- cd ios
58
- RCT_NEW_ARCH_ENABLED=1 pod install
59
- cd ..
60
- npx react-native run-ios
19
+ <CalculatorKeyboardView color="tomato" />
61
20
  ```
62
21
 
63
- **Note**: This library uses Fabric ComponentView (`.mm` files) and will not work without `RCT_NEW_ARCH_ENABLED=1`.
64
22
 
65
23
  ## Contributing
66
24
 
@@ -12,6 +12,6 @@ class CalculatorKeyboardPackage : ReactPackage {
12
12
  }
13
13
 
14
14
  override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
15
- return listOf(InputCalculatorViewManager())
15
+ return listOf(RCTInputCalculator())
16
16
  }
17
17
  }
@@ -1,21 +1,19 @@
1
1
  package com.calculatorkeyboard
2
2
 
3
3
  import android.annotation.SuppressLint
4
- import android.content.Context
5
4
  import android.content.res.ColorStateList
6
5
  import android.graphics.Color
7
6
  import android.graphics.drawable.GradientDrawable
8
7
  import android.view.Gravity
9
8
  import android.widget.Button
10
9
  import android.widget.ImageButton
10
+ import androidx.appcompat.app.AppCompatActivity
11
11
  import androidx.constraintlayout.widget.ConstraintLayout
12
12
  import com.facebook.react.uimanager.ThemedReactContext
13
13
  import org.mariuszgromada.math.mxparser.Expression
14
14
  import androidx.core.graphics.toColorInt
15
- import com.calculatorkeyboard.InputCalculatorViewManager.Companion.calculatorHeight
15
+ import com.calculatorkeyboard.RCTInputCalculator.Companion.calculatorHeight
16
16
  import com.facebook.react.bridge.Arguments
17
- import com.facebook.react.bridge.ReactContext
18
- import com.facebook.react.uimanager.UIManagerHelper
19
17
  import com.facebook.react.uimanager.events.RCTEventEmitter
20
18
 
21
19
  @SuppressLint("SetTextI18n", "ViewConstructor")
@@ -23,57 +21,53 @@ class CustomKeyboardView(
23
21
  context: ThemedReactContext,
24
22
  private val editText: CalculatorEditText
25
23
  ) : ConstraintLayout(context) {
26
- private val numWithCTAKeys = listOf(
24
+ private val keys = listOf(
27
25
  listOf("1", "2", "3", "÷", "back"),
28
26
  listOf("4", "5", "6", "×", "="),
29
- listOf("7", "8", "9", "-", "Tiếp"),
27
+ listOf("7", "8", "9", "-", "Xong"),
30
28
  listOf("000", "0", "+")
31
29
  )
32
- private val defaultKeys = listOf(
33
- listOf("1", "2", "3", "÷", "AC"),
34
- listOf("4", "5", "6", "×", "back"),
35
- listOf("7", "8", "9", "-", "="),
36
- listOf("000", "0", "+")
37
- )
38
- private val specialKeys = listOf("=", "-", "×", "÷", "back", "+", "AC")
30
+ private val specialKeys = listOf("=", "-", "×", "÷", "back", "+")
39
31
  private val separatorWidth = 8f
40
32
  private var specialButtonColor: Int = "#D8D8D8".toColorInt()
41
33
 
42
- private var keyboardMode: String = "NumDefault"
43
-
44
34
  private var customKeyButton: Button? = null
45
35
  private var customKeyButtonBackground: Int = "#D8D8D8".toColorInt()
46
36
  private var customKeyButtonTextColor: Int = Color.BLACK
47
37
  private var customKeyButtonState: String = "default"
48
38
 
49
39
  init {
40
+ val activity = context.currentActivity as? AppCompatActivity
41
+ if (activity != null) {
42
+ val displayMetrics = resources.displayMetrics
43
+ val widthButton = (displayMetrics.widthPixels - separatorWidth * 2 - 4 * separatorWidth) / 5f
44
+ val heightButton = (calculatorHeight - separatorWidth * 2 - 3 * separatorWidth) / 4
45
+
50
46
  isClickable = false
51
47
  isFocusable = false
52
48
  isFocusableInTouchMode = false
53
49
  clipToPadding = false
54
50
  clipChildren = false
55
- }
56
51
 
57
- private fun renderUI() {
58
- val displayMetrics = resources.displayMetrics
59
- val buttonWidth = (displayMetrics.widthPixels - separatorWidth * 2 - 4 * separatorWidth) / 5f
60
- val buttonHeight = (calculatorHeight - separatorWidth * 2 - 3 * separatorWidth) / 4
52
+ renderUI(widthButton, heightButton)
53
+ }
54
+
55
+ }
61
56
 
57
+ private fun renderUI(buttonWidth: Float, buttonHeight: Float) {
62
58
  var yOffset = separatorWidth
63
- val keys = if (keyboardMode == "NumWithCTA") numWithCTAKeys else defaultKeys
64
59
  for ((rowIndex, row) in keys.withIndex()) {
65
60
  var xOffset = separatorWidth
66
61
  for ((colIndex, key) in row.withIndex()) {
67
- val isMainKey = rowIndex == 2 && colIndex == 4
68
- val isMainCTAKey = isMainKey && keyboardMode == "NumWithCTA"
62
+ val isCustomKey = rowIndex == 2 && colIndex == 4
69
63
  val width = if (key == "000") buttonWidth * 2 + separatorWidth else buttonWidth
70
- val height = if (isMainKey) buttonHeight * 2 + separatorWidth else buttonHeight
64
+ val height = if (isCustomKey) buttonHeight * 2 + separatorWidth else buttonHeight
71
65
 
72
66
  val button = if (key == "back") {
73
67
  createImageButton(key, xOffset, yOffset, buttonWidth.toInt(), buttonHeight.toInt())
74
68
  } else {
75
- createButton(key, xOffset, yOffset, width.toInt(), height.toInt(), isMainKey, isMainCTAKey).also { b ->
76
- if (isMainCTAKey) customKeyButton = b
69
+ createButton(key, xOffset, yOffset, width.toInt(), height.toInt(), isCustomKey).also { b ->
70
+ if (isCustomKey) customKeyButton = b
77
71
  }
78
72
  }
79
73
 
@@ -91,8 +85,7 @@ class CustomKeyboardView(
91
85
  yOffset: Float,
92
86
  buttonWidth: Int,
93
87
  buttonHeight: Int,
94
- isMainKey: Boolean,
95
- isMainCTAKey: Boolean
88
+ isCustomKey: Boolean
96
89
  ): Button {
97
90
  return Button(context).apply {
98
91
  val shapeInit = GradientDrawable().apply {
@@ -105,7 +98,7 @@ class CustomKeyboardView(
105
98
  background = shapeInit
106
99
  text = key
107
100
  setTypeface(typeface)
108
- textSize = (if (isMainCTAKey) 18 else 24).toFloat()
101
+ textSize = (if (isCustomKey) 18 else 24).toFloat()
109
102
  setTextColor(Color.BLACK)
110
103
  stateListAnimator = null
111
104
  maxLines = 1
@@ -117,7 +110,7 @@ class CustomKeyboardView(
117
110
  constrainedWidth = false
118
111
  }
119
112
 
120
- if (specialKeys.contains(key) || isMainKey) {
113
+ if (specialKeys.contains(key)) {
121
114
  background = GradientDrawable().apply {
122
115
  shape = GradientDrawable.RECTANGLE
123
116
  cornerRadius = 24f
@@ -132,7 +125,7 @@ class CustomKeyboardView(
132
125
 
133
126
  translationX = xOffset.toInt().toFloat()
134
127
  translationY = yOffset.toInt().toFloat()
135
- setOnClickListener { onKeyPress(key, isMainCTAKey) }
128
+ setOnClickListener { onKeyPress(key, isCustomKey) }
136
129
  }
137
130
  }
138
131
 
@@ -170,15 +163,46 @@ class CustomKeyboardView(
170
163
  }
171
164
  }
172
165
 
173
- private fun onKeyPress(key: String, isMainCTAKey: Boolean) {
174
- if (isMainCTAKey) {
175
- emitCustomKey(context)
166
+ fun updateButtonColors(color: Int) {
167
+ specialButtonColor = color
168
+ for (i in 0 until childCount) {
169
+ val child = getChildAt(i)
170
+ if (child is Button) {
171
+ val key = child.text.toString()
172
+ if (specialKeys.contains(key)) {
173
+ if (key == "=") {
174
+ child.background = GradientDrawable().apply {
175
+ shape = GradientDrawable.RECTANGLE
176
+ cornerRadius = 24f
177
+ setColor(specialButtonColor)
178
+ }
179
+ } else {
180
+ child.background = GradientDrawable().apply {
181
+ shape = GradientDrawable.RECTANGLE
182
+ cornerRadius = 24f
183
+ setColor(specialButtonColor)
184
+ }
185
+ }
186
+ child.setTextColor(Color.BLACK)
187
+ }
188
+ } else if (child is ImageButton) {
189
+ child.background = GradientDrawable().apply {
190
+ shape = GradientDrawable.RECTANGLE
191
+ cornerRadius = 24f
192
+ setColor(specialButtonColor)
193
+ }
194
+ }
195
+ }
196
+ }
197
+
198
+ private fun onKeyPress(key: String, isCustomKey: Boolean) {
199
+ if (isCustomKey) {
200
+ emitCustomKey()
176
201
  return
177
202
  }
178
203
 
179
- emitKeyPress(context, key)
204
+ emitKeyPress(key)
180
205
  when (key) {
181
- "AC" -> clearText()
182
206
  "back" -> onBackSpace()
183
207
  "=" -> calculateResult()
184
208
  "×", "+", "-", "÷" -> keyDidPress(" $key ")
@@ -191,10 +215,6 @@ class CustomKeyboardView(
191
215
  editText.text?.replace(editText.selectionStart, editText.selectionEnd, key)
192
216
  }
193
217
 
194
- private fun clearText() {
195
- editText.text?.clear()
196
- }
197
-
198
218
  private fun onBackSpace() {
199
219
  val start = editText.selectionStart
200
220
  val end = editText.selectionEnd
@@ -231,56 +251,44 @@ class CustomKeyboardView(
231
251
  }
232
252
  }
233
253
 
234
- private fun emitKeyPress(context: Context, key: String) {
235
- val reactContext = context as ReactContext
236
- val surfaceId = UIManagerHelper.getSurfaceId(reactContext)
237
- val eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag(reactContext, editText.id)
238
- val payload =
239
- Arguments.createMap().apply {
240
- putString("key", key)
241
- }
242
- val event = OnKeyPressEvent(surfaceId, editText.id, payload)
243
-
244
- eventDispatcher?.dispatchEvent(event)
254
+ private fun emitKeyPress(key: String) {
255
+ val reactContext = context as ThemedReactContext
256
+ val params = Arguments.createMap().apply {
257
+ putString("key", key)
258
+ }
259
+ reactContext.getJSModule(RCTEventEmitter::class.java)
260
+ .receiveEvent(editText.id, "onKeyPress", params)
245
261
  }
246
262
 
247
- private fun emitCustomKey(context: Context) {
248
- val reactContext = context as ReactContext
249
- val surfaceId = UIManagerHelper.getSurfaceId(reactContext)
250
- val eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag(reactContext, editText.id)
251
-
252
- val event = OnCustomKeyPressEvent(surfaceId, editText.id)
253
-
254
- eventDispatcher?.dispatchEvent(event)
263
+ private fun emitCustomKey() {
264
+ val reactContext = context as ThemedReactContext
265
+ reactContext.getJSModule(RCTEventEmitter::class.java)
266
+ .receiveEvent(editText.id, "onCustomKeyEvent", null)
255
267
  }
256
268
 
257
269
  fun setCustomKeyText(text: String) {
258
270
  customKeyButton?.text = text
259
271
  }
260
272
 
261
- fun setMode(mode: String) {
262
- keyboardMode = mode
263
- renderUI()
264
- }
265
-
266
273
  fun setCustomKeyBackground(background: Int) {
267
274
  customKeyButtonBackground = background
268
- updateCustomKeyUI(background, customKeyButtonTextColor)
275
+ updateCustomKeyUI(background, customKeyButtonTextColor, customKeyButtonState)
269
276
  }
270
277
 
271
278
  fun setCustomKeyTextColor(textColor: Int) {
272
279
  customKeyButtonTextColor = textColor
273
- updateCustomKeyUI(customKeyButtonBackground, textColor)
280
+ updateCustomKeyUI(customKeyButtonBackground, textColor, customKeyButtonState)
274
281
  }
275
282
 
276
283
 
277
284
  fun setCustomKeyState(state: String) {
278
285
  customKeyButtonState = state
279
286
  customKeyButton?.isEnabled = state != "disable"
280
- updateCustomKeyUI(customKeyButtonBackground, customKeyButtonTextColor)
287
+ updateCustomKeyUI(customKeyButtonBackground, customKeyButtonTextColor, state)
281
288
  }
282
289
 
283
- private fun updateCustomKeyUI(background: Int, textColor: Int){
290
+ private fun updateCustomKeyUI(background: Int, textColor: Int, state: String){
291
+
284
292
  customKeyButton?.background = GradientDrawable().apply {
285
293
  shape = GradientDrawable.RECTANGLE
286
294
  cornerRadius = 24f
@@ -289,4 +297,5 @@ class CustomKeyboardView(
289
297
  customKeyButton?.setTextColor(textColor)
290
298
  }
291
299
 
300
+
292
301
  }
@@ -3,43 +3,20 @@ package com.calculatorkeyboard
3
3
  import android.annotation.SuppressLint
4
4
  import android.content.Context
5
5
  import android.graphics.Color
6
- import android.graphics.Typeface
7
- import android.os.Build
8
- import android.provider.Settings.Global.putString
9
- import android.text.Editable
10
- import android.text.TextWatcher
11
6
  import android.view.KeyEvent
12
7
  import android.view.inputmethod.InputMethodManager
13
8
  import androidx.core.graphics.toColorInt
14
9
  import androidx.core.view.ViewCompat
15
10
  import androidx.core.view.WindowInsetsCompat
16
- import androidx.core.widget.addTextChangedListener
17
- import com.facebook.react.bridge.Arguments
18
- import com.facebook.react.bridge.ReactContext
19
11
  import com.facebook.react.bridge.ReadableArray
20
- import com.facebook.react.bridge.ReadableMap
21
12
  import com.facebook.react.bridge.UiThreadUtil
22
- import com.facebook.react.module.annotations.ReactModule
23
13
  import com.facebook.react.uimanager.PixelUtil.dpToPx
24
- import com.facebook.react.uimanager.SimpleViewManager
25
14
  import com.facebook.react.uimanager.ThemedReactContext
26
- import com.facebook.react.uimanager.UIManagerHelper
27
- import com.facebook.react.uimanager.ViewManagerDelegate
28
15
  import com.facebook.react.uimanager.annotations.ReactProp
29
- import com.facebook.react.uimanager.events.RCTEventEmitter
30
- import com.facebook.react.viewmanagers.NativeInputCalculatorManagerDelegate
31
- import com.facebook.react.viewmanagers.NativeInputCalculatorManagerInterface
32
16
  import com.facebook.react.views.textinput.ReactEditText
33
17
  import com.facebook.react.views.textinput.ReactTextInputManager
34
18
 
35
- @ReactModule(name = InputCalculatorViewManager.REACT_CLASS)
36
- class InputCalculatorViewManager : SimpleViewManager<ReactEditText>(), NativeInputCalculatorManagerInterface<ReactEditText> {
37
- private val delegate: NativeInputCalculatorManagerDelegate<ReactEditText, InputCalculatorViewManager> =
38
- NativeInputCalculatorManagerDelegate(this)
39
-
40
- override fun getDelegate(): ViewManagerDelegate<ReactEditText> = delegate
41
-
42
- override fun getName() = REACT_CLASS
19
+ class RCTInputCalculator : ReactTextInputManager() {
43
20
 
44
21
  private var keyboardView: CustomKeyboardView? = null
45
22
  private lateinit var editText: CalculatorEditText
@@ -50,14 +27,15 @@ class InputCalculatorViewManager : SimpleViewManager<ReactEditText>(), NativeInp
50
27
  private var backListenerAttached = false
51
28
  private var overlayShowing = false
52
29
 
30
+ override fun getName() = REACT_CLASS
53
31
 
54
32
  companion object {
55
- const val REACT_CLASS = "NativeInputCalculator"
33
+ const val REACT_CLASS = "RCTInputCalculator"
56
34
  val calculatorHeight: Int = 240.dpToPx().toInt()
57
35
  }
58
36
 
59
37
  @ReactProp(name = "value")
60
- override fun setValue(view: ReactEditText, value: String?) {
38
+ fun setValue(view: ReactEditText, value: String?) {
61
39
  UiThreadUtil.runOnUiThread {
62
40
  val e = view.editableText ?: run { view.setText(value ?: ""); return@runOnUiThread }
63
41
  val newText = value ?: ""
@@ -70,72 +48,29 @@ class InputCalculatorViewManager : SimpleViewManager<ReactEditText>(), NativeInp
70
48
  }
71
49
  }
72
50
 
73
- override fun setTextAttributes(view: ReactEditText?, value: ReadableMap?) {
74
- val fontWeightStr = value?.getString("fontWeight")
75
- val fontSize = value?.getDouble("fontSize")
76
-
77
- fontWeightStr?.let { weightStr ->
78
- val weight = when (weightStr) {
79
- "100" -> 100
80
- "200" -> 200
81
- "300" -> 300
82
- "400", "normal" -> 400
83
- "500" -> 500
84
- "600" -> 600
85
- "700", "bold" -> 700
86
- "800" -> 800
87
- "900" -> 900
88
- else -> 400
89
- }
90
-
91
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
92
- view?.typeface = Typeface.create(view.typeface, weight, false)
93
- } else {
94
- view?.typeface = if (weight >= 600) {
95
- Typeface.create(view.typeface, Typeface.BOLD)
96
- } else {
97
- Typeface.create(view.typeface, Typeface.NORMAL)
98
- }
99
- }
100
- }
101
-
102
- fontSize?.let {
103
- view?.textSize = it.toFloat()
104
- }
105
- }
106
-
107
-
108
- @ReactProp(name = "mode")
109
- override fun setMode(view: ReactEditText, mode: String?) {
110
- keyboardView?.setMode(mode ?: "NumDefault")
111
- }
112
-
113
51
  @ReactProp(name = "customKeyText")
114
- override fun setCustomKeyText(view: ReactEditText, text: String?) {
115
- keyboardView?.setCustomKeyText(text ?: "Tiếp")
52
+ fun setCustomKeyText(view: ReactEditText, text: String?) {
53
+ keyboardView?.setCustomKeyText(text ?: "Xong")
116
54
  }
117
55
 
118
56
  @ReactProp(name = "customKeyBackground")
119
- override fun setCustomKeyBackground(view: ReactEditText, background: String?) {
57
+ fun setCustomKeyBackground(view: ReactEditText, background: String?) {
120
58
  keyboardView?.setCustomKeyBackground((background ?: "#d8d8d8").toColorInt())
121
59
  }
122
60
 
123
61
  @ReactProp(name = "customKeyTextColor")
124
- override fun setCustomKeyTextColor(view: ReactEditText, textColor: String?) {
62
+ fun setCustomKeyTextColor(view: ReactEditText, textColor: String?) {
125
63
  keyboardView?.setCustomKeyTextColor(textColor?.toColorInt() ?: Color.BLACK)
126
64
  }
127
65
 
128
66
  @ReactProp(name = "customKeyState")
129
- override fun setCustomKeyState(view: ReactEditText, state: String?) {
67
+ fun setCustomKeyState(view: ReactEditText, state: String?) {
130
68
  keyboardView?.setCustomKeyState(state ?: "default")
131
69
  }
132
70
 
133
- override fun focus(view: ReactEditText?) {
134
- UiThreadUtil.runOnUiThread { if (!editText.isFocused) editText.requestFocus() }
135
- }
136
-
137
- override fun blur(view: ReactEditText?) {
138
- UiThreadUtil.runOnUiThread { if (editText.isFocused) editText.clearFocus() }
71
+ @ReactProp(name = "keyboardColor")
72
+ fun setKeyboardColor(view: ReactEditText, color: String) {
73
+ keyboardView?.updateButtonColors(color.toColorInt())
139
74
  }
140
75
 
141
76
  @SuppressLint("ClickableViewAccessibility")
@@ -166,16 +101,6 @@ class InputCalculatorViewManager : SimpleViewManager<ReactEditText>(), NativeInp
166
101
  }
167
102
  false
168
103
  }
169
- addTextChangedListener(object : TextWatcher{
170
- override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
171
-
172
- override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
173
-
174
- override fun afterTextChanged(s: Editable?) {
175
- emitOnChange(context, s.toString())
176
- }
177
-
178
- })
179
104
  }
180
105
 
181
106
  keyboardView = CustomKeyboardView(context, editText).apply {
@@ -240,31 +165,33 @@ class InputCalculatorViewManager : SimpleViewManager<ReactEditText>(), NativeInp
240
165
  v.showSoftInputOnFocus = true
241
166
  }
242
167
 
243
- private fun emitOnChange(context: Context, text: String) {
244
- val reactContext = context as ReactContext
245
- val surfaceId = UIManagerHelper.getSurfaceId(reactContext)
246
- val eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag(reactContext, editText.id)
247
- val payload =
248
- Arguments.createMap().apply {
249
- putString("text", text)
250
- }
251
- val event = OnChangeEvent(surfaceId, editText.id, payload)
168
+ override fun getCommandsMap(): Map<String, Int> = mapOf("blur" to 1, "focus" to 2)
252
169
 
253
- eventDispatcher?.dispatchEvent(event)
170
+ override fun receiveCommand(reactEditText: ReactEditText, commandId: Int, args: ReadableArray?) {
171
+ when (commandId) {
172
+ 1 -> blur()
173
+ 2 -> focus()
174
+ }
254
175
  }
255
176
 
256
177
  override fun getExportedCustomBubblingEventTypeConstants(): MutableMap<String, Any> {
257
- val base = super.getExportedCustomBubblingEventTypeConstants()?.toMutableMap() ?: mutableMapOf()
178
+ val base = super.getExportedCustomBubblingEventTypeConstants().toMutableMap()
258
179
  base["onKeyPress"] = mapOf("phasedRegistrationNames" to mapOf("bubbled" to "onKeyPress"))
259
- base["onChange"] = mapOf("phasedRegistrationNames" to mapOf("bubbled" to "onChange"))
260
180
  return base
261
181
  }
262
182
 
263
183
  override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any> {
264
- val base = super.getExportedCustomDirectEventTypeConstants()?.toMutableMap() ?: mutableMapOf()
184
+ val base = super.getExportedCustomDirectEventTypeConstants().toMutableMap()
265
185
  base["onCustomKeyEvent"] = mapOf("registrationName" to "onCustomKeyEvent")
266
186
  return base
267
187
  }
268
188
 
189
+ private fun focus() {
190
+ UiThreadUtil.runOnUiThread { if (!editText.isFocused) editText.requestFocus() }
191
+ }
192
+
193
+ private fun blur() {
194
+ UiThreadUtil.runOnUiThread { if (editText.isFocused) editText.clearFocus() }
195
+ }
269
196
  }
270
197