-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.tsx
118 lines (103 loc) · 3.23 KB
/
index.tsx
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import React, {
DependencyList,
forwardRef,
useEffect,
useImperativeHandle,
useRef,
useState
} from 'react'
import { findNodeHandle, NativeModules, Platform, TextInput, TextInputProps } from 'react-native'
const { RNTextInputMask } = NativeModules as { RNTextInputMask: MaskOperations }
if (!RNTextInputMask) {
throw new Error(`NativeModule: RNTextInputMask is null.
To fix this issue try these steps:
• Rebuild and restart the app.
• Run the packager with \`--clearCache\` flag.
• If happening on iOS, run \`pod install\` in the \`ios\` directory and then rebuild and re-run the app.
• If this happens while testing with Jest, make sure to follow instructions in https://github.com/react-native-text-input-mask/react-native-text-input-mask#testing
`);
}
export const { mask, unmask, setMask } = RNTextInputMask
const TextInputMask = forwardRef<Handles, TextInputMaskProps>(({ mask: inputMask, defaultValue, value , multiline, onChangeText, autocomplete= true, autoskip = true, ...rest }, ref) => {
const input = useRef<TextInput>(null)
const [ maskedValue, setMaskedValue ] = useState<string>()
useEffectAsync(async () => {
if (!defaultValue) return
if (inputMask) {
const masked = await mask(inputMask, defaultValue, false)
setMaskedValue(masked)
} else {
setMaskedValue(defaultValue)
}
}, [])
useEffectAsync(async () => {
if (value === maskedValue) return
if (inputMask && value) {
const masked = await mask(inputMask, value, false)
setMaskedValue(masked)
} else {
setMaskedValue(value)
}
}, [value])
useEffect(() => {
const nodeId = findNodeHandle(input.current)
if (inputMask && nodeId) {
setMask(nodeId, inputMask, autocomplete, autoskip)
}
}, [inputMask])
useImperativeHandle(ref, () => ({
focus: () => {
input.current?.focus()
},
blur: () => {
input.current?.blur()
}
}))
return (
<TextInput
{...rest}
ref={input}
value={maskedValue}
multiline={inputMask && Platform.OS === 'ios' ? false : multiline}
onChangeText={async (masked) => {
setMaskedValue(masked)
if (inputMask) {
const unmasked = await unmask(inputMask, masked, true)
onChangeText?.(masked, unmasked)
} else {
onChangeText?.(masked)
}
}}
/>
)
})
export const useEffectAsync = (
operation: () => Promise<void>,
deps?: DependencyList
) => {
useEffect(() => {
operation().then()
}, deps)
}
interface MaskOperations {
mask: (mask: string, value: string, autocomplete: boolean) => Promise<string>,
unmask: (mask: string, value: string, autocomplete: boolean) => Promise<string>
setMask: (reactNode: number, mask: string, autocomplete: boolean, autoskip: boolean) => void
}
export interface TextInputMaskProps extends TextInputProps {
mask?: string
onChangeText?: (formatted: string, extracted?: string) => void
/**
* autocomplete pattern while editing text
*/
autocomplete?: boolean
/**
* automatically remove mask characters on backspace
*/
autoskip?: boolean
}
interface Handles {
focus: () => void
blur: () => void
}
export default TextInputMask