@onekeyfe/react-native-text-input 0.3.0 → 3.0.92

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 (77) hide show
  1. package/OneKeyTextInput.podspec +18 -0
  2. package/README.md +10 -28
  3. package/android/build.gradle +3 -3
  4. package/android/gradle.properties +5 -5
  5. package/android/src/main/java/com/textinput/TextInputViewManager.kt +14 -14
  6. package/ios/OneKeyTextInputPasteObserver.h +11 -0
  7. package/ios/OneKeyTextInputPasteObserver.mm +204 -0
  8. package/lib/module/AndroidTextInputNativeComponent.js +111 -0
  9. package/lib/{commonjs → module}/Input.js +127 -107
  10. package/lib/module/enum.js +7 -0
  11. package/lib/module/index.js +11 -0
  12. package/lib/module/package.json +1 -0
  13. package/lib/module/type.js +4 -0
  14. package/lib/typescript/package.json +1 -0
  15. package/lib/typescript/src/index.d.ts +4 -4
  16. package/lib/typescript/src/type.d.ts +2 -2
  17. package/package.json +32 -117
  18. package/react-native.config.js +12 -0
  19. package/src/AndroidTextInputNativeComponent.js +77 -88
  20. package/src/Input.js +242 -1027
  21. package/src/enum.ts +1 -1
  22. package/src/index.tsx +5 -5
  23. package/src/type.ts +2 -2
  24. package/android/generated/android/app/build/generated/source/codegen/java/com/facebook/react/viewmanagers/OneKeyTextInputManagerDelegate.java +0 -26
  25. package/android/generated/android/app/build/generated/source/codegen/java/com/facebook/react/viewmanagers/OneKeyTextInputManagerInterface.java +0 -17
  26. package/android/generated/android/app/build/generated/source/codegen/jni/CMakeLists.txt +0 -36
  27. package/android/generated/android/app/build/generated/source/codegen/jni/RNTextInputViewSpec-generated.cpp +0 -22
  28. package/android/generated/android/app/build/generated/source/codegen/jni/RNTextInputViewSpec.h +0 -24
  29. package/android/generated/android/app/build/generated/source/codegen/jni/react/renderer/components/RNTextInputViewSpec/ComponentDescriptors.cpp +0 -22
  30. package/android/generated/android/app/build/generated/source/codegen/jni/react/renderer/components/RNTextInputViewSpec/ComponentDescriptors.h +0 -24
  31. package/android/generated/android/app/build/generated/source/codegen/jni/react/renderer/components/RNTextInputViewSpec/EventEmitters.cpp +0 -24
  32. package/android/generated/android/app/build/generated/source/codegen/jni/react/renderer/components/RNTextInputViewSpec/EventEmitters.h +0 -25
  33. package/android/generated/android/app/build/generated/source/codegen/jni/react/renderer/components/RNTextInputViewSpec/Props.cpp +0 -25
  34. package/android/generated/android/app/build/generated/source/codegen/jni/react/renderer/components/RNTextInputViewSpec/Props.h +0 -27
  35. package/android/generated/android/app/build/generated/source/codegen/jni/react/renderer/components/RNTextInputViewSpec/RNTextInputViewSpecJSI-generated.cpp +0 -17
  36. package/android/generated/android/app/build/generated/source/codegen/jni/react/renderer/components/RNTextInputViewSpec/RNTextInputViewSpecJSI.h +0 -19
  37. package/android/generated/android/app/build/generated/source/codegen/jni/react/renderer/components/RNTextInputViewSpec/ShadowNodes.cpp +0 -17
  38. package/android/generated/android/app/build/generated/source/codegen/jni/react/renderer/components/RNTextInputViewSpec/ShadowNodes.h +0 -32
  39. package/android/generated/android/app/build/generated/source/codegen/jni/react/renderer/components/RNTextInputViewSpec/States.cpp +0 -16
  40. package/android/generated/android/app/build/generated/source/codegen/jni/react/renderer/components/RNTextInputViewSpec/States.h +0 -29
  41. package/android/src/newarch/TextInputViewManagerSpec.kt +0 -21
  42. package/android/src/oldarch/TextInputViewManagerSpec.kt +0 -9
  43. package/ios/TextInputViewManager.mm +0 -23
  44. package/ios/Utils.h +0 -8
  45. package/ios/Utils.m +0 -26
  46. package/ios/generated/build/generated/ios/RNTextInputViewSpec/RNTextInputViewSpec-generated.mm +0 -16
  47. package/ios/generated/build/generated/ios/RNTextInputViewSpec/RNTextInputViewSpec.h +0 -38
  48. package/ios/generated/build/generated/ios/RNTextInputViewSpecJSI-generated.cpp +0 -17
  49. package/ios/generated/build/generated/ios/RNTextInputViewSpecJSI.h +0 -19
  50. package/ios/generated/build/generated/ios/react/renderer/components/RNTextInputViewSpec/ComponentDescriptors.cpp +0 -22
  51. package/ios/generated/build/generated/ios/react/renderer/components/RNTextInputViewSpec/ComponentDescriptors.h +0 -24
  52. package/ios/generated/build/generated/ios/react/renderer/components/RNTextInputViewSpec/EventEmitters.cpp +0 -24
  53. package/ios/generated/build/generated/ios/react/renderer/components/RNTextInputViewSpec/EventEmitters.h +0 -25
  54. package/ios/generated/build/generated/ios/react/renderer/components/RNTextInputViewSpec/Props.cpp +0 -25
  55. package/ios/generated/build/generated/ios/react/renderer/components/RNTextInputViewSpec/Props.h +0 -27
  56. package/ios/generated/build/generated/ios/react/renderer/components/RNTextInputViewSpec/RCTComponentViewHelpers.h +0 -20
  57. package/ios/generated/build/generated/ios/react/renderer/components/RNTextInputViewSpec/ShadowNodes.cpp +0 -17
  58. package/ios/generated/build/generated/ios/react/renderer/components/RNTextInputViewSpec/ShadowNodes.h +0 -32
  59. package/ios/generated/build/generated/ios/react/renderer/components/RNTextInputViewSpec/States.cpp +0 -16
  60. package/ios/generated/build/generated/ios/react/renderer/components/RNTextInputViewSpec/States.h +0 -29
  61. package/lib/commonjs/AndroidTextInputNativeComponent.js +0 -152
  62. package/lib/commonjs/AndroidTextInputNativeComponent.js.map +0 -1
  63. package/lib/commonjs/Input.js.map +0 -1
  64. package/lib/commonjs/TextInputViewNativeComponent.ts +0 -9
  65. package/lib/commonjs/enum.js +0 -11
  66. package/lib/commonjs/enum.js.map +0 -1
  67. package/lib/commonjs/index.js +0 -28
  68. package/lib/commonjs/index.js.map +0 -1
  69. package/lib/commonjs/package.json +0 -1
  70. package/lib/commonjs/type.js +0 -6
  71. package/lib/commonjs/type.js.map +0 -1
  72. package/lib/typescript/src/TextInputViewNativeComponent.d.ts +0 -8
  73. package/lib/typescript/src/TextInputViewNativeComponent.d.ts.map +0 -1
  74. package/lib/typescript/src/enum.d.ts.map +0 -1
  75. package/lib/typescript/src/index.d.ts.map +0 -1
  76. package/lib/typescript/src/type.d.ts.map +0 -1
  77. package/src/TextInputViewNativeComponent.ts +0 -9
