@react-native-ohos/react-native-credit-card-input 1.0.1-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.
Files changed (66) hide show
  1. package/LICENSE +20 -0
  2. package/README.OpenSource +11 -0
  3. package/README.md +9 -0
  4. package/lib/commonjs/CreditCardInput.js +138 -0
  5. package/lib/commonjs/CreditCardInput.js.map +1 -0
  6. package/lib/commonjs/CreditCardView.js +175 -0
  7. package/lib/commonjs/CreditCardView.js.map +1 -0
  8. package/lib/commonjs/Icons.js +17 -0
  9. package/lib/commonjs/Icons.js.map +1 -0
  10. package/lib/commonjs/LiteCreditCardInput.js +189 -0
  11. package/lib/commonjs/LiteCreditCardInput.js.map +1 -0
  12. package/lib/commonjs/index.js +35 -0
  13. package/lib/commonjs/index.js.map +1 -0
  14. package/lib/commonjs/package.json +1 -0
  15. package/lib/commonjs/useCreditCardForm.js +95 -0
  16. package/lib/commonjs/useCreditCardForm.js.map +1 -0
  17. package/lib/module/CreditCardInput.js +134 -0
  18. package/lib/module/CreditCardInput.js.map +1 -0
  19. package/lib/module/CreditCardView.js +170 -0
  20. package/lib/module/CreditCardView.js.map +1 -0
  21. package/lib/module/Icons.js +13 -0
  22. package/lib/module/Icons.js.map +1 -0
  23. package/lib/module/LiteCreditCardInput.js +184 -0
  24. package/lib/module/LiteCreditCardInput.js.map +1 -0
  25. package/lib/module/index.js +7 -0
  26. package/lib/module/index.js.map +1 -0
  27. package/lib/module/package.json +1 -0
  28. package/lib/module/useCreditCardForm.js +89 -0
  29. package/lib/module/useCreditCardForm.js.map +1 -0
  30. package/lib/typescript/commonjs/jest.setup.d.ts +2 -0
  31. package/lib/typescript/commonjs/jest.setup.d.ts.map +1 -0
  32. package/lib/typescript/commonjs/package.json +1 -0
  33. package/lib/typescript/commonjs/src/CreditCardInput.d.ts +25 -0
  34. package/lib/typescript/commonjs/src/CreditCardInput.d.ts.map +1 -0
  35. package/lib/typescript/commonjs/src/CreditCardView.d.ts +23 -0
  36. package/lib/typescript/commonjs/src/CreditCardView.d.ts.map +1 -0
  37. package/lib/typescript/commonjs/src/Icons.d.ts +11 -0
  38. package/lib/typescript/commonjs/src/Icons.d.ts.map +1 -0
  39. package/lib/typescript/commonjs/src/LiteCreditCardInput.d.ts +19 -0
  40. package/lib/typescript/commonjs/src/LiteCreditCardInput.d.ts.map +1 -0
  41. package/lib/typescript/commonjs/src/index.d.ts +5 -0
  42. package/lib/typescript/commonjs/src/index.d.ts.map +1 -0
  43. package/lib/typescript/commonjs/src/useCreditCardForm.d.ts +25 -0
  44. package/lib/typescript/commonjs/src/useCreditCardForm.d.ts.map +1 -0
  45. package/lib/typescript/module/jest.setup.d.ts +2 -0
  46. package/lib/typescript/module/jest.setup.d.ts.map +1 -0
  47. package/lib/typescript/module/package.json +1 -0
  48. package/lib/typescript/module/src/CreditCardInput.d.ts +25 -0
  49. package/lib/typescript/module/src/CreditCardInput.d.ts.map +1 -0
  50. package/lib/typescript/module/src/CreditCardView.d.ts +23 -0
  51. package/lib/typescript/module/src/CreditCardView.d.ts.map +1 -0
  52. package/lib/typescript/module/src/Icons.d.ts +11 -0
  53. package/lib/typescript/module/src/Icons.d.ts.map +1 -0
  54. package/lib/typescript/module/src/LiteCreditCardInput.d.ts +19 -0
  55. package/lib/typescript/module/src/LiteCreditCardInput.d.ts.map +1 -0
  56. package/lib/typescript/module/src/index.d.ts +5 -0
  57. package/lib/typescript/module/src/index.d.ts.map +1 -0
  58. package/lib/typescript/module/src/useCreditCardForm.d.ts +25 -0
  59. package/lib/typescript/module/src/useCreditCardForm.d.ts.map +1 -0
  60. package/package.json +145 -0
  61. package/src/CreditCardInput.tsx +163 -0
  62. package/src/CreditCardView.tsx +248 -0
  63. package/src/Icons.ts +18 -0
  64. package/src/LiteCreditCardInput.tsx +226 -0
  65. package/src/index.tsx +12 -0
  66. package/src/useCreditCardForm.tsx +161 -0
