@react-native-ohos/react-native-text-input-mask 3.1.6-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.OpenSource +11 -0
- package/README.md +134 -0
- package/dist/babel.config.d.ts +7 -0
- package/dist/babel.config.js +16 -0
- package/dist/babel.config.js.map +1 -0
- package/dist/index.d.ts +138 -0
- package/dist/index.js +92 -0
- package/dist/index.js.map +1 -0
- package/dist/src/RNNativeTextInputMask.d.ts +129 -0
- package/dist/src/RNNativeTextInputMask.js +8 -0
- package/dist/src/RNNativeTextInputMask.js.map +1 -0
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.harmony.d.ts +127 -0
- package/dist/src/index.harmony.js +23 -0
- package/dist/src/index.harmony.js.map +1 -0
- package/dist/src/index.js +27 -0
- package/dist/src/index.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/harmony/text_input_mask/BuildProfile.ets +17 -0
- package/harmony/text_input_mask/Index.ets +7 -0
- package/harmony/text_input_mask/build-profile.json5 +31 -0
- package/harmony/text_input_mask/consumer-rules.txt +0 -0
- package/harmony/text_input_mask/hvigorfile.ts +6 -0
- package/harmony/text_input_mask/obfuscation-rules.txt +23 -0
- package/harmony/text_input_mask/oh-package.json5 +11 -0
- package/harmony/text_input_mask/src/main/cpp/CMakeLists.txt +9 -0
- package/harmony/text_input_mask/src/main/cpp/RNTextInputMask.cpp +415 -0
- package/harmony/text_input_mask/src/main/cpp/RNTextInputMask.h +93 -0
- package/harmony/text_input_mask/src/main/cpp/RNTextInputMaskPackage.h +32 -0
- package/harmony/text_input_mask/src/main/cpp/common/Compiler.h +175 -0
- package/harmony/text_input_mask/src/main/cpp/common/FormatError.h +23 -0
- package/harmony/text_input_mask/src/main/cpp/common/FormatSanitizer.h +231 -0
- package/harmony/text_input_mask/src/main/cpp/common/Mask.h +378 -0
- package/harmony/text_input_mask/src/main/cpp/common/RTLMask.h +79 -0
- package/harmony/text_input_mask/src/main/cpp/common/model/AffinityCalculationStrategy.h +58 -0
- package/harmony/text_input_mask/src/main/cpp/common/model/CaretString.h +76 -0
- package/harmony/text_input_mask/src/main/cpp/common/model/CaretStringIterator.h +58 -0
- package/harmony/text_input_mask/src/main/cpp/common/model/Next.h +25 -0
- package/harmony/text_input_mask/src/main/cpp/common/model/Notation.h +25 -0
- package/harmony/text_input_mask/src/main/cpp/common/model/RTLCaretStringIterator.h +23 -0
- package/harmony/text_input_mask/src/main/cpp/common/model/State.h +302 -0
- package/harmony/text_input_mask/src/main/cpp/common/model/common.h +95 -0
- package/harmony/text_input_mask/src/main/ets/RNTextInputMaskPackage.ts +29 -0
- package/harmony/text_input_mask/src/main/ets/RNTextInputMaskTurboModle.ts +33 -0
- package/harmony/text_input_mask/src/main/module.json5 +11 -0
- package/harmony/text_input_mask/src/main/resources/base/element/string.json +8 -0
- package/harmony/text_input_mask/src/main/resources/en_US/element/string.json +8 -0
- package/harmony/text_input_mask/src/main/resources/zh_CN/element/string.json +8 -0
- package/harmony/text_input_mask/ts.ts +8 -0
- package/harmony/text_input_mask.har +0 -0
- package/index.tsx +258 -0
- package/package.json +50 -0
- package/src/RNNativeTextInputMask.ts +143 -0
- package/src/index.harmony.ts +147 -0
- package/src/index.ts +36 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2017 Ivan Zotov
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"Name": "@react-native-ohos/react-native-text-input-mask",
|
|
4
|
+
"License": "MIT License",
|
|
5
|
+
"License File": " LICENSE ",
|
|
6
|
+
"Version Number": "3.1.6-rc.1",
|
|
7
|
+
"Owner" : "xiafeng@huawei.com",
|
|
8
|
+
"Upstream URL": "https://github.com/react-native-text-input-mask/react-native-text-input-mask",
|
|
9
|
+
"Description": "Text input mask for React Native on iOS and Android."
|
|
10
|
+
}
|
|
11
|
+
]
|
package/README.md
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# react-native-text-input-mask
|
|
2
|
+
Text input mask for React Native on iOS and Android.
|
|
3
|
+
|
|
4
|
+
<a href="https://www.npmjs.org/package/react-native-text-input-mask">
|
|
5
|
+
<img src="https://badge.fury.io/js/react-native-text-input-mask.svg" alt="NPM package version." />
|
|
6
|
+
</a>
|
|
7
|
+
<a href="https://github.com/react-native-community/react-native-text-input-mask/blob/master/LICENSE">
|
|
8
|
+
<img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT license." />
|
|
9
|
+
</a>
|
|
10
|
+
|
|
11
|
+
## Examples
|
|
12
|
+
|
|
13
|
+