package/src/Input.js CHANGED
@@ -1,5 +1,3 @@
1
- /* eslint-disable prettier/prettier */
2
-
3
1
  /**
4
2
  * Copyright (c) Meta Platforms, Inc. and affiliates.
5
3
  *
@@ -13,29 +11,79 @@
13
11
  import type {HostInstance} from 'react-native/src/private/types/HostInstance';
14
12
  import type {____TextStyle_Internal as TextStyleInternal} from 'react-native/Libraries/StyleSheet/StyleSheetTypes';
15
13
  import type {
14
+ BlurEvent,
15
+ FocusEvent,
16
16
  GestureResponderEvent,
17
- NativeSyntheticEvent,
18
17
  ScrollEvent,
19
18
  } from 'react-native/Libraries/Types/CoreEventTypes';
20
- import type {ViewProps} from 'react-native/Libraries/Components/View/ViewPropTypes';
21
- import type {TextInputInstance, TextInputType} from 'react-native/Libraries/Components/TextInput/TextInput.flow';
22
-
23
- import usePressability from 'react-native/Libraries/Pressability/usePressability.js';
24
- import flattenStyle from 'react-native/Libraries/StyleSheet/flattenStyle.js';
25
- import StyleSheet, {
26
- type ColorValue,
27
- type TextStyleProp,
28
- type ViewStyleProp,
29
- } from 'react-native/Libraries/StyleSheet/StyleSheet';
19
+ import type {
20
+ AutoCapitalize,
21
+ EnterKeyHintType,
22
+ EnterKeyHintTypeAndroid,
23
+ EnterKeyHintTypeIOS,
24
+ EnterKeyHintTypeOptions,
25
+ InputModeOptions,
26
+ KeyboardType,
27
+ KeyboardTypeAndroid,
28
+ KeyboardTypeIOS,
29
+ KeyboardTypeOptions,
30
+ ReturnKeyType,
31
+ ReturnKeyTypeAndroid,
32
+ ReturnKeyTypeIOS,
33
+ ReturnKeyTypeOptions,
34
+ Selection,
35
+ SubmitBehavior,
36
+ TextContentType,
37
+ TextInputAndroidProps,
38
+ TextInputBlurEvent,
39
+ TextInputChangeEvent,
40
+ TextInputContentSizeChangeEvent,
41
+ TextInputEditingEvent,
42
+ TextInputEndEditingEvent,
43
+ TextInputEvent,
44
+ TextInputFocusEvent,
45
+ TextInputInstance,
46
+ TextInputIOSProps,
47
+ TextInputKeyPressEvent,
48
+ TextInputProps,
49
+ TextInputSelectionChangeEvent,
50
+ TextInputSubmitEditingEvent,
51
+ TextInputType,
52
+ } from 'react-native/Libraries/Components/TextInput/TextInput.flow';
53
+
54
+ import usePressability from 'react-native/Libraries/Pressability/usePressability';
55
+ import flattenStyle from 'react-native/Libraries/StyleSheet/flattenStyle';
56
+ import StyleSheet, {type TextStyleProp} from 'react-native/Libraries/StyleSheet/StyleSheet';
30
57
  import Text from 'react-native/Libraries/Text/Text';
31
- import TextAncestor from 'react-native/Libraries/Text/TextAncestor';
58
+ import TextAncestorContext from 'react-native/Libraries/Text/TextAncestorContext';
32
59
  import Platform from 'react-native/Libraries/Utilities/Platform';
33
60
  import useMergeRefs from 'react-native/Libraries/Utilities/useMergeRefs';
34
61
  import TextInputState from 'react-native/Libraries/Components/TextInput/TextInputState';
35
62
  import invariant from 'invariant';
36
63
  import nullthrows from 'nullthrows';
37
64
  import * as React from 'react';
38
- import {useCallback, useLayoutEffect, useRef, useState} from 'react';
65
+ import {useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState} from 'react';
66
+ import {findNodeHandle, NativeEventEmitter, NativeModules} from 'react-native';
67
+
68
+ type OneKeyPasteItem = Readonly<{
69
+ type: string,
70
+ data: string,
71
+ }>;
72
+
73
+ type OneKeyPasteEvent = Readonly<{
74
+ nativeEvent: Readonly<{
75
+ items: ReadonlyArray<OneKeyPasteItem>,
76
+ }>,
77
+ }>;
78
+
79
+ type OneKeyTextInputProps = TextInputProps & {
80
+ onPaste?: ?(event: OneKeyPasteEvent) => void,
81
+ };
82
+
83
+ const iosPasteEmitter =
84
+ Platform.OS === 'ios' && NativeModules.OneKeyTextInputPasteObserver != null
85
+ ? new NativeEventEmitter(NativeModules.OneKeyTextInputPasteObserver)
86
+ : null;
39
87
 
40
88
  let AndroidTextInput;
41
89
  let AndroidTextInputCommands;
@@ -59,939 +107,70 @@ if (Platform.OS === 'android') {
59
107
  require('react-native/Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent').Commands;
60
108
  }
61
109
 
62
- export type TextInputChangeEventData = $ReadOnly<{
63
- eventCount: number,
64
- target: number,
65
- text: string,
66
- }>;
67
-
68
- export type TextInputChangeEvent =
69
- NativeSyntheticEvent<TextInputChangeEventData>;
70
-
71
- export type TextInputEvent = NativeSyntheticEvent<
72
- $ReadOnly<{
73
- eventCount: number,
74
- previousText: string,
75
- range: $ReadOnly<{
76
- start: number,
77
- end: number,
78
- }>,
79
- target: number,
80
- text: string,
81
- }>,
82
- >;
83
-
84
- export type TextInputContentSizeChangeEventData = $ReadOnly<{
85
- target: number,
86
- contentSize: $ReadOnly<{
87
- width: number,
88
- height: number,
89
- }>,
90
- }>;
91
-
92
- export type TextInputContentSizeChangeEvent =
93
- NativeSyntheticEvent<TextInputContentSizeChangeEventData>;
94
-
95
- export type TargetEvent = $ReadOnly<{
96
- target: number,
97
- }>;
98
-
99
- export type TextInputFocusEventData = TargetEvent;
100
-
101
- export type TextInputBlurEvent = NativeSyntheticEvent<TextInputFocusEventData>;
102
- export type TextInputFocusEvent = NativeSyntheticEvent<TextInputFocusEventData>;
103
-
104
- type Selection = $ReadOnly<{
105
- start: number,
106
- end: number,
107
- }>;
108
-
109
- export type TextInputSelectionChangeEventData = $ReadOnly<{
110
- ...TargetEvent,
111
- selection: Selection,
112
- }>;
113
-
114
- export type TextInputSelectionChangeEvent =
115
- NativeSyntheticEvent<TextInputSelectionChangeEventData>;
116
-
117
- type TextInputKeyPressEventData = $ReadOnly<{
118
- ...TargetEvent,
119
- key: string,
120
- target?: ?number,
121
- eventCount?: ?number,
122
- }>;
123
-
124
- export type TextInputKeyPressEvent =
125
- NativeSyntheticEvent<TextInputKeyPressEventData>;
126
-
127
- export type TextInputEndEditingEventData = $ReadOnly<{
128
- ...TargetEvent,
129
- eventCount: number,
130
- text: string,
131
- }>;
132
-
133
- export type TextInputEditingEvent =
134
- NativeSyntheticEvent<TextInputEndEditingEventData>;
135
-
136
- type DataDetectorTypesType =
137
- | 'phoneNumber'
138
- | 'link'
139
- | 'address'
140
- | 'calendarEvent'
141
- | 'trackingNumber'
142
- | 'flightNumber'
143
- | 'lookupSuggestion'
144
- | 'none'
145
- | 'all';
146
-
147
- export type KeyboardType =
148
- | 'default'
149
- | 'email-address'
150
- | 'numeric'
151
- | 'phone-pad'
152
- | 'number-pad'
153
- | 'decimal-pad'
154
- | 'url';
155
-
156
- export type KeyboardTypeIOS =
157
- | 'ascii-capable'
158
- | 'numbers-and-punctuation'
159
- | 'name-phone-pad'
160
- | 'twitter'
161
- | 'web-search'
162
- // iOS 10+ only
163
- | 'ascii-capable-number-pad';
164
-
165
- export type KeyboardTypeAndroid = 'visible-password';
166
-
167
- export type KeyboardTypeOptions =
168
- | KeyboardType
169
- | KeyboardTypeIOS
170
- | KeyboardTypeAndroid;
171
-
172
- export type InputModeOptions =
173
- | 'none'
174
- | 'text'
175
- | 'decimal'
176
- | 'numeric'
177
- | 'tel'
178
- | 'search'
179
- | 'email'
180
- | 'url';
181
-
182
- export type ReturnKeyType = 'done' | 'go' | 'next' | 'search' | 'send';
183
-
184
- export type ReturnKeyTypeIOS =
185
- | 'default'
186
- | 'emergency-call'
187
- | 'google'
188
- | 'join'
189
- | 'route'
190
- | 'yahoo';
191
-
192
- export type ReturnKeyTypeAndroid = 'none' | 'previous';
193
-
194
- export type ReturnKeyTypeOptions =
195
- | ReturnKeyType
196
- | ReturnKeyTypeIOS
197
- | ReturnKeyTypeAndroid;
198
-
199
- export type SubmitBehavior = 'submit' | 'blurAndSubmit' | 'newline';
200
-
201
- export type AutoCapitalize = 'none' | 'sentences' | 'words' | 'characters';
202
-
203
- export type TextContentType =
204
- | 'none'
205
- | 'URL'
206
- | 'addressCity'
207
- | 'addressCityAndState'
208
- | 'addressState'
209
- | 'countryName'
210
- | 'creditCardNumber'
211
- | 'creditCardExpiration'
212
- | 'creditCardExpirationMonth'
213
- | 'creditCardExpirationYear'
214
- | 'creditCardSecurityCode'
215
- | 'creditCardType'
216
- | 'creditCardName'
217
- | 'creditCardGivenName'
218
- | 'creditCardMiddleName'
219
- | 'creditCardFamilyName'
220
- | 'emailAddress'
221
- | 'familyName'
222
- | 'fullStreetAddress'
223
- | 'givenName'
224
- | 'jobTitle'
225
- | 'location'
226
- | 'middleName'
227
- | 'name'
228
- | 'namePrefix'
229
- | 'nameSuffix'
230
- | 'nickname'
231
- | 'organizationName'
232
- | 'postalCode'
233
- | 'streetAddressLine1'
234
- | 'streetAddressLine2'
235
- | 'sublocality'
236
- | 'telephoneNumber'
237
- | 'username'
238
- | 'password'
239
- | 'newPassword'
240
- | 'oneTimeCode'
241
- | 'birthdate'
242
- | 'birthdateDay'
243
- | 'birthdateMonth'
244
- | 'birthdateYear'
245
- | 'cellularEID'
246
- | 'cellularIMEI'
247
- | 'dateTime'
248
- | 'flightNumber'
249
- | 'shipmentTrackingNumber';
250
-
251
- export type EnterKeyHintTypeAndroid = 'previous';
252
-
253
- export type EnterKeyHintTypeIOS = 'enter';
254
-
255
- export type EnterKeyHintType = 'done' | 'go' | 'next' | 'search' | 'send';
256
-
257
- export type EnterKeyHintTypeOptions =
258
- | EnterKeyHintType
259
- | EnterKeyHintTypeAndroid
260
- | EnterKeyHintTypeIOS;
261
-
262
- type PasswordRules = string;
263
-
264
- export type TextInputIOSProps = $ReadOnly<{
265
- /**
266
- * If true, the keyboard shortcuts (undo/redo and copy buttons) are disabled. The default value is false.
267
- * @platform ios
268
- */
269
- disableKeyboardShortcuts?: ?boolean,
270
-
271
- /**
272
- * When the clear button should appear on the right side of the text view.
273
- * This property is supported only for single-line TextInput component.
274
- * @platform ios
275
- */
276
- clearButtonMode?: ?('never' | 'while-editing' | 'unless-editing' | 'always'),
277
-
278
- /**
279
- * If `true`, clears the text field automatically when editing begins.
280
- * @platform ios
281
- */
282
- clearTextOnFocus?: ?boolean,
283
-
284
- /**
285
- * Determines the types of data converted to clickable URLs in the text input.
286
- * Only valid if `multiline={true}` and `editable={false}`.
287
- * By default no data types are detected.
288
- *
289
- * You can provide one type or an array of many types.
290
- *
291
- * Possible values for `dataDetectorTypes` are:
292
- *
293
- * - `'phoneNumber'`
294
- * - `'link'`
295
- * - `'address'`
296
- * - `'calendarEvent'`
297
- * - `'none'`
298
- * - `'all'`
299
- *
300
- * @platform ios
301
- */
302
- dataDetectorTypes?:
303
- | ?DataDetectorTypesType
304
- | $ReadOnlyArray<DataDetectorTypesType>,
305
-
306
- /**
307
- * If `true`, the keyboard disables the return key when there is no text and
308
- * automatically enables it when there is text. The default value is `false`.
309
- * @platform ios
310
- */
311
- enablesReturnKeyAutomatically?: ?boolean,
312
-
313
- /**
314
- * An optional identifier which links a custom InputAccessoryView to
315
- * this text input. The InputAccessoryView is rendered above the
316
- * keyboard when this text input is focused.
317
- * @platform ios
318
- */
319
- inputAccessoryViewID?: ?string,
320
-
321
- /**
322
- * An optional label that overrides the default input accessory view button label.
323
- * @platform ios
324
- */
325
- inputAccessoryViewButtonLabel?: ?string,
326
-
327
- /**
328
- * Determines the color of the keyboard.
329
- * @platform ios
330
- */
331
- keyboardAppearance?: ?('default' | 'light' | 'dark'),
332
-
333
- /**
334
- * Provide rules for your password.
335
- * For example, say you want to require a password with at least eight characters consisting of a mix of uppercase and lowercase letters, at least one number, and at most two consecutive characters.
336
- * "required: upper; required: lower; required: digit; max-consecutive: 2; minlength: 8;"
337
- * @platform ios
338
- */
339
- passwordRules?: ?PasswordRules,
340
-
341
- /*
342
- * If `true`, allows TextInput to pass touch events to the parent component.
343
- * This allows components to be swipeable from the TextInput on iOS,
344
- * as is the case on Android by default.
345
- * If `false`, TextInput always asks to handle the input (except when disabled).
346
- * @platform ios
347
- */
348
- rejectResponderTermination?: ?boolean,
349
-
350
- /**
351
- * If `false`, scrolling of the text view will be disabled.
352
- * The default value is `true`. Does only work with 'multiline={true}'.
353
- * @platform ios
354
- */
355
- scrollEnabled?: ?boolean,
356
-
357
- /**
358
- * If `false`, disables spell-check style (i.e. red underlines).
359
- * The default value is inherited from `autoCorrect`.
360
- * @platform ios
361
- */
362
- spellCheck?: ?boolean,
363
-
364
- /**
365
- * Give the keyboard and the system information about the
366
- * expected semantic meaning for the content that users enter.
367
- * `autoComplete` property accomplishes same behavior and is recommended as its supported by both platforms.
368
- * Avoid using both `autoComplete` and `textContentType`, you can use `Platform.select` for differing platform behaviors.
369
- * For backwards compatibility, when both set, `textContentType` takes precedence on iOS.
370
- * @platform ios
371
- */
372
- textContentType?: ?TextContentType,
373
-
374
- /**
375
- * Set line break strategy on iOS.
376
- * @platform ios
377
- */
378
- lineBreakStrategyIOS?: ?('none' | 'standard' | 'hangul-word' | 'push-out'),
379
-
380
- /**
381
- * Set line break mode on iOS.
382
- * @platform ios
383
- */
384
- lineBreakModeIOS?: ?(
385
- | 'wordWrapping'
386
- | 'char'
387
- | 'clip'
388
- | 'head'
389
- | 'middle'
390
- | 'tail'
391
- ),
392
-
393
- /**
394
- * If `false`, the iOS system will not insert an extra space after a paste operation
395
- * neither delete one or two spaces after a cut or delete operation.
396
- *
397
- * The default value is `true`.
398
- *
399
- * @platform ios
400
- */
401
- smartInsertDelete?: ?boolean,
402
- }>;
403
-
404
- export type TextInputAndroidProps = $ReadOnly<{
405
- /**
406
- * When provided it will set the color of the cursor (or "caret") in the component.
407
- * Unlike the behavior of `selectionColor` the cursor color will be set independently
408
- * from the color of the text selection box.
409
- * @platform android
410
- */
411
- cursorColor?: ?ColorValue,
412
-
413
- /**
414
- * When `false`, if there is a small amount of space available around a text input
415
- * (e.g. landscape orientation on a phone), the OS may choose to have the user edit
416
- * the text inside of a full screen text input mode. When `true`, this feature is
417
- * disabled and users will always edit the text directly inside of the text input.
418
- * Defaults to `false`.
419
- * @platform android
420
- */
421
- disableFullscreenUI?: ?boolean,
422
-
423
- importantForAutofill?: ?(
424
- | 'auto'
425
- | 'no'
426
- | 'noExcludeDescendants'
427
- | 'yes'
428
- | 'yesExcludeDescendants'
429
- ),
430
-
431
- /**
432
- * If defined, the provided image resource will be rendered on the left.
433
- * The image resource must be inside `/android/app/src/main/res/drawable` and referenced
434
- * like
435
- * ```
436
- * <TextInput
437
- * inlineImageLeft='search_icon'
438
- * />
439
- * ```
440
- * @platform android
441
- */
442
- inlineImageLeft?: ?string,
443
-
444
- /**
445
- * Padding between the inline image, if any, and the text input itself.
446
- * @platform android
447
- */
448
- inlineImagePadding?: ?number,
449
-
450
- /**
451
- * Sets the number of lines for a `TextInput`. Use it with multiline set to
452
- * `true` to be able to fill the lines.
453
- * @platform android
454
- */
455
- numberOfLines?: ?number,
456
-
457
- /**
458
- * Sets the return key to the label. Use it instead of `returnKeyType`.
459
- * @platform android
460
- */
461
- returnKeyLabel?: ?string,
462
-
463
- /**
464
- * Sets the number of rows for a `TextInput`. Use it with multiline set to
465
- * `true` to be able to fill the lines.
466
- * @platform android
467
- */
468
- rows?: ?number,
469
-
470
- /**
471
- * When `false`, it will prevent the soft keyboard from showing when the field is focused.
472
- * Defaults to `true`.
473
- */
474
- showSoftInputOnFocus?: ?boolean,
475
-
476
- /**
477
- * Set text break strategy on Android API Level 23+, possible values are `simple`, `highQuality`, `balanced`
478
- * The default value is `simple`.
479
- * @platform android
480
- */
481
- textBreakStrategy?: ?('simple' | 'highQuality' | 'balanced'),
482
-
483
- /**
484
- * The color of the `TextInput` underline.
485
- * @platform android
486
- */
487
- underlineColorAndroid?: ?ColorValue,
488
- }>;
489
-
490
- export type TextInputProps = $ReadOnly<{
491
- ...$Diff<ViewProps, $ReadOnly<{style: ?ViewStyleProp}>>,
492
- ...TextInputIOSProps,
493
- ...TextInputAndroidProps,
494
-
495
- /**
496
- * Can tell `TextInput` to automatically capitalize certain characters.
497
- *
498
- * - `characters`: all characters.
499
- * - `words`: first letter of each word.
500
- * - `sentences`: first letter of each sentence (*default*).
501
- * - `none`: don't auto capitalize anything.
502
- */
503
- autoCapitalize?: ?AutoCapitalize,
504
-
505
- /**
506
- * Specifies autocomplete hints for the system, so it can provide autofill.
507
- * On Android, the system will always attempt to offer autofill by using heuristics to identify the type of content.
508
- * To disable autocomplete, set autoComplete to off.
509
- *
510
- * The following values work across platforms:
511
- *
512
- * - `additional-name`
513
- * - `address-line1`
514
- * - `address-line2`
515
- * - `birthdate-day` (iOS 17+)
516
- * - `birthdate-full` (iOS 17+)
517
- * - `birthdate-month` (iOS 17+)
518
- * - `birthdate-year` (iOS 17+)
519
- * - `cc-number`
520
- * - `cc-csc` (iOS 17+)
521
- * - `cc-exp` (iOS 17+)
522
- * - `cc-exp-day` (iOS 17+)
523
- * - `cc-exp-month` (iOS 17+)
524
- * - `cc-exp-year` (iOS 17+)
525
- * - `country`
526
- * - `current-password`
527
- * - `email`
528
- * - `family-name`
529
- * - `given-name`
530
- * - `honorific-prefix`
531
- * - `honorific-suffix`
532
- * - `name`
533
- * - `new-password`
534
- * - `off`
535
- * - `one-time-code`
536
- * - `postal-code`
537
- * - `street-address`
538
- * - `tel`
539
- * - `username`
540
- *
541
- * The following values work on iOS only:
542
- *
543
- * - `cc-name` (iOS 17+)
544
- * - `cc-given-name` (iOS 17+)
545
- * - `cc-middle-name` (iOS 17+)
546
- * - `cc-family-name` (iOS 17+)
547
- * - `cc-type` (iOS 17+)
548
- * - `nickname`
549
- * - `organization`
550
- * - `organization-title`
551
- * - `url`
552
- *
553
- * The following values work on Android only:
554
- *
555
- * - `gender`
556
- * - `name-family`
557
- * - `name-given`
558
- * - `name-middle`
559
- * - `name-middle-initial`
560
- * - `name-prefix`
561
- * - `name-suffix`
562
- * - `password`
563
- * - `password-new`
564
- * - `postal-address`
565
- * - `postal-address-country`
566
- * - `postal-address-extended`
567
- * - `postal-address-extended-postal-code`
568
- * - `postal-address-locality`
569
- * - `postal-address-region`
570
- * - `sms-otp`
571
- * - `tel-country-code`
572
- * - `tel-national`
573
- * - `tel-device`
574
- * - `username-new`
575
- */
576
- autoComplete?: ?(
577
- | 'additional-name'
578
- | 'address-line1'
579
- | 'address-line2'
580
- | 'birthdate-day'
581
- | 'birthdate-full'
582
- | 'birthdate-month'
583
- | 'birthdate-year'
584
- | 'cc-csc'
585
- | 'cc-exp'
586
- | 'cc-exp-day'
587
- | 'cc-exp-month'
588
- | 'cc-exp-year'
589
- | 'cc-number'
590
- | 'cc-name'
591
- | 'cc-given-name'
592
- | 'cc-middle-name'
593
- | 'cc-family-name'
594
- | 'cc-type'
595
- | 'country'
596
- | 'current-password'
597
- | 'email'
598
- | 'family-name'
599
- | 'gender'
600
- | 'given-name'
601
- | 'honorific-prefix'
602
- | 'honorific-suffix'
603
- | 'name'
604
- | 'name-family'
605
- | 'name-given'
606
- | 'name-middle'
607
- | 'name-middle-initial'
608
- | 'name-prefix'
609
- | 'name-suffix'
610
- | 'new-password'
611
- | 'nickname'
612
- | 'one-time-code'
613
- | 'organization'
614
- | 'organization-title'
615
- | 'password'
616
- | 'password-new'
617
- | 'postal-address'
618
- | 'postal-address-country'
619
- | 'postal-address-extended'
620
- | 'postal-address-extended-postal-code'
621
- | 'postal-address-locality'
622
- | 'postal-address-region'
623
- | 'postal-code'
624
- | 'street-address'
625
- | 'sms-otp'
626
- | 'tel'
627
- | 'tel-country-code'
628
- | 'tel-national'
629
- | 'tel-device'
630
- | 'url'
631
- | 'username'
632
- | 'username-new'
633
- | 'off'
634
- ),
635
-
636
- /**
637
- * If `false`, disables auto-correct. The default value is `true`.
638
- */
639
- autoCorrect?: ?boolean,
640
-
641
- /**
642
- * If `true`, focuses the input on `componentDidMount`.
643
- * The default value is `false`.
644
- */
645
- autoFocus?: ?boolean,
646
-
647
- /**
648
- * Specifies whether fonts should scale to respect Text Size accessibility settings. The
649
- * default is `true`.
650
- */
651
- allowFontScaling?: ?boolean,
652
-
653
- /**
654
- * If `true`, caret is hidden. The default value is `false`.
655
- *
656
- * On Android devices manufactured by Xiaomi with Android Q,
657
- * when keyboardType equals 'email-address'this will be set
658
- * in native to 'true' to prevent a system related crash. This
659
- * will cause cursor to be disabled as a side-effect.
660
- *
661
- */
662
- caretHidden?: ?boolean,
663
-
664
- /*
665
- * If `true`, contextMenuHidden is hidden. The default value is `false`.
666
- */
667
- contextMenuHidden?: ?boolean,
668
-
669
- /**
670
- * Provides an initial value that will change when the user starts typing.
671
- * Useful for simple use-cases where you do not want to deal with listening
672
- * to events and updating the value prop to keep the controlled state in sync.
673
- */
674
- defaultValue?: ?Stringish,
675
-
676
- /**
677
- * If `false`, text is not editable. The default value is `true`.
678
- */
679
- editable?: ?boolean,
680
-
681
- forwardedRef?: ?React.RefSetter<TextInputInstance>,
682
-
683
- /**
684
- * `enterKeyHint` defines what action label (or icon) to present for the enter key on virtual keyboards.
685
- *
686
- * The following values is supported:
687
- *
688
- * - `enter`
689
- * - `done`
690
- * - `go`
691
- * - `next`
692
- * - `previous`
693
- * - `search`
694
- * - `send`
695
- */
696
- enterKeyHint?: ?EnterKeyHintTypeOptions,
697
-
698
- /**
699
- * `inputMode` works like the `inputmode` attribute in HTML, it determines which
700
- * keyboard to open, e.g.`numeric` and has precedence over keyboardType
701
- *
702
- * Support the following values:
703
- *
704
- * - `none`
705
- * - `text`
706
- * - `decimal`
707
- * - `numeric`
708
- * - `tel`
709
- * - `search`
710
- * - `email`
711
- * - `url`
712
- */
713
- inputMode?: ?InputModeOptions,
714
-
715
- /**
716
- * Determines which keyboard to open, e.g.`numeric`.
717
- *
718
- * The following values work across platforms:
719
- *
720
- * - `default`
721
- * - `numeric`
722
- * - `number-pad`
723
- * - `decimal-pad`
724
- * - `email-address`
725
- * - `phone-pad`
726
- * - `url`
727
- *
728
- * *iOS Only*
729
- *
730
- * The following values work on iOS only:
731
- *
732
- * - `ascii-capable`
733
- * - `numbers-and-punctuation`
734
- * - `name-phone-pad`
735
- * - `twitter`
736
- * - `web-search`
737
- *
738
- * *Android Only*
739
- *
740
- * The following values work on Android only:
741
- *
742
- * - `visible-password`
743
- *
744
- */
745
- keyboardType?: ?KeyboardTypeOptions,
746
-
747
- /**
748
- * Specifies largest possible scale a font can reach when `allowFontScaling` is enabled.
749
- * Possible values:
750
- * `null/undefined` (default): inherit from the parent node or the global default (0)
751
- * `0`: no max, ignore parent/global default
752
- * `>= 1`: sets the maxFontSizeMultiplier of this node to this value
753
- */
754
- maxFontSizeMultiplier?: ?number,
755
-
756
- /**
757
- * Limits the maximum number of characters that can be entered. Use this
758
- * instead of implementing the logic in JS to avoid flicker.
759
- */
760
- maxLength?: ?number,
761
-
762
- /**
763
- * If `true`, the text input can be multiple lines.
764
- * The default value is `false`.
765
- */
766
- multiline?: ?boolean,
767
-
768
- /**
769
- * Callback that is called when the text input is blurred.
770
- */
771
- onBlur?: ?(e: TextInputBlurEvent) => mixed,
772
-
773
- /**
774
- * Callback that is called when the text input's text changes.
775
- */
776
- onChange?: ?(e: TextInputChangeEvent) => mixed,
777
-
778
- /**
779
- * Callback that is called when the text input's text changes.
780
- * Changed text is passed as an argument to the callback handler.
781
- */
782
- onChangeText?: ?(text: string) => mixed,
783
-
784
- /**
785
- * Callback that is called when the text input's content size changes.
786
- * This will be called with
787
- * `{ nativeEvent: { contentSize: { width, height } } }`.
788
- *
789
- * Only called for multiline text inputs.
790
- */
791
- onContentSizeChange?: ?(e: TextInputContentSizeChangeEvent) => mixed,
792
-
793
- /**
794
- * Callback that is called when text input ends.
795
- */
796
- onEndEditing?: ?(e: TextInputEditingEvent) => mixed,
797
-
798
- /**
799
- * Callback that is called when the text input is focused.
800
- */
801
- onFocus?: ?(e: TextInputFocusEvent) => mixed,
802
-
803
- /**
804
- * Callback that is called when a key is pressed.
805
- * This will be called with `{ nativeEvent: { key: keyValue } }`
806
- * where `keyValue` is `'Enter'` or `'Backspace'` for respective keys and
807
- * the typed-in character otherwise including `' '` for space.
808
- * Fires before `onChange` callbacks.
809
- */
810
- onKeyPress?: ?(e: TextInputKeyPressEvent) => mixed,
811
-
812
- /**
813
- * Called when a single tap gesture is detected.
814
- */
815
- onPress?: ?(event: GestureResponderEvent) => mixed,
816
-
817
- /**
818
- * Called when a touch is engaged.
819
- */
820
- onPressIn?: ?(event: GestureResponderEvent) => mixed,
821
-
822
- /**
823
- * Called when a touch is released.
824
- */
825
- onPressOut?: ?(event: GestureResponderEvent) => mixed,
826
-
827
- /**
828
- * Callback that is called when the text input selection is changed.
829
- * This will be called with
830
- * `{ nativeEvent: { selection: { start, end } } }`.
831
- */
832
- onSelectionChange?: ?(e: TextInputSelectionChangeEvent) => mixed,
833
-
834
- /**
835
- * Callback that is called when the text input's submit button is pressed.
836
- * Invalid if `multiline={true}` is specified.
837
- */
838
- onSubmitEditing?: ?(e: TextInputEditingEvent) => mixed,
839
-
840
- /**
841
- * Invoked on content scroll with `{ nativeEvent: { contentOffset: { x, y } } }`.
842
- * May also contain other properties from ScrollEvent but on Android contentSize
843
- * is not provided for performance reasons.
844
- */
845
- onScroll?: ?(e: ScrollEvent) => mixed,
846
-
847
- /**
848
- * The string that will be rendered before text input has been entered.
849
- */
850
- placeholder?: ?Stringish,
851
-
852
- /**
853
- * The text color of the placeholder string.
854
- */
855
- placeholderTextColor?: ?ColorValue,
856
-
857
- /** `readOnly` works like the `readonly` attribute in HTML.
858
- * If `true`, text is not editable. The default value is `false`.
859
- * See https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/readonly
860
- * for more details.
861
- */
862
- readOnly?: ?boolean,
863
-
864
- /**
865
- * Determines how the return key should look. On Android you can also use
866
- * `returnKeyLabel`.
867
- *
868
- * *Cross platform*
869
- *
870
- * The following values work across platforms:
871
- *
872
- * - `done`
873
- * - `go`
874
- * - `next`
875
- * - `search`
876
- * - `send`
877
- *
878
- * *Android Only*
879
- *
880
- * The following values work on Android only:
881
- *
882
- * - `none`
883
- * - `previous`
884
- *
885
- * *iOS Only*
886
- *
887
- * The following values work on iOS only:
888
- *
889
- * - `default`
890
- * - `emergency-call`
891
- * - `google`
892
- * - `join`
893
- * - `route`
894
- * - `yahoo`
895
- */
896
- returnKeyType?: ?ReturnKeyTypeOptions,
897
-
898
- /**
899
- * If `true`, the text input obscures the text entered so that sensitive text
900
- * like passwords stay secure. The default value is `false`. Does not work with 'multiline={true}'.
901
- */
902
- secureTextEntry?: ?boolean,
903
-
904
- /**
905
- * The start and end of the text input's selection. Set start and end to
906
- * the same value to position the cursor.
907
- */
908
- selection?: ?$ReadOnly<{
909
- start: number,
910
- end?: ?number,
911
- }>,
912
-
913
- /**
914
- * The highlight and cursor color of the text input.
915
- */
916
- selectionColor?: ?ColorValue,
917
-
918
- /**
919
- * The text selection handle color.
920
- * @platform android
921
- */
922
- selectionHandleColor?: ?ColorValue,
923
-
924
- /**
925
- * If `true`, all text will automatically be selected on focus.
926
- */
927
- selectTextOnFocus?: ?boolean,
110
+ export type {
111
+ AutoCapitalize,
112
+ BlurEvent,
113
+ EnterKeyHintType,
114
+ EnterKeyHintTypeAndroid,
115
+ EnterKeyHintTypeIOS,
116
+ EnterKeyHintTypeOptions,
117
+ FocusEvent,
118
+ InputModeOptions,
119
+ KeyboardType,
120
+ KeyboardTypeAndroid,
121
+ KeyboardTypeIOS,
122
+ KeyboardTypeOptions,
123
+ ReturnKeyType,
124
+ ReturnKeyTypeAndroid,
125
+ ReturnKeyTypeIOS,
126
+ ReturnKeyTypeOptions,
127
+ SubmitBehavior,
128
+ TextContentType,
129
+ TextInputAndroidProps,
130
+ TextInputBlurEvent,
131
+ TextInputChangeEvent,
132
+ TextInputContentSizeChangeEvent,
133
+ TextInputEditingEvent,
134
+ TextInputEndEditingEvent,
135
+ TextInputEvent,
136
+ TextInputFocusEvent,
137
+ TextInputIOSProps,
138
+ TextInputKeyPressEvent,
139
+ TextInputProps,
140
+ TextInputSelectionChangeEvent,
141
+ TextInputSubmitEditingEvent,
142
+ };
928
143
 
144
+ type TextInputStateType = Readonly<{
929
145
  /**
930
- * If `true`, the text field will blur when submitted.
931
- * The default value is true for single-line fields and false for
932
- * multiline fields. Note that for multiline fields, setting `blurOnSubmit`
933
- * to `true` means that pressing return will blur the field and trigger the
934
- * `onSubmitEditing` event instead of inserting a newline into the field.
935
- *
936
- * @deprecated
937
- * Note that `submitBehavior` now takes the place of `blurOnSubmit` and will
938
- * override any behavior defined by `blurOnSubmit`.
939
- * @see submitBehavior
146
+ * @deprecated Use currentlyFocusedInput
147
+ * Returns the ID of the currently focused text field, if one exists
148
+ * If no text field is focused it returns null
940
149
  */
941
- blurOnSubmit?: ?boolean,
150
+ currentlyFocusedField: () => ?number,
942
151
 
943
152
  /**
944
- * When the return key is pressed,
945
- *
946
- * For single line inputs:
947
- *
948
- * - `'newline`' defaults to `'blurAndSubmit'`
949
- * - `undefined` defaults to `'blurAndSubmit'`
950
- *
951
- * For multiline inputs:
952
- *
953
- * - `'newline'` adds a newline
954
- * - `undefined` defaults to `'newline'`
955
- *
956
- * For both single line and multiline inputs:
957
- *
958
- * - `'submit'` will only send a submit event and not blur the input
959
- * - `'blurAndSubmit`' will both blur the input and send a submit event
153
+ * Returns the ref of the currently focused text field, if one exists
154
+ * If no text field is focused it returns null
960
155
  */
961
- submitBehavior?: ?SubmitBehavior,
156
+ currentlyFocusedInput: () => ?HostInstance,
962
157
 
963
158
  /**
964
- * Note that not all Text styles are supported, an incomplete list of what is not supported includes:
965
- *
966
- * - `borderLeftWidth`
967
- * - `borderTopWidth`
968
- * - `borderRightWidth`
969
- * - `borderBottomWidth`
970
- * - `borderTopLeftRadius`
971
- * - `borderTopRightRadius`
972
- * - `borderBottomRightRadius`
973
- * - `borderBottomLeftRadius`
974
- *
975
- * see [Issue#7070](https://github.com/facebook/react-native/issues/7070)
976
- * for more detail.
977
- *
978
- * [Styles](docs/style.html)
159
+ * @param textField ref of the text field to focus
160
+ * Focuses the specified text field
161
+ * noop if the text field was already focused
979
162
  */
980
- style?: ?TextStyleProp,
163
+ focusTextInput: (textField: ?HostInstance) => void,
981
164
 
982
165
  /**
983
- * The value to show for the text input. `TextInput` is a controlled
984
- * component, which means the native value will be forced to match this
985
- * value prop if provided. For most uses, this works great, but in some
986
- * cases this may cause flickering - one common cause is preventing edits
987
- * by keeping value the same. In addition to simply setting the same value,
988
- * either set `editable={false}`, or set/update `maxLength` to prevent
989
- * unwanted edits without flicker.
166
+ * @param textField ref of the text field to focus
167
+ * Unfocuses the specified text field
168
+ * noop if it wasn't focused
990
169
  */
991
- value?: ?Stringish,
170
+ blurTextInput: (textField: ?HostInstance) => void,
992
171
  }>;
993
172
 
994
- type ViewCommands = $NonMaybeType<
173
+ type ViewCommands = NonNullable<
995
174
  | typeof AndroidTextInputCommands
996
175
  | typeof RCTMultilineTextInputNativeCommands
997
176
  | typeof RCTSinglelineTextInputNativeCommands,
@@ -1030,8 +209,8 @@ function useTextInputStateSynchronization({
1030
209
  const [lastNativeText, setLastNativeText] = useState<?Stringish>(props.value);
1031
210
  const [lastNativeSelectionState, setLastNativeSelection] =
1032
211
  useState<LastNativeSelection>({
1033
- selection: {start: -1, end: -1},
1034
- mostRecentEventCount: mostRecentEventCount,
212
+ mostRecentEventCount,
213
+ selection: {end: -1, start: -1},
1035
214
  });
1036
215
 
1037
216
  const lastNativeSelection = lastNativeSelectionState.selection;
@@ -1054,7 +233,7 @@ function useTextInputStateSynchronization({
1054
233
  lastNativeSelection.end !== selection.end)
1055
234
  ) {
1056
235
  nativeUpdate.selection = selection;
1057
- setLastNativeSelection({selection, mostRecentEventCount});
236
+ setLastNativeSelection({mostRecentEventCount, selection});
1058
237
  }
1059
238
 
1060
239
  if (Object.keys(nativeUpdate).length === 0) {
@@ -1082,7 +261,7 @@ function useTextInputStateSynchronization({
1082
261
  viewCommands,
1083
262
  ]);
1084
263
 
1085
- return {setLastNativeText, setLastNativeSelection};
264
+ return {setLastNativeSelection, setLastNativeText};
1086
265
  }
1087
266
 
1088
267
  /**
@@ -1196,7 +375,7 @@ function useTextInputStateSynchronization({
1196
375
  * or control this param programmatically with native code.
1197
376
  *
1198
377
  */
1199
- function InternalTextInput(props: TextInputProps): React.Node {
378
+ function InternalTextInput(props: OneKeyTextInputProps): React.Node {
1200
379
  const {
1201
380
  'aria-busy': ariaBusy,
1202
381
  'aria-checked': ariaChecked,
@@ -1210,17 +389,34 @@ function InternalTextInput(props: TextInputProps): React.Node {
1210
389
  selectionColor,
1211
390
  selectionHandleColor,
1212
391
  cursorColor,
392
+ onPaste,
1213
393
  ...otherProps
1214
394
  } = props;
1215
395
 
1216
396
  const inputRef = useRef<null | TextInputInstance>(null);
1217
397
 
398
+ useEffect(() => {
399
+ if (Platform.OS !== 'ios' || iosPasteEmitter == null || onPaste == null) {
400
+ return;
401
+ }
402
+ const subscription = iosPasteEmitter.addListener(
403
+ 'OneKeyTextInputPaste',
404
+ (event: {target: number, items: Array<OneKeyPasteItem>}) => {
405
+ const target = findNodeHandle(inputRef.current);
406
+ if (target != null && target === event.target) {
407
+ onPaste({nativeEvent: {items: event.items}});
408
+ }
409
+ },
410
+ );
411
+ return () => subscription.remove();
412
+ }, [onPaste]);
413
+
1218
414
  const selection: ?Selection =
1219
415
  propsSelection == null
1220
416
  ? null
1221
417
  : {
1222
- start: propsSelection.start,
1223
418
  end: propsSelection.end ?? propsSelection.start,
419
+ start: propsSelection.start,
1224
420
  };
1225
421
 
1226
422
  const text =
@@ -1239,9 +435,9 @@ function InternalTextInput(props: TextInputProps): React.Node {
1239
435
  const [mostRecentEventCount, setMostRecentEventCount] = useState<number>(0);
1240
436
  const {setLastNativeText, setLastNativeSelection} =
1241
437
  useTextInputStateSynchronization({
1242
- props,
1243
438
  inputRef,
1244
439
  mostRecentEventCount,
440
+ props,
1245
441
  selection,
1246
442
  text,
1247
443
  viewCommands,
@@ -1291,7 +487,14 @@ function InternalTextInput(props: TextInputProps): React.Node {
1291
487
  before we can get to the long term breaking change.
1292
488
  */
1293
489
  if (instance != null) {
490
+ // Register the input immediately when the ref is set so that focus()
491
+ // can be called from ref callbacks
492
+ // Double registering during useLayoutEffect is fine, because the underlying
493
+ // state is a Set.
494
+ TextInputState.registerInput(instance);
495
+
1294
496
  // $FlowFixMe[prop-missing] - See the explanation above.
497
+ // $FlowFixMe[unsafe-object-assign]
1295
498
  Object.assign(instance, {
1296
499
  clear(): void {
1297
500
  if (inputRef.current != null) {
@@ -1304,13 +507,17 @@ function InternalTextInput(props: TextInputProps): React.Node {
1304
507
  );
1305
508
  }
1306
509
  },
1307
- // TODO: Fix this returning true on null === null, when no input is focused
1308
- isFocused(): boolean {
1309
- return TextInputState.currentlyFocusedInput() === inputRef.current;
1310
- },
1311
510
  getNativeRef(): ?TextInputInstance {
1312
511
  return inputRef.current;
1313
512
  },
513
+ isFocused(): boolean {
514
+ const currentlyFocusedInput =
515
+ TextInputState.currentlyFocusedInput();
516
+ return (
517
+ currentlyFocusedInput != null &&
518
+ currentlyFocusedInput === inputRef.current
519
+ );
520
+ },
1314
521
  setSelection(start: number, end: number): void {
1315
522
  if (inputRef.current != null) {
1316
523
  viewCommands.setTextAndSelection(
@@ -1328,7 +535,7 @@ function InternalTextInput(props: TextInputProps): React.Node {
1328
535
  [mostRecentEventCount, viewCommands],
1329
536
  );
1330
537
 
1331
- // $FlowExpectedError[incompatible-call]
538
+ // $FlowExpectedError[incompatible-type]
1332
539
  const ref = useMergeRefs<HostInstance>(setLocalRef, props.forwardedRef);
1333
540
 
1334
541
  const _onChange = (event: TextInputChangeEvent) => {
@@ -1360,19 +567,19 @@ function InternalTextInput(props: TextInputProps): React.Node {
1360
567
  }
1361
568
 
1362
569
  setLastNativeSelection({
1363
- selection: event.nativeEvent.selection,
1364
570
  mostRecentEventCount,
571
+ selection: event.nativeEvent.selection,
1365
572
  });
1366
573
  };
1367
574
 
1368
- const _onFocus = (event: TextInputFocusEvent) => {
575
+ const _onFocus = (event: FocusEvent) => {
1369
576
  TextInputState.focusInput(inputRef.current);
1370
577
  if (props.onFocus) {
1371
578
  props.onFocus(event);
1372
579
  }
1373
580
  };
1374
581
 
1375
- const _onBlur = (event: TextInputBlurEvent) => {
582
+ const _onBlur = (event: BlurEvent) => {
1376
583
  TextInputState.blurInput(inputRef.current);
1377
584
  if (props.onBlur) {
1378
585
  props.onBlur(event);
@@ -1423,8 +630,9 @@ function InternalTextInput(props: TextInputProps): React.Node {
1423
630
  rejectResponderTermination,
1424
631
  } = props;
1425
632
 
1426
- const config = React.useMemo(
633
+ const config = useMemo(
1427
634
  () => ({
635
+ cancelable: Platform.OS === 'ios' ? !rejectResponderTermination : null,
1428
636
  hitSlop,
1429
637
  onPress: (event: GestureResponderEvent) => {
1430
638
  onPress?.(event);
@@ -1434,9 +642,8 @@ function InternalTextInput(props: TextInputProps): React.Node {
1434
642
  }
1435
643
  }
1436
644
  },
1437
- onPressIn: onPressIn,
1438
- onPressOut: onPressOut,
1439
- cancelable: Platform.OS === 'ios' ? !rejectResponderTermination : null,
645
+ onPressIn,
646
+ onPressOut,
1440
647
  }),
1441
648
  [
1442
649
  editable,
@@ -1459,6 +666,9 @@ function InternalTextInput(props: TextInputProps): React.Node {
1459
666
  // so omitting onBlur and onFocus pressability handlers here.
1460
667
  const {onBlur, onFocus, ...eventHandlers} = usePressability(config);
1461
668
 
669
+ const _accessibilityLabel =
670
+ props?.['aria-label'] ?? props?.accessibilityLabel;
671
+
1462
672
  let _accessibilityState;
1463
673
  if (
1464
674
  accessibilityState != null ||
@@ -1483,14 +693,14 @@ function InternalTextInput(props: TextInputProps): React.Node {
1483
693
  if (flattenedStyle != null) {
1484
694
  let overrides: ?{...TextStyleInternal} = null;
1485
695
  if (typeof flattenedStyle?.fontWeight === 'number') {
1486
- overrides = overrides || ({}: {...TextStyleInternal});
696
+ overrides = overrides || ({} as {...TextStyleInternal});
1487
697
  overrides.fontWeight =
1488
- // $FlowFixMe[incompatible-cast]
1489
- (flattenedStyle.fontWeight.toString(): TextStyleInternal['fontWeight']);
698
+ // $FlowFixMe[incompatible-type]
699
+ flattenedStyle.fontWeight.toString() as TextStyleInternal['fontWeight'];
1490
700
  }
1491
701
 
1492
702
  if (flattenedStyle.verticalAlign != null) {
1493
- overrides = overrides || ({}: {...TextStyleInternal});
703
+ overrides = overrides || ({} as {...TextStyleInternal});
1494
704
  overrides.textAlignVertical =
1495
705
  verticalAlignToTextAlignVerticalMap[flattenedStyle.verticalAlign];
1496
706
  overrides.verticalAlign = undefined;
@@ -1515,13 +725,19 @@ function InternalTextInput(props: TextInputProps): React.Node {
1515
725
  flattenedStyle.paddingVertical == null &&
1516
726
  flattenedStyle.paddingTop == null));
1517
727
 
728
+ const _accessibilityElementsHidden =
729
+ props['aria-hidden'] ?? props.accessibilityElementsHidden;
730
+
1518
731
  textInput = (
1519
732
  <RCTTextInputView
1520
733
  // Figure out imperative + forward refs.
1521
- ref={(ref: $FlowFixMe)}
734
+ ref={ref as $FlowFixMe}
1522
735
  {...otherProps}
1523
736
  {...eventHandlers}
737
+ acceptDragAndDropTypes={props.experimental_acceptDragAndDropTypes}
738
+ accessibilityLabel={_accessibilityLabel}
1524
739
  accessibilityState={_accessibilityState}
740
+ accessibilityElementsHidden={_accessibilityElementsHidden}
1525
741
  accessible={accessible}
1526
742
  submitBehavior={submitBehavior}
1527
743
  caretHidden={caretHidden}
@@ -1550,6 +766,10 @@ function InternalTextInput(props: TextInputProps): React.Node {
1550
766
  const autoCapitalize = props.autoCapitalize || 'sentences';
1551
767
  const _accessibilityLabelledBy =
1552
768
  props?.['aria-labelledby'] ?? props?.accessibilityLabelledBy;
769
+ const _importantForAccessibility =
770
+ props['aria-hidden'] === true
771
+ ? ('no-hide-descendants' as const)
772
+ : undefined;
1553
773
  const placeholder = props.placeholder ?? '';
1554
774
  let children = props.children;
1555
775
  const childCount = React.Children.count(children);
@@ -1562,14 +782,13 @@ function InternalTextInput(props: TextInputProps): React.Node {
1562
782
  }
1563
783
  // For consistency with iOS set cursor/selectionHandle color as selectionColor
1564
784
  const colorProps = {
785
+ cursorColor: cursorColor === undefined ? selectionColor : cursorColor,
1565
786
  selectionColor,
1566
787
  selectionHandleColor:
1567
788
  selectionHandleColor === undefined
1568
789
  ? selectionColor
1569
790
  : selectionHandleColor,
1570
- cursorColor: cursorColor === undefined ? selectionColor : cursorColor,
1571
791
  };
1572
- const { onPaste, ...rest } = otherProps;
1573
792
  textInput = (
1574
793
  /* $FlowFixMe[prop-missing] the types for AndroidTextInput don't match up
1575
794
  * exactly with the props for TextInput. This will need to get fixed */
@@ -1581,30 +800,33 @@ function InternalTextInput(props: TextInputProps): React.Node {
1581
800
  * fixed */
1582
801
  <AndroidTextInput
1583
802
  // Figure out imperative + forward refs.
1584
- ref={(ref: $FlowFixMe)}
1585
- {...rest}
803
+ ref={ref as $FlowFixMe}
804
+ {...otherProps}
1586
805
  {...colorProps}
1587
806
  {...eventHandlers}
1588
- onPaste={onPaste}
1589
- accessibilityState={_accessibilityState}
807
+ accessibilityLabel={_accessibilityLabel}
1590
808
  accessibilityLabelledBy={_accessibilityLabelledBy}
809
+ accessibilityState={_accessibilityState}
1591
810
  accessible={accessible}
811
+ acceptDragAndDropTypes={props.experimental_acceptDragAndDropTypes}
1592
812
  autoCapitalize={autoCapitalize}
1593
813
  submitBehavior={submitBehavior}
1594
814
  caretHidden={caretHidden}
1595
815
  children={children}
1596
816
  disableFullscreenUI={props.disableFullscreenUI}
1597
817
  focusable={tabIndex !== undefined ? !tabIndex : focusable}
818
+ importantForAccessibility={_importantForAccessibility}
1598
819
  mostRecentEventCount={mostRecentEventCount}
1599
820
  nativeID={id ?? props.nativeID}
1600
821
  numberOfLines={props.rows ?? props.numberOfLines}
1601
822
  onBlur={_onBlur}
1602
823
  onChange={_onChange}
1603
824
  onFocus={_onFocus}
825
+ onPaste={onPaste}
1604
826
  /* $FlowFixMe[prop-missing] the types for AndroidTextInput don't match
1605
827
  * up exactly with the props for TextInput. This will need to get fixed
1606
828
  */
1607
- /* $FlowFixMe[incompatible-type-arg] the types for AndroidTextInput
829
+ /* $FlowFixMe[incompatible-type] the types for AndroidTextInput
1608
830
  * don't match up exactly with the props for TextInput. This will need
1609
831
  * to get fixed */
1610
832
  onScroll={_onScroll}
@@ -1616,34 +838,34 @@ function InternalTextInput(props: TextInputProps): React.Node {
1616
838
  />
1617
839
  );
1618
840
  }
1619
- return (
1620
- <TextAncestor.Provider value={true}>{textInput}</TextAncestor.Provider>
1621
- );
841
+ return <TextAncestorContext value={true}>{textInput}</TextAncestorContext>;
1622
842
  }
1623
843
 
1624
844
  const enterKeyHintToReturnTypeMap = {
1625
- enter: 'default',
1626
845
  done: 'done',
846
+ enter: 'default',
1627
847
  go: 'go',
1628
848
  next: 'next',
1629
849
  previous: 'previous',
1630
850
  search: 'search',
1631
851
  send: 'send',
1632
- };
852
+ } as const;
1633
853
 
1634
854
  const inputModeToKeyboardTypeMap = {
1635
- none: 'default',
1636
- text: 'default',
1637
855
  decimal: 'decimal-pad',
856
+ email: 'email-address',
857
+ none: 'default',
1638
858
  numeric: 'number-pad',
859
+ search:
860
+ Platform.OS === 'ios' ? ('web-search' as const) : ('default' as const),
1639
861
  tel: 'phone-pad',
1640
- search: Platform.OS === 'ios' ? 'web-search' : 'default',
1641
- email: 'email-address',
862
+ text: 'default',
1642
863
  url: 'url',
1643
- };
864
+ } as const;
1644
865
 
1645
866
  // Map HTML autocomplete values to Android autoComplete values
1646
867
  const autoCompleteWebToAutoCompleteAndroidMap = {
868
+ 'additional-name': 'name-middle',
1647
869
  'address-line1': 'postal-address-region',
1648
870
  'address-line2': 'postal-address-locality',
1649
871
  bday: 'birthdate-full',
@@ -1658,12 +880,11 @@ const autoCompleteWebToAutoCompleteAndroidMap = {
1658
880
  country: 'postal-address-country',
1659
881
  'current-password': 'password',
1660
882
  email: 'email',
883
+ 'family-name': 'name-family',
884
+ 'given-name': 'name-given',
1661
885
  'honorific-prefix': 'name-prefix',
1662
886
  'honorific-suffix': 'name-suffix',
1663
887
  name: 'name',
1664
- 'additional-name': 'name-middle',
1665
- 'family-name': 'name-family',
1666
- 'given-name': 'name-given',
1667
888
  'new-password': 'password-new',
1668
889
  off: 'off',
1669
890
  'one-time-code': 'sms-otp',
@@ -1674,37 +895,37 @@ const autoCompleteWebToAutoCompleteAndroidMap = {
1674
895
  'tel-country-code': 'tel-country-code',
1675
896
  'tel-national': 'tel-national',
1676
897
  username: 'username',
1677
- };
898
+ } as const;
1678
899
 
1679
900
  // Map HTML autocomplete values to iOS textContentType values
1680
901
  const autoCompleteWebToTextContentTypeMap = {
902
+ 'additional-name': 'middleName',
1681
903
  'address-line1': 'streetAddressLine1',
1682
904
  'address-line2': 'streetAddressLine2',
1683
905
  bday: 'birthdate',
1684
906
  'bday-day': 'birthdateDay',
1685
907
  'bday-month': 'birthdateMonth',
1686
908
  'bday-year': 'birthdateYear',
909
+ 'cc-additional-name': 'creditCardMiddleName',
1687
910
  'cc-csc': 'creditCardSecurityCode',
911
+ 'cc-exp': 'creditCardExpiration',
1688
912
  'cc-exp-month': 'creditCardExpirationMonth',
1689
913
  'cc-exp-year': 'creditCardExpirationYear',
1690
- 'cc-exp': 'creditCardExpiration',
1691
- 'cc-given-name': 'creditCardGivenName',
1692
- 'cc-additional-name': 'creditCardMiddleName',
1693
914
  'cc-family-name': 'creditCardFamilyName',
915
+ 'cc-given-name': 'creditCardGivenName',
1694
916
  'cc-name': 'creditCardName',
1695
917
  'cc-number': 'creditCardNumber',
1696
918
  'cc-type': 'creditCardType',
1697
- 'current-password': 'password',
1698
919
  country: 'countryName',
920
+ 'current-password': 'password',
1699
921
  email: 'emailAddress',
1700
- name: 'name',
1701
- 'additional-name': 'middleName',
1702
922
  'family-name': 'familyName',
1703
923
  'given-name': 'givenName',
1704
- nickname: 'nickname',
1705
924
  'honorific-prefix': 'namePrefix',
1706
925
  'honorific-suffix': 'nameSuffix',
926
+ name: 'name',
1707
927
  'new-password': 'newPassword',
928
+ nickname: 'nickname',
1708
929
  off: 'none',
1709
930
  'one-time-code': 'oneTimeCode',
1710
931
  organization: 'organizationName',
@@ -1714,29 +935,30 @@ const autoCompleteWebToTextContentTypeMap = {
1714
935
  tel: 'telephoneNumber',
1715
936
  url: 'URL',
1716
937
  username: 'username',
1717
- };
938
+ } as const;
1718
939
 
1719
- const ExportedForwardRef: component(
1720
- ref: React.RefSetter<TextInputInstance>,
940
+ const TextInput: component(
941
+ ref?: React.RefSetter<TextInputInstance>,
1721
942
  ...props: React.ElementConfig<typeof InternalTextInput>
1722
- ) = React.forwardRef(function TextInput(
1723
- {
1724
- allowFontScaling = true,
1725
- rejectResponderTermination = true,
1726
- underlineColorAndroid = 'transparent',
1727
- autoComplete,
1728
- textContentType,
1729
- readOnly,
1730
- editable,
1731
- enterKeyHint,
1732
- returnKeyType,
1733
- inputMode,
1734
- showSoftInputOnFocus,
1735
- keyboardType,
1736
- ...restProps
1737
- },
1738
- forwardedRef: React.RefSetter<TextInputInstance>,
1739
- ) {
943
+ ) = function TextInput({
944
+ ref: forwardedRef,
945
+ allowFontScaling = true,
946
+ rejectResponderTermination = true,
947
+ underlineColorAndroid = 'transparent',
948
+ autoComplete,
949
+ textContentType,
950
+ readOnly,
951
+ editable,
952
+ enterKeyHint,
953
+ returnKeyType,
954
+ inputMode,
955
+ showSoftInputOnFocus,
956
+ keyboardType,
957
+ ...restProps
958
+ }: {
959
+ ref?: React.RefSetter<TextInputInstance>,
960
+ ...React.ElementConfig<typeof InternalTextInput>,
961
+ }) {
1740
962
  return (
1741
963
  <InternalTextInput
1742
964
  allowFontScaling={allowFontScaling}
@@ -1756,8 +978,8 @@ const ExportedForwardRef: component(
1756
978
  Platform.OS === 'android'
1757
979
  ? // $FlowFixMe[invalid-computed-prop]
1758
980
  // $FlowFixMe[prop-missing]
1759
- autoCompleteWebToAutoCompleteAndroidMap[autoComplete] ??
1760
- autoComplete
981
+ (autoCompleteWebToAutoCompleteAndroidMap[autoComplete] ??
982
+ autoComplete)
1761
983
  : undefined
1762
984
  }
1763
985
  textContentType={
@@ -1766,8 +988,7 @@ const ExportedForwardRef: component(
1766
988
  : Platform.OS === 'ios' &&
1767
989
  autoComplete &&
1768
990
  autoComplete in autoCompleteWebToTextContentTypeMap
1769
- ? // $FlowFixMe[invalid-computed-prop]
1770
- // $FlowFixMe[prop-missing]
991
+ ? // $FlowFixMe[prop-missing]
1771
992
  autoCompleteWebToTextContentTypeMap[autoComplete]
1772
993
  : textContentType
1773
994
  }
@@ -1775,26 +996,20 @@ const ExportedForwardRef: component(
1775
996
  forwardedRef={forwardedRef}
1776
997
  />
1777
998
  );
1778
- });
999
+ };
1779
1000
 
1780
- ExportedForwardRef.displayName = 'TextInput';
1001
+ TextInput.displayName = 'TextInput';
1781
1002
 
1782
1003
  // $FlowFixMe[prop-missing]
1783
- ExportedForwardRef.State = {
1784
- currentlyFocusedInput: TextInputState.currentlyFocusedInput,
1785
-
1004
+ TextInput.State = {
1005
+ blurTextInput: TextInputState.blurTextInput,
1786
1006
  currentlyFocusedField: TextInputState.currentlyFocusedField,
1007
+ currentlyFocusedInput: TextInputState.currentlyFocusedInput,
1787
1008
  focusTextInput: TextInputState.focusTextInput,
1788
- blurTextInput: TextInputState.blurTextInput,
1789
1009
  };
1790
1010
 
1791
- export type TextInputComponentStatics = $ReadOnly<{
1792
- State: $ReadOnly<{
1793
- currentlyFocusedInput: typeof TextInputState.currentlyFocusedInput,
1794
- currentlyFocusedField: typeof TextInputState.currentlyFocusedField,
1795
- focusTextInput: typeof TextInputState.focusTextInput,
1796
- blurTextInput: typeof TextInputState.blurTextInput,
1797
- }>,
1011
+ export type TextInputComponentStatics = Readonly<{
1012
+ State: TextInputStateType,
1798
1013
  }>;
1799
1014
 
1800
1015
  const styles = StyleSheet.create({
@@ -1808,10 +1023,10 @@ const styles = StyleSheet.create({
1808
1023
 
1809
1024
  const verticalAlignToTextAlignVerticalMap = {
1810
1025
  auto: 'auto',
1811
- top: 'top',
1812
1026
  bottom: 'bottom',
1813
1027
  middle: 'center',
1814
- };
1028
+ top: 'top',
1029
+ } as const;
1815
1030
 
1816
1031
  // $FlowFixMe[unclear-type] Unclear type. Using `any` type is not safe.
1817
- export default ExportedForwardRef as any as TextInputType;
1032
+ export default TextInput as any as TextInputType;