feat: Unify TextInput autoComplete and textContentType props (#34523)
Summary: This unifies the Android only `autoComplete` and the iOS only `textContentType` TextInput props with the web `autoComplete` values as requested on https://github.com/facebook/react-native/issues/34424. I left the `textContentType` prop and the current supported `autoComplete` values untouched in order to avoid having a breaking change. This also updates RNTester to include test cases using the new `autoComplete` values ## Changelog <!-- Help reviewers and the release process by writing your own changelog entry. For an example, see: https://reactnative.dev/contributing/changelogs-in-pull-requests --> [General] [Changed] - Unify TextInput autoComplete and textContentType props Pull Request resolved: https://github.com/facebook/react-native/pull/34523 Test Plan: 1. Open the RNTester app and navigate to the TextInput page 2. Test the `TextInput` component through the `Text Auto Complete` section https://user-images.githubusercontent.com/11707729/187118267-3b509631-7b84-47b7-a580-567a7f5b483f.mov Reviewed By: NickGerleman Differential Revision: D39104545 Pulled By: cipolleschi fbshipit-source-id: a0d4b1b9ab336854a741a9efe4a62c3da0b5c0f4
This commit is contained in:
Родитель
7ea54a4087
Коммит
73abcba40f
|
@ -229,6 +229,36 @@ export type enterKeyHintType =
|
|||
type PasswordRules = string;
|
||||
|
||||
type IOSProps = $ReadOnly<{|
|
||||
/**
|
||||
* Give the keyboard and the system information about the
|
||||
* expected semantic meaning for the content that users enter.
|
||||
* @platform ios
|
||||
*/
|
||||
autoComplete?: ?(
|
||||
| 'address-line1'
|
||||
| 'address-line2'
|
||||
| 'cc-number'
|
||||
| 'current-password'
|
||||
| 'country'
|
||||
| 'email'
|
||||
| 'name'
|
||||
| 'additional-name'
|
||||
| 'family-name'
|
||||
| 'given-name'
|
||||
| 'nickname'
|
||||
| 'honorific-prefix'
|
||||
| 'honorific-suffix'
|
||||
| 'new-password'
|
||||
| 'off'
|
||||
| 'one-time-code'
|
||||
| 'organization'
|
||||
| 'organization-title'
|
||||
| 'postal-code'
|
||||
| 'street-address'
|
||||
| 'tel'
|
||||
| 'url'
|
||||
| 'username'
|
||||
),
|
||||
/**
|
||||
* When the clear button should appear on the right side of the text view.
|
||||
* This property is supported only for single-line TextInput component.
|
||||
|
@ -411,6 +441,23 @@ type AndroidProps = $ReadOnly<{|
|
|||
| 'username'
|
||||
| 'username-new'
|
||||
| 'off'
|
||||
// additional HTML autocomplete values
|
||||
| 'address-line1'
|
||||
| 'address-line2'
|
||||
| 'bday'
|
||||
| 'bday-day'
|
||||
| 'bday-month'
|
||||
| 'bday-year'
|
||||
| 'country'
|
||||
| 'current-password'
|
||||
| 'honorific-prefix'
|
||||
| 'honorific-suffix'
|
||||
| 'additional-name'
|
||||
| 'family-name'
|
||||
| 'given-name'
|
||||
| 'new-password'
|
||||
| 'one-time-code'
|
||||
| 'sex'
|
||||
),
|
||||
|
||||
/**
|
||||
|
@ -1470,6 +1517,67 @@ const inputModeToKeyboardTypeMap = {
|
|||
url: 'url',
|
||||
};
|
||||
|
||||
// Map HTML autocomplete values to Android autoComplete values
|
||||
const autoCompleteWebToAutoCompleteAndroidMap = {
|
||||
'address-line1': 'postal-address-region',
|
||||
'address-line2': 'postal-address-locality',
|
||||
bday: 'birthdate-full',
|
||||
'bday-day': 'birthdate-day',
|
||||
'bday-month': 'birthdate-month',
|
||||
'bday-year': 'birthdate-year',
|
||||
'cc-csc': 'cc-csc',
|
||||
'cc-exp': 'cc-exp',
|
||||
'cc-exp-month': 'cc-exp-month',
|
||||
'cc-exp-year': 'cc-exp-year',
|
||||
'cc-number': 'cc-number',
|
||||
country: 'postal-address-country',
|
||||
'current-password': 'password',
|
||||
email: 'email',
|
||||
'honorific-prefix': 'name-prefix',
|
||||
'honorific-suffix': 'name-suffix',
|
||||
name: 'name',
|
||||
'additional-name': 'name-middle',
|
||||
'family-name': 'name-family',
|
||||
'given-name': 'name-given',
|
||||
'new-password': 'password-new',
|
||||
off: 'off',
|
||||
'one-time-code': 'sms-otp',
|
||||
'postal-code': 'postal-code',
|
||||
sex: 'gender',
|
||||
'street-address': 'street-address',
|
||||
tel: 'tel',
|
||||
'tel-country-code': 'tel-country-code',
|
||||
'tel-national': 'tel-national',
|
||||
username: 'username',
|
||||
};
|
||||
|
||||
// Map HTML autocomplete values to iOS textContentType values
|
||||
const autoCompleteWebToTextContentTypeMap = {
|
||||
'address-line1': 'streetAddressLine1',
|
||||
'address-line2': 'streetAddressLine2',
|
||||
'cc-number': 'creditCardNumber',
|
||||
'current-password': 'password',
|
||||
country: 'countryName',
|
||||
email: 'emailAddress',
|
||||
name: 'name',
|
||||
'additional-name': 'middleName',
|
||||
'family-name': 'familyName',
|
||||
'given-name': 'givenName',
|
||||
nickname: 'nickname',
|
||||
'honorific-prefix': 'namePrefix',
|
||||
'honorific-suffix': 'nameSuffix',
|
||||
'new-password': 'newPassword',
|
||||
off: 'none',
|
||||
'one-time-code': 'oneTimeCode',
|
||||
organization: 'organizationName',
|
||||
'organization-title': 'jobTitle',
|
||||
'postal-code': 'postalCode',
|
||||
'street-address': 'fullStreetAddress',
|
||||
tel: 'telephoneNumber',
|
||||
url: 'URL',
|
||||
username: 'username',
|
||||
};
|
||||
|
||||
const ExportedForwardRef: React.AbstractComponent<
|
||||
React.ElementConfig<typeof InternalTextInput>,
|
||||
React.ElementRef<HostComponent<mixed>> & ImperativeMethods,
|
||||
|
@ -1478,6 +1586,8 @@ const ExportedForwardRef: React.AbstractComponent<
|
|||
allowFontScaling = true,
|
||||
rejectResponderTermination = true,
|
||||
underlineColorAndroid = 'transparent',
|
||||
autoComplete,
|
||||
textContentType,
|
||||
readOnly,
|
||||
editable,
|
||||
enterKeyHint,
|
||||
|
@ -1502,6 +1612,21 @@ const ExportedForwardRef: React.AbstractComponent<
|
|||
keyboardType={
|
||||
inputMode ? inputModeToKeyboardTypeMap[inputMode] : keyboardType
|
||||
}
|
||||
autoComplete={
|
||||
Platform.OS === 'android'
|
||||
? // $FlowFixMe
|
||||
autoCompleteWebToAutoCompleteAndroidMap[autoComplete] ??
|
||||
autoComplete
|
||||
: undefined
|
||||
}
|
||||
textContentType={
|
||||
Platform.OS === 'ios' &&
|
||||
autoComplete &&
|
||||
autoComplete in autoCompleteWebToTextContentTypeMap
|
||||
? // $FlowFixMe
|
||||
autoCompleteWebToTextContentTypeMap[autoComplete]
|
||||
: textContentType
|
||||
}
|
||||
{...restProps}
|
||||
forwardedRef={forwardedRef}
|
||||
/>
|
||||
|
|
|
@ -437,6 +437,35 @@ exports.examples = ([
|
|||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Text Auto Complete',
|
||||
render: function (): React.Node {
|
||||
return (
|
||||
<View>
|
||||
<TextInput
|
||||
autoComplete="country"
|
||||
placeholder="country"
|
||||
style={styles.default}
|
||||
/>
|
||||
<TextInput
|
||||
autoComplete="postal-address-country"
|
||||
placeholder="postal-address-country"
|
||||
style={styles.default}
|
||||
/>
|
||||
<TextInput
|
||||
autoComplete="one-time-code"
|
||||
placeholder="one-time-code"
|
||||
style={styles.default}
|
||||
/>
|
||||
<TextInput
|
||||
autoComplete="sms-otp"
|
||||
placeholder="sms-otp"
|
||||
style={styles.default}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Return key',
|
||||
render: function (): React.Node {
|
||||
|
|
|
@ -798,6 +798,21 @@ exports.examples = ([
|
|||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Text Auto Complete',
|
||||
render: function (): React.Node {
|
||||
return (
|
||||
<View>
|
||||
<WithLabel label="country">
|
||||
<TextInput autoComplete="country" style={styles.default} />
|
||||
</WithLabel>
|
||||
<WithLabel label="one-time-code">
|
||||
<TextInput autoComplete="one-time-code" style={styles.default} />
|
||||
</WithLabel>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Text Content Type',
|
||||
render: function (): React.Node {
|
||||
|
|
Загрузка…
Ссылка в новой задаче