Skip to content

Commit 32fa643

Browse files
author
drawciamage
committed
Initial commit
0 parents  commit 32fa643

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+10805
-0
lines changed

.eslintrc

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"extends": "@react-native-community",
3+
"globals": {
4+
"it": true,
5+
"expect": true,
6+
"element": true,
7+
"describe": true,
8+
"by": true,
9+
"device": true,
10+
"beforeAll": true,
11+
"beforeEach": true,
12+
"afterAll": true,
13+
"jest": true,
14+
"jasmine": true
15+
}
16+
}

.gitattributes

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.pbxproj -text

.gitignore

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
2+
# OSX
3+
#
4+
.DS_Store
5+
6+
# node.js
7+
#
8+
node_modules/
9+
npm-debug.log
10+
yarn-error.log
11+
12+
13+
# Xcode
14+
#
15+
build/
16+
*.pbxuser
17+
!default.pbxuser
18+
*.mode1v3
19+
!default.mode1v3
20+
*.mode2v3
21+
!default.mode2v3
22+
*.perspectivev3
23+
!default.perspectivev3
24+
xcuserdata
25+
*.xccheckout
26+
*.moved-aside
27+
DerivedData
28+
*.hmap
29+
*.ipa
30+
*.xcuserstate
31+
project.xcworkspace
32+
33+
34+
# Android/IntelliJ
35+
#
36+
build/
37+
.idea
38+
.gradle
39+
local.properties
40+
*.iml
41+
42+
# BUCK
43+
buck-out/
44+
\.buckd/
45+
*.keystore
46+
ios/Pods

README.md

