react-native-typerich 1.0.0 → 2.2.0
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 +251 -10
- package/ReactNativeTypeRich.podspec +41 -0
- package/android/src/main/java/com/typerich/TypeRichTextInputView.kt +37 -10
- package/android/src/main/java/com/typerich/TypeRichTextInputViewManager.kt +5 -0
- package/ios/TypeRichTextInputView.h +27 -7
- package/ios/TypeRichTextInputView.mm +809 -26
- package/ios/cpp/TypeRichTextInputViewComponentDescriptor.h +19 -0
- package/ios/cpp/TypeRichTextInputViewShadowNode.h +44 -0
- package/ios/cpp/TypeRichTextInputViewShadowNode.mm +110 -0
- package/ios/cpp/TypeRichTextInputViewState.cpp +10 -0
- package/ios/cpp/TypeRichTextInputViewState.h +22 -0
- package/ios/inputTextView/TypeRichUITextView.h +14 -0
- package/ios/inputTextView/TypeRichUITextView.mm +100 -0
- package/ios/modules/commands/TypeRichTextInputCommands.h +24 -0
- package/ios/modules/commands/TypeRichTextInputCommands.mm +392 -0
- package/ios/utils/StringUtils.h +19 -0
- package/ios/utils/StringUtils.mm +15 -0
- package/ios/utils/TextInputUtils.h +26 -0
- package/ios/utils/TextInputUtils.mm +58 -0
- package/lib/module/TypeRichTextInput.js +13 -36
- package/lib/module/TypeRichTextInput.js.map +1 -1
- package/lib/module/TypeRichTextInputNativeComponent.ts +266 -52
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/types/TypeRichTextInput.js +4 -0
- package/lib/module/types/TypeRichTextInput.js.map +1 -0
- package/lib/typescript/src/TypeRichTextInput.d.ts +2 -22
- package/lib/typescript/src/TypeRichTextInput.d.ts.map +1 -1
- package/lib/typescript/src/TypeRichTextInputNativeComponent.d.ts +200 -14
- package/lib/typescript/src/TypeRichTextInputNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/types/TypeRichTextInput.d.ts +95 -0
- package/lib/typescript/src/types/TypeRichTextInput.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/TypeRichTextInput.tsx +20 -70
- package/src/TypeRichTextInputNativeComponent.ts +266 -52
- package/src/index.tsx +1 -5
- package/src/types/TypeRichTextInput.tsx +116 -0
- package/TypeRichTextInput.podspec +0 -20
- package/ios/TypeRichTextInputViewManager.mm +0 -27
package/README.md
CHANGED
|
@@ -8,39 +8,271 @@ currently available only for android
|
|
|
8
8
|
```sh
|
|
9
9
|
npm install react-native-typerich
|
|
10
10
|
```
|
|
11
|
+
> [!NOTE]
|
|
12
|
+
> you will need to prebuild app in expo
|
|
11
13
|
|
|
12
14
|
## Usage
|
|
13
15
|
|
|
14
|
-
```
|
|
16
|
+
```jsx
|
|
15
17
|
import { TypeRichTextInput } from 'react-native-typerich';
|
|
16
18
|
|
|
17
19
|
// ...
|
|
18
|
-
|
|
19
20
|
<TypeRichTextInput
|
|
20
|
-
ref={
|
|
21
|
+
ref={inputRef}
|
|
22
|
+
value={value}
|
|
21
23
|
style={styles.typeRichTextInput}
|
|
22
24
|
placeholder="Type here..."
|
|
23
25
|
placeholderTextColor="rgb(0, 26, 114)"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
editable={true}
|
|
27
|
+
selectionColor="deepskyblue"
|
|
28
|
+
cursorColor="dodgerblue"
|
|
26
29
|
autoCapitalize="words"
|
|
30
|
+
autoFocus
|
|
27
31
|
onChangeText={(text: string) => console.log(text)}
|
|
28
32
|
onFocus={() => console.log('focused')}
|
|
29
33
|
onBlur={() => console.log('blurred')}
|
|
30
34
|
onChangeSelection={(e: { start: number, end: number, text: string }) =>
|
|
31
35
|
console.log(e)
|
|
32
36
|
}
|
|
33
|
-
androidExperimentalSynchronousEvents={true}
|
|
34
|
-
multiline
|
|
35
|
-
numberOfLines={5}
|
|
36
37
|
onPasteImageData={(e) => {
|
|
38
|
+
setImage(e);
|
|
37
39
|
console.log(e);
|
|
38
40
|
}}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
androidExperimentalSynchronousEvents={true} // not tested very well
|
|
42
|
+
multiline
|
|
43
|
+
numberOfLines={5}
|
|
44
|
+
lineHeight={22}
|
|
45
|
+
fontFamily="serif"
|
|
46
|
+
fontStyle="italic"
|
|
47
|
+
fontWeight={'700'}
|
|
48
|
+
fontSize={26}
|
|
49
|
+
color="darkgreen"
|
|
41
50
|
/>;
|
|
42
51
|
```
|
|
43
52
|
|
|
53
|
+
## Props
|
|
54
|
+
|
|
55
|
+
- **Props that works Same as React Native's Default `TextInput`:**
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
value?: string;
|
|
59
|
+
autoFocus?: boolean;
|
|
60
|
+
editable?: boolean;
|
|
61
|
+
defaultValue?: string;
|
|
62
|
+
placeholder?: string;
|
|
63
|
+
placeholderTextColor?: ColorValue;
|
|
64
|
+
cursorColor?: ColorValue;
|
|
65
|
+
selectionColor?: ColorValue;
|
|
66
|
+
autoCapitalize?: string;
|
|
67
|
+
scrollEnabled?: boolean;
|
|
68
|
+
secureTextEntry?: boolean;
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
- **Styling Props you need to pass externally:**
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
color?: ColorValue;
|
|
75
|
+
fontSize?: Float;
|
|
76
|
+
fontFamily?: string;
|
|
77
|
+
fontWeight?: string;
|
|
78
|
+
fontStyle?: string;
|
|
79
|
+
lineHeight?: Float;
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
- **props that have some bugs:**
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
multiline?: boolean;
|
|
86
|
+
numberOfLines?: Int32;
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
> using this togather adds some extra height sometimes.
|
|
90
|
+
> use multline without numberOfLines and it works fine
|
|
91
|
+
> use `maxHeight` instead of number of lines
|
|
92
|
+
|
|
93
|
+
> [!NOTE]
|
|
94
|
+
> This is not a Major bug and the change is unnoticable
|
|
95
|
+
|
|
96
|
+
## Events
|
|
97
|
+
|
|
98
|
+
### 1. onFocus
|
|
99
|
+
|
|
100
|
+
callback signature
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
onFocus?: () => void;
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### 2. onBlur
|
|
107
|
+
|
|
108
|
+
callback signature
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
onBlur?: () => void;
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### 3. onChangeText
|
|
115
|
+
|
|
116
|
+
callback signature
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
onChangeText?: (value: string) => void;
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### 4. onChangeSelection
|
|
123
|
+
|
|
124
|
+
callback signature
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
onChangeSelection?: (event: {
|
|
128
|
+
start: number;
|
|
129
|
+
end: number;
|
|
130
|
+
text: string;
|
|
131
|
+
}) => void;
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### 4. onPasteImageData
|
|
135
|
+
|
|
136
|
+
> fires on when user paste image
|
|
137
|
+
|
|
138
|
+
callback signature
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
onPasteImageData?: (data: {
|
|
142
|
+
uri: string;
|
|
143
|
+
type: string;
|
|
144
|
+
fileName: string;
|
|
145
|
+
fileSize: Double;
|
|
146
|
+
source: 'keyboard' | 'clipboard' | 'context_menu'; // it never receives source as 'context_menu' and will be removed in future we suggest not using it
|
|
147
|
+
error?: { message: string };
|
|
148
|
+
}) => void;
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Event props
|
|
152
|
+
|
|
153
|
+
- `uri`: uri of the image, can be directly used or passed to Image comp
|
|
154
|
+
- `type`: mime type of image
|
|
155
|
+
- `fileName`: File name of image (always starts with `typerich_` prefix)
|
|
156
|
+
- `fileSize`: File Size in bytes
|
|
157
|
+
- `source`: its enum with two possible values
|
|
158
|
+
- `keyboard`: if its pasted from gboard's clipboard or is a sticker or something similar
|
|
159
|
+
- `clipboard`: if its pasted from context menu (long press)
|
|
160
|
+
- `error`: error message if there is any
|
|
161
|
+
|
|
162
|
+
## Commands
|
|
163
|
+
|
|
164
|
+
### 1. focus()
|
|
165
|
+
|
|
166
|
+
> use to get programmatic focus on TextInput
|
|
167
|
+
|
|
168
|
+
Command signature
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
focus: () => void;
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
useage
|
|
175
|
+
|
|
176
|
+
```ts
|
|
177
|
+
inputRef.current?.focus();
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### 2. blur()
|
|
181
|
+
|
|
182
|
+
> use to programmatically blur TextInput
|
|
183
|
+
|
|
184
|
+
Command signature
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
blur: () => void;
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
useage
|
|
191
|
+
|
|
192
|
+
```ts
|
|
193
|
+
inputRef.current?.blur();
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### 3. setText(text)
|
|
197
|
+
|
|
198
|
+
> use to set the value of TextInput (replaces whole content)
|
|
199
|
+
|
|
200
|
+
> [!NOTE]
|
|
201
|
+
> it does not updates selection automatically use have to call `setSelection()`
|
|
202
|
+
|
|
203
|
+
Command signature
|
|
204
|
+
|
|
205
|
+
```ts
|
|
206
|
+
setText: (text: string) => void;
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
useage
|
|
210
|
+
|
|
211
|
+
```ts
|
|
212
|
+
inputRef.current?.setText('This is Text');
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### 4. insertTextAt(start, end, text)
|
|
216
|
+
|
|
217
|
+
> use to insert value at specific position (keeps content of TextInput)
|
|
218
|
+
|
|
219
|
+
> [!NOTE]
|
|
220
|
+
> it preserves the cursor and updates the selection
|
|
221
|
+
> no need to call the `setSelection` after this
|
|
222
|
+
|
|
223
|
+
Command signature
|
|
224
|
+
|
|
225
|
+
```ts
|
|
226
|
+
insertTextAt: (start: number, end: number, text: string) => void;
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
useage
|
|
230
|
+
|
|
231
|
+
```ts
|
|
232
|
+
inputRef.current?.insertTextAt(4, 6, 'This is Text');
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### 5. setSelection(start, end)
|
|
236
|
+
|
|
237
|
+
> use to set the value of TextInput (replaces whole content)
|
|
238
|
+
|
|
239
|
+
Command signature
|
|
240
|
+
|
|
241
|
+
```ts
|
|
242
|
+
setSelection: (start: number, end: number) => void;
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
useage
|
|
246
|
+
|
|
247
|
+
```ts
|
|
248
|
+
inputRef.current?.setSelection(4, 6);
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### 6. getNativeRef()
|
|
252
|
+
|
|
253
|
+
> use to get the internal ref object of the TypeRichTextInput
|
|
254
|
+
|
|
255
|
+
> [!NOTE]
|
|
256
|
+
> you mostly does not need to use this
|
|
257
|
+
> only use this when you need to use the ref in certain cases like following
|
|
258
|
+
|
|
259
|
+
```ts
|
|
260
|
+
const hostRef = input?.getNativeRef?.();
|
|
261
|
+
const node = findNodeHandle(hostRef); // findNodeHandle is from 'react-native'
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Command signature
|
|
265
|
+
|
|
266
|
+
```ts
|
|
267
|
+
getNativeRef: () => any | null;
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
useage
|
|
271
|
+
|
|
272
|
+
```ts
|
|
273
|
+
inputRef.current?.getNativeRef();
|
|
274
|
+
```
|
|
275
|
+
|
|
44
276
|
## Contributing
|
|
45
277
|
|
|
46
278
|
- [Development workflow](CONTRIBUTING.md#development-workflow)
|
|
@@ -54,3 +286,12 @@ MIT
|
|
|
54
286
|
---
|
|
55
287
|
|
|
56
288
|
Made with [create-react-native-library](https://github.com/callstack/react-native-builder-bob)
|
|
289
|
+
|
|
290
|
+
## Credits
|
|
291
|
+
|
|
292
|
+
- **Divyanshu Patil** – Author & maintainer
|
|
293
|
+
- Built with help from the open-source community ❤️
|
|
294
|
+
|
|
295
|
+
### special thanks to [Software-Mansion](https://github.com/software-mansion) for the custom shadow node code
|
|
296
|
+
|
|
297
|
+
checkout [react-native-enriched](https://github.com/software-mansion/react-native-enriched) by [software-mansion](https://github.com/software-mansion)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = "ReactNativeTypeRich"
|
|
7
|
+
s.version = package["version"]
|
|
8
|
+
s.summary = package["description"]
|
|
9
|
+
s.homepage = package["homepage"]
|
|
10
|
+
s.license = package["license"]
|
|
11
|
+
s.authors = package["author"]
|
|
12
|
+
|
|
13
|
+
s.platforms = { :ios => min_ios_version_supported }
|
|
14
|
+
s.source = { :git => "https://github.com/divyanshu-patil/react-native-typerich.git", :tag => "#{s.version}" }
|
|
15
|
+
|
|
16
|
+
# s.source_files = "ios/**/*.{h,m,mm,swift,cpp}"
|
|
17
|
+
s.source_files = "ios/**/*.{h,m,mm,cpp}"
|
|
18
|
+
s.private_header_files = "ios/**/*.h"
|
|
19
|
+
|
|
20
|
+
s.public_header_files = [
|
|
21
|
+
"ios/**/*.h",
|
|
22
|
+
"ios/cpp/**/*.h"
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
s.header_mappings_dir = "ios"
|
|
26
|
+
|
|
27
|
+
s.pod_target_xcconfig = {
|
|
28
|
+
"HEADER_SEARCH_PATHS" => '"$(PODS_TARGET_SRCROOT)/ios"',
|
|
29
|
+
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
# Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
|
|
33
|
+
# See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.
|
|
34
|
+
if respond_to?(:install_modules_dependencies, true)
|
|
35
|
+
install_modules_dependencies(s)
|
|
36
|
+
else
|
|
37
|
+
s.dependency "React-Core"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
|
|
@@ -64,6 +64,7 @@ class TypeRichTextInputView : AppCompatEditText {
|
|
|
64
64
|
private var lineHeightPx: Int? = null
|
|
65
65
|
private var isSettingTextFromJS = false
|
|
66
66
|
private var isInitialized = false
|
|
67
|
+
private var disableImagePasting = false
|
|
67
68
|
|
|
68
69
|
constructor(context: Context) : super(context) {
|
|
69
70
|
prepareComponent()
|
|
@@ -140,23 +141,34 @@ class TypeRichTextInputView : AppCompatEditText {
|
|
|
140
141
|
override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection? {
|
|
141
142
|
val ic = super.onCreateInputConnection(outAttrs) ?: return null
|
|
142
143
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
144
|
+
if (!disableImagePasting) {
|
|
145
|
+
EditorInfoCompat.setContentMimeTypes(
|
|
146
|
+
outAttrs,
|
|
147
|
+
arrayOf("image/png", "image/jpg", "image/jpeg", "image/gif", "image/webp")
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
return InputConnectionCompat.createWrapper(ic, outAttrs, onCommitContent)
|
|
151
|
+
}
|
|
147
152
|
|
|
148
|
-
return
|
|
153
|
+
return ic
|
|
149
154
|
}
|
|
150
155
|
|
|
151
156
|
private val onCommitContent = InputConnectionCompat.OnCommitContentListener { info, flags, _ ->
|
|
152
157
|
try {
|
|
153
|
-
|
|
154
|
-
|
|
158
|
+
val hasPermission =
|
|
159
|
+
(flags and InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION) != 0
|
|
160
|
+
|
|
161
|
+
if (hasPermission) {
|
|
155
162
|
try {
|
|
156
163
|
info.requestPermission()
|
|
157
|
-
} catch (
|
|
158
|
-
|
|
164
|
+
} catch (_: Exception) {}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (disableImagePasting) {
|
|
168
|
+
if (hasPermission) {
|
|
169
|
+
try { info.releasePermission() } catch (_: Exception) {}
|
|
159
170
|
}
|
|
171
|
+
return@OnCommitContentListener false
|
|
160
172
|
}
|
|
161
173
|
|
|
162
174
|
val uri = info.contentUri
|
|
@@ -189,7 +201,7 @@ class TypeRichTextInputView : AppCompatEditText {
|
|
|
189
201
|
}
|
|
190
202
|
}
|
|
191
203
|
|
|
192
|
-
// paste handler
|
|
204
|
+
// context menu paste handler
|
|
193
205
|
override fun onTextContextMenuItem(id: Int): Boolean {
|
|
194
206
|
if (id == android.R.id.paste || id == android.R.id.pasteAsPlainText) {
|
|
195
207
|
val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as? ClipboardManager
|
|
@@ -198,6 +210,12 @@ class TypeRichTextInputView : AppCompatEditText {
|
|
|
198
210
|
val clip = clipboard.primaryClip ?: return super.onTextContextMenuItem(id)
|
|
199
211
|
val item = clip.getItemAt(0)
|
|
200
212
|
|
|
213
|
+
if (disableImagePasting) {
|
|
214
|
+
if (item.uri != null || item.intent?.data != null) {
|
|
215
|
+
return true
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
201
219
|
// uri
|
|
202
220
|
item.uri?.let { uri ->
|
|
203
221
|
val source = EnumPasteSource.CLIPBOARD.value
|
|
@@ -496,6 +514,7 @@ class TypeRichTextInputView : AppCompatEditText {
|
|
|
496
514
|
val sizePx = ceil(PixelUtil.toPixelFromSP(size))
|
|
497
515
|
fontSize = sizePx
|
|
498
516
|
setTextSize(TypedValue.COMPLEX_UNIT_PX, sizePx)
|
|
517
|
+
layoutManager.invalidateLayout()
|
|
499
518
|
}
|
|
500
519
|
|
|
501
520
|
fun setFontFamily(family: String?) {
|
|
@@ -539,6 +558,10 @@ class TypeRichTextInputView : AppCompatEditText {
|
|
|
539
558
|
}
|
|
540
559
|
|
|
541
560
|
fun setSecureTextEntry(isSecure: Boolean) {
|
|
561
|
+
if (isSecure) {
|
|
562
|
+
setMultiline(false)
|
|
563
|
+
maxLines = 1
|
|
564
|
+
}
|
|
542
565
|
transformationMethod =
|
|
543
566
|
if (isSecure)
|
|
544
567
|
android.text.method.PasswordTransformationMethod.getInstance()
|
|
@@ -572,6 +595,10 @@ class TypeRichTextInputView : AppCompatEditText {
|
|
|
572
595
|
}
|
|
573
596
|
}
|
|
574
597
|
|
|
598
|
+
fun setDisableImagePasting(disabled: Boolean){
|
|
599
|
+
this.disableImagePasting = disabled
|
|
600
|
+
}
|
|
601
|
+
|
|
575
602
|
override fun isLayoutRequested(): Boolean {
|
|
576
603
|
return false
|
|
577
604
|
}
|
|
@@ -145,6 +145,11 @@ class TypeRichTextInputViewManager :
|
|
|
145
145
|
view?.setLineHeightReact(lineHeight)
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
+
@ReactProp(name = "disableImagePasting")
|
|
149
|
+
override fun setDisableImagePasting(view: TypeRichTextInputView?, value: Boolean) {
|
|
150
|
+
view?.setDisableImagePasting(value)
|
|
151
|
+
}
|
|
152
|
+
|
|
148
153
|
override fun onAfterUpdateTransaction(view: TypeRichTextInputView) {
|
|
149
154
|
super.onAfterUpdateTransaction(view)
|
|
150
155
|
view.afterUpdateTransaction()
|
|
@@ -1,14 +1,34 @@
|
|
|
1
1
|
#import <React/RCTViewComponentView.h>
|
|
2
|
+
#import <react/renderer/core/State.h>
|
|
2
3
|
#import <UIKit/UIKit.h>
|
|
3
4
|
|
|
4
|
-
#ifndef TypeRichTextInputViewNativeComponent_h
|
|
5
|
-
#define TypeRichTextInputViewNativeComponent_h
|
|
6
|
-
|
|
7
5
|
NS_ASSUME_NONNULL_BEGIN
|
|
8
6
|
|
|
9
|
-
@interface TypeRichTextInputView : RCTViewComponentView
|
|
10
|
-
@end
|
|
7
|
+
@interface TypeRichTextInputView : RCTViewComponentView <UITextViewDelegate>
|
|
11
8
|
|
|
12
|
-
|
|
9
|
+
@property(nonatomic, assign) BOOL blockEmitting;
|
|
10
|
+
@property (atomic, assign) BOOL isUserTyping;
|
|
11
|
+
@property (atomic, assign) CFTimeInterval lastTypingTime;
|
|
12
|
+
|
|
13
|
+
- (CGSize)measureSize:(CGFloat)maxWidth;
|
|
14
|
+
|
|
15
|
+
// events
|
|
16
|
+
- (void)emitPasteImageEventWith:(NSString *)uri
|
|
17
|
+
type:(NSString *)type
|
|
18
|
+
fileName:(NSString *)fileName
|
|
19
|
+
fileSize:(NSUInteger)fileSize;
|
|
13
20
|
|
|
14
|
-
|
|
21
|
+
// commands
|
|
22
|
+
- (void)handleCommand:(NSString *)commandName
|
|
23
|
+
args:(NSArray *)args;
|
|
24
|
+
|
|
25
|
+
// helpers used by commands
|
|
26
|
+
- (BOOL)isTouchInProgress;
|
|
27
|
+
//- (BOOL)isHandlingUserInput;
|
|
28
|
+
- (void)invalidateTextLayoutFromCommand;
|
|
29
|
+
- (void)updatePlaceholderVisibilityFromCommand;
|
|
30
|
+
- (void)dispatchSelectionChangeIfNeeded;
|
|
31
|
+
- (BOOL)isDisableImagePasting;
|
|
32
|
+
|
|
33
|
+
@end
|
|
34
|
+
NS_ASSUME_NONNULL_END
|