package/package.json ADDED
@@ -0,0 +1,145 @@
1
+ {
2
+ "name": "@react-native-ohos/react-native-credit-card-input",
3
+ "version": "1.0.1-rc.1",
4
+ "description": "React native credit card input component",
5
+ "source": "./src/index.tsx",
6
+ "main": "./lib/commonjs/index.js",
7
+ "module": "./lib/module/index.js",
8
+ "types": "./lib/typescript/commonjs/src/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./lib/typescript/commonjs/src/index.d.ts",
12
+ "import": "./lib/module/index.js",
13
+ "require": "./lib/commonjs/index.js"
14
+ }
15
+ },
16
+ "harmony": {
17
+ "alias": "react-native-credit-card-input"
18
+ },
19
+ "files": [
20
+ "src",
21
+ "lib",
22
+ "android",
23
+ "ios",
24
+ "cpp",
25
+ "*.podspec",
26
+ "!ios/build",
27
+ "!android/build",
28
+ "!android/gradle",
29
+ "!android/gradlew",
30
+ "!android/gradlew.bat",
31
+ "!android/local.properties",
32
+ "!**/__tests__",
33
+ "!**/__fixtures__",
34
+ "!**/__mocks__",
35
+ "!**/.*"
36
+ ],
37
+ "scripts": {
38
+ "test": "jest",
39
+ "typecheck": "tsc --noEmit",
40
+ "lint": "eslint \"**/*.{js,ts,tsx}\"",
41
+ "clean": "del lib",
42
+ "build": "bob build"
43
+ },
44
+ "keywords": [
45
+ "react-native",
46
+ "ios",
47
+ "android"
48
+ ],
49
+ "license": "MIT",
50
+ "publishConfig": {
51
+ "registry": "https://registry.npmjs.org/"
52
+ },
53
+ "dependencies": {
54
+ "card-validator": "^10.0.0",
55
+ "react-native-credit-card-input": "^1.0.0",
56
+ "react-native-flip-card": "^3.5.7"
57
+ },
58
+ "devDependencies": {
59
+ "@commitlint/config-conventional": "^18.5.0",
60
+ "@evilmartians/lefthook": "^1.5.0",
61
+ "@react-native/eslint-config": "^0.73.1",
62
+ "@testing-library/react-native": "^12.5.1",
63
+ "@types/jest": "^29.5.5",
64
+ "@types/react": "^18.2.44",
65
+ "@types/react-native-flip-card": "^3.5.7",
66
+ "commitlint": "^18.5.0",
67
+ "del-cli": "^5.1.0",
68
+ "eslint": "^8.51.0",
69
+ "eslint-config-prettier": "^9.0.0",
70
+ "eslint-plugin-prettier": "^5.0.1",
71
+ "jest": "^29.7.0",
72
+ "prettier": "3.3.2",
73
+ "react": "18.3.1",
74
+ "react-native": "0.77.1",
75
+ "react-native-builder-bob": "^0.40.0",
76
+ "react-test-renderer": "^18.3.1",
77
+ "typescript": "^5.2.2"
78
+ },
79
+ "peerDependencies": {
80
+ "react": ">= 18.2.0",
81
+ "react-native": "*"
82
+ },
83
+ "resolutions": {
84
+ "@types/react": "^18.2.44"
85
+ },
86
+ "packageManager": "yarn@3.6.1",
87
+ "jest": {
88
+ "preset": "react-native",
89
+ "modulePathIgnorePatterns": [
90
+ "<rootDir>/lib/"
91
+ ],
92
+ "setupFilesAfterEnv": [
93
+ "<rootDir>/jest.setup.ts"
94
+ ]
95
+ },
96
+ "eslintConfig": {
97
+ "root": true,
98
+ "extends": [
99
+ "@react-native",
100
+ "prettier"
101
+ ],
102
+ "rules": {
103
+ "react/react-in-jsx-scope": "off",
104
+ "prettier/prettier": [
105
+ "error",
106
+ {
107
+ "quoteProps": "consistent",
108
+ "singleQuote": true,
109
+ "tabWidth": 2,
110
+ "trailingComma": "es5",
111
+ "useTabs": false,
112
+ "singleAttributePerLine": true
113
+ }
114
+ ]
115
+ }
116
+ },
117
+ "eslintIgnore": [
118
+ "node_modules/",
119
+ "lib/"
120
+ ],
121
+ "react-native-builder-bob": {
122
+ "source": "src",
123
+ "output": "lib",
124
+ "targets": [
125
+ [
126
+ "commonjs",
127
+ {
128
+ "esm": true
129
+ }
130
+ ],
131
+ [
132
+ "module",
133
+ {
134
+ "esm": true
135
+ }
136
+ ],
137
+ [
138
+ "typescript",
139
+ {
140
+ "project": "tsconfig.build.json"
141
+ }
142
+ ]
143
+ ]
144
+ }
145
+ }
@@ -0,0 +1,163 @@
1
+ import { useEffect, useRef } from 'react';
2
+ import {
3
+ StyleSheet,
4
+ Text,
5
+ TextInput,
6
+ View,
7
+ type TextStyle,
8
+ type ViewStyle,
9
+ } from 'react-native';
10
+ import {
11
+ useCreditCardForm,
12
+ type CreditCardFormData,
13
+ type CreditCardFormField,
14
+ } from './useCreditCardForm';
15
+
16
+ interface Props {
17
+ autoFocus?: boolean;
18
+ style?: ViewStyle;
19
+ labelStyle?: TextStyle;
20
+ inputStyle?: TextStyle;
21
+ placeholderColor?: string;
22
+ labels?: {
23
+ number: string;
24
+ expiry: string;
25
+ cvc: string;
26
+ };
27
+ placeholders?: {
28
+ number: string;
29
+ expiry: string;
30
+ cvc: string;
31
+ };
32
+ onChange: (formData: CreditCardFormData) => void;
33
+ onFocusField?: (field: CreditCardFormField) => void;
34
+ testID?: string;
35
+ }
36
+
37
+ const s = StyleSheet.create({
38
+ container: {
39
+ paddingVertical: 15,
40
+ paddingHorizontal: 15,
41
+ },
42
+ icon: {
43
+ width: 48,
44
+ height: 40,
45
+ resizeMode: 'contain',
46
+ },
47
+ numberInput: {},
48
+ extraContainer: {
49
+ flexDirection: 'row',
50
+ marginTop: 15,
51
+ },
52
+ expiryInputContainer: {
53
+ flex: 1,
54
+ marginRight: 5,
55
+ },
56
+ cvcInputContainer: {
57
+ flex: 1,
58
+ marginLeft: 5,
59
+ },
60
+ input: {
61
+ height: 40,
62
+ fontSize: 16,
63
+ borderBottomColor: 'darkgray',
64
+ borderBottomWidth: 1,
65
+ // // @ts-expect-error outlineWidth is used to hide the text-input outline on react-native-web
66
+ outlineWidth: 0,
67
+ },
68
+ inputLabel: {
69
+ fontSize: 14,
70
+ fontWeight: 600,
71
+ },
72
+ });
73
+
74
+ const CreditCardInput = (props: Props) => {
75
+ const {
76
+ autoFocus,
77
+ style,
78
+ labelStyle,
79
+ inputStyle,
80
+ placeholderColor = 'darkgray',
81
+ labels = {
82
+ number: 'CARD NUMBER',
83
+ expiry: 'EXPIRY',
84
+ cvc: 'CVC/CVV',
85
+ },
86
+ placeholders = {
87
+ number: '1234 5678 1234 5678',
88
+ expiry: 'MM/YY',
89
+ cvc: 'CVC',
90
+ },
91
+ onChange = () => {},
92
+ onFocusField = () => {},
93
+ testID,
94
+ } = props;
95
+
96
+ const { values, onChangeValue } = useCreditCardForm(onChange);
97
+
98
+ const numberInput = useRef<TextInput>(null);
99
+
100
+ useEffect(() => {
101
+ if (autoFocus) numberInput.current?.focus();
102
+ }, [autoFocus]);
103
+
104
+ return (
105
+ <View
106
+ style={[s.container, style]}
107
+ testID={testID}
108
+ >
109
+ <View style={[s.numberInput]}>
110
+ <Text style={[s.inputLabel, labelStyle]}>{labels.number}</Text>
111
+ <TextInput
112
+ ref={numberInput}
113
+ keyboardType="default"
114
+ style={[s.input, inputStyle]}
115
+ placeholderTextColor={placeholderColor}
116
+ placeholder={placeholders.number}
117
+ value={values.number}
118
+ onChangeText={(v) => onChangeValue('number', v)}
119
+ onFocus={() => onFocusField('number')}
120
+ autoCorrect={false}
121
+ underlineColorAndroid={'transparent'}
122
+ testID="CC_NUMBER"
123
+ />
124
+ </View>
125
+
126
+ <View style={[s.extraContainer]}>
127
+ <View style={s.expiryInputContainer}>
128
+ <Text style={[s.inputLabel, labelStyle]}>{labels.expiry}</Text>
129
+ <TextInput
130
+ keyboardType="default"
131
+ style={[s.input, inputStyle]}
132
+ placeholderTextColor={placeholderColor}
133
+ placeholder={placeholders.expiry}
134
+ value={values.expiry}
135
+ onChangeText={(v) => onChangeValue('expiry', v)}
136
+ onFocus={() => onFocusField('expiry')}
137
+ autoCorrect={false}
138
+ underlineColorAndroid={'transparent'}
139
+ testID="CC_EXPIRY"
140
+ />
141
+ </View>
142
+
143
+ <View style={s.cvcInputContainer}>
144
+ <Text style={[s.inputLabel, labelStyle]}>{labels.cvc}</Text>
145
+ <TextInput
146
+ keyboardType="default"
147
+ style={[s.input, inputStyle]}
148
+ placeholderTextColor={placeholderColor}
149
+ placeholder={placeholders.cvc}
150
+ value={values.cvc}
151
+ onChangeText={(v) => onChangeValue('cvc', v)}
152
+ onFocus={() => onFocusField('cvc')}
153
+ autoCorrect={false}
154
+ underlineColorAndroid={'transparent'}
155
+ testID="CC_CVC"
156
+ />
157
+ </View>
158
+ </View>
159
+ </View>
160
+ );
161
+ };
162
+
163
+ export default CreditCardInput;
@@ -0,0 +1,248 @@
1
+ import {
2
+ Image,
3
+ ImageBackground,
4
+ Platform,
5
+ StyleSheet,
6
+ Text,
7
+ View,
8
+ type ImageSourcePropType,
9
+ type ViewStyle,
10
+ } from 'react-native';
11
+ import FlipCard from 'react-native-flip-card';
12
+ import Icons from './Icons';
13
+ import { useMemo } from 'react';
14
+ import type { CreditCardIssuer } from './useCreditCardForm';
15
+
16
+ const CARD_SIZE = { width: 300, height: 190 };
17
+
18
+ const s = StyleSheet.create({
19
+ cardContainer: {},
20
+ cardFace: {
21
+ backgroundColor: '#444',
22
+ borderRadius: 10,
23
+ },
24
+ cardMagneticStripe: {
25
+ position: 'absolute',
26
+ left: 0,
27
+ right: 0,
28
+ top: 30,
29
+ height: 40,
30
+ backgroundColor: '#000',
31
+ },
32
+ icon: {
33
+ position: 'absolute',
34
+ top: 15,
35
+ right: 15,
36
+ width: 60,
37
+ height: 40,
38
+ resizeMode: 'contain',
39
+ },
40
+ baseText: {
41
+ color: 'rgba(255, 255, 255, 0.5)',
42
+ backgroundColor: 'transparent',
43
+ },
44
+ placeholder: {
45
+ color: 'rgba(255, 255, 255, 0.5)',
46
+ },
47
+ focusedField: {
48
+ fontWeight: 'bold',
49
+ color: 'rgba(255, 255, 255, 1)',
50
+ },
51
+ number: {
52
+ fontSize: 21,
53
+ position: 'absolute',
54
+ top: 95,
55
+ left: 28,
56
+ },
57
+ name: {
58
+ fontSize: 16,
59
+ position: 'absolute',
60
+ bottom: 20,
61
+ left: 25,
62
+ right: 100,
63
+ },
64
+ expiryLabel: {
65
+ fontSize: 9,
66
+ position: 'absolute',
67
+ bottom: 40,
68
+ left: 218,
69
+ },
70
+ expiry: {
71
+ fontSize: 16,
72
+ position: 'absolute',
73
+ bottom: 20,
74
+ left: 220,
75
+ },
76
+ amexCVC: {
77
+ fontSize: 16,
78
+ position: 'absolute',
79
+ top: 73,
80
+ right: 30,
81
+ },
82
+ cvc: {
83
+ fontSize: 16,
84
+ position: 'absolute',
85
+ top: 80,
86
+ right: 30,
87
+ },
88
+ });
89
+
90
+ interface Props {
91
+ focusedField?: 'name' | 'number' | 'expiry' | 'cvc';
92
+ type?: CreditCardIssuer;
93
+ name?: string;
94
+ number?: string;
95
+ expiry?: string;
96
+ cvc?: string;
97
+
98
+ placeholders?: {
99
+ number: string;
100
+ expiry: string;
101
+ cvc: string;
102
+ name: string;
103
+ };
104
+ style?: ViewStyle;
105
+
106
+ fontFamily?: string;
107
+ imageFront?: ImageSourcePropType;
108
+ imageBack?: ImageSourcePropType;
109
+ }
110
+
111
+ const CreditCardView = (props: Props) => {
112
+ const {
113
+ focusedField,
114
+ type,
115
+ name,
116
+ number,
117
+ expiry,
118
+ cvc,
119
+ placeholders = {
120
+ number: '•••• •••• •••• ••••',
121
+ name: '',
122
+ expiry: '••/••',
123
+ cvc: '•••',
124
+ },
125
+ imageFront,
126
+ imageBack,
127
+ fontFamily = Platform.select({
128
+ ios: 'Courier',
129
+ android: 'monospace',
130
+ web: 'monospace',
131
+ }),
132
+ style,
133
+ } = props;
134
+
135
+ const isAmex = type === 'american-express';
136
+ const shouldShowCardBack = !isAmex && focusedField === 'cvc';
137
+
138
+ const cardIcon = useMemo(() => {
139
+ if (type && Icons[type]) return Icons[type];
140
+ return null;
141
+ }, [type]);
142
+
143
+ return (
144
+ <View style={[s.cardContainer, CARD_SIZE, style]}>
145
+ <FlipCard
146
+ flipHorizontal
147
+ flipVertical={false}
148
+ friction={10}
149
+ perspective={2000}
150
+ clickable={false}
151
+ flip={shouldShowCardBack}
152
+ >
153
+ <ImageBackground
154
+ style={[CARD_SIZE, s.cardFace]}
155
+ source={imageFront}
156
+ >
157
+ {!!cardIcon && (
158
+ <Image
159
+ style={[s.icon]}
160
+ source={{ uri: cardIcon }}
161
+ />
162
+ )}
163
+
164
+ <Text
165
+ style={[
166
+ s.baseText,
167
+ { fontFamily },
168
+ s.number,
169
+ !number && s.placeholder,
170
+ focusedField === 'number' && s.focusedField,
171
+ ]}
172
+ >
173
+ {!number ? placeholders.number : number}
174
+ </Text>
175
+
176
+ <Text
177
+ style={[
178
+ s.baseText,
179
+ { fontFamily },
180
+ s.name,
181
+ !name && s.placeholder,
182
+ focusedField === 'name' && s.focusedField,
183
+ ]}
184
+ numberOfLines={1}
185
+ >
186
+ {!name ? placeholders.name : name.toUpperCase()}
187
+ </Text>
188
+
189
+ <Text
190
+ style={[
191
+ s.baseText,
192
+ { fontFamily },
193
+ s.expiryLabel,
194
+ s.placeholder,
195
+ focusedField === 'expiry' && s.focusedField,
196
+ ]}
197
+ >
198
+ MONTH/YEAR
199
+ </Text>
200
+ <Text
201
+ style={[
202
+ s.baseText,
203
+ { fontFamily },
204
+ s.expiry,
205
+ !expiry && s.placeholder,
206
+ focusedField === 'expiry' && s.focusedField,
207
+ ]}
208
+ >
209
+ {!expiry ? placeholders.expiry : expiry}
210
+ </Text>
211
+
212
+ {isAmex && (
213
+ <Text
214
+ style={[
215
+ s.baseText,
216
+ { fontFamily },
217
+ s.amexCVC,
218
+ !cvc && s.placeholder,
219
+ focusedField === 'cvc' && s.focusedField,
220
+ ]}
221
+ >
222
+ {!cvc ? placeholders.cvc : cvc}
223
+ </Text>
224
+ )}
225
+ </ImageBackground>
226
+
227
+ <ImageBackground
228
+ style={[CARD_SIZE, s.cardFace]}
229
+ source={imageBack}
230
+ >
231
+ <View style={s.cardMagneticStripe} />
232
+ <Text
233
+ style={[
234
+ s.baseText,
235
+ s.cvc,
236
+ !cvc && s.placeholder,
237
+ focusedField === 'cvc' && s.focusedField,
238
+ ]}
239
+ >
240
+ {!cvc ? placeholders.cvc : cvc}
241
+ </Text>
242
+ </ImageBackground>
243
+ </FlipCard>
244
+ </View>
245
+ );
246
+ };
247
+
248
+ export default CreditCardView;