|
|
14
|
+

|
|
15
|
+
|
|
16
|
+
## Setup
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install --save react-native-text-input-mask
|
|
20
|
+
|
|
21
|
+
# --- or ---
|
|
22
|
+
|
|
23
|
+
yarn add react-native-text-input-mask
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
# Installation
|
|
27
|
+
|
|
28
|
+
<details>
|
|
29
|
+
<summary><b>For RN >= 0.60</b></summary>
|
|
30
|
+
|
|
31
|
+
#### iOS
|
|
32
|
+
1. Configure pods (static or dynamic linking)
|
|
33
|
+
<details>
|
|
34
|
+
<summary>Static Library ( Podfile has no use_frameworks! ) </summary>
|
|
35
|
+
Add following lines to your target in `Podfile`. Linking is not required in React Native 0.60 and above.
|
|
36
|
+
|
|
37
|
+
```ruby
|
|
38
|
+
pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text', :modular_headers => true
|
|
39
|
+
```
|
|
40
|
+
</details>
|
|
41
|
+
<details>
|
|
42
|
+
<summary>Dynamic Framework ( Podfile has use_frameworks! ) </summary>
|
|
43
|
+
Add following lines to your target in `Podfile` if it doesnt exist. Linking is not required in React Native 0.60 and above.
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
use_frameworks!
|
|
47
|
+
```
|
|
48
|
+
</details>
|
|
49
|
+
|
|
50
|
+
2. Run `pod install` in the `ios` directory.
|
|
51
|
+
|
|
52
|
+
#### Android
|
|
53
|
+
|
|
54
|
+
No need to do anything.
|
|
55
|
+
|
|
56
|
+
</details>
|
|
57
|
+
|
|
58
|
+
<details><summary><b>For RN < 0.60</b></summary>
|
|
59
|
+
|
|
60
|
+
### WARNING! This is no longer officially supported, these instructions are out of date and may no longer work, we recommend upgrading to a newer version of React Native.
|
|
61
|
+
|
|
62
|
+
### Link
|
|
63
|
+
```bash
|
|
64
|
+
react-native link react-native-text-input-mask
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**iOS only:** you have to drag and drop `InputMask.framework` to `Embedded Binaries` in General tab of Target
|
|
68
|
+
|
|
69
|
+

