1- import React , { FC , useEffect , useState } from "react" ;
1+ import React , { useEffect , useState } from "react" ;
22import { TextInput } from "react-native" ;
33import { isString , isNumber , isNaN } from "lodash" ;
44
@@ -8,68 +8,67 @@ interface Props {
88 onChangeText ?: ( value ?: number ) => void ;
99}
1010
11- const NumberInput : FC < Props > = ( {
12- onChangeText,
13- value,
14- defaultValue,
15- ...props
16- } ) => {
17- const [ currentStringNumberValue , setCurrentStringNumberValue ] = useState ( "" ) ;
11+ const NumberInput = React . forwardRef < TextInput , Props > (
12+ ( { onChangeText, value, defaultValue, ...props } , ref ) => {
13+ const [ currentStringNumberValue , setCurrentStringNumberValue ] =
14+ useState ( "" ) ;
1815
19- const formatValueToStringNumber = ( valueToFormat ?: number | string ) => {
20- if ( valueToFormat != null ) {
21- if ( isString ( valueToFormat ) && valueToFormat !== "" ) {
22- if ( / ^ 0 [ 1 - 9 ] $ / . test ( valueToFormat ) ) {
23- return valueToFormat . slice ( 1 ) ;
24- } else if ( / ^ [ + - ] ? ( [ 0 - 9 ] + \. ? [ 0 - 9 ] * | \. [ 0 - 9 ] + ) $ / . test ( valueToFormat ) ) {
25- return valueToFormat ;
26- } else {
27- return currentStringNumberValue ;
16+ const formatValueToStringNumber = ( valueToFormat ?: number | string ) => {
17+ if ( valueToFormat != null ) {
18+ if ( isString ( valueToFormat ) && valueToFormat !== "" ) {
19+ if ( / ^ 0 [ 1 - 9 ] $ / . test ( valueToFormat ) ) {
20+ return valueToFormat . slice ( 1 ) ;
21+ } else if ( / ^ [ + - ] ? ( [ 0 - 9 ] + \. ? [ 0 - 9 ] * | \. [ 0 - 9 ] + ) $ / . test ( valueToFormat ) ) {
22+ return valueToFormat ;
23+ } else {
24+ return currentStringNumberValue ;
25+ }
26+ } else if ( isNumber ( valueToFormat ) && ! isNaN ( valueToFormat ) ) {
27+ return valueToFormat . toString ( ) ;
2828 }
29- } else if ( isNumber ( valueToFormat ) && ! isNaN ( valueToFormat ) ) {
30- return valueToFormat . toString ( ) ;
3129 }
32- }
3330
34- return "" ;
35- } ;
31+ return "" ;
32+ } ;
3633
37- const handleChangeText = ( newValue : string ) => {
38- const newStringNumberValue = formatValueToStringNumber ( newValue ) ;
39- const number = parseFloat ( newStringNumberValue ) ;
34+ const handleChangeText = ( newValue : string ) => {
35+ const newStringNumberValue = formatValueToStringNumber ( newValue ) ;
36+ const number = parseFloat ( newStringNumberValue ) ;
4037
41- setCurrentStringNumberValue ( newStringNumberValue ) ;
42- onChangeText ?.( number ) ;
43- } ;
38+ setCurrentStringNumberValue ( newStringNumberValue ) ;
39+ onChangeText ?.( number ) ;
40+ } ;
4441
45- // run handleChangeText with value prop only when value prop changes (and first render to reset currentStringNumberValue)
46- useEffect ( ( ) => {
47- const nextStringNumberValue = formatValueToStringNumber ( value ) ;
42+ // run handleChangeText with value prop only when value prop changes (and first render to reset currentStringNumberValue)
43+ useEffect ( ( ) => {
44+ const nextStringNumberValue = formatValueToStringNumber ( value ) ;
4845
49- if ( currentStringNumberValue !== nextStringNumberValue ) {
50- handleChangeText ( nextStringNumberValue ) ;
51- }
52- // eslint-disable-next-line react-hooks/exhaustive-deps
53- } , [ value ] ) ;
46+ if ( currentStringNumberValue !== nextStringNumberValue ) {
47+ handleChangeText ( nextStringNumberValue ) ;
48+ }
49+ // eslint-disable-next-line react-hooks/exhaustive-deps
50+ } , [ value ] ) ;
5451
55- // set currentStringNumberValue as defaultValue prop if there is a differnce on first render only
56- useEffect ( ( ) => {
57- const defaultStringNumberValue = formatValueToStringNumber ( defaultValue ) ;
52+ // set currentStringNumberValue as defaultValue prop if there is a differnce on first render only
53+ useEffect ( ( ) => {
54+ const defaultStringNumberValue = formatValueToStringNumber ( defaultValue ) ;
5855
59- if ( currentStringNumberValue !== defaultStringNumberValue ) {
60- setCurrentStringNumberValue ( defaultStringNumberValue ) ;
61- }
62- // eslint-disable-next-line react-hooks/exhaustive-deps
63- } , [ ] ) ;
56+ if ( currentStringNumberValue !== defaultStringNumberValue ) {
57+ setCurrentStringNumberValue ( defaultStringNumberValue ) ;
58+ }
59+ // eslint-disable-next-line react-hooks/exhaustive-deps
60+ } , [ ] ) ;
6461
65- return (
66- < TextInput
67- keyboardType = "numeric"
68- value = { currentStringNumberValue }
69- onChangeText = { handleChangeText }
70- { ...props }
71- />
72- ) ;
73- } ;
62+ return (
63+ < TextInput
64+ ref = { ref }
65+ keyboardType = "numeric"
66+ value = { currentStringNumberValue }
67+ onChangeText = { handleChangeText }
68+ { ...props }
69+ />
70+ ) ;
71+ }
72+ ) ;
7473
7574export default NumberInput ;
0 commit comments