sapo-components-ui-rn 1.0.76 → 1.0.78

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sapo-components-ui-rn",
3
- "version": "1.0.76",
3
+ "version": "1.0.78",
4
4
  "description": "React Native UI Components Library",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",
@@ -21,6 +21,8 @@ export interface NumberKeyboardProps {
21
21
  onChangeText?: (value: string) => void;
22
22
  /** Giá trị tối đa cho phép */
23
23
  maxValue?: number;
24
+ /** Giá trị tối thiểu cho phép */
25
+ minValue?: number;
24
26
  /** Loại input: integer hoặc float */
25
27
  type?: "integer" | "float";
26
28
  /** Số chữ số thập phân cho phép */
@@ -53,6 +55,7 @@ const NumberKeyboard: React.FC<NumberKeyboardProps> = ({
53
55
  label = "",
54
56
  onChangeText,
55
57
  maxValue = 999999999999,
58
+ minValue = 0,
56
59
  type = "integer",
57
60
  formatDecimal = 3,
58
61
  visible,
@@ -63,6 +66,7 @@ const NumberKeyboard: React.FC<NumberKeyboardProps> = ({
63
66
 
64
67
  const [inputValue, setInputValue] = useState<string>(value?.toString() || "");
65
68
  const [isFirstInput, setIsFirstInput] = useState<boolean>(true);
69
+ const [canSave, setCanSave] = useState<boolean>(true);
66
70
 
67
71
  useEffect(() => {
68
72
  if (visible) {
@@ -71,6 +75,16 @@ const NumberKeyboard: React.FC<NumberKeyboardProps> = ({
71
75
  }
72
76
  }, [visible, value]);
73
77
 
78
+ useEffect(() => {
79
+ const currentValue = Number(inputValue);
80
+ const minValueNumber = Number(minValue);
81
+ setCanSave(
82
+ !isNaN(currentValue) &&
83
+ !isNaN(minValueNumber) &&
84
+ currentValue >= minValueNumber
85
+ );
86
+ }, [inputValue, minValue]);
87
+
74
88
  const handleKeyPress = useCallback(
75
89
  (key: string) => {
76
90
  if (key === "del") {
@@ -81,7 +95,17 @@ const NumberKeyboard: React.FC<NumberKeyboardProps> = ({
81
95
 
82
96
  if (key === "000") {
83
97
  if (type === "integer" && inputValue.length > 0) {
84
- setInputValue((prev) => prev + "000");
98
+ const newInputValue = inputValue + "000";
99
+ const newValue = Number(newInputValue);
100
+ const maxValueNumber = Number(maxValue);
101
+
102
+ if (
103
+ !isNaN(newValue) &&
104
+ !isNaN(maxValueNumber) &&
105
+ newValue <= maxValueNumber
106
+ ) {
107
+ setInputValue(newInputValue);
108
+ }
85
109
  setIsFirstInput(false);
86
110
  }
87
111
  return;
@@ -89,7 +113,6 @@ const NumberKeyboard: React.FC<NumberKeyboardProps> = ({
89
113
 
90
114
  if (key === ".") {
91
115
  if (type === "float" && !inputValue.includes(".")) {
92
- // Nếu inputValue là "0" hoặc rỗng, giữ lại số 0 và thêm dấu "."
93
116
  if (inputValue === "0" || inputValue === "") {
94
117
  setInputValue("0.");
95
118
  } else {
@@ -106,6 +129,19 @@ const NumberKeyboard: React.FC<NumberKeyboardProps> = ({
106
129
  return;
107
130
  }
108
131
 
132
+ // Kiểm tra nếu input bắt đầu bằng 0 và không có dấu chấm
133
+ if (inputValue === "0") {
134
+ if (key === ".") {
135
+ setInputValue("0.");
136
+ return;
137
+ } else if (key >= "1" && key <= "9") {
138
+ setInputValue(key);
139
+ return;
140
+ } else {
141
+ return;
142
+ }
143
+ }
144
+
109
145
  const newInputValue = inputValue + key;
110
146
  const newValue = Number(newInputValue);
111
147
  const maxValueNumber = Number(maxValue);
@@ -133,18 +169,20 @@ const NumberKeyboard: React.FC<NumberKeyboardProps> = ({
133
169
  );
134
170
 
135
171
  const handleClear = useCallback(() => {
136
- setInputValue("0");
172
+ setInputValue("");
137
173
  setIsFirstInput(true);
138
174
  }, []);
139
175
 
140
176
  const handleSave = useCallback(() => {
177
+ if (!canSave) return;
178
+
141
179
  let finalValue = inputValue;
142
180
  if (inputValue.endsWith(".")) {
143
181
  finalValue = inputValue.slice(0, -1);
144
182
  }
145
183
  onChangeText?.(finalValue);
146
184
  onClose();
147
- }, [inputValue, onChangeText, onClose]);
185
+ }, [inputValue, onChangeText, onClose, canSave]);
148
186
 
149
187
  const handleClose = useCallback(() => {
150
188
  onClose();
@@ -169,10 +207,10 @@ const NumberKeyboard: React.FC<NumberKeyboardProps> = ({
169
207
  backgroundColor={colors.surfacePrimaryDefault}
170
208
  style={styles.modalContent}
171
209
  >
172
- <Text style={styles.modalTitle}>{label}</Text>
210
+ <Text style={[styles.text18, styles.modalTitle]}>{label}</Text>
173
211
  <View width={"100%"}>
174
212
  <View paddingHorizontal={SPACE_40}>
175
- <Text numberOfLines={1} style={styles.valueText}>
213
+ <Text numberOfLines={1} style={[styles.text30, styles.valueText]}>
176
214
  {formatNumberInput(inputValue, formatDecimal) || "0"}
177
215
  </Text>
178
216
  </View>
@@ -216,6 +254,7 @@ const NumberKeyboard: React.FC<NumberKeyboardProps> = ({
216
254
  <Text
217
255
  style={[
218
256
  styles.keyText,
257
+ styles.text22,
219
258
  key === "000" &&
220
259
  type === "float" &&
221
260
  styles.disabledKeyText,
@@ -238,7 +277,7 @@ const NumberKeyboard: React.FC<NumberKeyboardProps> = ({
238
277
  style={styles.actionButton}
239
278
  onPress={handleClose}
240
279
  >
241
- <Text style={styles.actionText}>Đóng</Text>
280
+ <Text style={[styles.actionText, styles.text16]}>Đóng</Text>
242
281
  </TouchableOpacity>
243
282
  <Spacer
244
283
  style={{ height: "100%" }}
@@ -251,7 +290,11 @@ const NumberKeyboard: React.FC<NumberKeyboardProps> = ({
251
290
  onPress={handleSave}
252
291
  >
253
292
  <Text
254
- style={[styles.actionText, { color: colors.textBrandDefault }]}
293
+ style={[
294
+ styles.actionText,
295
+ styles.text16,
296
+ { color: colors.textBrandDefault },
297
+ ]}
255
298
  >
256
299
  Lưu
257
300
  </Text>
@@ -278,13 +321,11 @@ const styles = StyleSheet.create({
278
321
  alignItems: "center",
279
322
  },
280
323
  modalTitle: {
281
- fontSize: 18,
282
324
  textAlign: "center",
283
325
  marginTop: 16,
284
326
  marginBottom: 8,
285
327
  },
286
328
  valueText: {
287
- fontSize: 30,
288
329
  textAlign: "center",
289
330
  },
290
331
  clearButton: {
@@ -311,7 +352,6 @@ const styles = StyleSheet.create({
311
352
  height: 48,
312
353
  },
313
354
  keyText: {
314
- fontSize: 22,
315
355
  fontWeight: "500",
316
356
  },
317
357
  actionRow: {
@@ -327,7 +367,6 @@ const styles = StyleSheet.create({
327
367
  paddingVertical: 12,
328
368
  },
329
369
  actionText: {
330
- fontSize: 16,
331
370
  fontWeight: "600",
332
371
  },
333
372
  disabledKey: {
@@ -38,7 +38,6 @@ export interface SelectionFieldProps extends TouchableOpacityProps {
38
38
  textProps?: IText;
39
39
  textColor?: string;
40
40
  labelColor?: string;
41
- size?: number;
42
41
  textStyle?: TextStyle;
43
42
  labelStyle?: TextStyle;
44
43
  disabled?: boolean;
@@ -61,7 +60,6 @@ const SelectionField = ({
61
60
  disabled = false,
62
61
  textColor,
63
62
  labelColor,
64
- size = 16,
65
63
  theme: themeOverrides,
66
64
  required = false,
67
65
  ...props
@@ -138,7 +136,6 @@ const SelectionField = ({
138
136
  <Text
139
137
  numberOfLines={1}
140
138
  color={getColor()}
141
- size={size}
142
139
  style={[disabled && disabledTextStyle, textStyle]}
143
140
  {...textProps}
144
141
  >
@@ -24,7 +24,7 @@ import {
24
24
  import ScaleButton from "../ScaleButton";
25
25
  import Text from "../Text";
26
26
  import View from "../View";
27
- import { useInternalTheme } from "../..//core/theming";
27
+ import { useInternalTheme } from "../../core/theming";
28
28
  import { ThemeProp } from "../../types";
29
29
  import Spacer from "../Spacer";
30
30
  import Icon from "../Icon";
@@ -138,8 +138,18 @@ const TextInputNumber = ({
138
138
  if (key === "del") {
139
139
  setInputValue((prev) => prev.slice(0, -1));
140
140
  } else if (key === "000") {
141
- if (type === "integer" && inputValue.length > 0) {
142
- setInputValue((prev) => prev + "000");
141
+ if (type === "integer") {
142
+ const newInputValue = inputValue + "000";
143
+ const newValue = Number(newInputValue);
144
+ const maxValueNumber = Number(maxValue);
145
+
146
+ if (
147
+ !isNaN(newValue) &&
148
+ !isNaN(maxValueNumber) &&
149
+ newValue <= maxValueNumber
150
+ ) {
151
+ setInputValue(newInputValue);
152
+ }
143
153
  setIsFirstInput(false);
144
154
  }
145
155
  } else if (key === ".") {
@@ -157,6 +167,19 @@ const TextInputNumber = ({
157
167
  setInputValue(key);
158
168
  setIsFirstInput(false);
159
169
  } else {
170
+ // Kiểm tra nếu input bắt đầu bằng 0 và không có dấu chấm
171
+ if (inputValue === "0") {
172
+ if (key === ".") {
173
+ setInputValue("0.");
174
+ return;
175
+ } else if (key >= "1" && key <= "9") {
176
+ setInputValue(key);
177
+ return;
178
+ } else {
179
+ return;
180
+ }
181
+ }
182
+
160
183
  const newInputValue = inputValue + key;
161
184
  const newValue = Number(newInputValue);
162
185
  const maxValueNumber = Number(maxValue);
@@ -168,13 +191,13 @@ const TextInputNumber = ({
168
191
  ) {
169
192
  if (inputValue.includes(".")) {
170
193
  const [intPart, decimalPart = ""] = inputValue.split(".");
171
- if (intPart.length < 12 && decimalPart.length === 0) {
194
+ if (newInputValue.length <= 12 && decimalPart.length === 0) {
172
195
  setInputValue((prev) => prev + key);
173
- } else if (decimalPart.length < 3) {
196
+ } else if (newInputValue.length <= 12 && decimalPart.length < 3) {
174
197
  setInputValue((prev) => prev + key);
175
198
  }
176
199
  } else {
177
- if (inputValue.length < 12) {
200
+ if (newInputValue.length <= 12) {
178
201
  setInputValue((prev) => prev + key);
179
202
  }
180
203
  }
@@ -246,7 +269,14 @@ const TextInputNumber = ({
246
269
  borderRadius: BORDER_RADIUS_6,
247
270
  },
248
271
 
249
- [styles.border, { borderColor: colors.borderPrimaryDefault }],
272
+ [
273
+ styles.border,
274
+ {
275
+ borderColor: isShowModalKeyboard
276
+ ? colors.borderBrandDefault
277
+ : colors.borderPrimaryDefault,
278
+ },
279
+ ],
250
280
 
251
281
  textError.length > 0 && [
252
282
  {
@@ -379,10 +409,13 @@ const TextInputNumber = ({
379
409
  backgroundColor={colors.surfacePrimaryDefault}
380
410
  style={styles.modalContent}
381
411
  >
382
- <Text style={styles.modalTitle}>{label}</Text>
412
+ <Text style={[styles.modalTitle, styles.text18]}>{label}</Text>
383
413
  <View width={"100%"}>
384
414
  <View paddingHorizontal={SPACE_40}>
385
- <Text numberOfLines={1} style={styles.valueText}>
415
+ <Text
416
+ numberOfLines={1}
417
+ style={[styles.text30, styles.valueText]}
418
+ >
386
419
  {formatNumberInput(inputValue, formatDecimal) || "0"}
387
420
  </Text>
388
421
  </View>
@@ -429,6 +462,7 @@ const TextInputNumber = ({
429
462
  <Text
430
463
  style={[
431
464
  styles.keyText,
465
+ styles.text22,
432
466
  key === "000" &&
433
467
  type === "float" &&
434
468
  styles.disabledKeyText,
@@ -451,7 +485,7 @@ const TextInputNumber = ({
451
485
  style={styles.actionButton}
452
486
  onPress={onCloseModalKeyboard}
453
487
  >
454
- <Text style={styles.actionText}>Đóng</Text>
488
+ <Text style={[styles.actionText, styles.text16]}>Đóng</Text>
455
489
  </TouchableOpacity>
456
490
  <Spacer
457
491
  style={{
@@ -469,6 +503,7 @@ const TextInputNumber = ({
469
503
  <Text
470
504
  style={[
471
505
  styles.actionText,
506
+ styles.text16,
472
507
  { color: colors.textBrandDefault },
473
508
  !canSave && { color: colors.textSecondary },
474
509
  ]}
@@ -513,14 +548,12 @@ const styles = StyleSheet.create({
513
548
  alignItems: "center",
514
549
  },
515
550
  modalTitle: {
516
- fontSize: 18,
517
551
  textAlign: "center",
518
552
  marginTop: 16,
519
553
  marginBottom: 8,
520
554
  },
521
555
 
522
556
  valueText: {
523
- fontSize: 30,
524
557
  textAlign: "center",
525
558
  },
526
559
  clearButton: {
@@ -547,7 +580,6 @@ const styles = StyleSheet.create({
547
580
  height: 48,
548
581
  },
549
582
  keyText: {
550
- fontSize: 22,
551
583
  fontWeight: "500",
552
584
  },
553
585
  actionRow: {
@@ -563,7 +595,6 @@ const styles = StyleSheet.create({
563
595
  paddingVertical: 12,
564
596
  },
565
597
  actionText: {
566
- fontSize: 16,
567
598
  fontWeight: "600",
568
599
  },
569
600
  disabledKey: {