|
|
70
|
+
|
|
71
|
+
### Manual installation
|
|
72
|
+
|
|
73
|
+
#### iOS
|
|
74
|
+
|
|
75
|
+
1. In XCode, in the project navigator, right click `Libraries` ➜ `Add Files to [your project's name]`
|
|
76
|
+
2. Go to `node_modules` ➜ `react-native-text-input-mask` and add `RNTextInputMask.xcodeproj`
|
|
77
|
+
3. In XCode, in the project navigator, select your project. Add `libRNTextInputMask.a` to your project's `Build Phases` ➜ `Link Binary With Libraries`
|
|
78
|
+
4. Run your project (`Cmd+R`)
|
|
79
|
+
|
|
80
|
+
#### Android
|
|
81
|
+
|
|
82
|
+
1. Open up `android/app/src/main/java/[...]/MainActivity.java`
|
|
83
|
+
- Add `import com.RNTextInputMask.RNTextInputMaskPackage;` to the imports at the top of the file
|
|
84
|
+
- Add `new RNTextInputMaskPackage()` to the list returned by the `getPackages()` method
|
|
85
|
+
2. Append the following lines to `android/settings.gradle`:
|
|
86
|
+
```
|
|
87
|
+
include ':react-native-text-input-mask'
|
|
88
|
+
project(':react-native-text-input-mask').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-text-input-mask/android')
|
|
89
|
+
```
|
|
90
|
+
3. Insert the following lines inside the dependencies block in `android/app/build.gradle`:
|
|
91
|
+
```
|
|
92
|
+
compile project(':react-native-text-input-mask')
|
|
93
|
+
```
|
|
94
|
+
</details>
|
|
95
|
+
|
|
96
|
+
## Usage
|
|
97
|
+
|
|
98
|
+
```javascript
|
|
99
|
+
import TextInputMask from 'react-native-text-input-mask';
|
|
100
|
+
...
|
|
101
|
+
<TextInputMask
|
|
102
|
+
onChangeText={(formatted, extracted) => {
|
|
103
|
+
console.log(formatted) // +1 (123) 456-78-90
|
|
104
|
+
console.log(extracted) // 1234567890
|
|
105
|
+
}}
|
|
106
|
+
mask={"+1 ([000]) [000] [00] [00]"}
|
|
107
|
+
/>
|
|
108
|
+
...
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Testing
|
|
112
|
+
|
|
113
|
+
### Jest
|
|
114
|
+
|
|
115
|
+
Make sure to [mock](https://jestjs.io/docs/en/manual-mocks#mocking-node-modules) the following to `jest.setup.js`:
|
|
116
|
+
```javascript
|
|
117
|
+
jest.mock('react-native-text-input-mask', () => ({
|
|
118
|
+
default: jest.fn(),
|
|
119
|
+
}))
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## More info
|
|
123
|
+
|
|
124
|
+
[RedMadRobot Input Mask Android](https://github.com/RedMadRobot/input-mask-android)
|
|
125
|
+
|
|
126
|
+
[RedMadRobot Input Mask IOS](https://github.com/RedMadRobot/input-mask-ios)
|
|
127
|
+
|
|
128
|
+
## Versioning
|
|
129
|
+
|
|
130
|
+
This project uses semantic versioning: MAJOR.MINOR.PATCH.
|
|
131
|
+
This means that releases within the same MAJOR version are always backwards compatible. For more info see [semver.org](http://semver.org/).
|
|
132
|
+
|
|
133
|
+
## Local Development and testing
|
|
134
|
+
To use a local copy with your project, it's highly recommended to use https://github.com/wix/wml
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
module.exports = {
|
|
3
|
+
presets: ['module:metro-react-native-babel-preset'],
|
|
4
|
+
plugins: [
|
|
5
|
+
[
|
|
6
|
+
'module-resolver',
|
|
7
|
+
{
|
|
8
|
+
alias: {
|
|
9
|
+
'@react-native-community/push-notification-ios': './js',
|
|
10
|
+
},
|
|
11
|
+
cwd: 'babelrc',
|
|
12
|
+
},
|
|
13
|
+
],
|
|
14
|
+
],
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=babel.config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"babel.config.js","sourceRoot":"","sources":["../babel.config.js"],"names":[],"mappings":";AAAA,MAAM,CAAC,OAAO,GAAG;IACf,OAAO,EAAE,CAAC,wCAAwC,CAAC;IACnD,OAAO,EAAE;QACP;YACE,iBAAiB;YACjB;gBACE,KAAK,EAAE;oBACL,+CAA+C,EAAE,MAAM;iBACxD;gBACD,GAAG,EAAE,SAAS;aACf;SACF;KACF;CACF,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import React, { DependencyList } from 'react';
|
|
2
|
+
import { TextInputProps } from 'react-native';
|
|
3
|
+
import HarmonyTextInputMask from './src/index.harmony';
|
|
4
|
+
export declare const mask: (mask: string, value: string, autocomplete: boolean) => Promise<string>;
|
|
5
|
+
export declare const unmask: (mask: string, value: string, autocomplete: boolean) => Promise<string>;
|
|
6
|
+
export declare const setMask: (reactNode: number, primaryFormat: string, options?: import("./src/index.harmony").MaskOptions) => void;
|
|
7
|
+
export declare const unmaskWithRightToLeft: typeof HarmonyTextInputMask.unmaskWithRightToLeft;
|
|
8
|
+
declare const TextInputMask: React.ForwardRefExoticComponent<TextInputMaskProps & React.RefAttributes<Handles>>;
|
|
9
|
+
export declare const useEffectAsync: (operation: () => Promise<void>, deps?: DependencyList) => void;
|
|
10
|
+
interface MaskOptions {
|
|
11
|
+
affineFormats?: string[];
|
|
12
|
+
customNotations?: Notation[];
|
|
13
|
+
affinityCalculationStrategy?: AffinityCalculationStrategy;
|
|
14
|
+
/**
|
|
15
|
+
* autocomplete pattern while editing text
|
|
16
|
+
*/
|
|
17
|
+
autocomplete?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* automatically remove mask characters on backspace
|
|
20
|
+
*/
|
|
21
|
+
autoskip?: boolean;
|
|
22
|
+
rightToLeft?: boolean;
|
|
23
|
+
}
|
|
24
|
+
type AffinityCalculationStrategy =
|
|
25
|
+
/**
|
|
26
|
+
* Default strategy.
|
|
27
|
+
*
|
|
28
|
+
* Uses ```Mask``` built-in mechanism to calculate total affinity between the text and the mask format.
|
|
29
|
+
*
|
|
30
|
+
* For example:
|
|
31
|
+
* ```
|
|
32
|
+
* format: [00].[00]
|
|
33
|
+
*
|
|
34
|
+
* input1: 1234
|
|
35
|
+
* input2: 12.34
|
|
36
|
+
* input3: 1.234
|
|
37
|
+
*
|
|
38
|
+
* affinity1 = 4 (symbols) - 1 (missed dot) = 3
|
|
39
|
+
* affinity2 = 5 (symbols) = 5
|
|
40
|
+
* affinity3 = 5 (symbols) - 1 (superfluous dot) - 1 (missed dot) = 3
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
'WHOLE_STRING' |
|
|
44
|
+
/**
|
|
45
|
+
* Finds the longest common prefix between the original text and the same text after applying the mask.
|
|
46
|
+
*
|
|
47
|
+
* For example:
|
|
48
|
+
* ```
|
|
49
|
+
* format1: +7 [000] [000]
|
|
50
|
+
* format2: 8 [000] [000]
|
|
51
|
+
*
|
|
52
|
+
* input: +7 12 345
|
|
53
|
+
* affinity1 = 5
|
|
54
|
+
* affinity2 = 0
|
|
55
|
+
*
|
|
56
|
+
* input: 8 12 345
|
|
57
|
+
* affinity1 = 0
|
|
58
|
+
* affinity2 = 4
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
'PREFIX' |
|
|
62
|
+
/**
|
|
63
|
+
* Affinity is tolerance between the length of the input and the total amount of text current mask can accommodate.
|
|
64
|
+
*
|
|
65
|
+
* If current mask can't accommodate all the text, the affinity equals `Int.min`.
|
|
66
|
+
*
|
|
67
|
+
* For example:
|
|
68
|
+
* ```
|
|
69
|
+
* format1: [00]-[0]
|
|
70
|
+
* format2: [00]-[000]
|
|
71
|
+
* format3: [00]-[00000]
|
|
72
|
+
*
|
|
73
|
+
* input affinity1 affinity2 affinity3
|
|
74
|
+
* 1 -3 -5 -7
|
|
75
|
+
* 12 -2 -4 -6
|
|
76
|
+
* 123 -1 -3 -5
|
|
77
|
+
* 12-3 0 -2 -4
|
|
78
|
+
* 1234 0 -2 -4
|
|
79
|
+
* 12345 Int.MIN_VALUE -1 -3
|
|
80
|
+
* 123456 Int.MIN_VALUE 0 -2
|
|
81
|
+
* ```
|
|
82
|
+
*
|
|
83
|
+
* This affinity calculation strategy comes in handy when the mask format radically changes depending on the input
|
|
84
|
+
* length.
|
|
85
|
+
*
|
|
86
|
+
* N.B.: Make sure the widest mask format is the primary mask format.
|
|
87
|
+
*/
|
|
88
|
+
'CAPACITY' |
|
|
89
|
+
/**
|
|
90
|
+
* Affinity is tolerance between the length of the extracted value and the total extracted value length current mask can accommodate.
|
|
91
|
+
*
|
|
92
|
+
* If current mask can't accommodate all the text, the affinity equals `Int.min`.
|
|
93
|
+
*
|
|
94
|
+
* For example:
|
|
95
|
+
* ```
|
|
96
|
+
* format1: [00]-[0]
|
|
97
|
+
* format2: [00]-[000]
|
|
98
|
+
* format3: [00]-[00000]
|
|
99
|
+
*
|
|
100
|
+
* input affinity1 affinity2 affinity3
|
|
101
|
+
* 1 -2 -4 -6
|
|
102
|
+
* 12 -1 -3 -5
|
|
103
|
+
* 123 0 -2 -4
|
|
104
|
+
* 12-3 0 -2 -4
|
|
105
|
+
* 1234 Int.MIN_VALUE -1 -3
|
|
106
|
+
* 12345 Int.MIN_VALUE 0 -2
|
|
107
|
+
* 123456 Int.MIN_VALUE Int.MIN_VALUE -1
|
|
108
|
+
* ```
|
|
109
|
+
*
|
|
110
|
+
* This affinity calculation strategy comes in handy when the mask format radically changes depending on the value
|
|
111
|
+
* length.
|
|
112
|
+
*
|
|
113
|
+
* N.B.: Make sure the widest mask format is the primary mask format.
|
|
114
|
+
*/
|
|
115
|
+
'EXTRACTED_VALUE_CAPACITY';
|
|
116
|
+
interface Notation {
|
|
117
|
+
/**
|
|
118
|
+
* A symbol in format string.
|
|
119
|
+
*/
|
|
120
|
+
character: string;
|
|
121
|
+
/**
|
|
122
|
+
* An associated character set of acceptable input characters.
|
|
123
|
+
*/
|
|
124
|
+
characterSet: string;
|
|
125
|
+
/**
|
|
126
|
+
* Is it an optional symbol or mandatory?
|
|
127
|
+
*/
|
|
128
|
+
isOptional: boolean;
|
|
129
|
+
}
|
|
130
|
+
export interface TextInputMaskProps extends TextInputProps, MaskOptions {
|
|
131
|
+
mask?: string;
|
|
132
|
+
onChangeText?: (formatted: string, extracted?: string) => void;
|
|
133
|
+
}
|
|
134
|
+
interface Handles {
|
|
135
|
+
focus: () => void;
|
|
136
|
+
blur: () => void;
|
|
137
|
+
}
|
|
138
|
+
export default TextInputMask;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
|
|
3
|
+
* Use of this source code is governed by a MIT license that can be
|
|
4
|
+
* found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
import { __awaiter, __rest } from "tslib";
|
|
7
|
+
import React, { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';
|
|
8
|
+
import { findNodeHandle, Platform, TextInput } from 'react-native';
|
|
9
|
+
import exportMasker from './src/index';
|
|
10
|
+
import HarmonyTextInputMask from './src/index.harmony';
|
|
11
|
+
const isIosAndroid = Platform.OS === 'ios' || Platform.OS === 'android';
|
|
12
|
+
export const mask = exportMasker.mask;
|
|
13
|
+
export const unmask = exportMasker.unmask;
|
|
14
|
+
export const setMask = exportMasker.setMask;
|
|
15
|
+
export const unmaskWithRightToLeft = HarmonyTextInputMask.unmaskWithRightToLeft;
|
|
16
|
+
const TextInputMask = forwardRef((_a, ref) => {
|
|
17
|
+
var { mask: primaryFormat, defaultValue, value, multiline, onChangeText, affineFormats, customNotations, affinityCalculationStrategy, autocomplete = true, autoskip = true, rightToLeft } = _a, rest = __rest(_a, ["mask", "defaultValue", "value", "multiline", "onChangeText", "affineFormats", "customNotations", "affinityCalculationStrategy", "autocomplete", "autoskip", "rightToLeft"]);
|
|
18
|
+
const input = useRef(null);
|
|
19
|
+
const [maskedValue, setMaskedValue] = useState();
|
|
20
|
+
const didLayout = useRef(false);
|
|
21
|
+
const handleLayout = () => {
|
|
22
|
+
didLayout.current = true;
|
|
23
|
+
const nodeId = findNodeHandle(input.current);
|
|
24
|
+
if (primaryFormat && nodeId) {
|
|
25
|
+
setMask(nodeId, primaryFormat, { affineFormats, affinityCalculationStrategy, customNotations, autocomplete, autoskip, rightToLeft });
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
useEffectAsync(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
29
|
+
const initialValue = value !== null && value !== void 0 ? value : defaultValue;
|
|
30
|
+
if (!initialValue)
|
|
31
|
+
return;
|
|
32
|
+
if (primaryFormat) {
|
|
33
|
+
const masked = yield mask(primaryFormat, initialValue, false);
|
|
34
|
+
setMaskedValue(masked);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
setMaskedValue(initialValue);
|
|
38
|
+
}
|
|
39
|
+
}), []);
|
|
40
|
+
useEffectAsync(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
41
|
+
if (value === maskedValue)
|
|
42
|
+
return;
|
|
43
|
+
if (primaryFormat && value) {
|
|
44
|
+
const masked = yield mask(primaryFormat, value, false);
|
|
45
|
+
setMaskedValue(masked);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
setMaskedValue(value);
|
|
49
|
+
}
|
|
50
|
+
}), [value]);
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
if (didLayout.current) {
|
|
53
|
+
const nodeId = findNodeHandle(input.current);
|
|
54
|
+
if (primaryFormat && nodeId) {
|
|
55
|
+
setMask(nodeId, primaryFormat, { affineFormats, affinityCalculationStrategy, customNotations, autocomplete, autoskip, rightToLeft });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}, [primaryFormat]);
|
|
59
|
+
useImperativeHandle(ref, () => ({
|
|
60
|
+
focus: () => {
|
|
61
|
+
var _a;
|
|
62
|
+
(_a = input.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
63
|
+
},
|
|
64
|
+
blur: () => {
|
|
65
|
+
var _a;
|
|
66
|
+
(_a = input.current) === null || _a === void 0 ? void 0 : _a.blur();
|
|
67
|
+
}
|
|
68
|
+
}));
|
|
69
|
+
return (<TextInput {...rest} ref={input} value={maskedValue} multiline={primaryFormat && Platform.OS === 'ios' ? false : multiline} onLayout={handleLayout} onChangeText={(masked) => __awaiter(void 0, void 0, void 0, function* () {
|
|
70
|
+
setMaskedValue(masked);
|
|
71
|
+
if (primaryFormat) {
|
|
72
|
+
if (isIosAndroid) {
|
|
73
|
+
const unmasked = yield unmask(primaryFormat, masked, true);
|
|
74
|
+
onChangeText === null || onChangeText === void 0 ? void 0 : onChangeText(masked, unmasked);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
const unmasked = yield unmaskWithRightToLeft(primaryFormat, masked, true, rightToLeft === undefined ? false : rightToLeft);
|
|
78
|
+
onChangeText === null || onChangeText === void 0 ? void 0 : onChangeText(masked, unmasked);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
onChangeText === null || onChangeText === void 0 ? void 0 : onChangeText(masked);
|
|
83
|
+
}
|
|
84
|
+
})}/>);
|
|
85
|
+
});
|
|
86
|
+
export const useEffectAsync = (operation, deps) => {
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
operation().then();
|
|
89
|
+
}, deps);
|
|
90
|
+
};
|
|
91
|
+
export default TextInputMask;
|
|
92
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import type { TurboModule } from "react-native/Libraries/TurboModule/RCTExport";
|
|
2
|
+
export interface MaskOptions {
|
|
3
|
+
affineFormats?: string[];
|
|
4
|
+
customNotations?: Notation[];
|
|
5
|
+
affinityCalculationStrategy?: AffinityCalculationStrategy;
|
|
6
|
+
/**
|
|
7
|
+
* autocomplete pattern while editing text
|
|
8
|
+
*/
|
|
9
|
+
autocomplete?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* automatically remove mask characters on backspace
|
|
12
|
+
*/
|
|
13
|
+
autoskip?: boolean;
|
|
14
|
+
rightToLeft?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export type AffinityCalculationStrategy =
|
|
17
|
+
/**
|
|
18
|
+
* Default strategy.
|
|
19
|
+
*
|
|
20
|
+
* Uses ```Mask``` built-in mechanism to calculate total affinity between the text and the mask format.
|
|
21
|
+
*
|
|
22
|
+
* For example:
|
|
23
|
+
* ```
|
|
24
|
+
* format: [00].[00]
|
|
25
|
+
*
|
|
26
|
+
* input1: 1234
|
|
27
|
+
* input2: 12.34
|
|
28
|
+
* input3: 1.234
|
|
29
|
+
*
|
|
30
|
+
* affinity1 = 4 (symbols) - 1 (missed dot) = 3
|
|
31
|
+
* affinity2 = 5 (symbols) = 5
|
|
32
|
+
* affinity3 = 5 (symbols) - 1 (superfluous dot) - 1 (missed dot) = 3
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
'WHOLE_STRING' |
|
|
36
|
+
/**
|
|
37
|
+
* Finds the longest common prefix between the original text and the same text after applying the mask.
|
|
38
|
+
*
|
|
39
|
+
* For example:
|
|
40
|
+
* ```
|
|
41
|
+
* format1: +7 [000] [000]
|
|
42
|
+
* format2: 8 [000] [000]
|
|
43
|
+
*
|
|
44
|
+
* input: +7 12 345
|
|
45
|
+
* affinity1 = 5
|
|
46
|
+
* affinity2 = 0
|
|
47
|
+
*
|
|
48
|
+
* input: 8 12 345
|
|
49
|
+
* affinity1 = 0
|
|
50
|
+
* affinity2 = 4
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
'PREFIX' |
|
|
54
|
+
/**
|
|
55
|
+
* Affinity is tolerance between the length of the input and the total amount of text current mask can accommodate.
|
|
56
|
+
*
|
|
57
|
+
* If current mask can't accommodate all the text, the affinity equals `Int.min`.
|
|
58
|
+
*
|
|
59
|
+
* For example:
|
|
60
|
+
* ```
|
|
61
|
+
* format1: [00]-[0]
|
|
62
|
+
* format2: [00]-[000]
|
|
63
|
+
* format3: [00]-[00000]
|
|
64
|
+
*
|
|
65
|
+
* input affinity1 affinity2 affinity3
|
|
66
|
+
* 1 -3 -5 -7
|
|
67
|
+
* 12 -2 -4 -6
|
|
68
|
+
* 123 -1 -3 -5
|
|
69
|
+
* 12-3 0 -2 -4
|
|
70
|
+
* 1234 0 -2 -4
|
|
71
|
+
* 12345 Int.MIN_VALUE -1 -3
|
|
72
|
+
* 123456 Int.MIN_VALUE 0 -2
|
|
73
|
+
* ```
|
|
74
|
+
*
|
|
75
|
+
* This affinity calculation strategy comes in handy when the mask format radically changes depending on the input
|
|
76
|
+
* length.
|
|
77
|
+
*
|
|
78
|
+
* N.B.: Make sure the widest mask format is the primary mask format.
|
|
79
|
+
*/
|
|
80
|
+
'CAPACITY' |
|
|
81
|
+
/**
|
|
82
|
+
* Affinity is tolerance between the length of the extracted value and the total extracted value length current mask can accommodate.
|
|
83
|
+
*
|
|
84
|
+
* If current mask can't accommodate all the text, the affinity equals `Int.min`.
|
|
85
|
+
*
|
|
86
|
+
* For example:
|
|
87
|
+
* ```
|
|
88
|
+
* format1: [00]-[0]
|
|
89
|
+
* format2: [00]-[000]
|
|
90
|
+
* format3: [00]-[00000]
|
|
91
|
+
*
|
|
92
|
+
* input affinity1 affinity2 affinity3
|
|
93
|
+
* 1 -2 -4 -6
|
|
94
|
+
* 12 -1 -3 -5
|
|
95
|
+
* 123 0 -2 -4
|
|
96
|
+
* 12-3 0 -2 -4
|
|
97
|
+
* 1234 Int.MIN_VALUE -1 -3
|
|
98
|
+
* 12345 Int.MIN_VALUE 0 -2
|
|
99
|
+
* 123456 Int.MIN_VALUE Int.MIN_VALUE -1
|
|
100
|
+
* ```
|
|
101
|
+
*
|
|
102
|
+
* This affinity calculation strategy comes in handy when the mask format radically changes depending on the value
|
|
103
|
+
* length.
|
|
104
|
+
*
|
|
105
|
+
* N.B.: Make sure the widest mask format is the primary mask format.
|
|
106
|
+
*/
|
|
107
|
+
'EXTRACTED_VALUE_CAPACITY';
|
|
108
|
+
interface Notation {
|
|
109
|
+
/**
|
|
110
|
+
* A symbol in format string.
|
|
111
|
+
*/
|
|
112
|
+
character: string;
|
|
113
|
+
/**
|
|
114
|
+
* An associated character set of acceptable input characters.
|
|
115
|
+
*/
|
|
116
|
+
characterSet: string;
|
|
117
|
+
/**
|
|
118
|
+
* Is it an optional symbol or mandatory?
|
|
119
|
+
*/
|
|
120
|
+
isOptional: boolean;
|
|
121
|
+
}
|
|
122
|
+
export interface Spec extends TurboModule {
|
|
123
|
+
mask(mask: string, value: string, autocomplete: boolean): Promise<string>;
|
|
124
|
+
unmask(mask: string, value: string, autocomplete: boolean): Promise<string>;
|
|
125
|
+
setMask(reactNode: number, primaryFormat: string, options?: MaskOptions): void;
|
|
126
|
+
unmaskWithRightToLeft(mask: string, value: string, autocomplete: boolean, rightToLeft: boolean): Promise<string>;
|
|
127
|
+
}
|
|
128
|
+
declare const _default: Spec;
|
|
129
|
+
export default _default;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
|
|
3
|
+
* Use of this source code is governed by a MIT license that can be
|
|
4
|
+
* found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
import { TurboModuleRegistry } from "react-native";
|
|
7
|
+
export default TurboModuleRegistry.get('RNTextInputMask');
|
|
8
|
+
//# sourceMappingURL=RNNativeTextInputMask.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RNNativeTextInputMask.js","sourceRoot":"","sources":["../../src/RNNativeTextInputMask.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,mBAAmB,EAAC,MAAM,cAAc,CAAC;AAuIlD,eAAe,mBAAmB,CAAC,GAAG,CAAO,iBAAiB,CAAS,CAAE"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { MaskOptions } from './index.harmony';
|
|
2
|
+
interface MaskOperations {
|
|
3
|
+
mask(mask: string, value: string, autocomplete: boolean): Promise<string>;
|
|
4
|
+
unmask(mask: string, value: string, autocomplete: boolean): Promise<string>;
|
|
5
|
+
setMask(reactNode: number, primaryFormat: string, options?: MaskOptions): void;
|
|
6
|
+
}
|
|
7
|
+
export declare const exportMasker: MaskOperations;
|
|
8
|
+
export default exportMasker;
|