diff --git a/README.md b/README.md
index 43a151d..5b9a336 100644
--- a/README.md
+++ b/README.md
@@ -24,28 +24,7 @@ yarn add react-native-text-input-mask
# Installation
- For RN >= 0.61
-
-#### iOS
-
-1. Add following lines to your target in `Podfile`
-```
-use_frameworks!
-pod 'RNInputMask', :path => '../node_modules/react-native-text-input-mask/ios/InputMask'
-```
-2. Run following command
-```bash
-cd ios && pod install
-```
-
-#### Android
-
-No need to do anything.
-
-
-
-
- For RN = 0.60.*
+ For RN >= 0.60
#### iOS
diff --git a/index.d.ts b/index.d.ts
new file mode 100644
index 0000000..bbed0c9
--- /dev/null
+++ b/index.d.ts
@@ -0,0 +1,18 @@
+import React, { ForwardRefExoticComponent, PropsWithoutRef, RefAttributes} from "react";
+import { TextInputProps, TextInput } from "react-native";
+
+export type onChangeTextMask = (
+ formatted?: string,
+ extracted?: string
+) => void;
+
+export interface TextInputMaskProps
+ extends Omit {
+ maskDefaultValue?: boolean;
+ mask?: string;
+ onChangeText?: onChangeTextMask;
+}
+
+declare const TextInputMask : ForwardRefExoticComponent & RefAttributes>;
+
+export default TextInputMask;
\ No newline at end of file
diff --git a/index.js b/index.js
index 408edad..dfbef9a 100644
--- a/index.js
+++ b/index.js
@@ -1,71 +1,108 @@
-import React, { Component } from 'react'
+import React, { useEffect, useRef, useImperativeHandle, useCallback } from "react";
import {
TextInput,
findNodeHandle,
NativeModules,
Platform
-} from 'react-native'
+} from "react-native";
-const mask = NativeModules.RNTextInputMask.mask
-const unmask = NativeModules.RNTextInputMask.unmask
-const setMask = NativeModules.RNTextInputMask.setMask
-export { mask, unmask, setMask }
+const mask = NativeModules.RNTextInputMask.mask;
+const unmask = NativeModules.RNTextInputMask.unmask;
+const setMask = NativeModules.RNTextInputMask.setMask;
+export { mask, unmask, setMask };
-export default class TextInputMask extends Component {
- static defaultProps = {
- maskDefaultValue: true,
- }
+function TextInputMask(props, ref){
+ const inputRef = useRef();
+ const prevMask = useRef(props.mask)
+ const prevValue = useRef(props.value)
+ const masked = useRef(false);
+ const isMounted = useRef(false);
- masked = false
+ const setNativeMask = useCallback(
+ (newInputMask)=>{
+ inputRef.current && setMask(findNodeHandle(inputRef.current), newInputMask);
+ },[inputRef.current]);
- componentDidMount() {
- if (this.props.maskDefaultValue &&
- this.props.mask &&
- this.props.value) {
- mask(this.props.mask, '' + this.props.value, text =>
- this.input && this.input.setNativeProps({ text }),
- )
- }
+ const setNativeTextMask = useCallback((value, inputMask)=>{
+ inputMask && mask(
+ inputMask,
+ "" + value,
+ text =>{
+ inputRef.current && inputRef.current.setNativeProps({ text });
+ prevValue.current = ""+ value;
+ }
+ );
+ },[inputRef.current, prevValue.current]);
- if (this.props.mask && !this.masked) {
- this.masked = true
- setMask(findNodeHandle(this.input), this.props.mask)
+ const onChangeText = useCallback(masked => {
+ if(masked === prevValue.current) return;
+ if (props.mask) {
+ const _unmasked = unmask(props.mask, masked, unmasked => {
+ props.onChangeText && props.onChangeText(masked, unmasked);
+ });
+ } else {
+ props.onChangeText && props.onChangeText(masked);
+ }
+ },[props.onChangeText,prevValue.current])
+
+ useImperativeHandle(ref,()=>({
+ isFocused : ()=>{
+ return inputRef.current && inputRef.current.isFocused()
+ },
+ focus: ()=>{
+ return inputRef.current && inputRef.current.focus();
+ },
+ blur : ()=>{
+ return inputRef.current && inputRef.current.blur();
+ },
+ clear: ()=>{
+ return inputRef.current && inputRef.current.clear();
+ },
+ setNativeProps : ({ mask: inputMask, text, ...nativeProps})=>{
+ if( (inputMask || props.mask) && (text || props.value)) setNativeTextMask(text || props.value, inputMask || props.mask);
+ if(inputMask !== props.mask) setNativeMask(inputMask);
+ return Object.keys(nativeProps).length && inputRef.current && inputRef.current.setNativeProps(nativeProps)
}
- }
-
- componentWillReceiveProps(nextProps) {
- if (nextProps.mask && (this.props.value !== nextProps.value)) {
- mask(this.props.mask, '' + nextProps.value, text =>
- this.input && this.input.setNativeProps({ text })
- );
+ }));
+
+ useEffect(() => {
+ if (props.maskDefaultValue && props.mask && props.value) setNativeTextMask(props.value, props.mask)
+ if (props.mask && !masked.current) {
+ setNativeMask(props.mask);
+ masked.current = true;
}
-
- if (this.props.mask !== nextProps.mask) {
- setMask(findNodeHandle(this.input), nextProps.mask)
+ isMounted.current = true;
+ return ()=>{
+ isMounted.current = false
}
+ }, []);
+
+ // Check if value change
+ if(props.value !== prevValue.current){
+ isMounted.current && setNativeTextMask(props.value,props.mask);
+ }
+ //Check if mask change
+ if(props.mask !== prevMask.current){
+ isMounted.current && setNativeMask(props.mask);
+ prevMask.current = props.mask;
}
- render() {
- return ( {
- this.input = ref
- if (typeof this.props.refInput === 'function') {
- this.props.refInput(ref)
- }
- }}
- multiline={this.props.mask && Platform.OS === 'ios' ? false : this.props.multiline}
- onChangeText={masked => {
- if (this.props.mask) {
- const _unmasked = unmask(this.props.mask, masked, unmasked => {
- this.props.onChangeText && this.props.onChangeText(masked, unmasked)
- })
- } else {
- this.props.onChangeText && this.props.onChangeText(masked)
- }
- }}
- />);
- }
+ multiline={props.mask && Platform.OS === "ios" ? false : props.multiline}
+ onChangeText={onChangeText}
+ />
+ );
}
+
+TextInputMask = React.forwardRef(TextInputMask);
+
+TextInputMask.defaultProps = {
+ maskDefaultValue: true
+};
+
+export default React.memo(TextInputMask,(prevProps,nextProps)=>prevProps.mask === nextProps.mask && prevProps.value === nextProps.value);
diff --git a/package.json b/package.json
index ca59f9d..eb03c92 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "react-native-text-input-mask",
- "version": "2.0.0",
+ "version": "2.0.1",
"description": "Text input mask for React Native.",
"main": "index.js",
"repository": {