@tbvjaos510/react-native-paste-input 0.9.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.
Files changed (108) hide show
  1. package/.circleci/config.yml +130 -0
  2. package/LICENSE +21 -0
  3. package/README.md +73 -0
  4. package/android/.project +17 -0
  5. package/android/.settings/org.eclipse.buildship.core.prefs +13 -0
  6. package/android/build.gradle +94 -0
  7. package/android/generated/java/com/facebook/react/viewmanagers/PasteTextInputManagerDelegate.java +236 -0
  8. package/android/generated/java/com/facebook/react/viewmanagers/PasteTextInputManagerInterface.java +84 -0
  9. package/android/generated/jni/CMakeLists.txt +36 -0
  10. package/android/generated/jni/PasteTextInputSpecs-generated.cpp +27 -0
  11. package/android/generated/jni/PasteTextInputSpecs.h +28 -0
  12. package/android/generated/jni/react/renderer/components/PasteTextInputSpecs/ComponentDescriptors.cpp +22 -0
  13. package/android/generated/jni/react/renderer/components/PasteTextInputSpecs/ComponentDescriptors.h +166 -0
  14. package/android/generated/jni/react/renderer/components/PasteTextInputSpecs/EventEmitters.cpp +183 -0
  15. package/android/generated/jni/react/renderer/components/PasteTextInputSpecs/EventEmitters.h +148 -0
  16. package/android/generated/jni/react/renderer/components/PasteTextInputSpecs/PasteTextInputSpecsJSI-generated.cpp +17 -0
  17. package/android/generated/jni/react/renderer/components/PasteTextInputSpecs/PasteTextInputSpecsJSI.h +19 -0
  18. package/android/generated/jni/react/renderer/components/PasteTextInputSpecs/Props.cpp +640 -0
  19. package/android/generated/jni/react/renderer/components/PasteTextInputSpecs/Props.h +144 -0
  20. package/android/generated/jni/react/renderer/components/PasteTextInputSpecs/ShadowNodes.cpp +247 -0
  21. package/android/generated/jni/react/renderer/components/PasteTextInputSpecs/ShadowNodes.h +95 -0
  22. package/android/generated/jni/react/renderer/components/PasteTextInputSpecs/States.cpp +14 -0
  23. package/android/generated/jni/react/renderer/components/PasteTextInputSpecs/States.h +19 -0
  24. package/android/gradle.properties +6 -0
  25. package/android/src/main/java/com/mattermost/pasteinputtext/IPasteInputListener.kt +8 -0
  26. package/android/src/main/java/com/mattermost/pasteinputtext/PasteInputActionCallback.kt +72 -0
  27. package/android/src/main/java/com/mattermost/pasteinputtext/PasteInputEditText.kt +60 -0
  28. package/android/src/main/java/com/mattermost/pasteinputtext/PasteInputFileFromUrl.kt +50 -0
  29. package/android/src/main/java/com/mattermost/pasteinputtext/PasteInputListener.kt +84 -0
  30. package/android/src/main/java/com/mattermost/pasteinputtext/PasteTextInputManager.kt +72 -0
  31. package/android/src/main/java/com/mattermost/pasteinputtext/PasteTextInputPackage.kt +14 -0
  32. package/android/src/main/java/com/mattermost/pasteinputtext/PasteTextInputPasteEvent.java +41 -0
  33. package/android/src/main/java/com/mattermost/pasteinputtext/RealPathUtil.kt +174 -0
  34. package/ios/NSData+MimeType.h +20 -0
  35. package/ios/NSData+MimeType.m +59 -0
  36. package/ios/PasteInput-Bridging-Header.h +1 -0
  37. package/ios/PasteInput.xcodeproj/project.pbxproj +319 -0
  38. package/ios/PasteInputTextView.h +20 -0
  39. package/ios/PasteInputTextView.m +68 -0
  40. package/ios/PasteInputView.h +18 -0
  41. package/ios/PasteInputView.m +96 -0
  42. package/ios/PasteTextInput.h +13 -0
  43. package/ios/PasteTextInput.mm +726 -0
  44. package/ios/PasteTextInputManager.mm +171 -0
  45. package/ios/Swime/MimeType.h +70 -0
  46. package/ios/Swime/MimeType.m +701 -0
  47. package/ios/Swime/Swime.h +14 -0
  48. package/ios/Swime/Swime.m +28 -0
  49. package/ios/Swime/SwimeProxy.h +18 -0
  50. package/ios/Swime/SwimeProxy.m +66 -0
  51. package/ios/Swime/SwimeUtils.h +12 -0
  52. package/ios/Swime/SwimeUtils.m +23 -0
  53. package/ios/UIImage+ImageEffects.h +112 -0
  54. package/ios/UIImage+ImageEffects.m +310 -0
  55. package/ios/UIImage+vImageScaling.h +16 -0
  56. package/ios/UIImage+vImageScaling.m +48 -0
  57. package/ios/UIPasteboard+GetImageInfo.h +19 -0
  58. package/ios/UIPasteboard+GetImageInfo.m +98 -0
  59. package/ios/generated/PasteTextInputSpecs/ComponentDescriptors.cpp +22 -0
  60. package/ios/generated/PasteTextInputSpecs/ComponentDescriptors.h +42 -0
  61. package/ios/generated/PasteTextInputSpecs/EventEmitters.cpp +41 -0
  62. package/ios/generated/PasteTextInputSpecs/EventEmitters.h +37 -0
  63. package/ios/generated/PasteTextInputSpecs/PasteTextInputSpecs-generated.mm +16 -0
  64. package/ios/generated/PasteTextInputSpecs/PasteTextInputSpecs.h +38 -0
  65. package/ios/generated/PasteTextInputSpecs/Props.cpp +142 -0
  66. package/ios/generated/PasteTextInputSpecs/Props.h +81 -0
  67. package/ios/generated/PasteTextInputSpecs/RCTComponentViewHelpers.h +106 -0
  68. package/ios/generated/PasteTextInputSpecs/ShadowNodes.cpp +127 -0
  69. package/ios/generated/PasteTextInputSpecs/ShadowNodes.h +85 -0
  70. package/ios/generated/PasteTextInputSpecs/States.cpp +16 -0
  71. package/ios/generated/PasteTextInputSpecs/States.h +53 -0
  72. package/ios/generated/PasteTextInputSpecsJSI-generated.cpp +17 -0
  73. package/ios/generated/PasteTextInputSpecsJSI.h +19 -0
  74. package/lib/commonjs/PasteTextInput.js +446 -0
  75. package/lib/commonjs/PasteTextInput.js.map +1 -0
  76. package/lib/commonjs/PasteTextInputNativeComponent.ts +277 -0
  77. package/lib/commonjs/index.js +25 -0
  78. package/lib/commonjs/index.js.map +1 -0
  79. package/lib/commonjs/module.d.js +2 -0
  80. package/lib/commonjs/module.d.js.map +1 -0
  81. package/lib/commonjs/package.json +1 -0
  82. package/lib/commonjs/types.js +6 -0
  83. package/lib/commonjs/types.js.map +1 -0
  84. package/lib/module/PasteTextInput.js +440 -0
  85. package/lib/module/PasteTextInput.js.map +1 -0
  86. package/lib/module/PasteTextInputNativeComponent.ts +277 -0
  87. package/lib/module/index.js +9 -0
  88. package/lib/module/index.js.map +1 -0
  89. package/lib/module/module.d.js +2 -0
  90. package/lib/module/module.d.js.map +1 -0
  91. package/lib/module/types.js +4 -0
  92. package/lib/module/types.js.map +1 -0
  93. package/lib/typescript/src/PasteTextInput.d.ts +5 -0
  94. package/lib/typescript/src/PasteTextInput.d.ts.map +1 -0
  95. package/lib/typescript/src/PasteTextInputNativeComponent.d.ts +168 -0
  96. package/lib/typescript/src/PasteTextInputNativeComponent.d.ts.map +1 -0
  97. package/lib/typescript/src/index.d.ts +6 -0
  98. package/lib/typescript/src/index.d.ts.map +1 -0
  99. package/lib/typescript/src/types.d.ts +56 -0
  100. package/lib/typescript/src/types.d.ts.map +1 -0
  101. package/package.json +140 -0
  102. package/react-native-paste-input.podspec +20 -0
  103. package/react-native.config.js +13 -0
  104. package/src/PasteTextInput.tsx +615 -0
  105. package/src/PasteTextInputNativeComponent.ts +277 -0
  106. package/src/index.ts +13 -0
  107. package/src/module.d.ts +4 -0
  108. package/src/types.ts +71 -0
