-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNumberField.tsx
More file actions
81 lines (76 loc) · 2.26 KB
/
NumberField.tsx
File metadata and controls
81 lines (76 loc) · 2.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import React, { useContext, useState, useEffect } from 'react';
import { View, TextInput, StyleSheet } from 'react-native';
import { ThemedText } from './ThemedText';
import { ThemeContext } from '@/theme/ThemeContext';
type NumberFieldProps = {
label: string;
value: number | string;
onValueChange: (value: number) => void;
};
export function NumberField({ label, value, onValueChange }: NumberFieldProps) {
const { theme } = useContext(ThemeContext);
const [inputValue, setInputValue] = useState(value?.toString() ?? "");
useEffect(() => {
setInputValue(value?.toString() ?? "");
}, [value]);
return (
<View style={styles.container}>
<ThemedText style={[styles.label, { color: theme === "dark" ? "#fff" : "#222" }]}>{label}</ThemedText>
<TextInput
style={[
styles.input,
{
backgroundColor: theme === "dark" ? "#222" : "#fff",
color: theme === "dark" ? "#fff" : "#222",
borderColor: theme === "dark" ? "#444" : "#ccc"
}
]}
keyboardType="decimal-pad"
value={inputValue}
onChangeText={text => {
// Allow only numbers, optional decimal, and optional leading minus
if (/^-?\d*\.?\d*$/.test(text)) {
setInputValue(text);
// Only call onValueChange if text is a valid number (not just "-" or ".")
// and does not end with a lone decimal point
if (
text !== "" &&
text !== "-" &&
text !== "." &&
text !== "-." &&
!text.match(/^-?\d+\.$/)
) {
const num = parseFloat(text);
if (!isNaN(num)) {
onValueChange(num);
}
}
}
}}
placeholder="Enter number"
placeholderTextColor={theme === "dark" ? "#888" : "#aaa"}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
marginVertical: 6,
width: "100%",
justifyContent: "space-between",
flexDirection: "row",
alignItems: "center"
},
label: {
fontSize: 16,
marginBottom: 2
},
input: {
borderWidth: 1,
borderColor: "#ccc",
borderRadius: 6,
padding: 6,
paddingHorizontal:8,
fontSize: 16
}
});