@momo-kits/calculator-keyboard 0.151.2-beta.2 → 0.152.1-beta.2

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.
@@ -6,6 +6,7 @@ import android.graphics.Color
6
6
  import android.graphics.drawable.GradientDrawable
7
7
  import android.text.Editable
8
8
  import android.view.Gravity
9
+ import android.view.MotionEvent
9
10
  import android.widget.Button
10
11
  import android.widget.EditText
11
12
  import android.widget.ImageButton
@@ -130,6 +131,7 @@ class CustomKeyboardView(
130
131
  translationX = xOffset.toInt().toFloat()
131
132
  translationY = yOffset.toInt().toFloat()
132
133
  setOnClickListener { onKeyPress(key, isMainCTAKey) }
134
+ applyTextPressedOpacity()
133
135
  }
134
136
  }
135
137
 
@@ -161,9 +163,56 @@ class CustomKeyboardView(
161
163
 
162
164
  translationX = xOffset
163
165
  translationY = yOffset
164
- setImageResource(android.R.drawable.ic_input_delete)
166
+ setImageResource(R.drawable.ic_back)
165
167
  setImageTintList(ColorStateList.valueOf(Color.BLACK))
166
168
  setOnClickListener { onKeyPress(key, false) }
169
+ applyImagePressedOpacity()
170
+ }
171
+ }
172
+
173
+ @SuppressLint("ClickableViewAccessibility")
174
+ private fun Button.applyTextPressedOpacity(
175
+ pressedAlpha: Float = 0.2f,
176
+ disabledAlpha: Float = 0.2f
177
+ ) {
178
+ fun updateColorAlpha(alpha: Float) {
179
+ val color = textColors.defaultColor
180
+ val a = (alpha * 255).toInt().coerceIn(0, 255)
181
+ val rgb = color and 0x00FFFFFF
182
+ setTextColor((a shl 24) or rgb)
183
+ }
184
+
185
+ updateColorAlpha(if (isEnabled) 1f else disabledAlpha)
186
+
187
+ setOnTouchListener { v, ev ->
188
+ when (ev.actionMasked) {
189
+ MotionEvent.ACTION_DOWN -> if (isEnabled) updateColorAlpha(pressedAlpha)
190
+ MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL ->
191
+ updateColorAlpha(if (isEnabled) 1f else disabledAlpha)
192
+ }
193
+ false
194
+ }
195
+ }
196
+
197
+ @SuppressLint("ClickableViewAccessibility")
198
+ fun ImageButton.applyImagePressedOpacity(
199
+ pressedAlpha: Float = 0.2f,
200
+ disabledAlpha: Float = 0.2f
201
+ ) {
202
+ fun updateImageAlpha(alpha: Float) {
203
+ drawable?.mutate()?.alpha = (alpha * 255).toInt().coerceIn(0, 255)
204
+ invalidate()
205
+ }
206
+
207
+ updateImageAlpha(if (isEnabled) 1f else disabledAlpha)
208
+
209
+ setOnTouchListener { _, ev ->
210
+ when (ev.actionMasked) {
211
+ MotionEvent.ACTION_DOWN -> if (isEnabled) updateImageAlpha(pressedAlpha)
212
+ MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL ->
213
+ updateImageAlpha(if (isEnabled) 1f else disabledAlpha)
214
+ }
215
+ false
167
216
  }
168
217
  }
169
218
 
