1/**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 * @format
8 */
9
10import type * as React from 'react';
11import {Constructor} from '../../../types/private/Utilities';
12import {TimerMixin} from '../../../types/private/TimerMixin';
13import {
14  HostComponent,
15  NativeMethods,
16} from '../../../types/public/ReactNativeTypes';
17import {ColorValue, StyleProp} from '../../StyleSheet/StyleSheet';
18import {TextStyle} from '../../StyleSheet/StyleSheetTypes';
19import {
20  NativeSyntheticEvent,
21  NativeTouchEvent,
22  TargetedEvent,
23} from '../../Types/CoreEventTypes';
24import EventEmitter from '../../vendor/emitter/EventEmitter';
25import {AccessibilityProps} from '../View/ViewAccessibility';
26import {ViewProps} from '../View/ViewPropTypes';
27
28export type KeyboardType =
29  | 'default'
30  | 'number-pad'
31  | 'decimal-pad'
32  | 'numeric'
33  | 'email-address'
34  | 'phone-pad'
35  | 'url';
36export type KeyboardTypeIOS =
37  | 'ascii-capable'
38  | 'numbers-and-punctuation'
39  | 'name-phone-pad'
40  | 'twitter'
41  | 'web-search';
42export type KeyboardTypeAndroid = 'visible-password';
43export type KeyboardTypeOptions =
44  | KeyboardType
45  | KeyboardTypeAndroid
46  | KeyboardTypeIOS;
47
48export type InputModeOptions =
49  | 'none'
50  | 'text'
51  | 'decimal'
52  | 'numeric'
53  | 'tel'
54  | 'search'
55  | 'email'
56  | 'url';
57
58export type ReturnKeyType = 'done' | 'go' | 'next' | 'search' | 'send';
59export type ReturnKeyTypeAndroid = 'none' | 'previous';
60export type ReturnKeyTypeIOS =
61  | 'default'
62  | 'google'
63  | 'join'
64  | 'route'
65  | 'yahoo'
66  | 'emergency-call';
67
68export type ReturnKeyTypeOptions =
69  | ReturnKeyType
70  | ReturnKeyTypeAndroid
71  | ReturnKeyTypeIOS;
72
73type DataDetectorTypes =
74  | 'phoneNumber'
75  | 'link'
76  | 'address'
77  | 'calendarEvent'
78  | 'none'
79  | 'all';
80
81/**
82 * DocumentSelectionState is responsible for maintaining selection information
83 * for a document.
84 *
85 * It is intended for use by AbstractTextEditor-based components for
86 * identifying the appropriate start/end positions to modify the
87 * DocumentContent, and for programmatically setting browser selection when
88 * components re-render.
89 */
90export interface DocumentSelectionState extends EventEmitter {
91  new (anchor: number, focus: number): DocumentSelectionState;
92
93  /**
94   * Apply an update to the state. If either offset value has changed,
95   * set the values and emit the `change` event. Otherwise no-op.
96   *
97   */
98  update(anchor: number, focus: number): void;
99
100  /**
101   * Given a max text length, constrain our selection offsets to ensure
102   * that the selection remains strictly within the text range.
103   *
104   */
105  constrainLength(maxLength: number): void;
106
107  focus(): void;
108  blur(): void;
109  hasFocus(): boolean;
110  isCollapsed(): boolean;
111  isBackward(): boolean;
112
113  getAnchorOffset(): number;
114  getFocusOffset(): number;
115  getStartOffset(): number;
116  getEndOffset(): number;
117  overlaps(start: number, end: number): boolean;
118}
119
120/**
121 * IOS Specific properties for TextInput
122 * @see https://reactnative.dev/docs/textinput#props
123 */
124export interface TextInputIOSProps {
125  /**
126   * enum('never', 'while-editing', 'unless-editing', 'always')
127   * When the clear button should appear on the right side of the text view
128   */
129  clearButtonMode?:
130    | 'never'
131    | 'while-editing'
132    | 'unless-editing'
133    | 'always'
134    | undefined;
135
136  /**
137   * If true, clears the text field automatically when editing begins
138   */
139  clearTextOnFocus?: boolean | undefined;
140
141  /**
142   * Determines the types of data converted to clickable URLs in the text input.
143   * Only valid if `multiline={true}` and `editable={false}`.
144   * By default no data types are detected.
145   *
146   * You can provide one type or an array of many types.
147   *
148   * Possible values for `dataDetectorTypes` are:
149   *
150   * - `'phoneNumber'`
151   * - `'link'`
152   * - `'address'`
153   * - `'calendarEvent'`
154   * - `'none'`
155   * - `'all'`
156   */
157  dataDetectorTypes?: DataDetectorTypes | DataDetectorTypes[] | undefined;
158
159  /**
160   * If true, the keyboard disables the return key when there is no text and automatically enables it when there is text.
161   * The default value is false.
162   */
163  enablesReturnKeyAutomatically?: boolean | undefined;
164
165  /**
166   * Determines the color of the keyboard.
167   */
168  keyboardAppearance?: 'default' | 'light' | 'dark' | undefined;
169
170  /**
171   * Provide rules for your password.
172   * 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.
173   * "required: upper; required: lower; required: digit; max-consecutive: 2; minlength: 8;"
174   */
175  passwordRules?: string | null | undefined;
176
177  /**
178   * If `true`, allows TextInput to pass touch events to the parent component.
179   * This allows components to be swipeable from the TextInput on iOS,
180   * as is the case on Android by default.
181   * If `false`, TextInput always asks to handle the input (except when disabled).
182   */
183  rejectResponderTermination?: boolean | null | undefined;
184
185  /**
186   * See DocumentSelectionState.js, some state that is responsible for maintaining selection information for a document
187   */
188  selectionState?: DocumentSelectionState | undefined;
189
190  /**
191   * If false, disables spell-check style (i.e. red underlines). The default value is inherited from autoCorrect
192   */
193  spellCheck?: boolean | undefined;
194
195  /**
196   * Give the keyboard and the system information about the expected
197   * semantic meaning for the content that users enter.
198   *
199   * For iOS 11+ you can set `textContentType` to `username` or `password` to
200   * enable autofill of login details from the device keychain.
201   *
202   * For iOS 12+ `newPassword` can be used to indicate a new password input the
203   * user may want to save in the keychain, and `oneTimeCode` can be used to indicate
204   * that a field can be autofilled by a code arriving in an SMS.
205   *
206   * To disable autofill, set textContentType to `none`.
207   *
208   * Possible values for `textContentType` are:
209   *
210   *  - `'none'`
211   *  - `'URL'`
212   *  - `'addressCity'`
213   *  - `'addressCityAndState'`
214   *  - `'addressState'`
215   *  - `'countryName'`
216   *  - `'creditCardNumber'`
217   *  - `'emailAddress'`
218   *  - `'familyName'`
219   *  - `'fullStreetAddress'`
220   *  - `'givenName'`
221   *  - `'jobTitle'`
222   *  - `'location'`
223   *  - `'middleName'`
224   *  - `'name'`
225   *  - `'namePrefix'`
226   *  - `'nameSuffix'`
227   *  - `'nickname'`
228   *  - `'organizationName'`
229   *  - `'postalCode'`
230   *  - `'streetAddressLine1'`
231   *  - `'streetAddressLine2'`
232   *  - `'sublocality'`
233   *  - `'telephoneNumber'`
234   *  - `'username'`
235   *  - `'password'`
236   *  - `'newPassword'`
237   *  - `'oneTimeCode'`
238   *
239   */
240  textContentType?:
241    | 'none'
242    | 'URL'
243    | 'addressCity'
244    | 'addressCityAndState'
245    | 'addressState'
246    | 'countryName'
247    | 'creditCardNumber'
248    | 'emailAddress'
249    | 'familyName'
250    | 'fullStreetAddress'
251    | 'givenName'
252    | 'jobTitle'
253    | 'location'
254    | 'middleName'
255    | 'name'
256    | 'namePrefix'
257    | 'nameSuffix'
258    | 'nickname'
259    | 'organizationName'
260    | 'postalCode'
261    | 'streetAddressLine1'
262    | 'streetAddressLine2'
263    | 'sublocality'
264    | 'telephoneNumber'
265    | 'username'
266    | 'password'
267    | 'newPassword'
268    | 'oneTimeCode'
269    | undefined;
270
271  /**
272   * If false, scrolling of the text view will be disabled. The default value is true. Only works with multiline={true}
273   */
274  scrollEnabled?: boolean | undefined;
275
276  /**
277   * Set line break strategy on iOS.
278   */
279  lineBreakStrategyIOS?:
280    | 'none'
281    | 'standard'
282    | 'hangul-word'
283    | 'push-out'
284    | undefined;
285}
286
287/**
288 * Android Specific properties for TextInput
289 * @see https://reactnative.dev/docs/textinput#props
290 */
291export interface TextInputAndroidProps {
292  /**
293   * When provided it will set the color of the cursor (or "caret") in the component.
294   * Unlike the behavior of `selectionColor` the cursor color will be set independently
295   * from the color of the text selection box.
296   * @platform android
297   */
298  cursorColor?: ColorValue | null | undefined;
299
300  /**
301   * Determines whether the individual fields in your app should be included in a
302   * view structure for autofill purposes on Android API Level 26+. Defaults to auto.
303   * To disable auto complete, use `off`.
304   *
305   * *Android Only*
306   *
307   * The following values work on Android only:
308   *
309   * - `auto` - let Android decide
310   * - `no` - not important for autofill
311   * - `noExcludeDescendants` - this view and its children aren't important for autofill
312   * - `yes` - is important for autofill
313   * - `yesExcludeDescendants` - this view is important for autofill but its children aren't
314   */
315  importantForAutofill?:
316    | 'auto'
317    | 'no'
318    | 'noExcludeDescendants'
319    | 'yes'
320    | 'yesExcludeDescendants'
321    | undefined;
322
323  /**
324   * When false, if there is a small amount of space available around a text input (e.g. landscape orientation on a phone),
325   *   the OS may choose to have the user edit the text inside of a full screen text input mode.
326   * When true, this feature is disabled and users will always edit the text directly inside of the text input.
327   * Defaults to false.
328   */
329  disableFullscreenUI?: boolean | undefined;
330
331  /**
332   * If defined, the provided image resource will be rendered on the left.
333   */
334  inlineImageLeft?: string | undefined;
335
336  /**
337   * Padding between the inline image, if any, and the text input itself.
338   */
339  inlineImagePadding?: number | undefined;
340
341  /**
342   * Sets the number of lines for a TextInput.
343   * Use it with multiline set to true to be able to fill the lines.
344   */
345  numberOfLines?: number | undefined;
346
347  /**
348   * Sets the return key to the label. Use it instead of `returnKeyType`.
349   * @platform android
350   */
351  returnKeyLabel?: string | undefined;
352
353  /**
354   * Set text break strategy on Android API Level 23+, possible values are simple, highQuality, balanced
355   * The default value is simple.
356   */
357  textBreakStrategy?: 'simple' | 'highQuality' | 'balanced' | undefined;
358
359  /**
360   * The color of the textInput underline.
361   */
362  underlineColorAndroid?: ColorValue | undefined;
363
364  /**
365   * Vertically align text when `multiline` is set to true
366   */
367  textAlignVertical?: 'auto' | 'top' | 'bottom' | 'center' | undefined;
368
369  /**
370   * When false, it will prevent the soft keyboard from showing when the field is focused. The default value is true
371   */
372  showSoftInputOnFocus?: boolean | undefined;
373
374  /**
375   * Vertically align text when `multiline` is set to true
376   */
377  verticalAlign?: 'auto' | 'top' | 'bottom' | 'middle' | undefined;
378}
379
380/**
381 * @see TextInputProps.onFocus
382 */
383export interface TextInputFocusEventData extends TargetedEvent {
384  text: string;
385  eventCount: number;
386}
387
388/**
389 * @see TextInputProps.onScroll
390 */
391export interface TextInputScrollEventData {
392  contentOffset: {x: number; y: number};
393}
394
395/**
396 * @see TextInputProps.onSelectionChange
397 */
398export interface TextInputSelectionChangeEventData extends TargetedEvent {
399  selection: {
400    start: number;
401    end: number;
402  };
403}
404
405/**
406 * @see TextInputProps.onKeyPress
407 */
408export interface TextInputKeyPressEventData {
409  key: string;
410}
411
412/**
413 * @see TextInputProps.onChange
414 */
415export interface TextInputChangeEventData extends TargetedEvent {
416  eventCount: number;
417  text: string;
418}
419
420/**
421 * @see TextInputProps.onContentSizeChange
422 */
423export interface TextInputContentSizeChangeEventData {
424  contentSize: {width: number; height: number};
425}
426
427/**
428 * @see TextInputProps.onEndEditing
429 */
430export interface TextInputEndEditingEventData {
431  text: string;
432}
433
434/**
435 * @see TextInputProps.onSubmitEditing
436 */
437export interface TextInputSubmitEditingEventData {
438  text: string;
439}
440
441/**
442 * @see TextInputProps.onTextInput
443 */
444export interface TextInputTextInputEventData {
445  text: string;
446  previousText: string;
447  range: {start: number; end: number};
448}
449
450/**
451 * @see https://reactnative.dev/docs/textinput#props
452 */
453export interface TextInputProps
454  extends ViewProps,
455    TextInputIOSProps,
456    TextInputAndroidProps,
457    AccessibilityProps {
458  /**
459   * Specifies whether fonts should scale to respect Text Size accessibility settings.
460   * The default is `true`.
461   */
462  allowFontScaling?: boolean | undefined;
463
464  /**
465   * Can tell TextInput to automatically capitalize certain characters.
466   *      characters: all characters,
467   *      words: first letter of each word
468   *      sentences: first letter of each sentence (default)
469   *      none: don't auto capitalize anything
470   *
471   * https://reactnative.dev/docs/textinput#autocapitalize
472   */
473  autoCapitalize?: 'none' | 'sentences' | 'words' | 'characters' | undefined;
474
475  /**
476   * Specifies autocomplete hints for the system, so it can provide autofill.
477   * On Android, the system will always attempt to offer autofill by using heuristics to identify the type of content.
478   * To disable autocomplete, set autoComplete to off.
479   *
480   * The following values work across platforms:
481   *
482   * - `additional-name`
483   * - `address-line1`
484   * - `address-line2`
485   * - `cc-number`
486   * - `country`
487   * - `current-password`
488   * - `email`
489   * - `family-name`
490   * - `given-name`
491   * - `honorific-prefix`
492   * - `honorific-suffix`
493   * - `name`
494   * - `new-password`
495   * - `off`
496   * - `one-time-code`
497   * - `postal-code`
498   * - `street-address`
499   * - `tel`
500   * - `username`
501   *
502   * The following values work on iOS only:
503   *
504   * - `nickname`
505   * - `organization`
506   * - `organization-title`
507   * - `url`
508   *
509   * The following values work on Android only:
510   *
511   * - `birthdate-day`
512   * - `birthdate-full`
513   * - `birthdate-month`
514   * - `birthdate-year`
515   * - `cc-csc`
516   * - `cc-exp`
517   * - `cc-exp-day`
518   * - `cc-exp-month`
519   * - `cc-exp-year`
520   * - `gender`
521   * - `name-family`
522   * - `name-given`
523   * - `name-middle`
524   * - `name-middle-initial`
525   * - `name-prefix`
526   * - `name-suffix`
527   * - `password`
528   * - `password-new`
529   * - `postal-address`
530   * - `postal-address-country`
531   * - `postal-address-extended`
532   * - `postal-address-extended-postal-code`
533   * - `postal-address-locality`
534   * - `postal-address-region`
535   * - `sms-otp`
536   * - `tel-country-code`
537   * - `tel-national`
538   * - `tel-device`
539   * - `username-new`
540   */
541  autoComplete?:
542    | 'additional-name'
543    | 'address-line1'
544    | 'address-line2'
545    | 'birthdate-day'
546    | 'birthdate-full'
547    | 'birthdate-month'
548    | 'birthdate-year'
549    | 'cc-csc'
550    | 'cc-exp'
551    | 'cc-exp-day'
552    | 'cc-exp-month'
553    | 'cc-exp-year'
554    | 'cc-number'
555    | 'country'
556    | 'current-password'
557    | 'email'
558    | 'family-name'
559    | 'gender'
560    | 'given-name'
561    | 'honorific-prefix'
562    | 'honorific-suffix'
563    | 'name'
564    | 'name-family'
565    | 'name-given'
566    | 'name-middle'
567    | 'name-middle-initial'
568    | 'name-prefix'
569    | 'name-suffix'
570    | 'new-password'
571    | 'nickname'
572    | 'one-time-code'
573    | 'organization'
574    | 'organization-title'
575    | 'password'
576    | 'password-new'
577    | 'postal-address'
578    | 'postal-address-country'
579    | 'postal-address-extended'
580    | 'postal-address-extended-postal-code'
581    | 'postal-address-locality'
582    | 'postal-address-region'
583    | 'postal-code'
584    | 'street-address'
585    | 'sms-otp'
586    | 'tel'
587    | 'tel-country-code'
588    | 'tel-national'
589    | 'tel-device'
590    | 'url'
591    | 'username'
592    | 'username-new'
593    | 'off'
594    | undefined;
595
596  /**
597   * If false, disables auto-correct.
598   * The default value is true.
599   */
600  autoCorrect?: boolean | undefined;
601
602  /**
603   * If true, focuses the input on componentDidMount.
604   * The default value is false.
605   */
606  autoFocus?: boolean | undefined;
607
608  /**
609   * If true, the text field will blur when submitted.
610   * The default value is true.
611   */
612  blurOnSubmit?: boolean | undefined;
613
614  /**
615   * If true, caret is hidden. The default value is false.
616   */
617  caretHidden?: boolean | undefined;
618
619  /**
620   * If true, context menu is hidden. The default value is false.
621   */
622  contextMenuHidden?: boolean | undefined;
623
624  /**
625   * Provides an initial value that will change when the user starts typing.
626   * Useful for simple use-cases where you don't want to deal with listening to events
627   * and updating the value prop to keep the controlled state in sync.
628   */
629  defaultValue?: string | undefined;
630
631  /**
632   * If false, text is not editable. The default value is true.
633   */
634  editable?: boolean | undefined;
635
636  /**
637   * enum("default", 'numeric', 'email-address', "ascii-capable", 'numbers-and-punctuation', 'url', 'number-pad', 'phone-pad', 'name-phone-pad',
638   * 'decimal-pad', 'twitter', 'web-search', 'visible-password')
639   * Determines which keyboard to open, e.g.numeric.
640   * The following values work across platforms: - default - numeric - email-address - phone-pad
641   * The following values work on iOS: - ascii-capable - numbers-and-punctuation - url - number-pad - name-phone-pad - decimal-pad - twitter - web-search
642   * The following values work on Android: - visible-password
643   */
644  keyboardType?: KeyboardTypeOptions | undefined;
645
646  /**
647   * Works like the inputmode attribute in HTML, it determines which keyboard to open, e.g. numeric and has precedence over keyboardType.
648   */
649  inputMode?: InputModeOptions | undefined;
650
651  /**
652   * Limits the maximum number of characters that can be entered.
653   * Use this instead of implementing the logic in JS to avoid flicker.
654   */
655  maxLength?: number | undefined;
656
657  /**
658   * If true, the text input can be multiple lines. The default value is false.
659   */
660  multiline?: boolean | undefined;
661
662  /**
663   * Callback that is called when the text input is blurred
664   */
665  onBlur?:
666    | ((e: NativeSyntheticEvent<TextInputFocusEventData>) => void)
667    | undefined;
668
669  /**
670   * Callback that is called when the text input's text changes.
671   */
672  onChange?:
673    | ((e: NativeSyntheticEvent<TextInputChangeEventData>) => void)
674    | undefined;
675
676  /**
677   * Callback that is called when the text input's text changes.
678   * Changed text is passed as an argument to the callback handler.
679   */
680  onChangeText?: ((text: string) => void) | undefined;
681
682  /**
683   * Callback that is called when the text input's content size changes.
684   * This will be called with
685   * `{ nativeEvent: { contentSize: { width, height } } }`.
686   *
687   * Only called for multiline text inputs.
688   */
689  onContentSizeChange?:
690    | ((e: NativeSyntheticEvent<TextInputContentSizeChangeEventData>) => void)
691    | undefined;
692
693  /**
694   * Callback that is called when text input ends.
695   */
696  onEndEditing?:
697    | ((e: NativeSyntheticEvent<TextInputEndEditingEventData>) => void)
698    | undefined;
699
700  /**
701   * Callback that is called when a touch is engaged.
702   */
703  onPressIn?: ((e: NativeSyntheticEvent<NativeTouchEvent>) => void) | undefined;
704
705  /**
706   * Callback that is called when a touch is released.
707   */
708  onPressOut?:
709    | ((e: NativeSyntheticEvent<NativeTouchEvent>) => void)
710    | undefined;
711
712  /**
713   * Callback that is called when the text input is focused
714   */
715  onFocus?:
716    | ((e: NativeSyntheticEvent<TextInputFocusEventData>) => void)
717    | undefined;
718
719  /**
720   * Callback that is called when the text input selection is changed.
721   */
722  onSelectionChange?:
723    | ((e: NativeSyntheticEvent<TextInputSelectionChangeEventData>) => void)
724    | undefined;
725
726  /**
727   * Callback that is called when the text input's submit button is pressed.
728   */
729  onSubmitEditing?:
730    | ((e: NativeSyntheticEvent<TextInputSubmitEditingEventData>) => void)
731    | undefined;
732
733  /**
734   * Callback that is called on new text input with the argument
735   *  `{ nativeEvent: { text, previousText, range: { start, end } } }`.
736   *
737   * This prop requires multiline={true} to be set.
738   */
739  onTextInput?:
740    | ((e: NativeSyntheticEvent<TextInputTextInputEventData>) => void)
741    | undefined;
742
743  /**
744   * Invoked on content scroll with
745   *  `{ nativeEvent: { contentOffset: { x, y } } }`.
746   *
747   * May also contain other properties from ScrollEvent but on Android contentSize is not provided for performance reasons.
748   */
749  onScroll?:
750    | ((e: NativeSyntheticEvent<TextInputScrollEventData>) => void)
751    | undefined;
752
753  /**
754   * Callback that is called when a key is pressed.
755   * This will be called with
756   *  `{ nativeEvent: { key: keyValue } }`
757   * where keyValue is 'Enter' or 'Backspace' for respective keys and the typed-in character otherwise including ' ' for space.
758   *
759   * Fires before onChange callbacks.
760   * Note: on Android only the inputs from soft keyboard are handled, not the hardware keyboard inputs.
761   */
762  onKeyPress?:
763    | ((e: NativeSyntheticEvent<TextInputKeyPressEventData>) => void)
764    | undefined;
765
766  /**
767   * The string that will be rendered before text input has been entered
768   */
769  placeholder?: string | undefined;
770
771  /**
772   * The text color of the placeholder string
773   */
774  placeholderTextColor?: ColorValue | undefined;
775
776  /**
777   * enum('default', 'go', 'google', 'join', 'next', 'route', 'search', 'send', 'yahoo', 'done', 'emergency-call')
778   * Determines how the return key should look.
779   */
780  returnKeyType?: ReturnKeyTypeOptions | undefined;
781
782  /**
783   * If true, the text input obscures the text entered so that sensitive text like passwords stay secure.
784   * The default value is false.
785   */
786  secureTextEntry?: boolean | undefined;
787
788  /**
789   * If true, all text will automatically be selected on focus
790   */
791  selectTextOnFocus?: boolean | undefined;
792
793  /**
794   * The start and end of the text input's selection. Set start and end to
795   * the same value to position the cursor.
796   */
797  selection?: {start: number; end?: number | undefined} | undefined;
798
799  /**
800   * The highlight (and cursor on ios) color of the text input
801   */
802  selectionColor?: ColorValue | undefined;
803
804  /**
805   * Styles
806   */
807  style?: StyleProp<TextStyle> | undefined;
808
809  /**
810   * Align the input text to the left, center, or right sides of the input field.
811   */
812  textAlign?: 'left' | 'center' | 'right' | undefined;
813
814  /**
815   * Used to locate this view in end-to-end tests
816   */
817  testID?: string | undefined;
818
819  /**
820   * Used to connect to an InputAccessoryView. Not part of react-natives documentation, but present in examples and
821   * code.
822   * See https://reactnative.dev/docs/inputaccessoryview for more information.
823   */
824  inputAccessoryViewID?: string | undefined;
825
826  /**
827   * The value to show for the text input. TextInput is a controlled component,
828   * which means the native value will be forced to match this value prop if provided.
829   * For most uses this works great, but in some cases this may cause flickering - one common cause is preventing edits by keeping value the same.
830   * In addition to simply setting the same value, either set editable={false},
831   * or set/update maxLength to prevent unwanted edits without flicker.
832   */
833  value?: string | undefined;
834
835  /**
836   * Specifies largest possible scale a font can reach when allowFontScaling is enabled. Possible values:
837   * - null/undefined (default): inherit from the parent node or the global default (0)
838   * - 0: no max, ignore parent/global default
839   * - >= 1: sets the maxFontSizeMultiplier of this node to this value
840   */
841  maxFontSizeMultiplier?: number | null | undefined;
842}
843
844/**
845 * This class is responsible for coordinating the "focused"
846 * state for TextInputs. All calls relating to the keyboard
847 * should be funneled through here
848 */
849interface TextInputState {
850  /**
851   * @deprecated Use currentlyFocusedInput
852   * Returns the ID of the currently focused text field, if one exists
853   * If no text field is focused it returns null
854   */
855  currentlyFocusedField(): number;
856
857  /**
858   * Returns the ref of the currently focused text field, if one exists
859   * If no text field is focused it returns null
860   */
861  currentlyFocusedInput(): React.ElementRef<HostComponent<unknown>>;
862
863  /**
864   * @param textField ref of the text field to focus
865   * Focuses the specified text field
866   * noop if the text field was already focused
867   */
868  focusTextInput(textField?: React.ElementRef<HostComponent<unknown>>): void;
869
870  /**
871   * @param textField ref of the text field to focus
872   * Unfocuses the specified text field
873   * noop if it wasn't focused
874   */
875  blurTextInput(textField?: React.ElementRef<HostComponent<unknown>>): void;
876}
877
878/**
879 * @see https://reactnative.dev/docs/textinput#methods
880 */
881declare class TextInputComponent extends React.Component<TextInputProps> {}
882declare const TextInputBase: Constructor<NativeMethods> &
883  Constructor<TimerMixin> &
884  typeof TextInputComponent;
885export class TextInput extends TextInputBase {
886  /**
887   * Access the current focus state.
888   */
889  static State: TextInputState;
890
891  /**
892   * Returns if the input is currently focused.
893   */
894  isFocused: () => boolean;
895
896  /**
897   * Removes all text from the input.
898   */
899  clear: () => void;
900}
901