@@ -0,0 +1,615 @@
1
+ import * as React from 'react';
2
+ import PasteTextInputNativeComponent, {
3
+ Commands,
4
+ } from './PasteTextInputNativeComponent';
5
+ import type {
6
+ PasteEvent,
7
+ PasteInputProps,
8
+ PasteTextInputInstance,
9
+ Selection,
10
+ SubmitBehavior,
11
+ } from './types';
12
+ import {
13
+ Platform,
14
+ StyleSheet,
15
+ Text,
16
+ type HostComponent,
17
+ type KeyboardTypeOptions,
18
+ type NativeSyntheticEvent,
19
+ type NativeTouchEvent,
20
+ type ReturnKeyTypeOptions,
21
+ type TextInputChangeEventData,
22
+ type TextInputFocusEventData,
23
+ type TextInputScrollEventData,
24
+ type TextInputSelectionChangeEventData,
25
+ } from 'react-native';
26
+
27
+ import TextAncestor from 'react-native/Libraries/Text/TextAncestor';
28
+ import TextInputState from 'react-native/Libraries/Components/TextInput/TextInputState';
29
+ import usePressability from 'react-native/Libraries/Pressability/usePressability';
30
+ import flattenStyle from 'react-native/Libraries/StyleSheet/flattenStyle';
31
+ import nullthrows from 'nullthrows';
32
+
33
+ const emptyFunctionThatReturnsTrue = () => true;
34
+
35
+ function useMergeRefs<Instance>(
36
+ ...refs: ReadonlyArray<React.ForwardedRef<Instance> | null | undefined>
37
+ ): (arg0: Instance | null) => void {
38
+ return React.useCallback(
39
+ (current: Instance | null) => {
40
+ for (const ref of refs) {
41
+ if (ref != null) {
42
+ if (typeof ref === 'function') {
43
+ ref(current);
44
+ } else {
45
+ ref.current = current;
46
+ }
47
+ }
48
+ }
49
+ },
50
+ [...refs] // eslint-disable-line react-hooks/exhaustive-deps
51
+ );
52
+ }
53
+
54
+ function InternalTextInput(props: PasteInputProps): React.ReactNode {
55
+ const {
56
+ 'aria-busy': ariaBusy,
57
+ 'aria-checked': ariaChecked,
58
+ 'aria-disabled': ariaDisabled,
59
+ 'aria-expanded': ariaExpanded,
60
+ 'aria-selected': ariaSelected,
61
+ accessibilityState,
62
+ id,
63
+ tabIndex,
64
+ 'selection': propsSelection,
65
+ selectionColor,
66
+ // selectionHandleColor,
67
+ // cursorColor,
68
+ ...otherProps
69
+ } = props;
70
+
71
+ const inputRef = React.useRef<null | React.ElementRef<HostComponent<any>>>(
72
+ null
73
+ );
74
+
75
+ const selection: Selection | null = React.useMemo(
76
+ () =>
77
+ propsSelection == null
78
+ ? null
79
+ : {
80
+ start: propsSelection.start,
81
+ end: propsSelection.end ?? propsSelection.start,
82
+ },
83
+ [propsSelection]
84
+ );
85
+
86
+ const [mostRecentEventCount, setMostRecentEventCount] =
87
+ React.useState<number>(0);
88
+ const [lastNativeText, setLastNativeText] = React.useState<
89
+ string | undefined
90
+ >(props.value);
91
+ const [lastNativeSelectionState, setLastNativeSelection] = React.useState<{
92
+ selection: Selection;
93
+ mostRecentEventCount: number;
94
+ }>({
95
+ selection: { start: -1, end: -1 },
96
+ mostRecentEventCount,
97
+ });
98
+
99
+ const lastNativeSelection = lastNativeSelectionState.selection;
100
+ const text =
101
+ typeof props.value === 'string'
102
+ ? props.value
103
+ : typeof props.defaultValue === 'string'
104
+ ? props.defaultValue
105
+ : undefined;
106
+
107
+ // This is necessary in case native updates the text and JS decides
108
+ // that the update should be ignored and we should stick with the value
109
+ // that we have in JS.
110
+ React.useLayoutEffect(() => {
111
+ const nativeUpdate: { text?: string; selection?: Selection } = {};
112
+
113
+ if (lastNativeText !== props.value && typeof props.value === 'string') {
114
+ nativeUpdate.text = props.value;
115
+ setLastNativeText(props.value);
116
+ }
117
+
118
+ if (
119
+ selection &&
120
+ lastNativeSelection &&
121
+ (lastNativeSelection.start !== selection.start ||
122
+ lastNativeSelection.end !== selection.end)
123
+ ) {
124
+ nativeUpdate.selection = selection;
125
+ setLastNativeSelection({ selection, mostRecentEventCount });
126
+ }
127
+
128
+ if (Object.keys(nativeUpdate).length === 0) {
129
+ return;
130
+ }
131
+
132
+ if (inputRef.current != null) {
133
+ Commands.setTextAndSelection(
134
+ inputRef.current,
135
+ mostRecentEventCount,
136
+ text,
137
+ selection?.start ?? -1,
138
+ selection?.end ?? -1
139
+ );
140
+ }
141
+ }, [
142
+ mostRecentEventCount,
143
+ inputRef,
144
+ props.value,
145
+ props.defaultValue,
146
+ lastNativeText,
147
+ selection,
148
+ lastNativeSelection,
149
+ text,
150
+ ]);
151
+
152
+ let children = props.children;
153
+ const childCount = React.Children.count(children);
154
+ if (props.value != null && childCount) {
155
+ throw new Error('Cannot specify both value and children');
156
+ }
157
+ if (childCount > 1) {
158
+ children = <Text>{children}</Text>;
159
+ }
160
+
161
+ React.useLayoutEffect(() => {
162
+ const inputRefValue = inputRef.current;
163
+
164
+ if (inputRefValue != null) {
165
+ TextInputState.registerInput(inputRefValue);
166
+ }
167
+
168
+ return () => {
169
+ if (inputRefValue != null) {
170
+ TextInputState.unregisterInput(inputRefValue);
171
+ }
172
+
173
+ if (TextInputState.currentlyFocusedInput() === inputRefValue) {
174
+ nullthrows(inputRefValue).blur();
175
+ }
176
+ };
177
+ }, [inputRef]);
178
+
179
+ const setLocalRef = React.useCallback(
180
+ (instance: PasteTextInputInstance | null) => {
181
+ inputRef.current = instance;
182
+ if (instance != null) {
183
+ // $FlowFixMe[incompatible-use] - See the explanation above.
184
+ Object.assign(instance, {
185
+ clear(): void {
186
+ if (inputRef.current != null) {
187
+ Commands.setTextAndSelection(
188
+ inputRef.current,
189
+ mostRecentEventCount,
190
+ '',
191
+ 0,
192
+ 0
193
+ );
194
+ }
195
+ },
196
+ // TODO: Fix this returning true on null === null, when no input is focused
197
+ isFocused(): boolean {
198
+ return (
199
+ TextInputState.currentlyFocusedInput() ===
200
+ inputRef.current
201
+ );
202
+ },
203
+ getNativeRef(): null | React.ElementRef<
204
+ HostComponent<any>
205
+ > {
206
+ return inputRef.current;
207
+ },
208
+ setSelection(start: number, end: number): void {
209
+ if (inputRef.current != null) {
210
+ Commands.setTextAndSelection(
211
+ inputRef.current,
212
+ mostRecentEventCount,
213
+ null,
214
+ start,
215
+ end
216
+ );
217
+ }
218
+ },
219
+ });
220
+ }
221
+ },
222
+ [mostRecentEventCount]
223
+ );
224
+
225
+ const ref = useMergeRefs<PasteTextInputInstance>(
226
+ setLocalRef,
227
+ props.forwardedRef
228
+ );
229
+
230
+ const _onChange = (
231
+ event: NativeSyntheticEvent<TextInputChangeEventData>
232
+ ) => {
233
+ const currentText = event.nativeEvent.text;
234
+ props.onChange && props.onChange(event);
235
+ props.onChangeText && props.onChangeText(currentText);
236
+
237
+ if (inputRef.current == null) {
238
+ // calling `props.onChange` or `props.onChangeText`
239
+ // may clean up the input itself. Exits here.
240
+ return;
241
+ }
242
+
243
+ setLastNativeText(currentText);
244
+ // This must happen last, after we call setLastNativeText.
245
+ // Different ordering can cause bugs when editing AndroidTextInputs
246
+ // with multiple Fragments.
247
+ // We must update this so that controlled input updates work.
248
+ setMostRecentEventCount(event.nativeEvent.eventCount);
249
+ };
250
+
251
+ const _onBlur = (event: NativeSyntheticEvent<TextInputFocusEventData>) => {
252
+ TextInputState.blurInput(inputRef.current);
253
+ if (props.onBlur) {
254
+ props.onBlur(event);
255
+ }
256
+ };
257
+
258
+ const _onFocus = (event: NativeSyntheticEvent<TextInputFocusEventData>) => {
259
+ TextInputState.focusInput(inputRef.current);
260
+ if (props.onFocus) {
261
+ props.onFocus(event);
262
+ }
263
+ };
264
+
265
+ const _onPaste = (event: PasteEvent) => {
266
+ if (props.onPaste) {
267
+ const { data, error } = event.nativeEvent;
268
+ props.onPaste(error?.message, data);
269
+ }
270
+ };
271
+
272
+ const _onScroll = (
273
+ event: NativeSyntheticEvent<TextInputScrollEventData>
274
+ ) => {
275
+ props.onScroll && props.onScroll(event);
276
+ };
277
+
278
+ const _onSelectionChange = (
279
+ event: NativeSyntheticEvent<TextInputSelectionChangeEventData>
280
+ ) => {
281
+ props.onSelectionChange && props.onSelectionChange(event);
282
+
283
+ if (inputRef.current == null) {
284
+ // calling `props.onSelectionChange`
285
+ // may clean up the input itself. Exits here.
286
+ return;
287
+ }
288
+
289
+ setLastNativeSelection({
290
+ selection: event.nativeEvent.selection,
291
+ mostRecentEventCount,
292
+ });
293
+ };
294
+
295
+ const multiline = props.multiline ?? false;
296
+
297
+ let submitBehavior: SubmitBehavior;
298
+ if (props.submitBehavior != null) {
299
+ // `submitBehavior` is set explicitly
300
+ if (!multiline && props.submitBehavior === 'newline') {
301
+ // For single line text inputs, `'newline'` is not a valid option
302
+ submitBehavior = 'blurAndSubmit';
303
+ } else {
304
+ submitBehavior = props.submitBehavior;
305
+ }
306
+ } else if (multiline) {
307
+ if (props.blurOnSubmit === true) {
308
+ submitBehavior = 'blurAndSubmit';
309
+ } else {
310
+ submitBehavior = 'newline';
311
+ }
312
+ } else {
313
+ // Single line
314
+ if (props.blurOnSubmit !== false) {
315
+ submitBehavior = 'blurAndSubmit';
316
+ } else {
317
+ submitBehavior = 'submit';
318
+ }
319
+ }
320
+
321
+ const accessible = props.accessible !== false;
322
+ const focusable = props.focusable !== false;
323
+
324
+ const {
325
+ editable,
326
+ hitSlop,
327
+ onPress,
328
+ onPressIn,
329
+ onPressOut,
330
+ rejectResponderTermination,
331
+ } = props;
332
+
333
+ const config = React.useMemo(
334
+ () => ({
335
+ hitSlop,
336
+ onPress: (event: NativeSyntheticEvent<NativeTouchEvent>) => {
337
+ onPress?.(event);
338
+ if (editable !== false) {
339
+ if (inputRef.current != null) {
340
+ inputRef.current.focus();
341
+ }
342
+ }
343
+ },
344
+ onPressIn: onPressIn,
345
+ onPressOut: onPressOut,
346
+ cancelable:
347
+ Platform.OS === 'ios' ? !rejectResponderTermination : null,
348
+ }),
349
+ [
350
+ editable,
351
+ hitSlop,
352
+ onPress,
353
+ onPressIn,
354
+ onPressOut,
355
+ rejectResponderTermination,
356
+ ]
357
+ );
358
+
359
+ // Hide caret during test runs due to a flashing caret
360
+ // makes screenshot tests flakey
361
+ let caretHidden = props.caretHidden;
362
+ if (Platform.isTesting) {
363
+ caretHidden = true;
364
+ }
365
+
366
+ // TextInput handles onBlur and onFocus events
367
+ // so omitting onBlur and onFocus pressability handlers here.
368
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
369
+ const { onBlur, onFocus, ...eventHandlers } = usePressability(config) || {};
370
+
371
+ let _accessibilityState;
372
+ if (
373
+ accessibilityState != null ||
374
+ ariaBusy != null ||
375
+ ariaChecked != null ||
376
+ ariaDisabled != null ||
377
+ ariaExpanded != null ||
378
+ ariaSelected != null
379
+ ) {
380
+ _accessibilityState = {
381
+ busy: ariaBusy ?? accessibilityState?.busy,
382
+ checked: ariaChecked ?? accessibilityState?.checked,
383
+ disabled: ariaDisabled ?? accessibilityState?.disabled,
384
+ expanded: ariaExpanded ?? accessibilityState?.expanded,
385
+ selected: ariaSelected ?? accessibilityState?.selected,
386
+ };
387
+ }
388
+
389
+ const style = flattenStyle(props.style);
390
+
391
+ const useMultilineDefaultStyle =
392
+ props.multiline === true &&
393
+ (style == null ||
394
+ (style.padding == null &&
395
+ style.paddingVertical == null &&
396
+ style.paddingTop == null));
397
+
398
+ const textInput = (
399
+ <PasteTextInputNativeComponent
400
+ ref={ref}
401
+ {...otherProps}
402
+ {...eventHandlers}
403
+ accessibilityState={_accessibilityState}
404
+ accessible={accessible}
405
+ submitBehavior={submitBehavior}
406
+ caretHidden={caretHidden}
407
+ dataDetectorTypes={props.dataDetectorTypes}
408
+ focusable={tabIndex !== undefined ? !tabIndex : focusable}
409
+ mostRecentEventCount={mostRecentEventCount}
410
+ nativeID={id ?? props.nativeID}
411
+ onBlur={_onBlur}
412
+ onChange={_onChange}
413
+ onContentSizeChange={props.onContentSizeChange}
414
+ onFocus={_onFocus}
415
+ onPaste={_onPaste}
416
+ onScroll={_onScroll}
417
+ onSelectionChange={_onSelectionChange}
418
+ onSelectionChangeShouldSetResponder={emptyFunctionThatReturnsTrue}
419
+ selection={selection}
420
+ selectionColor={selectionColor}
421
+ style={StyleSheet.compose(
422
+ useMultilineDefaultStyle ? styles.multilineDefault : null,
423
+ style
424
+ )}
425
+ text={text}
426
+ children={children}
427
+ />
428
+ );
429
+
430
+ return (
431
+ <TextAncestor.Provider value={true}>{textInput}</TextAncestor.Provider>
432
+ );
433
+ }
434
+
435
+ const enterKeyHintToReturnTypeMap: Record<string, ReturnKeyTypeOptions> = {
436
+ enter: 'default',
437
+ done: 'done',
438
+ go: 'go',
439
+ next: 'next',
440
+ previous: 'previous',
441
+ search: 'search',
442
+ send: 'send',
443
+ };
444
+
445
+ const inputModeToKeyboardTypeMap: Record<string, KeyboardTypeOptions> = {
446
+ none: 'default',
447
+ text: 'default',
448
+ decimal: 'decimal-pad',
449
+ numeric: 'number-pad',
450
+ tel: 'phone-pad',
451
+ search: Platform.OS === 'ios' ? 'web-search' : 'default',
452
+ email: 'email-address',
453
+ url: 'url',
454
+ };
455
+
456
+ // Map HTML autocomplete values to Android autoComplete values
457
+ const autoCompleteWebToAutoCompleteAndroidMap: Record<string, string> = {
458
+ 'address-line1': 'postal-address-region',
459
+ 'address-line2': 'postal-address-locality',
460
+ 'bday': 'birthdate-full',
461
+ 'bday-day': 'birthdate-day',
462
+ 'bday-month': 'birthdate-month',
463
+ 'bday-year': 'birthdate-year',
464
+ 'cc-csc': 'cc-csc',
465
+ 'cc-exp': 'cc-exp',
466
+ 'cc-exp-month': 'cc-exp-month',
467
+ 'cc-exp-year': 'cc-exp-year',
468
+ 'cc-number': 'cc-number',
469
+ 'country': 'postal-address-country',
470
+ 'current-password': 'password',
471
+ 'email': 'email',
472
+ 'honorific-prefix': 'name-prefix',
473
+ 'honorific-suffix': 'name-suffix',
474
+ 'name': 'name',
475
+ 'additional-name': 'name-middle',
476
+ 'family-name': 'name-family',
477
+ 'given-name': 'name-given',
478
+ 'new-password': 'password-new',
479
+ 'off': 'off',
480
+ 'one-time-code': 'sms-otp',
481
+ 'postal-code': 'postal-code',
482
+ 'sex': 'gender',
483
+ 'street-address': 'street-address',
484
+ 'tel': 'tel',
485
+ 'tel-country-code': 'tel-country-code',
486
+ 'tel-national': 'tel-national',
487
+ 'username': 'username',
488
+ };
489
+
490
+ // Map HTML autocomplete values to iOS textContentType values
491
+ const autoCompleteWebToTextContentTypeMap = {
492
+ 'address-line1': 'streetAddressLine1',
493
+ 'address-line2': 'streetAddressLine2',
494
+ 'bday': 'birthdate',
495
+ 'bday-day': 'birthdateDay',
496
+ 'bday-month': 'birthdateMonth',
497
+ 'bday-year': 'birthdateYear',
498
+ 'cc-csc': 'creditCardSecurityCode',
499
+ 'cc-exp-month': 'creditCardExpirationMonth',
500
+ 'cc-exp-year': 'creditCardExpirationYear',
501
+ 'cc-exp': 'creditCardExpiration',
502
+ 'cc-given-name': 'creditCardGivenName',
503
+ 'cc-additional-name': 'creditCardMiddleName',
504
+ 'cc-family-name': 'creditCardFamilyName',
505
+ 'cc-name': 'creditCardName',
506
+ 'cc-number': 'creditCardNumber',
507
+ 'cc-type': 'creditCardType',
508
+ 'current-password': 'password',
509
+ 'country': 'countryName',
510
+ 'email': 'emailAddress',
511
+ 'name': 'name',
512
+ 'additional-name': 'middleName',
513
+ 'family-name': 'familyName',
514
+ 'given-name': 'givenName',
515
+ 'nickname': 'nickname',
516
+ 'honorific-prefix': 'namePrefix',
517
+ 'honorific-suffix': 'nameSuffix',
518
+ 'new-password': 'newPassword',
519
+ 'off': 'none',
520
+ 'one-time-code': 'oneTimeCode',
521
+ 'organization': 'organizationName',
522
+ 'organization-title': 'jobTitle',
523
+ 'postal-code': 'postalCode',
524
+ 'street-address': 'fullStreetAddress',
525
+ 'tel': 'telephoneNumber',
526
+ 'url': 'URL',
527
+ 'username': 'username',
528
+ };
529
+
530
+ const verticalAlignToTextAlignVerticalMap: Record<string, string> = {
531
+ auto: 'auto',
532
+ top: 'top',
533
+ bottom: 'bottom',
534
+ middle: 'center',
535
+ };
536
+
537
+ const ExportedForwardRef = React.forwardRef(function PasteTextInput(
538
+ {
539
+ allowFontScaling = true,
540
+ rejectResponderTermination = true,
541
+ underlineColorAndroid = 'transparent',
542
+ autoComplete,
543
+ textContentType,
544
+ readOnly,
545
+ editable,
546
+ enterKeyHint,
547
+ returnKeyType,
548
+ inputMode,
549
+ showSoftInputOnFocus,
550
+ keyboardType,
551
+ ...restProps
552
+ }: PasteInputProps,
553
+ forwardedRef: React.ForwardedRef<PasteTextInputInstance>
554
+ ) {
555
+ let style = flattenStyle(restProps.style);
556
+
557
+ if (style?.verticalAlign != null) {
558
+ style.textAlignVertical =
559
+ verticalAlignToTextAlignVerticalMap[style.verticalAlign];
560
+ delete style.verticalAlign;
561
+ }
562
+
563
+ return (
564
+ <InternalTextInput
565
+ allowFontScaling={allowFontScaling}
566
+ rejectResponderTermination={rejectResponderTermination}
567
+ underlineColorAndroid={underlineColorAndroid}
568
+ editable={readOnly !== undefined ? !readOnly : editable}
569
+ returnKeyType={
570
+ enterKeyHint
571
+ ? enterKeyHintToReturnTypeMap[enterKeyHint]
572
+ : returnKeyType
573
+ }
574
+ keyboardType={
575
+ inputMode ? inputModeToKeyboardTypeMap[inputMode] : keyboardType
576
+ }
577
+ showSoftInputOnFocus={
578
+ inputMode == null ? showSoftInputOnFocus : inputMode !== 'none'
579
+ }
580
+ autoComplete={
581
+ Platform.OS === 'android'
582
+ ? // @ts-ignore
583
+ (autoCompleteWebToAutoCompleteAndroidMap[autoComplete] ??
584
+ autoComplete)
585
+ : undefined
586
+ }
587
+ textContentType={
588
+ textContentType != null
589
+ ? textContentType
590
+ : Platform.OS === 'ios' &&
591
+ autoComplete &&
592
+ autoComplete in autoCompleteWebToTextContentTypeMap
593
+ ? // @ts-ignore
594
+ autoCompleteWebToTextContentTypeMap[autoComplete]
595
+ : textContentType
596
+ }
597
+ {...restProps}
598
+ forwardedRef={forwardedRef}
599
+ style={style}
600
+ />
601
+ );
602
+ });
603
+
604
+ ExportedForwardRef.displayName = 'PasteTextInput';
605
+
606
+ const styles = StyleSheet.create({
607
+ multilineDefault: {
608
+ // This default top inset makes RCTMultilineTextInputView seem as close as possible
609
+ // to single-line RCTSinglelineTextInputView defaults, using the system defaults
610
+ // of font size 17 and a height of 31 points.
611
+ paddingTop: 5,
612
+ },
613
+ });
614
+
615
+ export default ExportedForwardRef;