@@ -183,11 +232,14 @@ class CustomKeyboardView(
183
232
  Event.emitKeyPress(context, editText.id, key)
184
233
 
185
234
  val text = editText.text ?: return
235
+ val cursorPos = editText.selectionStart
186
236
  val plain = text.toString()
187
- val isEmpty = plain.isEmpty()
237
+ val isStartPosition = cursorPos == 72 || cursorPos == 0
188
238
  val isJustZero = plain == "0"
189
239
  val endsWithOperator = plain.endsWithAny(" + ", " - ", " × ", " ÷ ")
190
240
  val endsWithSingleZeroAfterOp = plain.endsWith(" 0")
241
+ val posBeforeOperator = text.substring(0, cursorPos).endsWithAny(" + ", " - ", " × ", " ÷ ")
242
+ && editText.length() > cursorPos
191
243
 
192
244
  when (key) {
193
245
  "AC" -> clearText()
@@ -196,7 +248,7 @@ class CustomKeyboardView(
196
248
  "×", "+", "-", "÷" -> if (!text.isEmpty()) keyDidPress(" $key ")
197
249
  "0", "000" -> {
198
250
  when {
199
- isEmpty -> {}
251
+ isStartPosition || posBeforeOperator -> {}
200
252
  key == "000" && endsWithOperator -> text.insertAtCaret(editText, "0")
201
253
  endsWithSingleZeroAfterOp || isJustZero -> {}
202
254
  else -> text.insertAtCaret(editText, key)
@@ -9,6 +9,7 @@ import android.text.Editable
9
9
  import android.text.TextWatcher
10
10
  import android.view.KeyEvent
11
11
  import android.view.inputmethod.InputMethodManager
12
+ import androidx.annotation.RequiresApi
12
13
  import androidx.core.graphics.toColorInt
13
14
  import androidx.core.view.ViewCompat
14
15
  import androidx.core.view.WindowInsetsCompat
@@ -112,6 +113,16 @@ class InputCalculatorViewManager : SimpleViewManager<ReactEditText>(), NativeInp
112
113
  keyboardView?.setMode(mode ?: "NumDefault")
113
114
  }
114
115
 
116
+ @RequiresApi(Build.VERSION_CODES.Q)
117
+ override fun setSelectionColor(
118
+ view: ReactEditText?,
119
+ value: String?
120
+ ) {
121
+ if (value == null) return
122
+ view?.highlightColor = value.toColorInt()
123
+ view?.textCursorDrawable?.setTint(value.toColorInt())
124
+ }
125
+
115
126
  @ReactProp(name = "customKeyText")
116
127
  override fun setCustomKeyText(view: ReactEditText, text: String?) {
117
128
  keyboardView?.setCustomKeyText(text ?: "Tiếp")
@@ -0,0 +1,9 @@
1
+ <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
+ android:width="24dp"
3
+ android:height="24dp"
4
+ android:viewportWidth="960"
5
+ android:viewportHeight="960">
6
+ <path
7
+ android:pathData="m456,640 l104,-104 104,104 56,-56 -104,-104 104,-104 -56,-56 -104,104 -104,-104 -56,56 104,104 -104,104 56,56ZM360,800q-19,0 -36,-8.5T296,768L80,480l216,-288q11,-15 28,-23.5t36,-8.5h440q33,0 56.5,23.5T880,240v480q0,33 -23.5,56.5T800,800L360,800ZM180,480l180,240h440v-480L360,240L180,480ZM580,480Z"
8
+ android:fillColor="#1f1f1f"/>
9
+ </vector>
@@ -12,6 +12,7 @@ NS_ASSUME_NONNULL_BEGIN
12
12
  - (void)calculateResult;
13
13
  - (void)emitCustomKey;
14
14
  - (void)emitKeyPress:(NSString *)key;
15
+ - (NSInteger)getCursorPosition;
15
16
 
16
17
  @end
17
18
 
@@ -198,23 +198,24 @@
198
198
 
199
199
  [self.input emitKeyPress:key];
200
200
 
201
- NSString *text = self.input.getText ?: @"";
202
- BOOL isEmpty = (text.length == 0);
201
+ NSString *text = [self.input getText] ?: @"";
202
+ NSInteger cursorPos = [self.input getCursorPosition];
203
203
  BOOL isJustZero = [text isEqualToString:@"0"];
204
204
 
205
- BOOL endsWithPlus = [text hasSuffix:@" + "];
206
- BOOL endsWithMinus = [text hasSuffix:@" - "];
207
- BOOL endsWithMul = [text hasSuffix:@" × "];
208
- BOOL endsWithDiv = [text hasSuffix:@" ÷ "];
209
- BOOL endsWithOperator = (endsWithPlus || endsWithMinus || endsWithMul || endsWithDiv);
210
-
205
+ NSArray<NSString *> *ops = @[ @" + ", @" - ", @" × ", @" ÷ " ];
206
+ BOOL endsWithOperator = endsWithAny(text, ops);
211
207
  BOOL endsWithSingleZeroAfterOp = [text hasSuffix:@" 0"];
212
208
 
209
+ BOOL isStartPosition = (cursorPos == 72 || cursorPos == 0);
210
+ NSString *prefix = (cursorPos > 0 && cursorPos <= (NSInteger)text.length)
211
+ ? [text substringToIndex:cursorPos] : @"";
212
+ BOOL posBeforeOperator = endsWithAny(prefix, ops) && (text.length > (NSUInteger)cursorPos);
213
+
213
214
  BOOL (^isOpKey)(NSString *) = ^BOOL(NSString *k) {
214
215
  return [k isEqualToString:@"+"] || [k isEqualToString:@"-"] ||
215
216
  [k isEqualToString:@"×"] || [k isEqualToString:@"÷"];
216
217
  };
217
- void (^insert)(NSString *) = ^(NSString *s) { [self.input keyDidPress:s]; };
218
+ void (^insertAtCaret)(NSString *) = ^(NSString *s) { [self.input keyDidPress:s]; };
218
219
  void (^replaceTrailingZeroWith)(NSString *) = ^(NSString *s) {
219
220
  [self.input onBackSpace];
220
221
  [self.input keyDidPress:s];
@@ -224,39 +225,28 @@
224
225
  [self.input keyDidPress:s];
225
226
  };
226
227
 
227
- if ([key isEqualToString:@"AC"]) {
228
- [self.input clearText];
229
- return;
230
- }
231
-
232
- if ([key isEqualToString:@"back"]) {
233
- [self.input onBackSpace];
234
- return;
235
- }
236
-
237
- if ([key isEqualToString:@"="]) {
238
- [self.input calculateResult];
239
- return;
240
- }
228
+ if ([key isEqualToString:@"AC"]) { [self.input clearText]; return; }
229
+ if ([key isEqualToString:@"back"]) { [self.input onBackSpace]; return; }
230
+ if ([key isEqualToString:@"="]) { [self.input calculateResult]; return; }
241
231
 
242
232
  if (isOpKey(key)) {
243
- if (!isEmpty) {
244
- insert([NSString stringWithFormat:@" %@ ", key]);
233
+ if (text.length > 0) {
234
+ insertAtCaret([NSString stringWithFormat:@" %@ ", key]);
245
235
  }
246
236
  return;
247
237
  }
248
238
 
249
239
  if ([key isEqualToString:@"0"] || [key isEqualToString:@"000"]) {
250
- if (isEmpty) return;
240
+ if (isStartPosition || posBeforeOperator) return;
251
241
 
252
242
  if ([key isEqualToString:@"000"] && endsWithOperator) {
253
- insert(@"0");
243
+ insertAtCaret(@"0");
254
244
  return;
255
245
  }
256
246
 
257
247
  if (endsWithSingleZeroAfterOp || isJustZero) return;
258
248
 
259
- insert(key);
249
+ insertAtCaret(key);
260
250
  return;
261
251
  }
262
252
 
@@ -265,10 +255,15 @@
265
255
  } else if (endsWithSingleZeroAfterOp) {
266
256
  replaceTrailingZeroWith(key);
267
257
  } else {
268
- insert(key);
258
+ insertAtCaret(key);
269
259
  }
270
260
  }
271
261
 
272
262
 
263
+ static BOOL endsWithAny(NSString *text, NSArray<NSString *> *suffixes) {
264
+ for (NSString *s in suffixes) { if ([text hasSuffix:s]) return YES; }
265
+ return NO;
266
+ }
267
+
273
268
  @end
274
269
 
@@ -140,6 +140,10 @@ using namespace facebook::react;
140
140
  }];
141
141
  }
142
142
 
143
+ if (oldViewProps.selectionColor != newViewProps.selectionColor) {
144
+ _textField.tintColor = [Utils colorFromHex:RCTNSStringFromString(newViewProps.selectionColor)];
145
+ }
146
+
143
147
  [super updateProps:props oldProps:oldProps];
144
148
  }
