@onekeyfe/react-native-text-input 0.2.5 → 0.2.8
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/android/generated/android/app/build/generated/source/codegen/java/com/facebook/react/viewmanagers/OneKeyTextInputManagerDelegate.java +3 -2
- package/android/generated/android/app/build/generated/source/codegen/java/com/facebook/react/viewmanagers/OneKeyTextInputManagerInterface.java +2 -1
- package/android/generated/android/app/build/generated/source/codegen/jni/CMakeLists.txt +4 -17
- package/ios/generated/build/generated/ios/RNTextInputViewSpec/RNTextInputViewSpec.h +3 -0
- package/lib/commonjs/AndroidTextInputNativeComponent.js +152 -0
- package/lib/commonjs/AndroidTextInputNativeComponent.js.map +1 -0
- package/lib/commonjs/Input.js +140 -273
- package/lib/commonjs/Input.js.map +1 -1
- package/lib/commonjs/TextInputViewNativeComponent.ts +9 -0
- package/lib/commonjs/index.js +4 -14
- package/lib/commonjs/index.js.map +1 -1
- package/lib/typescript/src/TextInputViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/enum.d.ts.map +1 -0
- package/lib/typescript/{commonjs/src → src}/index.d.ts +0 -1
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/type.d.ts.map +1 -0
- package/package.json +8 -18
- package/src/AndroidTextInputNativeComponent.js +767 -0
- package/src/Input.js +418 -247
- package/src/index.tsx +1 -1
- package/ios/generated/build/generated/ios/FBReactNativeSpec/FBReactNativeSpec-generated.mm +0 -1881
- package/ios/generated/build/generated/ios/FBReactNativeSpec/FBReactNativeSpec.h +0 -2321
- package/ios/generated/build/generated/ios/FBReactNativeSpecJSI-generated.cpp +0 -2785
- package/ios/generated/build/generated/ios/FBReactNativeSpecJSI.h +0 -7511
- package/ios/generated/build/generated/ios/RCTModulesConformingToProtocolsProvider.h +0 -18
- package/ios/generated/build/generated/ios/RCTModulesConformingToProtocolsProvider.mm +0 -33
- package/lib/commonjs/TextInputViewNativeComponent.js +0 -10
- package/lib/commonjs/TextInputViewNativeComponent.js.map +0 -1
- package/lib/module/Input.js +0 -667
- package/lib/module/Input.js.map +0 -1
- package/lib/module/TextInputViewNativeComponent.js +0 -5
- package/lib/module/TextInputViewNativeComponent.js.map +0 -1
- package/lib/module/enum.js +0 -7
- package/lib/module/enum.js.map +0 -1
- package/lib/module/index.js +0 -9
- package/lib/module/index.js.map +0 -1
- package/lib/module/type.js +0 -4
- package/lib/module/type.js.map +0 -1
- package/lib/typescript/commonjs/src/TextInputViewNativeComponent.d.ts.map +0 -1
- package/lib/typescript/commonjs/src/enum.d.ts.map +0 -1
- package/lib/typescript/commonjs/src/index.d.ts.map +0 -1
- package/lib/typescript/commonjs/src/type.d.ts.map +0 -1
- package/lib/typescript/module/package.json +0 -1
- package/lib/typescript/module/src/TextInputViewNativeComponent.d.ts +0 -8
- package/lib/typescript/module/src/TextInputViewNativeComponent.d.ts.map +0 -1
- package/lib/typescript/module/src/enum.d.ts +0 -4
- package/lib/typescript/module/src/enum.d.ts.map +0 -1
- package/lib/typescript/module/src/index.d.ts +0 -8
- package/lib/typescript/module/src/index.d.ts.map +0 -1
- package/lib/typescript/module/src/type.d.ts +0 -16
- package/lib/typescript/module/src/type.d.ts.map +0 -1
- /package/lib/{typescript/commonjs → commonjs}/package.json +0 -0
- /package/lib/typescript/{commonjs/src → src}/TextInputViewNativeComponent.d.ts +0 -0
- /package/lib/typescript/{commonjs/src → src}/enum.d.ts +0 -0
- /package/lib/typescript/{commonjs/src → src}/type.d.ts +0 -0
package/src/Input.js
CHANGED
|
@@ -10,17 +10,19 @@
|
|
|
10
10
|
* @format
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import type {
|
|
13
|
+
import type {HostInstance} from 'react-native/src/private/types/HostInstance';
|
|
14
|
+
import type {____TextStyle_Internal as TextStyleInternal} from 'react-native/Libraries/StyleSheet/StyleSheetTypes';
|
|
14
15
|
import type {
|
|
15
|
-
|
|
16
|
+
GestureResponderEvent,
|
|
17
|
+
NativeSyntheticEvent,
|
|
16
18
|
ScrollEvent,
|
|
17
|
-
SyntheticEvent,
|
|
18
19
|
} from 'react-native/Libraries/Types/CoreEventTypes';
|
|
19
|
-
import type {ViewProps} from 'react-native/Libraries/
|
|
20
|
-
import type {TextInputType} from '
|
|
20
|
+
import type {ViewProps} from 'react-native/Libraries/Components/View/ViewPropTypes';
|
|
21
|
+
import type {TextInputInstance, TextInputType} from 'react-native/Libraries/Components/TextInput/TextInput.flow';
|
|
21
22
|
|
|
22
|
-
import
|
|
23
|
-
import
|
|
23
|
+
import * as ReactNativeFeatureFlags from 'react-native/src/private/featureflags/ReactNativeFeatureFlags.js';
|
|
24
|
+
import usePressability from 'react-native/Libraries/Pressability/usePressability.js';
|
|
25
|
+
import flattenStyle from 'react-native/Libraries/StyleSheet/flattenStyle.js';
|
|
24
26
|
import StyleSheet, {
|
|
25
27
|
type ColorValue,
|
|
26
28
|
type TextStyleProp,
|
|
@@ -36,14 +38,6 @@ import nullthrows from 'nullthrows';
|
|
|
36
38
|
import * as React from 'react';
|
|
37
39
|
import {useCallback, useLayoutEffect, useRef, useState} from 'react';
|
|
38
40
|
|
|
39
|
-
type ReactRefSetter<T> = {current: null | T, ...} | ((ref: null | T) => mixed);
|
|
40
|
-
type TextInputInstance = React.ElementRef<HostComponent<mixed>> & {
|
|
41
|
-
+clear: () => void,
|
|
42
|
-
+isFocused: () => boolean,
|
|
43
|
-
+getNativeRef: () => ?React.ElementRef<HostComponent<mixed>>,
|
|
44
|
-
+setSelection: (start: number, end: number) => void,
|
|
45
|
-
};
|
|
46
|
-
|
|
47
41
|
let AndroidTextInput;
|
|
48
42
|
let AndroidTextInputCommands;
|
|
49
43
|
let RCTSinglelineTextInputView;
|
|
@@ -52,9 +46,9 @@ let RCTMultilineTextInputView;
|
|
|
52
46
|
let RCTMultilineTextInputNativeCommands;
|
|
53
47
|
|
|
54
48
|
if (Platform.OS === 'android') {
|
|
55
|
-
AndroidTextInput = require('./
|
|
49
|
+
AndroidTextInput = require('./AndroidTextInputNativeComponent').default;
|
|
56
50
|
AndroidTextInputCommands =
|
|
57
|
-
require('
|
|
51
|
+
require('./AndroidTextInputNativeComponent').Commands;
|
|
58
52
|
} else if (Platform.OS === 'ios') {
|
|
59
53
|
RCTSinglelineTextInputView =
|
|
60
54
|
require('react-native/Libraries/Components/TextInput/RCTSingelineTextInputNativeComponent').default;
|
|
@@ -66,73 +60,79 @@ if (Platform.OS === 'android') {
|
|
|
66
60
|
require('react-native/Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent').Commands;
|
|
67
61
|
}
|
|
68
62
|
|
|
69
|
-
export type
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|}>,
|
|
75
|
-
>;
|
|
63
|
+
export type TextInputChangeEventData = $ReadOnly<{
|
|
64
|
+
eventCount: number,
|
|
65
|
+
target: number,
|
|
66
|
+
text: string,
|
|
67
|
+
}>;
|
|
76
68
|
|
|
77
|
-
export type
|
|
78
|
-
|
|
69
|
+
export type TextInputChangeEvent =
|
|
70
|
+
NativeSyntheticEvent<TextInputChangeEventData>;
|
|
71
|
+
|
|
72
|
+
export type TextInputEvent = NativeSyntheticEvent<
|
|
73
|
+
$ReadOnly<{
|
|
79
74
|
eventCount: number,
|
|
80
75
|
previousText: string,
|
|
81
|
-
range: $ReadOnly<{
|
|
76
|
+
range: $ReadOnly<{
|
|
82
77
|
start: number,
|
|
83
78
|
end: number,
|
|
84
|
-
|
|
79
|
+
}>,
|
|
85
80
|
target: number,
|
|
86
81
|
text: string,
|
|
87
|
-
|
|
82
|
+
}>,
|
|
88
83
|
>;
|
|
89
84
|
|
|
90
|
-
export type
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|}>,
|
|
98
|
-
>;
|
|
85
|
+
export type TextInputContentSizeChangeEventData = $ReadOnly<{
|
|
86
|
+
target: number,
|
|
87
|
+
contentSize: $ReadOnly<{
|
|
88
|
+
width: number,
|
|
89
|
+
height: number,
|
|
90
|
+
}>,
|
|
91
|
+
}>;
|
|
99
92
|
|
|
100
|
-
type
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
93
|
+
export type TextInputContentSizeChangeEvent =
|
|
94
|
+
NativeSyntheticEvent<TextInputContentSizeChangeEventData>;
|
|
95
|
+
|
|
96
|
+
export type TargetEvent = $ReadOnly<{
|
|
97
|
+
target: number,
|
|
98
|
+
}>;
|
|
105
99
|
|
|
106
|
-
export type
|
|
107
|
-
export type FocusEvent = TargetEvent;
|
|
100
|
+
export type TextInputFocusEventData = TargetEvent;
|
|
108
101
|
|
|
109
|
-
type
|
|
102
|
+
export type TextInputBlurEvent = NativeSyntheticEvent<TextInputFocusEventData>;
|
|
103
|
+
export type TextInputFocusEvent = NativeSyntheticEvent<TextInputFocusEventData>;
|
|
104
|
+
|
|
105
|
+
type Selection = $ReadOnly<{
|
|
110
106
|
start: number,
|
|
111
107
|
end: number,
|
|
112
|
-
|
|
108
|
+
}>;
|
|
113
109
|
|
|
114
|
-
export type
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|}>,
|
|
119
|
-
>;
|
|
110
|
+
export type TextInputSelectionChangeEventData = $ReadOnly<{
|
|
111
|
+
...TargetEvent,
|
|
112
|
+
selection: Selection,
|
|
113
|
+
}>;
|
|
120
114
|
|
|
121
|
-
export type
|
|
122
|
-
|
|
123
|
-
key: string,
|
|
124
|
-
target?: ?number,
|
|
125
|
-
eventCount?: ?number,
|
|
126
|
-
|}>,
|
|
127
|
-
>;
|
|
115
|
+
export type TextInputSelectionChangeEvent =
|
|
116
|
+
NativeSyntheticEvent<TextInputSelectionChangeEventData>;
|
|
128
117
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
118
|
+
type TextInputKeyPressEventData = $ReadOnly<{
|
|
119
|
+
...TargetEvent,
|
|
120
|
+
key: string,
|
|
121
|
+
target?: ?number,
|
|
122
|
+
eventCount?: ?number,
|
|
123
|
+
}>;
|
|
124
|
+
|
|
125
|
+
export type TextInputKeyPressEvent =
|
|
126
|
+
NativeSyntheticEvent<TextInputKeyPressEventData>;
|
|
127
|
+
|
|
128
|
+
export type TextInputEndEditingEventData = $ReadOnly<{
|
|
129
|
+
...TargetEvent,
|
|
130
|
+
eventCount: number,
|
|
131
|
+
text: string,
|
|
132
|
+
}>;
|
|
133
|
+
|
|
134
|
+
export type TextInputEditingEvent =
|
|
135
|
+
NativeSyntheticEvent<TextInputEndEditingEventData>;
|
|
136
136
|
|
|
137
137
|
type DataDetectorTypesType =
|
|
138
138
|
| 'phoneNumber'
|
|
@@ -146,26 +146,31 @@ type DataDetectorTypesType =
|
|
|
146
146
|
| 'all';
|
|
147
147
|
|
|
148
148
|
export type KeyboardType =
|
|
149
|
-
// Cross Platform
|
|
150
149
|
| 'default'
|
|
151
150
|
| 'email-address'
|
|
152
151
|
| 'numeric'
|
|
153
152
|
| 'phone-pad'
|
|
154
153
|
| 'number-pad'
|
|
155
154
|
| 'decimal-pad'
|
|
156
|
-
| 'url'
|
|
157
|
-
|
|
155
|
+
| 'url';
|
|
156
|
+
|
|
157
|
+
export type KeyboardTypeIOS =
|
|
158
158
|
| 'ascii-capable'
|
|
159
159
|
| 'numbers-and-punctuation'
|
|
160
160
|
| 'name-phone-pad'
|
|
161
161
|
| 'twitter'
|
|
162
162
|
| 'web-search'
|
|
163
163
|
// iOS 10+ only
|
|
164
|
-
| 'ascii-capable-number-pad'
|
|
165
|
-
|
|
166
|
-
|
|
164
|
+
| 'ascii-capable-number-pad';
|
|
165
|
+
|
|
166
|
+
export type KeyboardTypeAndroid = 'visible-password';
|
|
167
167
|
|
|
168
|
-
export type
|
|
168
|
+
export type KeyboardTypeOptions =
|
|
169
|
+
| KeyboardType
|
|
170
|
+
| KeyboardTypeIOS
|
|
171
|
+
| KeyboardTypeAndroid;
|
|
172
|
+
|
|
173
|
+
export type InputModeOptions =
|
|
169
174
|
| 'none'
|
|
170
175
|
| 'text'
|
|
171
176
|
| 'decimal'
|
|
@@ -175,17 +180,9 @@ export type InputMode =
|
|
|
175
180
|
| 'email'
|
|
176
181
|
| 'url';
|
|
177
182
|
|
|
178
|
-
export type ReturnKeyType =
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
| 'go'
|
|
182
|
-
| 'next'
|
|
183
|
-
| 'search'
|
|
184
|
-
| 'send'
|
|
185
|
-
// Android-only
|
|
186
|
-
| 'none'
|
|
187
|
-
| 'previous'
|
|
188
|
-
// iOS-only
|
|
183
|
+
export type ReturnKeyType = 'done' | 'go' | 'next' | 'search' | 'send';
|
|
184
|
+
|
|
185
|
+
export type ReturnKeyTypeIOS =
|
|
189
186
|
| 'default'
|
|
190
187
|
| 'emergency-call'
|
|
191
188
|
| 'google'
|
|
@@ -193,6 +190,13 @@ export type ReturnKeyType =
|
|
|
193
190
|
| 'route'
|
|
194
191
|
| 'yahoo';
|
|
195
192
|
|
|
193
|
+
export type ReturnKeyTypeAndroid = 'none' | 'previous';
|
|
194
|
+
|
|
195
|
+
export type ReturnKeyTypeOptions =
|
|
196
|
+
| ReturnKeyType
|
|
197
|
+
| ReturnKeyTypeIOS
|
|
198
|
+
| ReturnKeyTypeAndroid;
|
|
199
|
+
|
|
196
200
|
export type SubmitBehavior = 'submit' | 'blurAndSubmit' | 'newline';
|
|
197
201
|
|
|
198
202
|
export type AutoCapitalize = 'none' | 'sentences' | 'words' | 'characters';
|
|
@@ -238,23 +242,33 @@ export type TextContentType =
|
|
|
238
242
|
| 'birthdate'
|
|
239
243
|
| 'birthdateDay'
|
|
240
244
|
| 'birthdateMonth'
|
|
241
|
-
| 'birthdateYear'
|
|
245
|
+
| 'birthdateYear'
|
|
246
|
+
| 'cellularEID'
|
|
247
|
+
| 'cellularIMEI'
|
|
248
|
+
| 'dateTime'
|
|
249
|
+
| 'flightNumber'
|
|
250
|
+
| 'shipmentTrackingNumber';
|
|
242
251
|
|
|
243
|
-
export type
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
|
252
|
-
|
|
253
|
-
| 'enter';
|
|
252
|
+
export type EnterKeyHintTypeAndroid = 'previous';
|
|
253
|
+
|
|
254
|
+
export type EnterKeyHintTypeIOS = 'enter';
|
|
255
|
+
|
|
256
|
+
export type EnterKeyHintType = 'done' | 'go' | 'next' | 'search' | 'send';
|
|
257
|
+
|
|
258
|
+
export type EnterKeyHintTypeOptions =
|
|
259
|
+
| EnterKeyHintType
|
|
260
|
+
| EnterKeyHintTypeAndroid
|
|
261
|
+
| EnterKeyHintTypeIOS;
|
|
254
262
|
|
|
255
263
|
type PasswordRules = string;
|
|
256
264
|
|
|
257
|
-
type
|
|
265
|
+
export type TextInputIOSProps = $ReadOnly<{
|
|
266
|
+
/**
|
|
267
|
+
* If true, the keyboard shortcuts (undo/redo and copy buttons) are disabled. The default value is false.
|
|
268
|
+
* @platform ios
|
|
269
|
+
*/
|
|
270
|
+
disableKeyboardShortcuts?: ?boolean,
|
|
271
|
+
|
|
258
272
|
/**
|
|
259
273
|
* When the clear button should appear on the right side of the text view.
|
|
260
274
|
* This property is supported only for single-line TextInput component.
|
|
@@ -305,6 +319,12 @@ type IOSProps = $ReadOnly<{|
|
|
|
305
319
|
*/
|
|
306
320
|
inputAccessoryViewID?: ?string,
|
|
307
321
|
|
|
322
|
+
/**
|
|
323
|
+
* An optional label that overrides the default input accessory view button label.
|
|
324
|
+
* @platform ios
|
|
325
|
+
*/
|
|
326
|
+
inputAccessoryViewButtonLabel?: ?string,
|
|
327
|
+
|
|
308
328
|
/**
|
|
309
329
|
* Determines the color of the keyboard.
|
|
310
330
|
* @platform ios
|
|
@@ -358,6 +378,19 @@ type IOSProps = $ReadOnly<{|
|
|
|
358
378
|
*/
|
|
359
379
|
lineBreakStrategyIOS?: ?('none' | 'standard' | 'hangul-word' | 'push-out'),
|
|
360
380
|
|
|
381
|
+
/**
|
|
382
|
+
* Set line break mode on iOS.
|
|
383
|
+
* @platform ios
|
|
384
|
+
*/
|
|
385
|
+
lineBreakModeIOS?: ?(
|
|
386
|
+
| 'wordWrapping'
|
|
387
|
+
| 'char'
|
|
388
|
+
| 'clip'
|
|
389
|
+
| 'head'
|
|
390
|
+
| 'middle'
|
|
391
|
+
| 'tail'
|
|
392
|
+
),
|
|
393
|
+
|
|
361
394
|
/**
|
|
362
395
|
* If `false`, the iOS system will not insert an extra space after a paste operation
|
|
363
396
|
* neither delete one or two spaces after a cut or delete operation.
|
|
@@ -367,9 +400,9 @@ type IOSProps = $ReadOnly<{|
|
|
|
367
400
|
* @platform ios
|
|
368
401
|
*/
|
|
369
402
|
smartInsertDelete?: ?boolean,
|
|
370
|
-
|
|
403
|
+
}>;
|
|
371
404
|
|
|
372
|
-
type
|
|
405
|
+
export type TextInputAndroidProps = $ReadOnly<{
|
|
373
406
|
/**
|
|
374
407
|
* When provided it will set the color of the cursor (or "caret") in the component.
|
|
375
408
|
* Unlike the behavior of `selectionColor` the cursor color will be set independently
|
|
@@ -453,12 +486,12 @@ type AndroidProps = $ReadOnly<{|
|
|
|
453
486
|
* @platform android
|
|
454
487
|
*/
|
|
455
488
|
underlineColorAndroid?: ?ColorValue,
|
|
456
|
-
|
|
489
|
+
}>;
|
|
457
490
|
|
|
458
|
-
export type
|
|
459
|
-
...$Diff<ViewProps, $ReadOnly<{
|
|
460
|
-
...
|
|
461
|
-
...
|
|
491
|
+
export type TextInputProps = $ReadOnly<{
|
|
492
|
+
...$Diff<ViewProps, $ReadOnly<{style: ?ViewStyleProp}>>,
|
|
493
|
+
...TextInputIOSProps,
|
|
494
|
+
...TextInputAndroidProps,
|
|
462
495
|
|
|
463
496
|
/**
|
|
464
497
|
* Can tell `TextInput` to automatically capitalize certain characters.
|
|
@@ -646,7 +679,7 @@ export type Props = $ReadOnly<{|
|
|
|
646
679
|
*/
|
|
647
680
|
editable?: ?boolean,
|
|
648
681
|
|
|
649
|
-
forwardedRef?: ?
|
|
682
|
+
forwardedRef?: ?React.RefSetter<TextInputInstance>,
|
|
650
683
|
|
|
651
684
|
/**
|
|
652
685
|
* `enterKeyHint` defines what action label (or icon) to present for the enter key on virtual keyboards.
|
|
@@ -661,7 +694,7 @@ export type Props = $ReadOnly<{|
|
|
|
661
694
|
* - `search`
|
|
662
695
|
* - `send`
|
|
663
696
|
*/
|
|
664
|
-
enterKeyHint?: ?
|
|
697
|
+
enterKeyHint?: ?EnterKeyHintTypeOptions,
|
|
665
698
|
|
|
666
699
|
/**
|
|
667
700
|
* `inputMode` works like the `inputmode` attribute in HTML, it determines which
|
|
@@ -678,7 +711,7 @@ export type Props = $ReadOnly<{|
|
|
|
678
711
|
* - `email`
|
|
679
712
|
* - `url`
|
|
680
713
|
*/
|
|
681
|
-
inputMode?: ?
|
|
714
|
+
inputMode?: ?InputModeOptions,
|
|
682
715
|
|
|
683
716
|
/**
|
|
684
717
|
* Determines which keyboard to open, e.g.`numeric`.
|
|
@@ -710,7 +743,7 @@ export type Props = $ReadOnly<{|
|
|
|
710
743
|
* - `visible-password`
|
|
711
744
|
*
|
|
712
745
|
*/
|
|
713
|
-
keyboardType?: ?
|
|
746
|
+
keyboardType?: ?KeyboardTypeOptions,
|
|
714
747
|
|
|
715
748
|
/**
|
|
716
749
|
* Specifies largest possible scale a font can reach when `allowFontScaling` is enabled.
|
|
@@ -736,12 +769,12 @@ export type Props = $ReadOnly<{|
|
|
|
736
769
|
/**
|
|
737
770
|
* Callback that is called when the text input is blurred.
|
|
738
771
|
*/
|
|
739
|
-
onBlur?: ?(e:
|
|
772
|
+
onBlur?: ?(e: TextInputBlurEvent) => mixed,
|
|
740
773
|
|
|
741
774
|
/**
|
|
742
775
|
* Callback that is called when the text input's text changes.
|
|
743
776
|
*/
|
|
744
|
-
onChange?: ?(e:
|
|
777
|
+
onChange?: ?(e: TextInputChangeEvent) => mixed,
|
|
745
778
|
|
|
746
779
|
/**
|
|
747
780
|
* Callback that is called when the text input's text changes.
|
|
@@ -756,17 +789,17 @@ export type Props = $ReadOnly<{|
|
|
|
756
789
|
*
|
|
757
790
|
* Only called for multiline text inputs.
|
|
758
791
|
*/
|
|
759
|
-
onContentSizeChange?: ?(e:
|
|
792
|
+
onContentSizeChange?: ?(e: TextInputContentSizeChangeEvent) => mixed,
|
|
760
793
|
|
|
761
794
|
/**
|
|
762
795
|
* Callback that is called when text input ends.
|
|
763
796
|
*/
|
|
764
|
-
onEndEditing?: ?(e:
|
|
797
|
+
onEndEditing?: ?(e: TextInputEditingEvent) => mixed,
|
|
765
798
|
|
|
766
799
|
/**
|
|
767
800
|
* Callback that is called when the text input is focused.
|
|
768
801
|
*/
|
|
769
|
-
onFocus?: ?(e:
|
|
802
|
+
onFocus?: ?(e: TextInputFocusEvent) => mixed,
|
|
770
803
|
|
|
771
804
|
/**
|
|
772
805
|
* Callback that is called when a key is pressed.
|
|
@@ -775,35 +808,35 @@ export type Props = $ReadOnly<{|
|
|
|
775
808
|
* the typed-in character otherwise including `' '` for space.
|
|
776
809
|
* Fires before `onChange` callbacks.
|
|
777
810
|
*/
|
|
778
|
-
onKeyPress?: ?(e:
|
|
811
|
+
onKeyPress?: ?(e: TextInputKeyPressEvent) => mixed,
|
|
779
812
|
|
|
780
813
|
/**
|
|
781
814
|
* Called when a single tap gesture is detected.
|
|
782
815
|
*/
|
|
783
|
-
onPress?: ?(event:
|
|
816
|
+
onPress?: ?(event: GestureResponderEvent) => mixed,
|
|
784
817
|
|
|
785
818
|
/**
|
|
786
819
|
* Called when a touch is engaged.
|
|
787
820
|
*/
|
|
788
|
-
onPressIn?: ?(event:
|
|
821
|
+
onPressIn?: ?(event: GestureResponderEvent) => mixed,
|
|
789
822
|
|
|
790
823
|
/**
|
|
791
824
|
* Called when a touch is released.
|
|
792
825
|
*/
|
|
793
|
-
onPressOut?: ?(event:
|
|
826
|
+
onPressOut?: ?(event: GestureResponderEvent) => mixed,
|
|
794
827
|
|
|
795
828
|
/**
|
|
796
829
|
* Callback that is called when the text input selection is changed.
|
|
797
830
|
* This will be called with
|
|
798
831
|
* `{ nativeEvent: { selection: { start, end } } }`.
|
|
799
832
|
*/
|
|
800
|
-
onSelectionChange?: ?(e:
|
|
833
|
+
onSelectionChange?: ?(e: TextInputSelectionChangeEvent) => mixed,
|
|
801
834
|
|
|
802
835
|
/**
|
|
803
836
|
* Callback that is called when the text input's submit button is pressed.
|
|
804
837
|
* Invalid if `multiline={true}` is specified.
|
|
805
838
|
*/
|
|
806
|
-
onSubmitEditing?: ?(e:
|
|
839
|
+
onSubmitEditing?: ?(e: TextInputEditingEvent) => mixed,
|
|
807
840
|
|
|
808
841
|
/**
|
|
809
842
|
* Invoked on content scroll with `{ nativeEvent: { contentOffset: { x, y } } }`.
|
|
@@ -861,7 +894,7 @@ export type Props = $ReadOnly<{|
|
|
|
861
894
|
* - `route`
|
|
862
895
|
* - `yahoo`
|
|
863
896
|
*/
|
|
864
|
-
returnKeyType?: ?
|
|
897
|
+
returnKeyType?: ?ReturnKeyTypeOptions,
|
|
865
898
|
|
|
866
899
|
/**
|
|
867
900
|
* If `true`, the text input obscures the text entered so that sensitive text
|
|
@@ -873,10 +906,10 @@ export type Props = $ReadOnly<{|
|
|
|
873
906
|
* The start and end of the text input's selection. Set start and end to
|
|
874
907
|
* the same value to position the cursor.
|
|
875
908
|
*/
|
|
876
|
-
selection?: ?$ReadOnly<{
|
|
909
|
+
selection?: ?$ReadOnly<{
|
|
877
910
|
start: number,
|
|
878
911
|
end?: ?number,
|
|
879
|
-
|
|
912
|
+
}>,
|
|
880
913
|
|
|
881
914
|
/**
|
|
882
915
|
* The highlight and cursor color of the text input.
|
|
@@ -957,10 +990,190 @@ export type Props = $ReadOnly<{|
|
|
|
957
990
|
* unwanted edits without flicker.
|
|
958
991
|
*/
|
|
959
992
|
value?: ?Stringish,
|
|
960
|
-
|
|
993
|
+
}>;
|
|
994
|
+
|
|
995
|
+
type ViewCommands = $NonMaybeType<
|
|
996
|
+
| typeof AndroidTextInputCommands
|
|
997
|
+
| typeof RCTMultilineTextInputNativeCommands
|
|
998
|
+
| typeof RCTSinglelineTextInputNativeCommands,
|
|
999
|
+
>;
|
|
1000
|
+
|
|
1001
|
+
type LastNativeSelection = {
|
|
1002
|
+
selection: Selection,
|
|
1003
|
+
mostRecentEventCount: number,
|
|
1004
|
+
};
|
|
961
1005
|
|
|
962
1006
|
const emptyFunctionThatReturnsTrue = () => true;
|
|
963
1007
|
|
|
1008
|
+
/**
|
|
1009
|
+
* This hook handles the synchronization between the state of the text input
|
|
1010
|
+
* in native and in JavaScript. This is necessary due to the asynchronous nature
|
|
1011
|
+
* of text input events.
|
|
1012
|
+
*/
|
|
1013
|
+
function useTextInputStateSynchronization_STATE({
|
|
1014
|
+
props,
|
|
1015
|
+
mostRecentEventCount,
|
|
1016
|
+
selection,
|
|
1017
|
+
inputRef,
|
|
1018
|
+
text,
|
|
1019
|
+
viewCommands,
|
|
1020
|
+
}: {
|
|
1021
|
+
props: TextInputProps,
|
|
1022
|
+
mostRecentEventCount: number,
|
|
1023
|
+
selection: ?Selection,
|
|
1024
|
+
inputRef: React.RefObject<null | TextInputInstance>,
|
|
1025
|
+
text?: string,
|
|
1026
|
+
viewCommands: ViewCommands,
|
|
1027
|
+
}): {
|
|
1028
|
+
setLastNativeText: string => void,
|
|
1029
|
+
setLastNativeSelection: LastNativeSelection => void,
|
|
1030
|
+
} {
|
|
1031
|
+
const [lastNativeText, setLastNativeText] = useState<?Stringish>(props.value);
|
|
1032
|
+
const [lastNativeSelectionState, setLastNativeSelection] =
|
|
1033
|
+
useState<LastNativeSelection>({
|
|
1034
|
+
selection: {start: -1, end: -1},
|
|
1035
|
+
mostRecentEventCount: mostRecentEventCount,
|
|
1036
|
+
});
|
|
1037
|
+
|
|
1038
|
+
const lastNativeSelection = lastNativeSelectionState.selection;
|
|
1039
|
+
|
|
1040
|
+
// This is necessary in case native updates the text and JS decides
|
|
1041
|
+
// that the update should be ignored and we should stick with the value
|
|
1042
|
+
// that we have in JS.
|
|
1043
|
+
useLayoutEffect(() => {
|
|
1044
|
+
const nativeUpdate: {text?: string, selection?: Selection} = {};
|
|
1045
|
+
|
|
1046
|
+
if (lastNativeText !== props.value && typeof props.value === 'string') {
|
|
1047
|
+
nativeUpdate.text = props.value;
|
|
1048
|
+
setLastNativeText(props.value);
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
if (
|
|
1052
|
+
selection &&
|
|
1053
|
+
lastNativeSelection &&
|
|
1054
|
+
(lastNativeSelection.start !== selection.start ||
|
|
1055
|
+
lastNativeSelection.end !== selection.end)
|
|
1056
|
+
) {
|
|
1057
|
+
nativeUpdate.selection = selection;
|
|
1058
|
+
setLastNativeSelection({selection, mostRecentEventCount});
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
if (Object.keys(nativeUpdate).length === 0) {
|
|
1062
|
+
return;
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
if (inputRef.current != null) {
|
|
1066
|
+
viewCommands.setTextAndSelection(
|
|
1067
|
+
inputRef.current,
|
|
1068
|
+
mostRecentEventCount,
|
|
1069
|
+
text,
|
|
1070
|
+
selection?.start ?? -1,
|
|
1071
|
+
selection?.end ?? -1,
|
|
1072
|
+
);
|
|
1073
|
+
}
|
|
1074
|
+
}, [
|
|
1075
|
+
mostRecentEventCount,
|
|
1076
|
+
inputRef,
|
|
1077
|
+
props.value,
|
|
1078
|
+
props.defaultValue,
|
|
1079
|
+
lastNativeText,
|
|
1080
|
+
selection,
|
|
1081
|
+
lastNativeSelection,
|
|
1082
|
+
text,
|
|
1083
|
+
viewCommands,
|
|
1084
|
+
]);
|
|
1085
|
+
|
|
1086
|
+
return {setLastNativeText, setLastNativeSelection};
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
/**
|
|
1090
|
+
* This hook handles the synchronization between the state of the text input
|
|
1091
|
+
* in native and in JavaScript. This is necessary due to the asynchronous nature
|
|
1092
|
+
* of text input events.
|
|
1093
|
+
*/
|
|
1094
|
+
function useTextInputStateSynchronization_REFS({
|
|
1095
|
+
props,
|
|
1096
|
+
mostRecentEventCount,
|
|
1097
|
+
selection,
|
|
1098
|
+
inputRef,
|
|
1099
|
+
text,
|
|
1100
|
+
viewCommands,
|
|
1101
|
+
}: {
|
|
1102
|
+
props: TextInputProps,
|
|
1103
|
+
mostRecentEventCount: number,
|
|
1104
|
+
selection: ?Selection,
|
|
1105
|
+
inputRef: React.RefObject<null | TextInputInstance>,
|
|
1106
|
+
text?: string,
|
|
1107
|
+
viewCommands: ViewCommands,
|
|
1108
|
+
}): {
|
|
1109
|
+
setLastNativeText: string => void,
|
|
1110
|
+
setLastNativeSelection: LastNativeSelection => void,
|
|
1111
|
+
} {
|
|
1112
|
+
const lastNativeTextRef = useRef<?Stringish>(props.value);
|
|
1113
|
+
const lastNativeSelectionRef = useRef<LastNativeSelection>({
|
|
1114
|
+
selection: {start: -1, end: -1},
|
|
1115
|
+
mostRecentEventCount: mostRecentEventCount,
|
|
1116
|
+
});
|
|
1117
|
+
|
|
1118
|
+
// This is necessary in case native updates the text and JS decides
|
|
1119
|
+
// that the update should be ignored and we should stick with the value
|
|
1120
|
+
// that we have in JS.
|
|
1121
|
+
useLayoutEffect(() => {
|
|
1122
|
+
const nativeUpdate: {text?: string, selection?: Selection} = {};
|
|
1123
|
+
|
|
1124
|
+
const lastNativeSelection = lastNativeSelectionRef.current.selection;
|
|
1125
|
+
|
|
1126
|
+
if (
|
|
1127
|
+
lastNativeTextRef.current !== props.value &&
|
|
1128
|
+
typeof props.value === 'string'
|
|
1129
|
+
) {
|
|
1130
|
+
nativeUpdate.text = props.value;
|
|
1131
|
+
lastNativeTextRef.current = props.value;
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
if (
|
|
1135
|
+
selection &&
|
|
1136
|
+
lastNativeSelection &&
|
|
1137
|
+
(lastNativeSelection.start !== selection.start ||
|
|
1138
|
+
lastNativeSelection.end !== selection.end)
|
|
1139
|
+
) {
|
|
1140
|
+
nativeUpdate.selection = selection;
|
|
1141
|
+
lastNativeSelectionRef.current = {selection, mostRecentEventCount};
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
if (Object.keys(nativeUpdate).length === 0) {
|
|
1145
|
+
return;
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
if (inputRef.current != null) {
|
|
1149
|
+
viewCommands.setTextAndSelection(
|
|
1150
|
+
inputRef.current,
|
|
1151
|
+
mostRecentEventCount,
|
|
1152
|
+
text,
|
|
1153
|
+
selection?.start ?? -1,
|
|
1154
|
+
selection?.end ?? -1,
|
|
1155
|
+
);
|
|
1156
|
+
}
|
|
1157
|
+
}, [
|
|
1158
|
+
mostRecentEventCount,
|
|
1159
|
+
inputRef,
|
|
1160
|
+
props.value,
|
|
1161
|
+
props.defaultValue,
|
|
1162
|
+
selection,
|
|
1163
|
+
text,
|
|
1164
|
+
viewCommands,
|
|
1165
|
+
]);
|
|
1166
|
+
|
|
1167
|
+
return {
|
|
1168
|
+
setLastNativeText: lastNativeText => {
|
|
1169
|
+
lastNativeTextRef.current = lastNativeText;
|
|
1170
|
+
},
|
|
1171
|
+
setLastNativeSelection: lastNativeSelection => {
|
|
1172
|
+
lastNativeSelectionRef.current = lastNativeSelection;
|
|
1173
|
+
},
|
|
1174
|
+
};
|
|
1175
|
+
}
|
|
1176
|
+
|
|
964
1177
|
/**
|
|
965
1178
|
* A foundational component for inputting text into the app via a
|
|
966
1179
|
* keyboard. Props provide configurability for several features, such as
|
|
@@ -1072,7 +1285,7 @@ const emptyFunctionThatReturnsTrue = () => true;
|
|
|
1072
1285
|
* or control this param programmatically with native code.
|
|
1073
1286
|
*
|
|
1074
1287
|
*/
|
|
1075
|
-
function InternalTextInput(props:
|
|
1288
|
+
function InternalTextInput(props: TextInputProps): React.Node {
|
|
1076
1289
|
const {
|
|
1077
1290
|
'aria-busy': ariaBusy,
|
|
1078
1291
|
'aria-checked': ariaChecked,
|
|
@@ -1089,9 +1302,8 @@ function InternalTextInput(props: Props): React.Node {
|
|
|
1089
1302
|
...otherProps
|
|
1090
1303
|
} = props;
|
|
1091
1304
|
|
|
1092
|
-
const inputRef = useRef<null |
|
|
1305
|
+
const inputRef = useRef<null | TextInputInstance>(null);
|
|
1093
1306
|
|
|
1094
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1095
1307
|
const selection: ?Selection =
|
|
1096
1308
|
propsSelection == null
|
|
1097
1309
|
? null
|
|
@@ -1100,80 +1312,33 @@ function InternalTextInput(props: Props): React.Node {
|
|
|
1100
1312
|
end: propsSelection.end ?? propsSelection.start,
|
|
1101
1313
|
};
|
|
1102
1314
|
|
|
1103
|
-
const [mostRecentEventCount, setMostRecentEventCount] = useState<number>(0);
|
|
1104
|
-
const [lastNativeText, setLastNativeText] = useState<?Stringish>(props.value);
|
|
1105
|
-
const [lastNativeSelectionState, setLastNativeSelection] = useState<{|
|
|
1106
|
-
selection: Selection,
|
|
1107
|
-
mostRecentEventCount: number,
|
|
1108
|
-
|}>({
|
|
1109
|
-
selection: {start: -1, end: -1},
|
|
1110
|
-
mostRecentEventCount: mostRecentEventCount,
|
|
1111
|
-
});
|
|
1112
|
-
|
|
1113
|
-
const lastNativeSelection = lastNativeSelectionState.selection;
|
|
1114
|
-
|
|
1115
|
-
let viewCommands;
|
|
1116
|
-
if (AndroidTextInputCommands) {
|
|
1117
|
-
viewCommands = AndroidTextInputCommands;
|
|
1118
|
-
} else {
|
|
1119
|
-
viewCommands =
|
|
1120
|
-
props.multiline === true
|
|
1121
|
-
? RCTMultilineTextInputNativeCommands
|
|
1122
|
-
: RCTSinglelineTextInputNativeCommands;
|
|
1123
|
-
}
|
|
1124
|
-
|
|
1125
1315
|
const text =
|
|
1126
1316
|
typeof props.value === 'string'
|
|
1127
1317
|
? props.value
|
|
1128
1318
|
: typeof props.defaultValue === 'string'
|
|
1129
1319
|
? props.defaultValue
|
|
1130
|
-
:
|
|
1320
|
+
: undefined;
|
|
1131
1321
|
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1322
|
+
const viewCommands =
|
|
1323
|
+
AndroidTextInputCommands ||
|
|
1324
|
+
(props.multiline === true
|
|
1325
|
+
? RCTMultilineTextInputNativeCommands
|
|
1326
|
+
: RCTSinglelineTextInputNativeCommands);
|
|
1137
1327
|
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
}
|
|
1152
|
-
|
|
1153
|
-
if (Object.keys(nativeUpdate).length === 0) {
|
|
1154
|
-
return;
|
|
1155
|
-
}
|
|
1156
|
-
|
|
1157
|
-
if (inputRef.current != null) {
|
|
1158
|
-
viewCommands.setTextAndSelection(
|
|
1159
|
-
inputRef.current,
|
|
1160
|
-
mostRecentEventCount,
|
|
1161
|
-
text,
|
|
1162
|
-
selection?.start ?? -1,
|
|
1163
|
-
selection?.end ?? -1,
|
|
1164
|
-
);
|
|
1165
|
-
}
|
|
1166
|
-
}, [
|
|
1167
|
-
mostRecentEventCount,
|
|
1168
|
-
inputRef,
|
|
1169
|
-
props.value,
|
|
1170
|
-
props.defaultValue,
|
|
1171
|
-
lastNativeText,
|
|
1172
|
-
selection,
|
|
1173
|
-
lastNativeSelection,
|
|
1174
|
-
text,
|
|
1175
|
-
viewCommands,
|
|
1176
|
-
]);
|
|
1328
|
+
const [mostRecentEventCount, setMostRecentEventCount] = useState<number>(0);
|
|
1329
|
+
const useTextInputStateSynchronization =
|
|
1330
|
+
ReactNativeFeatureFlags.useRefsForTextInputState()
|
|
1331
|
+
? useTextInputStateSynchronization_REFS
|
|
1332
|
+
: useTextInputStateSynchronization_STATE;
|
|
1333
|
+
const {setLastNativeText, setLastNativeSelection} =
|
|
1334
|
+
useTextInputStateSynchronization({
|
|
1335
|
+
props,
|
|
1336
|
+
inputRef,
|
|
1337
|
+
mostRecentEventCount,
|
|
1338
|
+
selection,
|
|
1339
|
+
text,
|
|
1340
|
+
viewCommands,
|
|
1341
|
+
});
|
|
1177
1342
|
|
|
1178
1343
|
useLayoutEffect(() => {
|
|
1179
1344
|
const inputRefValue = inputRef.current;
|
|
@@ -1189,10 +1354,11 @@ function InternalTextInput(props: Props): React.Node {
|
|
|
1189
1354
|
}
|
|
1190
1355
|
};
|
|
1191
1356
|
}
|
|
1192
|
-
}, [
|
|
1357
|
+
}, []);
|
|
1193
1358
|
|
|
1194
1359
|
const setLocalRef = useCallback(
|
|
1195
|
-
(instance:
|
|
1360
|
+
(instance: HostInstance | null) => {
|
|
1361
|
+
// $FlowExpectedError[incompatible-type]
|
|
1196
1362
|
inputRef.current = instance;
|
|
1197
1363
|
|
|
1198
1364
|
/*
|
|
@@ -1218,7 +1384,7 @@ function InternalTextInput(props: Props): React.Node {
|
|
|
1218
1384
|
before we can get to the long term breaking change.
|
|
1219
1385
|
*/
|
|
1220
1386
|
if (instance != null) {
|
|
1221
|
-
// $FlowFixMe[
|
|
1387
|
+
// $FlowFixMe[prop-missing] - See the explanation above.
|
|
1222
1388
|
Object.assign(instance, {
|
|
1223
1389
|
clear(): void {
|
|
1224
1390
|
if (inputRef.current != null) {
|
|
@@ -1235,7 +1401,7 @@ function InternalTextInput(props: Props): React.Node {
|
|
|
1235
1401
|
isFocused(): boolean {
|
|
1236
1402
|
return TextInputState.currentlyFocusedInput() === inputRef.current;
|
|
1237
1403
|
},
|
|
1238
|
-
getNativeRef(): ?
|
|
1404
|
+
getNativeRef(): ?TextInputInstance {
|
|
1239
1405
|
return inputRef.current;
|
|
1240
1406
|
},
|
|
1241
1407
|
setSelection(start: number, end: number): void {
|
|
@@ -1255,9 +1421,10 @@ function InternalTextInput(props: Props): React.Node {
|
|
|
1255
1421
|
[mostRecentEventCount, viewCommands],
|
|
1256
1422
|
);
|
|
1257
1423
|
|
|
1258
|
-
|
|
1424
|
+
// $FlowExpectedError[incompatible-call]
|
|
1425
|
+
const ref = useMergeRefs<HostInstance>(setLocalRef, props.forwardedRef);
|
|
1259
1426
|
|
|
1260
|
-
const _onChange = (event:
|
|
1427
|
+
const _onChange = (event: TextInputChangeEvent) => {
|
|
1261
1428
|
const currentText = event.nativeEvent.text;
|
|
1262
1429
|
props.onChange && props.onChange(event);
|
|
1263
1430
|
props.onChangeText && props.onChangeText(currentText);
|
|
@@ -1276,7 +1443,7 @@ function InternalTextInput(props: Props): React.Node {
|
|
|
1276
1443
|
setMostRecentEventCount(event.nativeEvent.eventCount);
|
|
1277
1444
|
};
|
|
1278
1445
|
|
|
1279
|
-
const _onSelectionChange = (event:
|
|
1446
|
+
const _onSelectionChange = (event: TextInputSelectionChangeEvent) => {
|
|
1280
1447
|
props.onSelectionChange && props.onSelectionChange(event);
|
|
1281
1448
|
|
|
1282
1449
|
if (inputRef.current == null) {
|
|
@@ -1291,14 +1458,14 @@ function InternalTextInput(props: Props): React.Node {
|
|
|
1291
1458
|
});
|
|
1292
1459
|
};
|
|
1293
1460
|
|
|
1294
|
-
const _onFocus = (event:
|
|
1461
|
+
const _onFocus = (event: TextInputFocusEvent) => {
|
|
1295
1462
|
TextInputState.focusInput(inputRef.current);
|
|
1296
1463
|
if (props.onFocus) {
|
|
1297
1464
|
props.onFocus(event);
|
|
1298
1465
|
}
|
|
1299
1466
|
};
|
|
1300
1467
|
|
|
1301
|
-
const _onBlur = (event:
|
|
1468
|
+
const _onBlur = (event: TextInputBlurEvent) => {
|
|
1302
1469
|
TextInputState.blurInput(inputRef.current);
|
|
1303
1470
|
if (props.onBlur) {
|
|
1304
1471
|
props.onBlur(event);
|
|
@@ -1352,7 +1519,7 @@ function InternalTextInput(props: Props): React.Node {
|
|
|
1352
1519
|
const config = React.useMemo(
|
|
1353
1520
|
() => ({
|
|
1354
1521
|
hitSlop,
|
|
1355
|
-
onPress: (event:
|
|
1522
|
+
onPress: (event: GestureResponderEvent) => {
|
|
1356
1523
|
onPress?.(event);
|
|
1357
1524
|
if (editable !== false) {
|
|
1358
1525
|
if (inputRef.current != null) {
|
|
@@ -1383,7 +1550,7 @@ function InternalTextInput(props: Props): React.Node {
|
|
|
1383
1550
|
|
|
1384
1551
|
// TextInput handles onBlur and onFocus events
|
|
1385
1552
|
// so omitting onBlur and onFocus pressability handlers here.
|
|
1386
|
-
const {onBlur, onFocus, ...eventHandlers} = usePressability(config)
|
|
1553
|
+
const {onBlur, onFocus, ...eventHandlers} = usePressability(config);
|
|
1387
1554
|
|
|
1388
1555
|
let _accessibilityState;
|
|
1389
1556
|
if (
|
|
@@ -1403,12 +1570,29 @@ function InternalTextInput(props: Props): React.Node {
|
|
|
1403
1570
|
};
|
|
1404
1571
|
}
|
|
1405
1572
|
|
|
1406
|
-
|
|
1573
|
+
// Keep the original (potentially nested) style when possible, as React can diff these more efficiently
|
|
1574
|
+
let _style = props.style;
|
|
1575
|
+
const flattenedStyle = flattenStyle<TextStyleProp>(props.style);
|
|
1576
|
+
if (flattenedStyle != null) {
|
|
1577
|
+
let overrides: ?{...TextStyleInternal} = null;
|
|
1578
|
+
if (typeof flattenedStyle?.fontWeight === 'number') {
|
|
1579
|
+
overrides = overrides || ({}: {...TextStyleInternal});
|
|
1580
|
+
overrides.fontWeight =
|
|
1581
|
+
// $FlowFixMe[incompatible-cast]
|
|
1582
|
+
(flattenedStyle.fontWeight.toString(): TextStyleInternal['fontWeight']);
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1585
|
+
if (flattenedStyle.verticalAlign != null) {
|
|
1586
|
+
overrides = overrides || ({}: {...TextStyleInternal});
|
|
1587
|
+
overrides.textAlignVertical =
|
|
1588
|
+
verticalAlignToTextAlignVerticalMap[flattenedStyle.verticalAlign];
|
|
1589
|
+
overrides.verticalAlign = undefined;
|
|
1590
|
+
}
|
|
1407
1591
|
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1592
|
+
if (overrides != null) {
|
|
1593
|
+
// $FlowFixMe[incompatible-type]
|
|
1594
|
+
_style = [_style, overrides];
|
|
1595
|
+
}
|
|
1412
1596
|
}
|
|
1413
1597
|
|
|
1414
1598
|
if (Platform.OS === 'ios') {
|
|
@@ -1419,15 +1603,15 @@ function InternalTextInput(props: Props): React.Node {
|
|
|
1419
1603
|
|
|
1420
1604
|
const useMultilineDefaultStyle =
|
|
1421
1605
|
props.multiline === true &&
|
|
1422
|
-
(
|
|
1423
|
-
(
|
|
1424
|
-
|
|
1425
|
-
|
|
1606
|
+
(flattenedStyle == null ||
|
|
1607
|
+
(flattenedStyle.padding == null &&
|
|
1608
|
+
flattenedStyle.paddingVertical == null &&
|
|
1609
|
+
flattenedStyle.paddingTop == null));
|
|
1426
1610
|
|
|
1427
1611
|
textInput = (
|
|
1428
1612
|
<RCTTextInputView
|
|
1429
|
-
//
|
|
1430
|
-
ref={ref}
|
|
1613
|
+
// Figure out imperative + forward refs.
|
|
1614
|
+
ref={(ref: $FlowFixMe)}
|
|
1431
1615
|
{...otherProps}
|
|
1432
1616
|
{...eventHandlers}
|
|
1433
1617
|
accessibilityState={_accessibilityState}
|
|
@@ -1438,6 +1622,7 @@ function InternalTextInput(props: Props): React.Node {
|
|
|
1438
1622
|
focusable={tabIndex !== undefined ? !tabIndex : focusable}
|
|
1439
1623
|
mostRecentEventCount={mostRecentEventCount}
|
|
1440
1624
|
nativeID={id ?? props.nativeID}
|
|
1625
|
+
numberOfLines={props.rows ?? props.numberOfLines}
|
|
1441
1626
|
onBlur={_onBlur}
|
|
1442
1627
|
onChange={_onChange}
|
|
1443
1628
|
onContentSizeChange={props.onContentSizeChange}
|
|
@@ -1449,7 +1634,7 @@ function InternalTextInput(props: Props): React.Node {
|
|
|
1449
1634
|
selectionColor={selectionColor}
|
|
1450
1635
|
style={StyleSheet.compose(
|
|
1451
1636
|
useMultilineDefaultStyle ? styles.multilineDefault : null,
|
|
1452
|
-
|
|
1637
|
+
_style,
|
|
1453
1638
|
)}
|
|
1454
1639
|
text={text}
|
|
1455
1640
|
/>
|
|
@@ -1477,6 +1662,7 @@ function InternalTextInput(props: Props): React.Node {
|
|
|
1477
1662
|
: selectionHandleColor,
|
|
1478
1663
|
cursorColor: cursorColor === undefined ? selectionColor : cursorColor,
|
|
1479
1664
|
};
|
|
1665
|
+
const { onPaste, ...rest } = otherProps;
|
|
1480
1666
|
textInput = (
|
|
1481
1667
|
/* $FlowFixMe[prop-missing] the types for AndroidTextInput don't match up
|
|
1482
1668
|
* exactly with the props for TextInput. This will need to get fixed */
|
|
@@ -1487,11 +1673,12 @@ function InternalTextInput(props: Props): React.Node {
|
|
|
1487
1673
|
* match up exactly with the props for TextInput. This will need to get
|
|
1488
1674
|
* fixed */
|
|
1489
1675
|
<AndroidTextInput
|
|
1490
|
-
//
|
|
1491
|
-
ref={ref}
|
|
1492
|
-
{...
|
|
1676
|
+
// Figure out imperative + forward refs.
|
|
1677
|
+
ref={(ref: $FlowFixMe)}
|
|
1678
|
+
{...rest}
|
|
1493
1679
|
{...colorProps}
|
|
1494
1680
|
{...eventHandlers}
|
|
1681
|
+
onPaste={onPaste}
|
|
1495
1682
|
accessibilityState={_accessibilityState}
|
|
1496
1683
|
accessibilityLabelledBy={_accessibilityLabelledBy}
|
|
1497
1684
|
accessible={accessible}
|
|
@@ -1516,7 +1703,7 @@ function InternalTextInput(props: Props): React.Node {
|
|
|
1516
1703
|
onScroll={_onScroll}
|
|
1517
1704
|
onSelectionChange={_onSelectionChange}
|
|
1518
1705
|
placeholder={placeholder}
|
|
1519
|
-
style={
|
|
1706
|
+
style={_style}
|
|
1520
1707
|
text={text}
|
|
1521
1708
|
textBreakStrategy={props.textBreakStrategy}
|
|
1522
1709
|
/>
|
|
@@ -1622,11 +1809,10 @@ const autoCompleteWebToTextContentTypeMap = {
|
|
|
1622
1809
|
username: 'username',
|
|
1623
1810
|
};
|
|
1624
1811
|
|
|
1625
|
-
const ExportedForwardRef:
|
|
1626
|
-
React.
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
> = React.forwardRef(function TextInput(
|
|
1812
|
+
const ExportedForwardRef: component(
|
|
1813
|
+
ref: React.RefSetter<TextInputInstance>,
|
|
1814
|
+
...props: React.ElementConfig<typeof InternalTextInput>
|
|
1815
|
+
) = React.forwardRef(function TextInput(
|
|
1630
1816
|
{
|
|
1631
1817
|
allowFontScaling = true,
|
|
1632
1818
|
rejectResponderTermination = true,
|
|
@@ -1642,22 +1828,8 @@ const ExportedForwardRef: React.AbstractComponent<
|
|
|
1642
1828
|
keyboardType,
|
|
1643
1829
|
...restProps
|
|
1644
1830
|
},
|
|
1645
|
-
forwardedRef:
|
|
1831
|
+
forwardedRef: React.RefSetter<TextInputInstance>,
|
|
1646
1832
|
) {
|
|
1647
|
-
// $FlowFixMe[underconstrained-implicit-instantiation]
|
|
1648
|
-
let style = flattenStyle(restProps.style);
|
|
1649
|
-
|
|
1650
|
-
if (style?.verticalAlign != null) {
|
|
1651
|
-
// $FlowFixMe[prop-missing]
|
|
1652
|
-
// $FlowFixMe[cannot-write]
|
|
1653
|
-
style.textAlignVertical =
|
|
1654
|
-
// $FlowFixMe[invalid-computed-prop]
|
|
1655
|
-
verticalAlignToTextAlignVerticalMap[style.verticalAlign];
|
|
1656
|
-
// $FlowFixMe[prop-missing]
|
|
1657
|
-
// $FlowFixMe[cannot-write]
|
|
1658
|
-
delete style.verticalAlign;
|
|
1659
|
-
}
|
|
1660
|
-
|
|
1661
1833
|
return (
|
|
1662
1834
|
<InternalTextInput
|
|
1663
1835
|
allowFontScaling={allowFontScaling}
|
|
@@ -1694,7 +1866,6 @@ const ExportedForwardRef: React.AbstractComponent<
|
|
|
1694
1866
|
}
|
|
1695
1867
|
{...restProps}
|
|
1696
1868
|
forwardedRef={forwardedRef}
|
|
1697
|
-
style={style}
|
|
1698
1869
|
/>
|
|
1699
1870
|
);
|
|
1700
1871
|
});
|
|
@@ -1710,14 +1881,14 @@ ExportedForwardRef.State = {
|
|
|
1710
1881
|
blurTextInput: TextInputState.blurTextInput,
|
|
1711
1882
|
};
|
|
1712
1883
|
|
|
1713
|
-
export type TextInputComponentStatics = $ReadOnly<{
|
|
1714
|
-
State: $ReadOnly<{
|
|
1884
|
+
export type TextInputComponentStatics = $ReadOnly<{
|
|
1885
|
+
State: $ReadOnly<{
|
|
1715
1886
|
currentlyFocusedInput: typeof TextInputState.currentlyFocusedInput,
|
|
1716
1887
|
currentlyFocusedField: typeof TextInputState.currentlyFocusedField,
|
|
1717
1888
|
focusTextInput: typeof TextInputState.focusTextInput,
|
|
1718
1889
|
blurTextInput: typeof TextInputState.blurTextInput,
|
|
1719
|
-
|
|
1720
|
-
|
|
1890
|
+
}>,
|
|
1891
|
+
}>;
|
|
1721
1892
|
|
|
1722
1893
|
const styles = StyleSheet.create({
|
|
1723
1894
|
multilineDefault: {
|
|
@@ -1736,4 +1907,4 @@ const verticalAlignToTextAlignVerticalMap = {
|
|
|
1736
1907
|
};
|
|
1737
1908
|
|
|
1738
1909
|
// $FlowFixMe[unclear-type] Unclear type. Using `any` type is not safe.
|
|
1739
|
-
|
|
1910
|
+
export default ExportedForwardRef as any as TextInputType;
|