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: https://github.com/facebook/react-native/pull/21575

Differential Revision: D14102949

Pulled By: hramos

fbshipit-source-id: 7601aeaca0332a1f3ce8da8020dba037b700853a
This commit is contained in:
Cassio Zen
2019-02-15 09:13:05 -08:00
committed by Facebook Github Bot
parent 53b87dcfff
commit f15145639d
2 changed files with 89 additions and 0 deletions
@@ -529,6 +529,41 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
view.setFilters(newFilters);
}
@ReactProp(name = "autoComplete")
public void setTextContentType(ReactEditText view, @Nullable String autocomplete) {
if (autocomplete == null) {
view.setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO);
} else if ("username".equals(autocomplete)) {
view.setAutofillHints(View.AUTOFILL_HINT_USERNAME);
} else if ("password".equals(autocomplete)) {
view.setAutofillHints(View.AUTOFILL_HINT_PASSWORD);
} else if ("email".equals(autocomplete)) {
view.setAutofillHints(View.AUTOFILL_HINT_EMAIL_ADDRESS);
} else if ("name".equals(autocomplete)) {
view.setAutofillHints(View.AUTOFILL_HINT_NAME);
} else if ("tel".equals(autocomplete)) {
view.setAutofillHints(View.AUTOFILL_HINT_PHONE);
} else if ("street-address".equals(autocomplete)) {
view.setAutofillHints(View.AUTOFILL_HINT_POSTAL_ADDRESS);
} else if ("postal-code".equals(autocomplete)) {
view.setAutofillHints(View.AUTOFILL_HINT_POSTAL_CODE);
} else if ("cc-number".equals(autocomplete)) {
view.setAutofillHints(View.AUTOFILL_HINT_CREDIT_CARD_NUMBER);
} else if ("cc-csc".equals(autocomplete)) {
view.setAutofillHints(View.AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE);
} else if ("cc-exp".equals(autocomplete)) {
view.setAutofillHints(View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DATE);
} else if ("cc-exp-month".equals(autocomplete)) {
view.setAutofillHints(View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH);
} else if ("cc-exp-year".equals(autocomplete)) {
view.setAutofillHints(View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR);
} else if ("off".equals(autocomplete)) {
view.setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO);
} else {
throw new JSApplicationIllegalArgumentException("Invalid autocomplete option: " + autocomplete);
}
}
@ReactProp(name = "autoCorrect")
public void setAutoCorrect(ReactEditText view, @Nullable Boolean autoCorrect) {
// clear auto correct flags, set SUGGESTIONS or NO_SUGGESTIONS depending on value