@momo-kits/calculator-keyboard 0.150.2-phuc.15 → 0.151.1-beta.2
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/README.md +45 -3
- package/android/src/main/java/com/calculatorkeyboard/CalculatorKeyboardPackage.kt +1 -1
- package/android/src/main/java/com/calculatorkeyboard/CustomKeyboardView.kt +242 -108
- package/android/src/main/java/com/calculatorkeyboard/Event.kt +129 -0
- package/android/src/main/java/com/calculatorkeyboard/{RCTInputCalculator.kt → InputCalculatorViewManager.kt} +105 -33
- package/ios/CalculatorKeyboardView.h +32 -0
- package/ios/CalculatorKeyboardView.mm +274 -0
- package/ios/NativeInputCalculator.h +11 -0
- package/ios/NativeInputCalculator.mm +500 -0
- package/ios/Utils.h +10 -0
- package/ios/Utils.mm +25 -0
- package/package.json +21 -131
- package/react-native-calculator-keyboard.podspec +5 -4
- package/src/InputCalculatorNativeComponent.ts +71 -0
- package/src/index.tsx +93 -43
- package/ios/CalculatorKeyboardView.swift +0 -153
- package/ios/InputCalculator-Bridging-Header.h +0 -23
- package/ios/InputCalculator.m +0 -85
- package/ios/InputCalculator.swift +0 -158
- package/ios/extension.swift +0 -23
- package/lib/commonjs/index.js +0 -72
- package/lib/commonjs/index.js.map +0 -1
- package/lib/module/index.js +0 -67
- package/lib/module/index.js.map +0 -1
- package/lib/typescript/commonjs/package.json +0 -1
- package/lib/typescript/commonjs/src/index.d.ts +0 -23
- package/lib/typescript/commonjs/src/index.d.ts.map +0 -1
- package/lib/typescript/module/package.json +0 -1
- package/lib/typescript/module/src/index.d.ts +0 -23
- package/lib/typescript/module/src/index.d.ts.map +0 -1
package/package.json
CHANGED
|
@@ -1,22 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@momo-kits/calculator-keyboard",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.151.1-beta.2",
|
|
4
4
|
"description": "react native calculator keyboard",
|
|
5
|
-
"
|
|
6
|
-
"main": "./lib/commonjs/index.js",
|
|
7
|
-
"module": "./lib/module/index.js",
|
|
8
|
-
"exports": {
|
|
9
|
-
".": {
|
|
10
|
-
"import": {
|
|
11
|
-
"types": "./lib/typescript/module/src/index.d.ts",
|
|
12
|
-
"default": "./lib/module/index.js"
|
|
13
|
-
},
|
|
14
|
-
"require": {
|
|
15
|
-
"types": "./lib/typescript/commonjs/src/index.d.ts",
|
|
16
|
-
"default": "./lib/commonjs/index.js"
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
},
|
|
5
|
+
"main": "./src/index.tsx",
|
|
20
6
|
"files": [
|
|
21
7
|
"src",
|
|
22
8
|
"lib",
|
|
@@ -40,9 +26,7 @@
|
|
|
40
26
|
"test": "jest",
|
|
41
27
|
"typecheck": "tsc",
|
|
42
28
|
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
43
|
-
"
|
|
44
|
-
"build": "bob build",
|
|
45
|
-
"release": "release-it"
|
|
29
|
+
"build": "echo"
|
|
46
30
|
},
|
|
47
31
|
"keywords": [
|
|
48
32
|
"react-native",
|
|
@@ -62,124 +46,30 @@
|
|
|
62
46
|
"publishConfig": {
|
|
63
47
|
"registry": "https://registry.npmjs.org/"
|
|
64
48
|
},
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
|
|
71
|
-
"@types/jest": "^29.5.5",
|
|
72
|
-
"@types/react": "^18.2.44",
|
|
73
|
-
"commitlint": "^17.0.2",
|
|
74
|
-
"del-cli": "^5.1.0",
|
|
75
|
-
"eslint": "^8.51.0",
|
|
76
|
-
"eslint-config-prettier": "^9.0.0",
|
|
77
|
-
"eslint-plugin-prettier": "^5.0.1",
|
|
78
|
-
"jest": "^29.7.0",
|
|
79
|
-
"prettier": "^3.0.3",
|
|
80
|
-
"react": "18.3.1",
|
|
81
|
-
"react-native": "0.76.5",
|
|
82
|
-
"react-native-builder-bob": "^0.32.0",
|
|
83
|
-
"release-it": "^17.10.0",
|
|
84
|
-
"turbo": "^1.10.7",
|
|
85
|
-
"typescript": "^5.2.2"
|
|
86
|
-
},
|
|
87
|
-
"resolutions": {
|
|
88
|
-
"@types/react": "^18.2.44"
|
|
89
|
-
},
|
|
90
|
-
"peerDependencies": {
|
|
91
|
-
"react": "*",
|
|
92
|
-
"react-native": "*"
|
|
93
|
-
},
|
|
94
|
-
"jest": {
|
|
95
|
-
"preset": "react-native",
|
|
96
|
-
"modulePathIgnorePatterns": [
|
|
97
|
-
"<rootDir>/example/node_modules",
|
|
98
|
-
"<rootDir>/lib/"
|
|
99
|
-
]
|
|
100
|
-
},
|
|
101
|
-
"commitlint": {
|
|
102
|
-
"extends": [
|
|
103
|
-
"@commitlint/config-conventional"
|
|
104
|
-
]
|
|
105
|
-
},
|
|
106
|
-
"release-it": {
|
|
107
|
-
"git": {
|
|
108
|
-
"commitMessage": "chore: release ${version}",
|
|
109
|
-
"tagName": "v${version}"
|
|
110
|
-
},
|
|
111
|
-
"npm": {
|
|
112
|
-
"publish": true
|
|
113
|
-
},
|
|
114
|
-
"github": {
|
|
115
|
-
"release": true
|
|
49
|
+
"codegenConfig": {
|
|
50
|
+
"name": "CalculatorKeyboardSpecs",
|
|
51
|
+
"type": "components",
|
|
52
|
+
"jsSrcsDir": "src",
|
|
53
|
+
"android": {
|
|
54
|
+
"javaPackageName": "com.calculatorkeyboard"
|
|
116
55
|
},
|
|
117
|
-
"
|
|
118
|
-
"
|
|
119
|
-
"
|
|
56
|
+
"ios": {
|
|
57
|
+
"componentProvider": {
|
|
58
|
+
"NativeInputCalculator": "NativeInputCalculator"
|
|
120
59
|
}
|
|
121
60
|
}
|
|
122
61
|
},
|
|
123
|
-
"
|
|
124
|
-
"
|
|
125
|
-
"
|
|
126
|
-
"@react-native",
|
|
127
|
-
"prettier"
|
|
128
|
-
],
|
|
129
|
-
"rules": {
|
|
130
|
-
"react/react-in-jsx-scope": "off",
|
|
131
|
-
"prettier/prettier": [
|
|
132
|
-
"error",
|
|
133
|
-
{
|
|
134
|
-
"quoteProps": "consistent",
|
|
135
|
-
"singleQuote": true,
|
|
136
|
-
"tabWidth": 2,
|
|
137
|
-
"trailingComma": "es5",
|
|
138
|
-
"useTabs": false
|
|
139
|
-
}
|
|
140
|
-
]
|
|
141
|
-
}
|
|
142
|
-
},
|
|
143
|
-
"eslintIgnore": [
|
|
144
|
-
"node_modules/",
|
|
145
|
-
"lib/"
|
|
146
|
-
],
|
|
147
|
-
"prettier": {
|
|
148
|
-
"quoteProps": "consistent",
|
|
149
|
-
"singleQuote": true,
|
|
150
|
-
"tabWidth": 2,
|
|
151
|
-
"trailingComma": "es5",
|
|
152
|
-
"useTabs": false
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"react": "19.0.0",
|
|
64
|
+
"react-native": "0.80.1"
|
|
153
65
|
},
|
|
154
|
-
"
|
|
155
|
-
"
|
|
156
|
-
"
|
|
157
|
-
"
|
|
158
|
-
[
|
|
159
|
-
"commonjs",
|
|
160
|
-
{
|
|
161
|
-
"esm": true
|
|
162
|
-
}
|
|
163
|
-
],
|
|
164
|
-
[
|
|
165
|
-
"module",
|
|
166
|
-
{
|
|
167
|
-
"esm": true
|
|
168
|
-
}
|
|
169
|
-
],
|
|
170
|
-
[
|
|
171
|
-
"typescript",
|
|
172
|
-
{
|
|
173
|
-
"project": "tsconfig.build.json",
|
|
174
|
-
"esm": true
|
|
175
|
-
}
|
|
176
|
-
]
|
|
177
|
-
]
|
|
66
|
+
"peerDependencies": {
|
|
67
|
+
"react": "*",
|
|
68
|
+
"react-native": "*",
|
|
69
|
+
"@momo-kits/foundation": "latest"
|
|
178
70
|
},
|
|
179
|
-
"
|
|
180
|
-
"
|
|
181
|
-
"languages": "kotlin-swift",
|
|
182
|
-
"version": "0.45.5"
|
|
71
|
+
"engines": {
|
|
72
|
+
"node": ">=18.0.0"
|
|
183
73
|
},
|
|
184
74
|
"dependencies": {}
|
|
185
75
|
}
|
|
@@ -5,7 +5,7 @@ folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1
|
|
|
5
5
|
|
|
6
6
|
Pod::Spec.new do |s|
|
|
7
7
|
s.name = "react-native-calculator-keyboard"
|
|
8
|
-
s.version = "
|
|
8
|
+
s.version = package["version"]
|
|
9
9
|
s.summary = package["description"]
|
|
10
10
|
s.homepage = package["homepage"]
|
|
11
11
|
s.license = package["license"]
|
|
@@ -14,9 +14,10 @@ Pod::Spec.new do |s|
|
|
|
14
14
|
s.platforms = { :ios => min_ios_version_supported }
|
|
15
15
|
s.source = { :git => "https://github.com/wem2017/react-native-calculator-keyboard.git/react-native-calculator-keyboard.git", :tag => "#{s.version}" }
|
|
16
16
|
|
|
17
|
-
s.source_files = "ios/**/*.{h,m,mm
|
|
18
|
-
s.
|
|
19
|
-
|
|
17
|
+
s.source_files = "ios/**/*.{h,m,mm}"
|
|
18
|
+
# s.public_header_files = "ios/CalculatorKeyboardView.h"
|
|
19
|
+
# s.private_header_files = "ios/NativeInputCalculator.h"
|
|
20
|
+
|
|
20
21
|
# Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
|
|
21
22
|
# See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.
|
|
22
23
|
if respond_to?(:install_modules_dependencies, true)
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type * as React from 'react';
|
|
2
|
+
import type { HostComponent, ViewProps } from 'react-native';
|
|
3
|
+
import {
|
|
4
|
+
CodegenTypes,
|
|
5
|
+
codegenNativeComponent,
|
|
6
|
+
codegenNativeCommands,
|
|
7
|
+
} from 'react-native';
|
|
8
|
+
|
|
9
|
+
export type CustomKeyBackground = 'primary' | 'default' | string;
|
|
10
|
+
|
|
11
|
+
export enum CustomKeyState {
|
|
12
|
+
Default = 'default',
|
|
13
|
+
Disable = 'disable',
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export enum Mode {
|
|
17
|
+
NumDefault = 'NumDefault',
|
|
18
|
+
NumWithCTA = 'NumWithCTA',
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type OnKeyPressEvent = Readonly<{
|
|
22
|
+
key: string;
|
|
23
|
+
}>;
|
|
24
|
+
|
|
25
|
+
export type OnChangeEvent = Readonly<{
|
|
26
|
+
text: string;
|
|
27
|
+
}>;
|
|
28
|
+
|
|
29
|
+
export type OnResultEvent = Readonly<{
|
|
30
|
+
result: string;
|
|
31
|
+
}>;
|
|
32
|
+
|
|
33
|
+
export type TextAttributes = Readonly<{
|
|
34
|
+
fontSize?: CodegenTypes.Float | undefined;
|
|
35
|
+
fontWeight?: string | undefined;
|
|
36
|
+
placeholder?: string | undefined;
|
|
37
|
+
placeholderTextColor?: string | undefined;
|
|
38
|
+
}>;
|
|
39
|
+
|
|
40
|
+
export interface NativeInputCalculatorProps extends ViewProps {
|
|
41
|
+
value?: string;
|
|
42
|
+
textAttributes?: TextAttributes;
|
|
43
|
+
mode?: string;
|
|
44
|
+
customKeyText?: string;
|
|
45
|
+
customKeyBackground?: string;
|
|
46
|
+
customKeyTextColor?: string;
|
|
47
|
+
customKeyState?: string;
|
|
48
|
+
onChange?: CodegenTypes.BubblingEventHandler<OnChangeEvent>;
|
|
49
|
+
onKeyPress?: CodegenTypes.BubblingEventHandler<OnKeyPressEvent>;
|
|
50
|
+
onResult?: CodegenTypes.BubblingEventHandler<OnResultEvent>;
|
|
51
|
+
onBlur?: CodegenTypes.BubblingEventHandler<{}>;
|
|
52
|
+
onFocus?: CodegenTypes.BubblingEventHandler<{}>;
|
|
53
|
+
onCustomKeyEvent?: CodegenTypes.DirectEventHandler<{}>;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface NativeInputCalculatorCommands {
|
|
57
|
+
focus(
|
|
58
|
+
viewRef: React.ElementRef<HostComponent<NativeInputCalculatorProps>>,
|
|
59
|
+
): void;
|
|
60
|
+
blur(
|
|
61
|
+
viewRef: React.ElementRef<HostComponent<NativeInputCalculatorProps>>,
|
|
62
|
+
): void;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export const Commands = codegenNativeCommands<NativeInputCalculatorCommands>({
|
|
66
|
+
supportedCommands: ['focus', 'blur'],
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
export default codegenNativeComponent<NativeInputCalculatorProps>(
|
|
70
|
+
'NativeInputCalculator',
|
|
71
|
+
);
|
package/src/index.tsx
CHANGED
|
@@ -1,28 +1,49 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useContext } from 'react';
|
|
3
|
+
import { ApplicationContext, Colors } from '@momo-kits/foundation';
|
|
2
4
|
import {
|
|
3
|
-
type ColorValue,
|
|
4
|
-
findNodeHandle,
|
|
5
5
|
type NativeSyntheticEvent,
|
|
6
|
-
processColor,
|
|
7
|
-
requireNativeComponent,
|
|
8
|
-
type TextInputChangeEventData,
|
|
9
6
|
type TextInputProps,
|
|
10
|
-
|
|
7
|
+
StyleSheet,
|
|
8
|
+
StyleProp,
|
|
9
|
+
TextStyle,
|
|
11
10
|
} from 'react-native';
|
|
11
|
+
import NativeInputCalculator, {
|
|
12
|
+
OnResultEvent,
|
|
13
|
+
TextAttributes,
|
|
14
|
+
} from './InputCalculatorNativeComponent';
|
|
15
|
+
import { Commands } from './InputCalculatorNativeComponent';
|
|
12
16
|
|
|
13
|
-
const
|
|
14
|
-
const NativeInput = requireNativeComponent<any>(NAME);
|
|
17
|
+
const NativeInput = NativeInputCalculator;
|
|
15
18
|
|
|
16
19
|
type KeyPressEvent = { nativeEvent: { key: string } };
|
|
17
20
|
|
|
18
21
|
interface InputCalculatorProps extends TextInputProps {
|
|
19
22
|
text?: string | undefined;
|
|
20
|
-
|
|
23
|
+
mode?: Mode;
|
|
24
|
+
onBlur?: () => void;
|
|
25
|
+
onFocus?: () => void;
|
|
26
|
+
onResult?: (e: OnResultEvent) => void;
|
|
21
27
|
onKeyPress?: (e: KeyPressEvent) => void;
|
|
22
28
|
customKeyText?: string | undefined;
|
|
23
|
-
customKeyBackground?:
|
|
24
|
-
customKeyState?:
|
|
29
|
+
customKeyBackground?: CustomKeyBackground;
|
|
30
|
+
customKeyState?: CustomKeyState;
|
|
25
31
|
onCustomKeyEvent?: () => void;
|
|
32
|
+
style?: StyleProp<TextStyle>;
|
|
33
|
+
placeholder?: string | undefined;
|
|
34
|
+
placeholderTextColor?: string | undefined;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export type CustomKeyBackground = 'primary' | 'default' | string;
|
|
38
|
+
|
|
39
|
+
export enum CustomKeyState {
|
|
40
|
+
Default = 'default',
|
|
41
|
+
Disable = 'disable',
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export enum Mode {
|
|
45
|
+
NumDefault = 'NumDefault',
|
|
46
|
+
NumWithCTA = 'NumWithCTA',
|
|
26
47
|
}
|
|
27
48
|
|
|
28
49
|
export type InputCalculatorRef = {
|
|
@@ -30,6 +51,30 @@ export type InputCalculatorRef = {
|
|
|
30
51
|
blur: () => void;
|
|
31
52
|
};
|
|
32
53
|
|
|
54
|
+
const omitUndefined = <T extends object>(obj: T): T =>
|
|
55
|
+
Object.fromEntries(
|
|
56
|
+
Object.entries(obj).filter(([, v]) => v !== undefined),
|
|
57
|
+
) as T;
|
|
58
|
+
|
|
59
|
+
function isEmpty(obj: object | undefined | null) {
|
|
60
|
+
return !obj || Object.keys(obj).length === 0;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function styleToTextAttributes(
|
|
64
|
+
style?: StyleProp<TextStyle>,
|
|
65
|
+
placeholder?: string,
|
|
66
|
+
placeholderTextColor?: string,
|
|
67
|
+
): Readonly<TextAttributes> {
|
|
68
|
+
const s = StyleSheet.flatten(style) ?? {};
|
|
69
|
+
const attrs: TextAttributes = {
|
|
70
|
+
fontSize: s.fontSize ?? undefined,
|
|
71
|
+
fontWeight: (s.fontWeight as TextAttributes['fontWeight']) ?? undefined,
|
|
72
|
+
placeholder,
|
|
73
|
+
placeholderTextColor,
|
|
74
|
+
};
|
|
75
|
+
return Object.freeze(omitUndefined(attrs));
|
|
76
|
+
}
|
|
77
|
+
|
|
33
78
|
const InputCalculator = React.forwardRef<
|
|
34
79
|
InputCalculatorRef,
|
|
35
80
|
InputCalculatorProps
|
|
@@ -37,66 +82,71 @@ const InputCalculator = React.forwardRef<
|
|
|
37
82
|
(
|
|
38
83
|
{
|
|
39
84
|
customKeyBackground = 'default',
|
|
40
|
-
|
|
85
|
+
mode = Mode.NumDefault,
|
|
41
86
|
customKeyText,
|
|
87
|
+
onBlur,
|
|
88
|
+
onFocus,
|
|
89
|
+
onResult,
|
|
42
90
|
onKeyPress,
|
|
43
|
-
customKeyState =
|
|
91
|
+
customKeyState = CustomKeyState.Default,
|
|
44
92
|
onCustomKeyEvent,
|
|
93
|
+
style,
|
|
45
94
|
...props
|
|
46
95
|
},
|
|
47
|
-
ref
|
|
96
|
+
ref,
|
|
48
97
|
) => {
|
|
98
|
+
const { theme } = useContext(ApplicationContext);
|
|
49
99
|
const nativeRef = React.useRef<any>(null);
|
|
50
100
|
|
|
51
|
-
const _onChange = (
|
|
52
|
-
event: NativeSyntheticEvent<TextInputChangeEventData>
|
|
53
|
-
) => {
|
|
101
|
+
const _onChange = (event: NativeSyntheticEvent<any>) => {
|
|
54
102
|
const currentText = event.nativeEvent.text;
|
|
55
|
-
props.onChange
|
|
56
|
-
props.onChangeText
|
|
103
|
+
props.onChange?.(event);
|
|
104
|
+
props.onChangeText?.(currentText);
|
|
57
105
|
};
|
|
58
106
|
|
|
59
107
|
const text = props.text ?? props.defaultValue ?? '';
|
|
60
|
-
let keyBackground =
|
|
61
|
-
let textKeyColor =
|
|
108
|
+
let keyBackground = Colors.black_06;
|
|
109
|
+
let textKeyColor = Colors.black_20;
|
|
62
110
|
|
|
63
|
-
if (
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
111
|
+
if (mode === Mode.NumWithCTA) {
|
|
112
|
+
if (customKeyBackground === 'primary') {
|
|
113
|
+
keyBackground = theme.colors.primary;
|
|
114
|
+
textKeyColor = Colors.black_01;
|
|
115
|
+
}
|
|
67
116
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
117
|
+
if (customKeyState === CustomKeyState.Disable) {
|
|
118
|
+
keyBackground = theme.colors.background.disable;
|
|
119
|
+
textKeyColor = Colors.black_01;
|
|
120
|
+
}
|
|
71
121
|
}
|
|
72
122
|
|
|
73
123
|
React.useImperativeHandle(ref, () => ({
|
|
74
124
|
focus() {
|
|
75
|
-
|
|
76
|
-
if (!node) return;
|
|
77
|
-
const config = UIManager.getViewManagerConfig(NAME);
|
|
78
|
-
if (config?.Commands?.focus != null) {
|
|
79
|
-
UIManager.dispatchViewManagerCommand(node, config.Commands.focus, []);
|
|
80
|
-
}
|
|
125
|
+
if (nativeRef.current) Commands.focus(nativeRef.current);
|
|
81
126
|
},
|
|
82
127
|
blur() {
|
|
83
|
-
|
|
84
|
-
if (!node) return;
|
|
85
|
-
const config = UIManager.getViewManagerConfig(NAME);
|
|
86
|
-
if (config?.Commands?.blur != null) {
|
|
87
|
-
UIManager.dispatchViewManagerCommand(node, config.Commands.blur, []);
|
|
88
|
-
}
|
|
128
|
+
if (nativeRef.current) Commands.blur(nativeRef.current);
|
|
89
129
|
},
|
|
90
130
|
}));
|
|
91
131
|
|
|
132
|
+
const derivedTA = React.useMemo(
|
|
133
|
+
() => styleToTextAttributes(style, props.placeholder, props.placeholderTextColor),
|
|
134
|
+
[style, props.placeholder, props.placeholderTextColor],
|
|
135
|
+
);
|
|
136
|
+
|
|
92
137
|
return (
|
|
93
138
|
<NativeInput
|
|
94
139
|
{...props}
|
|
140
|
+
style={style}
|
|
141
|
+
textAttributes={isEmpty(derivedTA) ? undefined : derivedTA}
|
|
95
142
|
ref={nativeRef}
|
|
96
143
|
onChange={_onChange}
|
|
144
|
+
onBlur={onBlur}
|
|
145
|
+
onFocus={onFocus}
|
|
146
|
+
onResult={onResult}
|
|
97
147
|
onKeyPress={onKeyPress}
|
|
98
148
|
value={text}
|
|
99
|
-
|
|
149
|
+
mode={mode}
|
|
100
150
|
customKeyText={customKeyText}
|
|
101
151
|
customKeyBackground={keyBackground}
|
|
102
152
|
customKeyTextColor={textKeyColor}
|
|
@@ -104,7 +154,7 @@ const InputCalculator = React.forwardRef<
|
|
|
104
154
|
onCustomKeyEvent={onCustomKeyEvent}
|
|
105
155
|
/>
|
|
106
156
|
);
|
|
107
|
-
}
|
|
157
|
+
},
|
|
108
158
|
);
|
|
109
159
|
|
|
110
160
|
export default InputCalculator;
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import UIKit
|
|
2
|
-
import Foundation
|
|
3
|
-
|
|
4
|
-
import UIKit
|
|
5
|
-
import Foundation
|
|
6
|
-
|
|
7
|
-
class CalculatorKeyboardView: UIView {
|
|
8
|
-
weak var input: InputCalculator?
|
|
9
|
-
|
|
10
|
-
private let keys: [[String]] = [
|
|
11
|
-
["1", "2", "3", "÷", "back"],
|
|
12
|
-
["4", "5", "6", "×", "="],
|
|
13
|
-
["7", "8", "9", "-", "Xong"],
|
|
14
|
-
["000", "0", "+"],
|
|
15
|
-
]
|
|
16
|
-
private let SEPARATOR_WIDTH: CGFloat = 4
|
|
17
|
-
private let specialKeys: Set<String> = ["=", "-", "×", "÷", "back", "+"]
|
|
18
|
-
|
|
19
|
-
var customKeyText: String? { didSet { updateCustomKeyTitle() } }
|
|
20
|
-
var customKeyBackground: String? { didSet { updateCustomKeyBackground() } }
|
|
21
|
-
var customKeyTextColor: String? { didSet { updateCustomKeyBackground() } }
|
|
22
|
-
var customKeyState: String? { didSet { updateCustomKeyBackground() } }
|
|
23
|
-
private weak var customKeyButton: UIButton?
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
override init(frame: CGRect) {
|
|
27
|
-
super.init(frame: frame)
|
|
28
|
-
setup()
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
required init?(coder aDecoder: NSCoder) {
|
|
32
|
-
fatalError("init(coder:) has not been implemented")
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
public func setKeyboardColor(_ color: UIColor) {
|
|
36
|
-
self.setup(color)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
private func setup(_ color: UIColor = UIColor(hex: "#d8d8d8")) {
|
|
40
|
-
self.subviews.forEach { $0.removeFromSuperview() }
|
|
41
|
-
|
|
42
|
-
backgroundColor = UIColor(hex: "#f2f2f6")
|
|
43
|
-
let buttonWidth = (UIScreen.main.bounds.width - SEPARATOR_WIDTH * 2 - 4 * SEPARATOR_WIDTH) / 5
|
|
44
|
-
let buttonHeight: CGFloat = (240 - SEPARATOR_WIDTH * 2 - 3 * SEPARATOR_WIDTH) / 4
|
|
45
|
-
|
|
46
|
-
// Create a wrapper view
|
|
47
|
-
let contentView = UIView()
|
|
48
|
-
contentView.translatesAutoresizingMaskIntoConstraints = false
|
|
49
|
-
addSubview(contentView)
|
|
50
|
-
|
|
51
|
-
// Set contentView constraints
|
|
52
|
-
NSLayoutConstraint.activate([
|
|
53
|
-
contentView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: SEPARATOR_WIDTH),
|
|
54
|
-
contentView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -SEPARATOR_WIDTH),
|
|
55
|
-
contentView.topAnchor.constraint(equalTo: topAnchor, constant: SEPARATOR_WIDTH),
|
|
56
|
-
contentView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -SEPARATOR_WIDTH)
|
|
57
|
-
])
|
|
58
|
-
|
|
59
|
-
// Add buttons to the wrapper view
|
|
60
|
-
var yOffset: CGFloat = 0
|
|
61
|
-
for (rowIndex, row) in keys.enumerated() {
|
|
62
|
-
var xOffset: CGFloat = 0
|
|
63
|
-
for (colIndex, key) in row.enumerated() {
|
|
64
|
-
let isCustomKey = colIndex == 4 && rowIndex == 2
|
|
65
|
-
let button = UIButton(type: .system)
|
|
66
|
-
button.backgroundColor = UIColor.white
|
|
67
|
-
button.layer.cornerRadius = 8
|
|
68
|
-
let title = isCustomKey ? (customKeyText ?? key) : key
|
|
69
|
-
button.setTitle(title, for: .normal)
|
|
70
|
-
button.setTitleColor(.black, for: .normal)
|
|
71
|
-
button.titleLabel?.font = UIFont.systemFont(ofSize: isCustomKey ? 18 : 24, weight: .medium)
|
|
72
|
-
button.nativeID = key
|
|
73
|
-
button.tag = isCustomKey ? 1 : 0
|
|
74
|
-
|
|
75
|
-
var buttonFrame = CGRect(x: xOffset, y: yOffset, width: buttonWidth, height: buttonHeight)
|
|
76
|
-
if isCustomKey {
|
|
77
|
-
buttonFrame.size.height = buttonHeight * 2 + SEPARATOR_WIDTH
|
|
78
|
-
}
|
|
79
|
-
if key == "000" {
|
|
80
|
-
buttonFrame.size.width = buttonWidth * 2 + SEPARATOR_WIDTH
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
button.frame = buttonFrame
|
|
84
|
-
|
|
85
|
-
if key == "back" {
|
|
86
|
-
button.setTitle("", for: .normal)
|
|
87
|
-
let image = UIImage(systemName: "delete.backward", withConfiguration: UIImage.SymbolConfiguration(weight: .bold))
|
|
88
|
-
button.setImage(image, for: .normal)
|
|
89
|
-
button.tintColor = .black
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if specialKeys.contains(key) {
|
|
93
|
-
button.setTitleColor(.black, for: .normal)
|
|
94
|
-
button.backgroundColor = color
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if isCustomKey {
|
|
98
|
-
self.customKeyButton = button
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
button.addTarget(self, action: #selector(keyPressed(_:)), for: .touchUpInside)
|
|
102
|
-
contentView.addSubview(button)
|
|
103
|
-
|
|
104
|
-
// Adjust xOffset for the next button in the row
|
|
105
|
-
xOffset += buttonFrame.width + SEPARATOR_WIDTH
|
|
106
|
-
}
|
|
107
|
-
// Adjust yOffset for the next row
|
|
108
|
-
yOffset += buttonHeight + SEPARATOR_WIDTH
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
private func updateCustomKeyTitle() {
|
|
113
|
-
guard let btn = customKeyButton, let title = customKeyText else { return }
|
|
114
|
-
btn.setTitle(title, for: .normal)
|
|
115
|
-
btn.setImage(nil, for: .normal)
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
private func updateCustomKeyBackground() {
|
|
119
|
-
guard let btn = customKeyButton,
|
|
120
|
-
let background = customKeyBackground,
|
|
121
|
-
let textColor = customKeyTextColor,
|
|
122
|
-
let state = customKeyState else { return }
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
btn.isEnabled = state != "disable"
|
|
127
|
-
btn.backgroundColor = UIColor(hex: background)
|
|
128
|
-
btn.setTitleColor(UIColor(hex: textColor), for: .normal)
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
@objc private func keyPressed(_ sender: UIButton) {
|
|
134
|
-
guard let key = sender.nativeID else { return }
|
|
135
|
-
let isCustomKey = sender.tag == 1
|
|
136
|
-
if (isCustomKey) {
|
|
137
|
-
input?.emitCustomKey()
|
|
138
|
-
return
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
input?.emitKeyPress(key)
|
|
142
|
-
switch key {
|
|
143
|
-
case "back":
|
|
144
|
-
input?.onBackSpace()
|
|
145
|
-
case "=":
|
|
146
|
-
input?.calculateResult()
|
|
147
|
-
case "+", "-", "÷", "×":
|
|
148
|
-
input?.keyDidPress(" \(key) ")
|
|
149
|
-
default:
|
|
150
|
-
input?.keyDidPress(key)
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
#import <React/RCTBridgeModule.h>
|
|
2
|
-
#import <React/RCTViewManager.h>
|
|
3
|
-
#import <React/RCTBaseTextInputViewManager.h>
|
|
4
|
-
#import <React/RCTSinglelineTextInputView.h>
|
|
5
|
-
#import <React/RCTUITextField.h>
|
|
6
|
-
#import <React/RCTBaseTextInputViewManager.h>
|
|
7
|
-
|
|
8
|
-
#import <React/RCTBridge.h>
|
|
9
|
-
#import <React/RCTConvert.h>
|
|
10
|
-
#import <React/RCTFont.h>
|
|
11
|
-
#import <React/RCTShadowView+Layout.h>
|
|
12
|
-
#import <React/RCTShadowView.h>
|
|
13
|
-
#import <React/RCTUIManager.h>
|
|
14
|
-
#import <React/RCTUIManagerObserverCoordinator.h>
|
|
15
|
-
#import <React/RCTUIManagerUtils.h>
|
|
16
|
-
|
|
17
|
-
#import <React/RCTBaseTextInputShadowView.h>
|
|
18
|
-
#import <React/RCTBaseTextInputView.h>
|
|
19
|
-
#import <React/RCTConvert+Text.h>
|
|
20
|
-
|
|
21
|
-
@interface Calculator : NSObject <RCTBridgeModule>
|
|
22
|
-
|
|
23
|
-
@end
|