145
149
 
@@ -490,6 +494,13 @@ static UIFontWeight _UIFontWeightFromString(std::string_view s) {
490
494
  }
491
495
  }
492
496
 
497
+ - (NSInteger)getCursorPosition
498
+ {
499
+ UITextRange *sel = _textField.selectedTextRange;
500
+ if (!sel) return 0;
501
+ return [_textField offsetFromPosition:_textField.beginningOfDocument
502
+ toPosition:sel.start];
503
+ }
493
504
 
494
505
  @end
495
506
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/calculator-keyboard",
3
- "version": "0.151.2-beta.2",
3
+ "version": "0.152.1-beta.2",
4
4
  "description": "react native calculator keyboard",
5
5
  "main": "./src/index.tsx",
6
6
  "files": [
@@ -41,6 +41,7 @@ export interface NativeInputCalculatorProps extends ViewProps {
41
41
  value?: string;
42
42
  textAttributes?: TextAttributes;
43
43
  mode?: string;
44
+ selectionColor?: string;
44
45
  customKeyText?: string;
45
46
  customKeyBackground?: string;
46
47
  customKeyTextColor?: string;
package/src/index.tsx CHANGED
@@ -21,6 +21,7 @@ type KeyPressEvent = { nativeEvent: { key: string } };
21
21
  interface InputCalculatorProps extends TextInputProps {
22
22
  text?: string | undefined;
23
23
  mode?: Mode;
24
+ selectionColor?: string | undefined;
24
25
  onBlur?: () => void;
25
26
  onFocus?: () => void;
26
27
  onResult?: (e: OnResultEvent) => void;
@@ -83,6 +84,7 @@ const InputCalculator = React.forwardRef<
83
84
  {
84
85
  customKeyBackground = 'default',
85
86
  mode = Mode.NumDefault,
87
+ selectionColor,
86
88
  customKeyText,
87
89
  onBlur,
88
90
  onFocus,
@@ -147,6 +149,7 @@ const InputCalculator = React.forwardRef<
147
149
  onKeyPress={onKeyPress}
148
150
  value={text}
149
151
  mode={mode}
152
+ selectionColor={selectionColor}
150
153
  customKeyText={customKeyText}
151
154
  customKeyBackground={keyBackground}
152
155
  customKeyTextColor={textKeyColor}