+176
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
<h1 align="center">
2+
<br>
3+
React-Native-Text-Input-Mask
4+
<br>
5+
</h1>
6+
7+
<h3 align="center">Text input mask for React Native on iOS and Android.</h4>
8+
9+
<h4 align="center">Forked from
10+
<a href="https://github.com/react-native-community/react-native-text-input-mask">react-native-community/react-native-text-input-mask</a> (Ivan Zotov).
11+
</h4>
12+
13+
<h4 align="center">
14+
<a href="https://github.com/drawciamage/react-native-text-input-mask/LICENSE">
15+
<img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT license." />
16+
</a>
17+
</h4>
18+
19+
## 📝 Additional Features
20+
21+
- Rewritten with React Hooks.
22+
- Eslint-config updated to 1.1.0.
23+
- Fix "componentWillReceiveProps" Warnings.
24+
- Fix "FATAL EXCEPTION: IndexOutOfBoundsException".
25+
- Fix "Android Backspace Rendering Issue".
26+
27+
<br>
28+
ONLY TESTED IN ANDROID 9.
29+
30+
## 💻 Examples
31+
32+
<h4 align="center">
33+
34+
![React Native Text Input Mask iOS](https://s3.amazonaws.com/react-native-text-input-mask/react-native-text-input-mask-ios.gif)
35+
![React Native Text Input Mask Android](https://s3.amazonaws.com/react-native-text-input-mask/react-native-text-input-mask-android-updated.gif)
36+
37+
</h4>
38+
39+
## 🏗️ Setup
40+
41+
```bash
42+
npm install --save drawciamage/react-native-text-input-mask
43+
# --- or ---
44+
yarn add https://github.com/drawciamage/react-native-text-input-mask.git
45+
```
46+
47+
# 💻 Installation
48+
49+
<details>
50+
<summary><b>For RN >= 0.61</b></summary>
51+
52+
#### iOS
53+
54+
1. Add following lines to your target in `Podfile`
55+
56+
```
57+
use_frameworks!
58+
pod 'RNInputMask', :path => '../node_modules/react-native-text-input-mask/ios/InputMask'
59+
```
60+
61+
2. Run following command
62+
63+
```bash
64+
cd ios && pod install
65+
```
66+
67+
#### Android
68+
69+
No need to do anything.
70+
71+
</details>
72+
73+
<details>
74+
<summary><b>For RN = 0.60.*</b></summary>
75+
76+
#### iOS
77+
78+
1. In XCode, in the project navigator, right click your `[your project's name]` folder, choose ➜ `Add Files to [your project's name]`
79+
80+
![Create Swift File](https://i.imgur.com/00K5UZ1.png)
81+
82+
2. Select `Swift File``Next`
83+
84+
![Create Swift File](https://i.imgur.com/Mdc9MLk.png)
85+
86+
3. Specify name for example `Dummy.swift``Create`
87+
88+
![Create Swift File](https://i.imgur.com/2HSk7Jp.png)
89+
90+
4. Now a pop up is shown select `Create Bridging Header`
91+
92+
![Create Swift File](https://i.imgur.com/f2zA0n9.png)
93+
94+
5. Add following line to your target in `Podfile`
95+
96+
```
97+
pod 'RNInputMask', :path => '../node_modules/react-native-text-input-mask/ios/InputMask'
98+
```
99+
100+
6. Run following command
101+
102+
```bash
103+
cd ios && pod install
104+
```
105+
106+
#### Android
107+
108+
No need to do anything.
109+
110+
</details>
111+
112+
<details><summary><b>For RN < 0.60</b></summary>
113+
114+
### Auto Linking
115+
116+
```bash
117+
react-native link react-native-text-input-mask
118+
```
119+
120+
**iOS only:** you have to drag and drop `InputMask.framework` to `Embedded Binaries` in General tab of Target
121+
122+
![](https://cdn-images-1.medium.com/max/2000/1*J0TPrRhkAKspVvv-JaZHjA.png)
123+
124+
### Manual installation
125+
126+
#### iOS
127+
128+
1. In XCode, in the project navigator, right click `Libraries``Add Files to [your project's name]`
129+
2. Go to `node_modules``react-native-text-input-mask` and add `RNTextInputMask.xcodeproj`
130+
3. In XCode, in the project navigator, select your project. Add `libRNTextInputMask.a` to your project's `Build Phases``Link Binary With Libraries`
131+
4. Run your project (`Cmd+R`)
132+
133+
#### Android
134+
135+
1. Open up `android/app/src/main/java/[...]/MainActivity.java`
136+
137+
- Add `import com.RNTextInputMask.RNTextInputMaskPackage;` to the imports at the top of the file
138+
- Add `new RNTextInputMaskPackage()` to the list returned by the `getPackages()` method
139+
140+
2. Append the following lines to `android/settings.gradle`:
141+
```
142+
include ':react-native-text-input-mask'
143+
project(':react-native-text-input-mask').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-text-input-mask/android')
144+
```
145+
3. Insert the following lines inside the dependencies block in `android/app/build.gradle`:
146+
`compile project(':react-native-text-input-mask')`
147+
</details>
148+
149+
## 👨‍🏫 Usage
150+
151+
```javascript
152+
import React, { useRef } from "react";
153+
import TextInputMask from 'react-native-text-input-mask';
154+
...
155+
const input = useRef();
156+
<TextInputMask
157+
refInput={ref => { input.current = ref }}
158+
onChangeText={(formatted, extracted) => {
159+
console.log(formatted) // +1 (123) 456-78-90
160+
console.log(extracted) // 1234567890
161+
}}
162+
mask={"+1 ([000]) [000] [00] [00]"}
163+
/>
164+
...
165+
```
166+
167+
## 📝 More info
168+
169+
[RedMadRobot Input Mask Android](https://github.com/RedMadRobot/input-mask-android)
170+
171+
[RedMadRobot Input Mask IOS](https://github.com/RedMadRobot/input-mask-ios)
172+
173+
## 📆 Versioning
174+
175+
This project uses semantic versioning: MAJOR.MINOR.PATCH.
176+
This means that releases within the same MAJOR version are always backwards compatible. For more info see [semver.org](http://semver.org/).

android/build.gradle

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
apply plugin: 'com.android.library'
2+
3+
def safeExtGet(prop, fallback) {
4+
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
5+
}
6+
7+
android {
8+
compileSdkVersion safeExtGet('compileSdkVersion', 28)
9+
buildToolsVersion safeExtGet('buildToolsVersion', '28.0.3')
10+
11+
defaultConfig {
12+
minSdkVersion safeExtGet('minSdkVersion', 16)
13+
targetSdkVersion safeExtGet('targetSdkVersion', 28)
14+
versionCode 1
15+
versionName "1.0.0"
16+
}
17+
buildTypes {
18+
release {
19+
minifyEnabled false
20+
}
21+
}
22+
lintOptions {
23+
abortOnError false
24+
}
25+
}
26+
27+
dependencies {
28+
implementation 'com.facebook.react:react-native:+'
29+
implementation 'com.redmadrobot:inputmask:4.1.0'
30+
implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.3.21'
31+
}

android/src/main/AndroidManifest.xml

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2+
package="com.RNTextInputMask">
3+
</manifest>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package com.RNTextInputMask;
2+
3+
import android.widget.EditText;
4+
import android.text.TextWatcher;
5+
import com.facebook.react.uimanager.UIManagerModule;
6+
import com.facebook.react.uimanager.UIBlock;
7+
import com.facebook.react.uimanager.NativeViewHierarchyManager;
8+
import com.facebook.react.bridge.ReactApplicationContext;
9+
import com.facebook.react.bridge.ReactContextBaseJavaModule;
10+
import com.facebook.react.bridge.ReactMethod;
11+
import com.facebook.react.bridge.Callback;
12+
import com.redmadrobot.inputmask.MaskedTextChangedListener;
13+
import com.redmadrobot.inputmask.model.CaretString;
14+
import com.redmadrobot.inputmask.helper.Mask;
15+
16+
public class RNTextInputMaskModule extends ReactContextBaseJavaModule {
17+
18+
private static final int TEXT_CHANGE_LISTENER_TAG_KEY = 123456789;
19+
20+
21+
22+
ReactApplicationContext reactContext;
23+
24+
public RNTextInputMaskModule(ReactApplicationContext reactContext) {
25+
super(reactContext);
26+
this.reactContext = reactContext;
27+
}
28+
29+
@Override
30+
public String getName() {
31+
return "RNTextInputMask";
32+
}
33+
34+
@ReactMethod
35+
public void mask(final String maskString,
36+
final String inputValue,
37+
final Callback onResult) {
38+
final Mask mask = new Mask(maskString);
39+
final String input = inputValue;
40+
final Mask.Result result = mask.apply(
41+
new CaretString(
42+
input,
43+
input.length()
44+
),
45+
false
46+
);
47+
final String output = result.getFormattedText().getString();
48+
onResult.invoke(output);
49+
}
50+
51+
@ReactMethod
52+
public void unmask(final String maskString,
53+
final String inputValue,
54+
final Callback onResult) {
55+
final Mask mask = new Mask(maskString);
56+
final String input = inputValue;
57+
final Mask.Result result = mask.apply(
58+
new CaretString(
59+
input,
60+
input.length()
61+
),
62+
true
63+
);
64+
final String output = result.getExtractedValue();
65+
onResult.invoke(output);
66+
}
67+
68+
@ReactMethod
69+
public void setMask(final int tag, final String mask) {
70+
// We need to use prependUIBlock instead of addUIBlock since subsequent UI operations in
71+
// the queue might be removing the view we're looking to update.
72+
reactContext.getNativeModule(UIManagerModule.class).prependUIBlock(new UIBlock() {
73+
@Override
74+
public void execute(NativeViewHierarchyManager nativeViewHierarchyManager) {
75+
// The view needs to be resolved before running on the UI thread because there's
76+
// a delay before the UI queue can pick up the runnable.
77+
final EditText editText = (EditText) nativeViewHierarchyManager.resolveView(tag);
78+
79+
reactContext.runOnUiQueueThread(new Runnable() {
80+
@Override
81+
public void run() {
82+
MaskedTextChangedListener listener = new MaskedTextChangedListener(
83+
mask,
84+
true,
85+
editText,
86+
null,
87+
null
88+
);
89+
90+
if (editText.getTag(TEXT_CHANGE_LISTENER_TAG_KEY) != null) {
91+
editText.removeTextChangedListener((TextWatcher) editText.getTag(TEXT_CHANGE_LISTENER_TAG_KEY));
92+
}
93+
94+
editText.setTag(TEXT_CHANGE_LISTENER_TAG_KEY, listener);
95+
editText.addTextChangedListener(listener);
96+
}
97+
});
98+
}
99+
});
100+
}
101+
}

0 commit comments

Comments
 (0)