react-native-platform-components 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -30
- package/android/src/main/java/com/platformcomponents/PCButtonGroupView.kt +498 -0
- package/android/src/main/java/com/platformcomponents/PCButtonGroupViewManager.kt +191 -0
- package/android/src/main/java/com/platformcomponents/PCButtonSupport.kt +127 -0
- package/android/src/main/java/com/platformcomponents/PCButtonView.kt +345 -0
- package/android/src/main/java/com/platformcomponents/PCButtonViewManager.kt +126 -0
- package/android/src/main/java/com/platformcomponents/PCExpressive.kt +107 -0
- package/android/src/main/java/com/platformcomponents/PCFloatingToolbarView.kt +115 -0
- package/android/src/main/java/com/platformcomponents/PCFloatingToolbarViewManager.kt +65 -0
- package/android/src/main/java/com/platformcomponents/PCSegmentedControlView.kt +11 -3
- package/android/src/main/java/com/platformcomponents/PCSegmentedControlViewManager.kt +6 -1
- package/android/src/main/java/com/platformcomponents/PCTextFieldView.kt +1018 -0
- package/android/src/main/java/com/platformcomponents/PCTextFieldViewManager.kt +248 -0
- package/android/src/main/java/com/platformcomponents/PlatformComponentsPackage.kt +4 -0
- package/android/src/main/res/values/attrs.xml +13 -0
- package/android/src/main/res/values/styles.xml +183 -0
- package/ios/PCButton.h +10 -0
- package/ios/PCButton.mm +196 -0
- package/ios/PCButtonGroup.h +10 -0
- package/ios/PCButtonGroup.mm +256 -0
- package/ios/PCButtonGroupView.swift +254 -0
- package/ios/PCButtonSupport.swift +141 -0
- package/ios/PCButtonView.swift +155 -0
- package/ios/PCFloatingToolbar.h +10 -0
- package/ios/PCFloatingToolbar.mm +76 -0
- package/ios/PCFloatingToolbarView.swift +95 -0
- package/ios/PCTextField.h +10 -0
- package/ios/PCTextField.mm +391 -0
- package/ios/PCTextFieldView.swift +1012 -0
- package/lib/commonjs/Button.js +77 -0
- package/lib/commonjs/Button.js.map +1 -0
- package/lib/commonjs/ButtonGroup.js +99 -0
- package/lib/commonjs/ButtonGroup.js.map +1 -0
- package/lib/commonjs/ButtonGroupNativeComponent.ts +121 -0
- package/lib/commonjs/ButtonNativeComponent.ts +76 -0
- package/lib/commonjs/FloatingToolbar.js +69 -0
- package/lib/commonjs/FloatingToolbar.js.map +1 -0
- package/lib/commonjs/FloatingToolbarNativeComponent.ts +31 -0
- package/lib/commonjs/SegmentedControl.js +11 -85
- package/lib/commonjs/SegmentedControl.js.map +1 -1
- package/lib/commonjs/SegmentedControlNativeComponent.ts +3 -0
- package/lib/commonjs/TextField.js +195 -0
- package/lib/commonjs/TextField.js.map +1 -0
- package/lib/commonjs/TextFieldNativeComponent.ts +218 -0
- package/lib/commonjs/focusRegistry.js +78 -0
- package/lib/commonjs/focusRegistry.js.map +1 -0
- package/lib/commonjs/icons.js +92 -0
- package/lib/commonjs/icons.js.map +1 -0
- package/lib/commonjs/index.js +66 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/index.web.js +32 -2
- package/lib/commonjs/index.web.js.map +1 -1
- package/lib/commonjs/labelStyle.js +27 -0
- package/lib/commonjs/labelStyle.js.map +1 -0
- package/lib/commonjs/reactNativeInternals.d.js +2 -0
- package/lib/commonjs/reactNativeInternals.d.js.map +1 -0
- package/lib/module/Button.js +70 -0
- package/lib/module/Button.js.map +1 -0
- package/lib/module/ButtonGroup.js +92 -0
- package/lib/module/ButtonGroup.js.map +1 -0
- package/lib/module/ButtonGroupNativeComponent.ts +121 -0
- package/lib/module/ButtonNativeComponent.ts +76 -0
- package/lib/module/FloatingToolbar.js +62 -0
- package/lib/module/FloatingToolbar.js.map +1 -0
- package/lib/module/FloatingToolbarNativeComponent.ts +31 -0
- package/lib/module/SegmentedControl.js +12 -87
- package/lib/module/SegmentedControl.js.map +1 -1
- package/lib/module/SegmentedControlNativeComponent.ts +3 -0
- package/lib/module/TextField.js +189 -0
- package/lib/module/TextField.js.map +1 -0
- package/lib/module/TextFieldNativeComponent.ts +218 -0
- package/lib/module/focusRegistry.js +74 -0
- package/lib/module/focusRegistry.js.map +1 -0
- package/lib/module/icons.js +87 -0
- package/lib/module/icons.js.map +1 -0
- package/lib/module/index.js +6 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +28 -0
- package/lib/module/index.web.js.map +1 -1
- package/lib/module/labelStyle.js +23 -0
- package/lib/module/labelStyle.js.map +1 -0
- package/lib/module/reactNativeInternals.d.js +2 -0
- package/lib/module/reactNativeInternals.d.js.map +1 -0
- package/lib/typescript/commonjs/docs/sidebars.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/Button.d.ts +76 -0
- package/lib/typescript/commonjs/src/Button.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/ButtonGroup.d.ts +102 -0
- package/lib/typescript/commonjs/src/ButtonGroup.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/ButtonGroupNativeComponent.d.ts +93 -0
- package/lib/typescript/commonjs/src/ButtonGroupNativeComponent.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/ButtonNativeComponent.d.ts +57 -0
- package/lib/typescript/commonjs/src/ButtonNativeComponent.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/FloatingToolbar.d.ts +45 -0
- package/lib/typescript/commonjs/src/FloatingToolbar.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/FloatingToolbarNativeComponent.d.ts +24 -0
- package/lib/typescript/commonjs/src/FloatingToolbarNativeComponent.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/SegmentedControl.d.ts +17 -46
- package/lib/typescript/commonjs/src/SegmentedControl.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/SegmentedControlNativeComponent.d.ts +2 -0
- package/lib/typescript/commonjs/src/SegmentedControlNativeComponent.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/TextField.d.ts +174 -0
- package/lib/typescript/commonjs/src/TextField.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/TextFieldNativeComponent.d.ts +162 -0
- package/lib/typescript/commonjs/src/TextFieldNativeComponent.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/focusRegistry.d.ts +13 -0
- package/lib/typescript/commonjs/src/focusRegistry.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/icons.d.ts +52 -0
- package/lib/typescript/commonjs/src/icons.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/index.d.ts +6 -0
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/index.web.d.ts +121 -0
- package/lib/typescript/commonjs/src/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/labelStyle.d.ts +20 -0
- package/lib/typescript/commonjs/src/labelStyle.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/sharedTypes.d.ts +6 -1
- package/lib/typescript/commonjs/src/sharedTypes.d.ts.map +1 -1
- package/lib/typescript/module/docs/sidebars.d.ts.map +1 -1
- package/lib/typescript/module/src/Button.d.ts +76 -0
- package/lib/typescript/module/src/Button.d.ts.map +1 -0
- package/lib/typescript/module/src/ButtonGroup.d.ts +102 -0
- package/lib/typescript/module/src/ButtonGroup.d.ts.map +1 -0
- package/lib/typescript/module/src/ButtonGroupNativeComponent.d.ts +93 -0
- package/lib/typescript/module/src/ButtonGroupNativeComponent.d.ts.map +1 -0
- package/lib/typescript/module/src/ButtonNativeComponent.d.ts +57 -0
- package/lib/typescript/module/src/ButtonNativeComponent.d.ts.map +1 -0
- package/lib/typescript/module/src/FloatingToolbar.d.ts +45 -0
- package/lib/typescript/module/src/FloatingToolbar.d.ts.map +1 -0
- package/lib/typescript/module/src/FloatingToolbarNativeComponent.d.ts +24 -0
- package/lib/typescript/module/src/FloatingToolbarNativeComponent.d.ts.map +1 -0
- package/lib/typescript/module/src/SegmentedControl.d.ts +17 -46
- package/lib/typescript/module/src/SegmentedControl.d.ts.map +1 -1
- package/lib/typescript/module/src/SegmentedControlNativeComponent.d.ts +2 -0
- package/lib/typescript/module/src/SegmentedControlNativeComponent.d.ts.map +1 -1
- package/lib/typescript/module/src/TextField.d.ts +174 -0
- package/lib/typescript/module/src/TextField.d.ts.map +1 -0
- package/lib/typescript/module/src/TextFieldNativeComponent.d.ts +162 -0
- package/lib/typescript/module/src/TextFieldNativeComponent.d.ts.map +1 -0
- package/lib/typescript/module/src/focusRegistry.d.ts +13 -0
- package/lib/typescript/module/src/focusRegistry.d.ts.map +1 -0
- package/lib/typescript/module/src/icons.d.ts +52 -0
- package/lib/typescript/module/src/icons.d.ts.map +1 -0
- package/lib/typescript/module/src/index.d.ts +6 -0
- package/lib/typescript/module/src/index.d.ts.map +1 -1
- package/lib/typescript/module/src/index.web.d.ts +121 -0
- package/lib/typescript/module/src/index.web.d.ts.map +1 -1
- package/lib/typescript/module/src/labelStyle.d.ts +20 -0
- package/lib/typescript/module/src/labelStyle.d.ts.map +1 -0
- package/lib/typescript/module/src/sharedTypes.d.ts +6 -1
- package/lib/typescript/module/src/sharedTypes.d.ts.map +1 -1
- package/package.json +25 -4
- package/react-native.config.js +3 -0
- package/shared/PCButtonComponentDescriptors-custom.h +22 -0
- package/shared/PCButtonGroupComponentDescriptors-custom.h +22 -0
- package/shared/PCButtonGroupShadowNode-custom.cpp +48 -0
- package/shared/PCButtonGroupShadowNode-custom.h +55 -0
- package/shared/PCButtonGroupState-custom.h +61 -0
- package/shared/PCButtonShadowNode-custom.cpp +48 -0
- package/shared/PCButtonShadowNode-custom.h +55 -0
- package/shared/PCButtonState-custom.h +61 -0
- package/shared/PCTextFieldComponentDescriptors-custom.h +22 -0
- package/shared/PCTextFieldShadowNode-custom.cpp +47 -0
- package/shared/PCTextFieldShadowNode-custom.h +55 -0
- package/shared/PCTextFieldState-custom.h +61 -0
- package/shared/react/renderer/components/PlatformComponentsViewSpec/ComponentDescriptors.h +3 -0
- package/src/Button.tsx +144 -0
- package/src/ButtonGroup.tsx +233 -0
- package/src/ButtonGroupNativeComponent.ts +121 -0
- package/src/ButtonNativeComponent.ts +76 -0
- package/src/FloatingToolbar.tsx +113 -0
- package/src/FloatingToolbarNativeComponent.ts +31 -0
- package/src/SegmentedControl.tsx +26 -118
- package/src/SegmentedControlNativeComponent.ts +3 -0
- package/src/TextField.tsx +494 -0
- package/src/TextFieldNativeComponent.ts +218 -0
- package/src/focusRegistry.ts +89 -0
- package/src/icons.ts +116 -0
- package/src/index.tsx +6 -0
- package/src/index.web.tsx +194 -0
- package/src/labelStyle.ts +36 -0
- package/src/reactNativeInternals.d.ts +22 -0
- package/src/sharedTypes.ts +7 -1
|
@@ -0,0 +1,494 @@
|
|
|
1
|
+
// TextField.tsx
|
|
2
|
+
import React, {
|
|
3
|
+
forwardRef,
|
|
4
|
+
useCallback,
|
|
5
|
+
useImperativeHandle,
|
|
6
|
+
useLayoutEffect,
|
|
7
|
+
useMemo,
|
|
8
|
+
useRef,
|
|
9
|
+
useState,
|
|
10
|
+
} from 'react';
|
|
11
|
+
import type { NativeSyntheticEvent, ViewProps } from 'react-native';
|
|
12
|
+
|
|
13
|
+
import NativeTextField, {
|
|
14
|
+
Commands,
|
|
15
|
+
type TextFieldChangeEvent as NativeChangeEvent,
|
|
16
|
+
type TextFieldTextEvent as NativeTextEvent,
|
|
17
|
+
} from './TextFieldNativeComponent';
|
|
18
|
+
import { resolveIcon, type PlatformIcon } from './icons';
|
|
19
|
+
import { normalizeLabelStyle, type LabelStyle } from './labelStyle';
|
|
20
|
+
import { focusRegistry } from './focusRegistry';
|
|
21
|
+
import type { AndroidMaterialMode } from './sharedTypes';
|
|
22
|
+
|
|
23
|
+
/** Keyboard to show; the React Native `TextInput` values. */
|
|
24
|
+
export type TextFieldKeyboardType =
|
|
25
|
+
| 'default'
|
|
26
|
+
| 'number-pad'
|
|
27
|
+
| 'decimal-pad'
|
|
28
|
+
| 'numeric'
|
|
29
|
+
| 'email-address'
|
|
30
|
+
| 'phone-pad'
|
|
31
|
+
| 'url'
|
|
32
|
+
| 'ascii-capable'
|
|
33
|
+
| 'numbers-and-punctuation'
|
|
34
|
+
| 'name-phone-pad'
|
|
35
|
+
| 'twitter'
|
|
36
|
+
| 'web-search'
|
|
37
|
+
| 'visible-password';
|
|
38
|
+
|
|
39
|
+
/** Return key label; the React Native `TextInput` values. */
|
|
40
|
+
export type TextFieldReturnKeyType =
|
|
41
|
+
'default' | 'done' | 'go' | 'next' | 'search' | 'send' | 'none' | 'previous';
|
|
42
|
+
|
|
43
|
+
/** Autofill hint; a cross-platform subset of the React Native `TextInput` values. */
|
|
44
|
+
export type TextFieldAutoComplete =
|
|
45
|
+
| 'off'
|
|
46
|
+
| 'username'
|
|
47
|
+
| 'password'
|
|
48
|
+
| 'new-password'
|
|
49
|
+
| 'one-time-code'
|
|
50
|
+
| 'email'
|
|
51
|
+
| 'name'
|
|
52
|
+
| 'given-name'
|
|
53
|
+
| 'family-name'
|
|
54
|
+
| 'tel'
|
|
55
|
+
| 'street-address'
|
|
56
|
+
| 'postal-code'
|
|
57
|
+
| 'country'
|
|
58
|
+
| 'cc-number'
|
|
59
|
+
| 'cc-exp'
|
|
60
|
+
| 'cc-csc'
|
|
61
|
+
| 'url';
|
|
62
|
+
|
|
63
|
+
export type TextFieldAutoCapitalize =
|
|
64
|
+
'none' | 'sentences' | 'words' | 'characters';
|
|
65
|
+
|
|
66
|
+
export type TextFieldClearButtonMode =
|
|
67
|
+
'never' | 'while-editing' | 'unless-editing' | 'always';
|
|
68
|
+
|
|
69
|
+
/** An iOS text trait: the system default, on, or off. */
|
|
70
|
+
export type TextFieldIOSChoice = 'default' | 'yes' | 'no';
|
|
71
|
+
|
|
72
|
+
/** Focus, blur and submit events carry the text at that moment. */
|
|
73
|
+
export type TextFieldEvent = NativeSyntheticEvent<{ text: string }>;
|
|
74
|
+
|
|
75
|
+
/** Change events carry the text and the native edit counter. */
|
|
76
|
+
export type TextFieldChangeEvent = NativeSyntheticEvent<{
|
|
77
|
+
text: string;
|
|
78
|
+
eventCount: number;
|
|
79
|
+
}>;
|
|
80
|
+
|
|
81
|
+
/** Methods available through the `ref`. */
|
|
82
|
+
export interface TextFieldRef {
|
|
83
|
+
/** Focuses the field and shows the keyboard. */
|
|
84
|
+
focus(): void;
|
|
85
|
+
/** Removes focus and hides the keyboard. */
|
|
86
|
+
blur(): void;
|
|
87
|
+
/** Clears the text. Fires `onChangeText('')`. */
|
|
88
|
+
clear(): void;
|
|
89
|
+
/** Whether the field currently has focus. */
|
|
90
|
+
isFocused(): boolean;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface TextFieldProps extends Omit<
|
|
94
|
+
ViewProps,
|
|
95
|
+
'onFocus' | 'onBlur' | 'children'
|
|
96
|
+
> {
|
|
97
|
+
/**
|
|
98
|
+
* Controlled text. Native keeps what the user typed until the next
|
|
99
|
+
* `onChangeText` round-trip, so updating state from `onChangeText` never
|
|
100
|
+
* drops characters.
|
|
101
|
+
*/
|
|
102
|
+
value?: string;
|
|
103
|
+
|
|
104
|
+
/** Initial text of an uncontrolled field. */
|
|
105
|
+
defaultValue?: string;
|
|
106
|
+
|
|
107
|
+
/** Called with the new text on every edit. */
|
|
108
|
+
onChangeText?: (text: string) => void;
|
|
109
|
+
|
|
110
|
+
/** Called on every edit with the native event. */
|
|
111
|
+
onChange?: (event: TextFieldChangeEvent) => void;
|
|
112
|
+
|
|
113
|
+
/** Called when the field gains focus. */
|
|
114
|
+
onFocus?: (event: TextFieldEvent) => void;
|
|
115
|
+
|
|
116
|
+
/** Called when the field loses focus. */
|
|
117
|
+
onBlur?: (event: TextFieldEvent) => void;
|
|
118
|
+
|
|
119
|
+
/** Called when the return key is pressed. Single-line fields only. */
|
|
120
|
+
onSubmitEditing?: (event: TextFieldEvent) => void;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Field label. Android: the Material floating label. iOS: a caption above
|
|
124
|
+
* the field, which takes the tint color while focused.
|
|
125
|
+
*/
|
|
126
|
+
label?: string;
|
|
127
|
+
|
|
128
|
+
/** Placeholder shown while the field is empty. */
|
|
129
|
+
placeholder?: string;
|
|
130
|
+
|
|
131
|
+
/** Helper text below the field. */
|
|
132
|
+
supportingText?: string;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Error state. A string is shown below the field in place of the
|
|
136
|
+
* supporting text; `true` marks the field as invalid and keeps the
|
|
137
|
+
* supporting text.
|
|
138
|
+
*/
|
|
139
|
+
error?: boolean | string;
|
|
140
|
+
|
|
141
|
+
/** Text shown before the input, inside the field (a currency sign). */
|
|
142
|
+
prefix?: string;
|
|
143
|
+
|
|
144
|
+
/** Text shown after the input, inside the field (a unit). */
|
|
145
|
+
suffix?: string;
|
|
146
|
+
|
|
147
|
+
/** Icon at the start of the field. */
|
|
148
|
+
leadingIcon?: PlatformIcon;
|
|
149
|
+
|
|
150
|
+
/** Icon at the end of the field. Pressing it calls `onTrailingIconPress`. */
|
|
151
|
+
trailingIcon?: PlatformIcon;
|
|
152
|
+
|
|
153
|
+
/** Called when the trailing icon is pressed. */
|
|
154
|
+
onTrailingIconPress?: () => void;
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* When to show a clear button inside the field. Default: `'never'`.
|
|
158
|
+
* Android shows the Material clear icon while the field has text.
|
|
159
|
+
*/
|
|
160
|
+
clearButtonMode?: TextFieldClearButtonMode;
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Shows a button that toggles `secureTextEntry`, for password fields.
|
|
164
|
+
* Android: the Material password toggle. iOS: an eye button.
|
|
165
|
+
*/
|
|
166
|
+
passwordToggle?: boolean;
|
|
167
|
+
|
|
168
|
+
/** Shows the character count below the field (`12 / 100` with `maxLength`). */
|
|
169
|
+
showCharacterCount?: boolean;
|
|
170
|
+
|
|
171
|
+
/** Maximum number of characters. */
|
|
172
|
+
maxLength?: number;
|
|
173
|
+
|
|
174
|
+
/** Keyboard to show. Default: `'default'`. */
|
|
175
|
+
keyboardType?: TextFieldKeyboardType;
|
|
176
|
+
|
|
177
|
+
/** Return key label. Default: `'default'`. */
|
|
178
|
+
returnKeyType?: TextFieldReturnKeyType;
|
|
179
|
+
|
|
180
|
+
/** Automatic capitalization. Default: `'sentences'`. */
|
|
181
|
+
autoCapitalize?: TextFieldAutoCapitalize;
|
|
182
|
+
|
|
183
|
+
/** Auto-correction and suggestions. Default: `true`. */
|
|
184
|
+
autoCorrect?: boolean;
|
|
185
|
+
|
|
186
|
+
/** Obscures the text, for passwords. */
|
|
187
|
+
secureTextEntry?: boolean;
|
|
188
|
+
|
|
189
|
+
/** Multi-line field that grows with its content. Return inserts a newline. */
|
|
190
|
+
multiline?: boolean;
|
|
191
|
+
|
|
192
|
+
/** Whether the text can be edited. Default: `true`. */
|
|
193
|
+
editable?: boolean;
|
|
194
|
+
|
|
195
|
+
/** Focuses the field when it mounts. */
|
|
196
|
+
autoFocus?: boolean;
|
|
197
|
+
|
|
198
|
+
/** Selects all text when the field gains focus. */
|
|
199
|
+
selectTextOnFocus?: boolean;
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Autofill hint. Android: autofill hints. iOS: `textContentType`, which
|
|
203
|
+
* also enables the password and one-time-code suggestions.
|
|
204
|
+
*/
|
|
205
|
+
autoComplete?: TextFieldAutoComplete;
|
|
206
|
+
|
|
207
|
+
/** iOS: keyboard appearance. Default: `'default'`. */
|
|
208
|
+
keyboardAppearance?: 'default' | 'light' | 'dark';
|
|
209
|
+
|
|
210
|
+
/** Font of the input text. */
|
|
211
|
+
textStyle?: LabelStyle;
|
|
212
|
+
|
|
213
|
+
/** Screen-reader label. Defaults to `label`. */
|
|
214
|
+
accessibilityLabel?: string;
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* iOS-specific configuration. Each trait defaults to the system default.
|
|
218
|
+
*/
|
|
219
|
+
ios?: {
|
|
220
|
+
/**
|
|
221
|
+
* Writing Tools (iOS 18): `'complete'` allows rewrites in place,
|
|
222
|
+
* `'limited'` only the overlay panel, `'none'` disables them.
|
|
223
|
+
*/
|
|
224
|
+
writingTools?: 'default' | 'complete' | 'limited' | 'none';
|
|
225
|
+
|
|
226
|
+
/** Inline predictive text (iOS 17). */
|
|
227
|
+
inlinePrediction?: TextFieldIOSChoice;
|
|
228
|
+
|
|
229
|
+
/** Smart quotes. */
|
|
230
|
+
smartQuotes?: TextFieldIOSChoice;
|
|
231
|
+
|
|
232
|
+
/** Smart dashes. */
|
|
233
|
+
smartDashes?: TextFieldIOSChoice;
|
|
234
|
+
|
|
235
|
+
/** Smart insert and delete (spaces around pasted words). */
|
|
236
|
+
smartInsertDelete?: TextFieldIOSChoice;
|
|
237
|
+
|
|
238
|
+
/** Math expression completion, `1+1=` (iOS 18). */
|
|
239
|
+
mathExpressionCompletion?: TextFieldIOSChoice;
|
|
240
|
+
|
|
241
|
+
/** `UITextField.borderStyle`. Default: `'roundedRect'`. */
|
|
242
|
+
borderStyle?: 'roundedRect' | 'none' | 'line' | 'bezel';
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Where the label sits: above the field (default), or in a leading
|
|
246
|
+
* column with the field beside it, the layout of the grouped forms in
|
|
247
|
+
* Contacts and Settings. Pair `'leading'` with `borderStyle: 'none'`
|
|
248
|
+
* inside your own grouped row.
|
|
249
|
+
*/
|
|
250
|
+
labelPlacement?: 'above' | 'leading';
|
|
251
|
+
|
|
252
|
+
/** Width of the leading label column, in points. Default: 100. */
|
|
253
|
+
labelWidth?: number;
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Android-specific configuration
|
|
258
|
+
*/
|
|
259
|
+
android?: {
|
|
260
|
+
/**
|
|
261
|
+
* Material preference: the Material 3 text field (default), or
|
|
262
|
+
* `'system'` for the platform `EditText` (the hint as placeholder,
|
|
263
|
+
* supporting text below, icons as compound drawables; no box, floating
|
|
264
|
+
* label, clear button, password toggle, counter, prefix or suffix).
|
|
265
|
+
*/
|
|
266
|
+
material?: AndroidMaterialMode;
|
|
267
|
+
|
|
268
|
+
/** Material 3 text field style. Default: `'outlined'`. */
|
|
269
|
+
variant?: 'outlined' | 'filled';
|
|
270
|
+
|
|
271
|
+
/** The dense variant, a shorter field. */
|
|
272
|
+
dense?: boolean;
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
/** Test identifier */
|
|
276
|
+
testID?: string;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
type NativeTextFieldInstance = React.ComponentRef<typeof NativeTextField>;
|
|
280
|
+
|
|
281
|
+
export const TextField = forwardRef<TextFieldRef, TextFieldProps>(
|
|
282
|
+
function TextFieldComponent(props, ref): React.ReactElement {
|
|
283
|
+
const {
|
|
284
|
+
value,
|
|
285
|
+
defaultValue,
|
|
286
|
+
onChangeText,
|
|
287
|
+
onChange,
|
|
288
|
+
onFocus,
|
|
289
|
+
onBlur,
|
|
290
|
+
onSubmitEditing,
|
|
291
|
+
label,
|
|
292
|
+
placeholder,
|
|
293
|
+
supportingText,
|
|
294
|
+
error,
|
|
295
|
+
prefix,
|
|
296
|
+
suffix,
|
|
297
|
+
leadingIcon,
|
|
298
|
+
trailingIcon,
|
|
299
|
+
onTrailingIconPress,
|
|
300
|
+
clearButtonMode,
|
|
301
|
+
passwordToggle,
|
|
302
|
+
showCharacterCount,
|
|
303
|
+
maxLength,
|
|
304
|
+
keyboardType,
|
|
305
|
+
returnKeyType,
|
|
306
|
+
autoCapitalize,
|
|
307
|
+
autoCorrect,
|
|
308
|
+
secureTextEntry,
|
|
309
|
+
multiline,
|
|
310
|
+
editable,
|
|
311
|
+
autoFocus,
|
|
312
|
+
selectTextOnFocus,
|
|
313
|
+
autoComplete,
|
|
314
|
+
keyboardAppearance,
|
|
315
|
+
textStyle,
|
|
316
|
+
accessibilityLabel,
|
|
317
|
+
ios,
|
|
318
|
+
android,
|
|
319
|
+
...viewProps
|
|
320
|
+
} = props;
|
|
321
|
+
|
|
322
|
+
const nativeRef = useRef<NativeTextFieldInstance>(null);
|
|
323
|
+
const focused = useRef(false);
|
|
324
|
+
|
|
325
|
+
// The same synchronization as React Native's TextInput: every native edit
|
|
326
|
+
// reports an event count, and a controlled value is pushed with the last
|
|
327
|
+
// count JS has seen. Native drops the update when the user has typed
|
|
328
|
+
// since, and the edit that follows brings JS back in line.
|
|
329
|
+
const [mostRecentEventCount, setMostRecentEventCount] = useState(0);
|
|
330
|
+
const [lastNativeText, setLastNativeText] = useState<string | undefined>(
|
|
331
|
+
value ?? defaultValue
|
|
332
|
+
);
|
|
333
|
+
|
|
334
|
+
// Registered like a TextInput, so Keyboard.dismiss() and the ScrollView
|
|
335
|
+
// keyboard props treat the field as one (see focusRegistry.ts)
|
|
336
|
+
useLayoutEffect(() => {
|
|
337
|
+
const node = nativeRef.current;
|
|
338
|
+
if (node == null) return undefined;
|
|
339
|
+
focusRegistry.register(node);
|
|
340
|
+
return () => focusRegistry.unregister(node);
|
|
341
|
+
}, []);
|
|
342
|
+
|
|
343
|
+
useLayoutEffect(() => {
|
|
344
|
+
if (typeof value !== 'string' || value === lastNativeText) return;
|
|
345
|
+
setLastNativeText(value);
|
|
346
|
+
const node = nativeRef.current;
|
|
347
|
+
if (node != null) {
|
|
348
|
+
Commands.setText(node, mostRecentEventCount, value);
|
|
349
|
+
}
|
|
350
|
+
}, [value, lastNativeText, mostRecentEventCount]);
|
|
351
|
+
|
|
352
|
+
useImperativeHandle(
|
|
353
|
+
ref,
|
|
354
|
+
() => ({
|
|
355
|
+
focus: () => {
|
|
356
|
+
const node = nativeRef.current;
|
|
357
|
+
if (node != null) Commands.focus(node);
|
|
358
|
+
},
|
|
359
|
+
blur: () => {
|
|
360
|
+
const node = nativeRef.current;
|
|
361
|
+
if (node != null) Commands.blur(node);
|
|
362
|
+
},
|
|
363
|
+
clear: () => {
|
|
364
|
+
const node = nativeRef.current;
|
|
365
|
+
if (node != null) Commands.clear(node);
|
|
366
|
+
},
|
|
367
|
+
isFocused: () => focused.current,
|
|
368
|
+
}),
|
|
369
|
+
[]
|
|
370
|
+
);
|
|
371
|
+
|
|
372
|
+
const handleChange = useCallback(
|
|
373
|
+
(event: NativeSyntheticEvent<NativeChangeEvent>) => {
|
|
374
|
+
const { text, eventCount } = event.nativeEvent;
|
|
375
|
+
setMostRecentEventCount(eventCount);
|
|
376
|
+
setLastNativeText(text);
|
|
377
|
+
onChange?.(event);
|
|
378
|
+
onChangeText?.(text);
|
|
379
|
+
},
|
|
380
|
+
[onChange, onChangeText]
|
|
381
|
+
);
|
|
382
|
+
|
|
383
|
+
const handleFocus = useCallback(
|
|
384
|
+
(event: NativeSyntheticEvent<NativeTextEvent>) => {
|
|
385
|
+
focused.current = true;
|
|
386
|
+
focusRegistry.focused(nativeRef.current);
|
|
387
|
+
onFocus?.(event);
|
|
388
|
+
},
|
|
389
|
+
[onFocus]
|
|
390
|
+
);
|
|
391
|
+
|
|
392
|
+
const handleBlur = useCallback(
|
|
393
|
+
(event: NativeSyntheticEvent<NativeTextEvent>) => {
|
|
394
|
+
focused.current = false;
|
|
395
|
+
focusRegistry.blurred(nativeRef.current);
|
|
396
|
+
onBlur?.(event);
|
|
397
|
+
},
|
|
398
|
+
[onBlur]
|
|
399
|
+
);
|
|
400
|
+
|
|
401
|
+
const handleSubmit = useCallback(
|
|
402
|
+
(event: NativeSyntheticEvent<NativeTextEvent>) => {
|
|
403
|
+
onSubmitEditing?.(event);
|
|
404
|
+
},
|
|
405
|
+
[onSubmitEditing]
|
|
406
|
+
);
|
|
407
|
+
|
|
408
|
+
const handleTrailingIconPress = useCallback(() => {
|
|
409
|
+
onTrailingIconPress?.();
|
|
410
|
+
}, [onTrailingIconPress]);
|
|
411
|
+
|
|
412
|
+
const nativeLeadingIcon = useMemo(
|
|
413
|
+
() => resolveIcon(leadingIcon),
|
|
414
|
+
[leadingIcon]
|
|
415
|
+
);
|
|
416
|
+
const nativeTrailingIcon = useMemo(
|
|
417
|
+
() => resolveIcon(trailingIcon),
|
|
418
|
+
[trailingIcon]
|
|
419
|
+
);
|
|
420
|
+
const nativeTextStyle = useMemo(
|
|
421
|
+
() => normalizeLabelStyle(textStyle),
|
|
422
|
+
[textStyle]
|
|
423
|
+
);
|
|
424
|
+
|
|
425
|
+
const nativeIOS = useMemo(
|
|
426
|
+
() => ({
|
|
427
|
+
writingTools: ios?.writingTools ?? '',
|
|
428
|
+
inlinePrediction: ios?.inlinePrediction ?? '',
|
|
429
|
+
smartQuotes: ios?.smartQuotes ?? '',
|
|
430
|
+
smartDashes: ios?.smartDashes ?? '',
|
|
431
|
+
smartInsertDelete: ios?.smartInsertDelete ?? '',
|
|
432
|
+
mathExpressionCompletion: ios?.mathExpressionCompletion ?? '',
|
|
433
|
+
borderStyle: ios?.borderStyle ?? '',
|
|
434
|
+
labelPlacement: ios?.labelPlacement ?? '',
|
|
435
|
+
labelWidth: ios?.labelWidth ?? 0,
|
|
436
|
+
}),
|
|
437
|
+
[ios]
|
|
438
|
+
);
|
|
439
|
+
|
|
440
|
+
const nativeAndroid = useMemo(
|
|
441
|
+
() => ({
|
|
442
|
+
material: android?.material ?? 'm3',
|
|
443
|
+
variant: android?.variant ?? 'outlined',
|
|
444
|
+
density: android?.dense ? 'dense' : 'standard',
|
|
445
|
+
}),
|
|
446
|
+
[android]
|
|
447
|
+
);
|
|
448
|
+
|
|
449
|
+
return (
|
|
450
|
+
<NativeTextField
|
|
451
|
+
ref={nativeRef}
|
|
452
|
+
initialText={value ?? defaultValue ?? ''}
|
|
453
|
+
label={label ?? ''}
|
|
454
|
+
placeholder={placeholder ?? ''}
|
|
455
|
+
supportingText={supportingText ?? ''}
|
|
456
|
+
errorState={error ? 'error' : 'none'}
|
|
457
|
+
errorText={typeof error === 'string' ? error : ''}
|
|
458
|
+
prefix={prefix ?? ''}
|
|
459
|
+
suffix={suffix ?? ''}
|
|
460
|
+
leadingIcon={nativeLeadingIcon}
|
|
461
|
+
trailingIcon={nativeTrailingIcon}
|
|
462
|
+
clearButtonMode={clearButtonMode ?? 'never'}
|
|
463
|
+
passwordToggle={passwordToggle ? 'shown' : 'hidden'}
|
|
464
|
+
characterCount={showCharacterCount ? 'shown' : 'hidden'}
|
|
465
|
+
maxLength={maxLength ?? 0}
|
|
466
|
+
keyboardType={keyboardType ?? 'default'}
|
|
467
|
+
returnKeyType={returnKeyType ?? 'default'}
|
|
468
|
+
autoCapitalize={autoCapitalize ?? 'sentences'}
|
|
469
|
+
autoCorrect={autoCorrect === false ? 'disabled' : 'enabled'}
|
|
470
|
+
secureTextEntry={secureTextEntry ? 'secure' : 'plain'}
|
|
471
|
+
lines={multiline ? 'multiline' : 'single'}
|
|
472
|
+
interactivity={editable === false ? 'disabled' : 'enabled'}
|
|
473
|
+
autoFocus={autoFocus ? 'focus' : 'none'}
|
|
474
|
+
selectTextOnFocus={selectTextOnFocus ? 'select' : 'keep'}
|
|
475
|
+
autoComplete={autoComplete ?? ''}
|
|
476
|
+
keyboardAppearance={keyboardAppearance ?? 'default'}
|
|
477
|
+
textStyle={nativeTextStyle}
|
|
478
|
+
spokenLabel={accessibilityLabel ?? ''}
|
|
479
|
+
ios={nativeIOS}
|
|
480
|
+
android={nativeAndroid}
|
|
481
|
+
onFieldChange={handleChange}
|
|
482
|
+
onFieldFocus={handleFocus}
|
|
483
|
+
onFieldBlur={handleBlur}
|
|
484
|
+
onFieldSubmit={onSubmitEditing ? handleSubmit : undefined}
|
|
485
|
+
onTrailingIconPress={
|
|
486
|
+
onTrailingIconPress ? handleTrailingIconPress : undefined
|
|
487
|
+
}
|
|
488
|
+
{...viewProps}
|
|
489
|
+
/>
|
|
490
|
+
);
|
|
491
|
+
}
|
|
492
|
+
);
|
|
493
|
+
|
|
494
|
+
TextField.displayName = 'TextField';
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
// TextFieldNativeComponent.ts
|
|
2
|
+
import type * as React from 'react';
|
|
3
|
+
import type { HostComponent, ViewProps } from 'react-native';
|
|
4
|
+
import { codegenNativeCommands, codegenNativeComponent } from 'react-native';
|
|
5
|
+
import type { BubblingEventHandler, Double, Int32 } from './codegenTypes';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Icon fields, pre-resolved on the JS side (see icons.ts).
|
|
9
|
+
*/
|
|
10
|
+
export type TextFieldIconProps = Readonly<{
|
|
11
|
+
iconType: string; // '' | 'sfSymbol' | 'drawable' | 'image'
|
|
12
|
+
iconName: string; // SF Symbol (iOS) or drawable resource name (Android)
|
|
13
|
+
iconUri: string; // Resolved image URI when iconType === 'image'
|
|
14
|
+
iconScale: Double; // Resolved image scale when iconType === 'image'
|
|
15
|
+
iconTinted: string; // 'true' | 'false' — draw the image as a tinted template
|
|
16
|
+
}>;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Text font. Empty strings / 0 mean "platform default".
|
|
20
|
+
*/
|
|
21
|
+
export type TextFieldTextStyleProps = Readonly<{
|
|
22
|
+
fontFamily?: string;
|
|
23
|
+
fontSize?: Double;
|
|
24
|
+
fontWeight?: string; // 'normal' | 'bold' | '100'..'900'
|
|
25
|
+
fontStyle?: string; // 'normal' | 'italic'
|
|
26
|
+
}>;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Fired on every edit. `eventCount` is the native edit counter that JS hands
|
|
30
|
+
* back with `setText`, so a stale controlled value can't overwrite what the
|
|
31
|
+
* user typed since.
|
|
32
|
+
*/
|
|
33
|
+
export type TextFieldChangeEvent = Readonly<{
|
|
34
|
+
text: string;
|
|
35
|
+
eventCount: Int32;
|
|
36
|
+
}>;
|
|
37
|
+
|
|
38
|
+
/** Focus, blur and submit carry the text at that moment. */
|
|
39
|
+
export type TextFieldTextEvent = Readonly<{
|
|
40
|
+
text: string;
|
|
41
|
+
}>;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* iOS-specific configuration. Every field is '' for the platform default.
|
|
45
|
+
*/
|
|
46
|
+
export type TextFieldIOSProps = Readonly<{
|
|
47
|
+
/** 'default' | 'complete' | 'limited' | 'none' (iOS 18) */
|
|
48
|
+
writingTools?: string;
|
|
49
|
+
/** 'default' | 'yes' | 'no' (iOS 17) */
|
|
50
|
+
inlinePrediction?: string;
|
|
51
|
+
/** 'default' | 'yes' | 'no' */
|
|
52
|
+
smartQuotes?: string;
|
|
53
|
+
/** 'default' | 'yes' | 'no' */
|
|
54
|
+
smartDashes?: string;
|
|
55
|
+
/** 'default' | 'yes' | 'no' */
|
|
56
|
+
smartInsertDelete?: string;
|
|
57
|
+
/** 'default' | 'yes' | 'no' (iOS 18) */
|
|
58
|
+
mathExpressionCompletion?: string;
|
|
59
|
+
/** 'roundedRect' | 'none' | 'line' | 'bezel' */
|
|
60
|
+
borderStyle?: string;
|
|
61
|
+
/** 'above' | 'leading': where the label sits */
|
|
62
|
+
labelPlacement?: string;
|
|
63
|
+
/** Width of a leading label column in points; 0 = default */
|
|
64
|
+
labelWidth?: Double;
|
|
65
|
+
}>;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Android-specific configuration.
|
|
69
|
+
*/
|
|
70
|
+
export type TextFieldAndroidProps = Readonly<{
|
|
71
|
+
/** 'm3' | 'system' (AndroidMaterialMode) */
|
|
72
|
+
material?: string;
|
|
73
|
+
/** 'outlined' | 'filled' */
|
|
74
|
+
variant?: string;
|
|
75
|
+
/** 'standard' | 'dense' */
|
|
76
|
+
density?: string;
|
|
77
|
+
}>;
|
|
78
|
+
|
|
79
|
+
export interface TextFieldNativeProps extends ViewProps {
|
|
80
|
+
/**
|
|
81
|
+
* Text applied when the native view is created. Later updates go through
|
|
82
|
+
* the `setText` command so they can be checked against `eventCount`.
|
|
83
|
+
*/
|
|
84
|
+
initialText?: string;
|
|
85
|
+
|
|
86
|
+
/** Floating label (Android) / caption above the field (iOS). */
|
|
87
|
+
label?: string;
|
|
88
|
+
|
|
89
|
+
/** Placeholder shown while the field is empty. */
|
|
90
|
+
placeholder?: string;
|
|
91
|
+
|
|
92
|
+
/** Helper text below the field. */
|
|
93
|
+
supportingText?: string;
|
|
94
|
+
|
|
95
|
+
/** 'none' | 'error' */
|
|
96
|
+
errorState?: string;
|
|
97
|
+
|
|
98
|
+
/** Error message shown instead of the supporting text. */
|
|
99
|
+
errorText?: string;
|
|
100
|
+
|
|
101
|
+
/** Text shown before the input, inside the field. */
|
|
102
|
+
prefix?: string;
|
|
103
|
+
|
|
104
|
+
/** Text shown after the input, inside the field. */
|
|
105
|
+
suffix?: string;
|
|
106
|
+
|
|
107
|
+
/** Icon at the start of the field. */
|
|
108
|
+
leadingIcon?: TextFieldIconProps;
|
|
109
|
+
|
|
110
|
+
/** Icon at the end of the field; pressing it fires onTrailingIconPress. */
|
|
111
|
+
trailingIcon?: TextFieldIconProps;
|
|
112
|
+
|
|
113
|
+
/** 'never' | 'while-editing' | 'unless-editing' | 'always' */
|
|
114
|
+
clearButtonMode?: string;
|
|
115
|
+
|
|
116
|
+
/** 'shown' | 'hidden': a button that toggles secure text entry. */
|
|
117
|
+
passwordToggle?: string;
|
|
118
|
+
|
|
119
|
+
/** 'shown' | 'hidden': the character counter. */
|
|
120
|
+
characterCount?: string;
|
|
121
|
+
|
|
122
|
+
/** Maximum number of UTF-16 characters; 0 = unlimited. */
|
|
123
|
+
maxLength?: Int32;
|
|
124
|
+
|
|
125
|
+
/** React Native keyboardType value. */
|
|
126
|
+
keyboardType?: string;
|
|
127
|
+
|
|
128
|
+
/** React Native returnKeyType value. */
|
|
129
|
+
returnKeyType?: string;
|
|
130
|
+
|
|
131
|
+
/** 'none' | 'sentences' | 'words' | 'characters' */
|
|
132
|
+
autoCapitalize?: string;
|
|
133
|
+
|
|
134
|
+
/** 'enabled' | 'disabled' */
|
|
135
|
+
autoCorrect?: string;
|
|
136
|
+
|
|
137
|
+
/** 'secure' | 'plain' */
|
|
138
|
+
secureTextEntry?: string;
|
|
139
|
+
|
|
140
|
+
/** 'single' | 'multiline' */
|
|
141
|
+
lines?: string;
|
|
142
|
+
|
|
143
|
+
/** 'enabled' | 'disabled' */
|
|
144
|
+
interactivity?: string;
|
|
145
|
+
|
|
146
|
+
/** 'focus' | 'none': focus the field when it mounts. */
|
|
147
|
+
autoFocus?: string;
|
|
148
|
+
|
|
149
|
+
/** 'select' | 'keep': select all text on focus. */
|
|
150
|
+
selectTextOnFocus?: string;
|
|
151
|
+
|
|
152
|
+
/** React Native autoComplete value; '' = platform default. */
|
|
153
|
+
autoComplete?: string;
|
|
154
|
+
|
|
155
|
+
/** 'default' | 'light' | 'dark' (iOS keyboard appearance) */
|
|
156
|
+
keyboardAppearance?: string;
|
|
157
|
+
|
|
158
|
+
/** Font of the input text. */
|
|
159
|
+
textStyle?: TextFieldTextStyleProps;
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Screen-reader label, applied to the native field rather than the host
|
|
163
|
+
* view. Empty means "use the label".
|
|
164
|
+
*/
|
|
165
|
+
spokenLabel?: string;
|
|
166
|
+
|
|
167
|
+
ios?: TextFieldIOSProps;
|
|
168
|
+
android?: TextFieldAndroidProps;
|
|
169
|
+
|
|
170
|
+
/** Fired on every user edit. */
|
|
171
|
+
onFieldChange?: BubblingEventHandler<TextFieldChangeEvent>;
|
|
172
|
+
|
|
173
|
+
/** Fired when the field gains focus. */
|
|
174
|
+
onFieldFocus?: BubblingEventHandler<TextFieldTextEvent>;
|
|
175
|
+
|
|
176
|
+
/** Fired when the field loses focus. */
|
|
177
|
+
onFieldBlur?: BubblingEventHandler<TextFieldTextEvent>;
|
|
178
|
+
|
|
179
|
+
/** Fired when the keyboard's return key is pressed (single-line). */
|
|
180
|
+
onFieldSubmit?: BubblingEventHandler<TextFieldTextEvent>;
|
|
181
|
+
|
|
182
|
+
/** Fired when the trailing icon is pressed. */
|
|
183
|
+
onTrailingIconPress?: BubblingEventHandler<Readonly<{}>>;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
type NativeTextFieldComponent = HostComponent<TextFieldNativeProps>;
|
|
187
|
+
|
|
188
|
+
// `React.ElementRef` rather than `React.ComponentRef`: the codegen shipped with
|
|
189
|
+
// React Native 0.81 (and the 0.76 Android floor) only accepts the former.
|
|
190
|
+
interface NativeCommands {
|
|
191
|
+
/** Focuses the field and shows the keyboard. */
|
|
192
|
+
focus: (viewRef: React.ElementRef<NativeTextFieldComponent>) => void;
|
|
193
|
+
|
|
194
|
+
/** Removes focus and hides the keyboard. */
|
|
195
|
+
blur: (viewRef: React.ElementRef<NativeTextFieldComponent>) => void;
|
|
196
|
+
|
|
197
|
+
/** Clears the text; fires onFieldChange like a user edit. */
|
|
198
|
+
clear: (viewRef: React.ElementRef<NativeTextFieldComponent>) => void;
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Replaces the text, unless the user has edited since `eventCount` was
|
|
202
|
+
* reported, in which case the update is dropped and the next edit event
|
|
203
|
+
* brings JS back in sync.
|
|
204
|
+
*/
|
|
205
|
+
setText: (
|
|
206
|
+
viewRef: React.ElementRef<NativeTextFieldComponent>,
|
|
207
|
+
eventCount: Int32,
|
|
208
|
+
text: string
|
|
209
|
+
) => void;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export const Commands: NativeCommands = codegenNativeCommands<NativeCommands>({
|
|
213
|
+
supportedCommands: ['focus', 'blur', 'clear', 'setText'],
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
export default codegenNativeComponent<TextFieldNativeProps>(
|
|
217
|
+
'PCTextField'
|
|
218
|
+
) as NativeTextFieldComponent;
|