Skip to content

Commit 179d490

Browse files
Cassio Zengrabbou
authored andcommitted
Add autoComplete prop (#21575)
Summary: TL;DR: Setting `autoComplete` will allow the system to suggest autofill options for the `<TextInput>` component. Android Oreo introduced the AutoFill Framework, for secure communication between an app and autofill services (e.g. Password managers). When using `<TextInput>` on Android Oreo+, the system already tries to autofill (based on heuristics), but there is no way to set configuring options or disable. The quick solution would be to just add the same Android attributes (`autofillHints` & `importantForAutofill`) in React Native TextInput, but that doesn't bond well with the cross-platform nature of the library. Introduces an `autoComplete` prop based on HTML's `autocomplete` attribute, mapping to Android `autofillHints` & `importantForAutofill` and serving as a proper placeholder for autofill/autocomplete in other platforms: Also gives you the ability to disable autofill by setting autocomplete="off". Pull Request resolved: #21575 Differential Revision: D14102949 Pulled By: hramos fbshipit-source-id: 7601aeaca0332a1f3ce8da8020dba037b700853a
1 parent 2f33b50 commit 179d490

2 files changed

Lines changed: 89 additions & 0 deletions

File tree

‎Libraries/Components/TextInput/TextInput.js‎

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,21 @@ type IOSProps = $ReadOnly<{|
223223
|}>;
224224

225225
typeAndroidProps=$ReadOnly<{|
226+
autoCompleteType?: ?(
227+
|'cc-csc'
228+
|'cc-exp'
229+
|'cc-exp-month'
230+
|'cc-exp-year'
231+
|'cc-number'
232+
|'email'
233+
|'name'
234+
|'password'
235+
|'postal-code'
236+
|'street-address'
237+
|'tel'
238+
|'username'
239+
|'off'
240+
),
226241
returnKeyLabel?: ?string,
227242
numberOfLines?: ?number,
228243
disableFullscreenUI?: ?boolean,
@@ -413,6 +428,45 @@ const TextInput = createReactClass({
413428
'words',
414429
'characters',
415430
]),
431+
/**
432+
* Determines which content to suggest on auto complete, e.g.`username`.
433+
* To disable auto complete, use `off`.
434+
*
435+
* *Android Only*
436+
*
437+
* The following values work on Android only:
438+
*
439+
* - `username`
440+
* - `password`
441+
* - `email`
442+
* - `name`
443+
* - `tel`
444+
* - `street-address`
445+
* - `postal-code`
446+
* - `cc-number`
447+
* - `cc-csc`
448+
* - `cc-exp`
449+
* - `cc-exp-month`
450+
* - `cc-exp-year`
451+
* - `off`
452+
*
453+
* @platform android
454+
*/
455+
autoCompleteType: PropTypes.oneOf([
456+
'cc-csc',
457+
'cc-exp',
458+
'cc-exp-month',
459+
'cc-exp-year',
460+
'cc-number',
461+
'email',
462+
'name',
463+
'password',
464+
'postal-code',
465+
'street-address',
466+
'tel',
467+
'username',
468+
'off',
469+
]),
416470
/**
417471
* If `false`, disables auto-correct. The default value is `true`.
418472
*/

‎ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,41 @@ public void setMaxLength(ReactEditText view, @Nullable Integer maxLength) {
528528
view.setFilters(newFilters);
529529
}
530530

531+
@ReactProp(name = "autoComplete")
532+
publicvoidsetTextContentType(ReactEditTextview, @NullableStringautocomplete) {
533+
if (autocomplete == null) {
534+
view.setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO);
535+
} elseif ("username".equals(autocomplete)) {
536+
view.setAutofillHints(View.AUTOFILL_HINT_USERNAME);
537+
} elseif ("password".equals(autocomplete)) {
538+
view.setAutofillHints(View.AUTOFILL_HINT_PASSWORD);
539+
} elseif ("email".equals(autocomplete)) {
540+
view.setAutofillHints(View.AUTOFILL_HINT_EMAIL_ADDRESS);
541+
} elseif ("name".equals(autocomplete)) {
542+
view.setAutofillHints(View.AUTOFILL_HINT_NAME);
543+
} elseif ("tel".equals(autocomplete)) {
544+
view.setAutofillHints(View.AUTOFILL_HINT_PHONE);
545+
} elseif ("street-address".equals(autocomplete)) {
546+
view.setAutofillHints(View.AUTOFILL_HINT_POSTAL_ADDRESS);
547+
} elseif ("postal-code".equals(autocomplete)) {
548+
view.setAutofillHints(View.AUTOFILL_HINT_POSTAL_CODE);
549+
} elseif ("cc-number".equals(autocomplete)) {
550+
view.setAutofillHints(View.AUTOFILL_HINT_CREDIT_CARD_NUMBER);
551+
} elseif ("cc-csc".equals(autocomplete)) {
552+
view.setAutofillHints(View.AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE);
553+
} elseif ("cc-exp".equals(autocomplete)) {
554+
view.setAutofillHints(View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DATE);
555+
} elseif ("cc-exp-month".equals(autocomplete)) {
556+
view.setAutofillHints(View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH);
557+
} elseif ("cc-exp-year".equals(autocomplete)) {
558+
view.setAutofillHints(View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR);
559+
} elseif ("off".equals(autocomplete)) {
560+
view.setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO);
561+
} else {
562+
thrownewJSApplicationIllegalArgumentException("Invalid autocomplete option: " + autocomplete);
563+
}
564+
}
565+
531566
@ReactProp(name = "autoCorrect")
532567
publicvoidsetAutoCorrect(ReactEditTextview, @NullableBooleanautoCorrect) {
533568
// clear auto correct flags, set SUGGESTIONS or NO_SUGGESTIONS depending on value

0 commit comments

Comments
 (0)