-
Notifications
You must be signed in to change notification settings - Fork 24.9k
Description
Note: All web props mentioned in this umbrella issue are available as part of the React Native 0.71 release
Add support for Web props to core components
Contingent on RFC feedback. This is the umbrella issue for basic React DOM / Web props support on React Native components, as described in this proposal: "RFC: Reduce fragmentation across platforms".
Each of the tasks listed below can be tackled with individual PRs that link back to this issue. Not every task has a known solution or implementation yet, so feel free to discuss implementation details in the comments. Each new prop should take priority over any existing equivalents.
Common props
These props should be supported by core components, i.e., <Image>, <View>, <Text>, <TextInput>, etc.
Prop aliases
- Add
aria-labelalias foraccessibilityLabel. feat: adding aria-label alias for accessibilityLabel #34502 - Add
aria-labelledbyalias foraccessibilityLabelledBy. feat : add aria labelled as alias for accessibilityLabelledBy #34725 - Add
aria-modalalias foraccessibilityViewIsModal(iOS). feat: added aria-modal as alias for accessibilityViewIsModal(iOS) #34506 - Add
idalias fornativeID. feat: Add id prop to Text, TouchableWithoutFeedback and View components #34522
Accessibility State. #34524
- Add
aria-busyalias foraccessibilityState.busy. - Add
aria-checkedalias foraccessibilityState.checked.- Support
mixedvalue fix: add mixed to aria-checked typings #34633
- Support
- Add
aria-disabledalias foraccessibilityState.disabled. - Add
aria-expandedalias foraccessibilityState.expanded. - Add
aria-selectedalias foraccessibilityState.selected.
Accessibility Value. #34535
- Add
aria-valuemaxalias foraccessibilityValue.max. - Add
aria-valueminalias foraccessibilityValue.min. - Add
aria-valuenowalias foraccessibilityValue.now. - Add
aria-valuetextalias foraccessibilityValue.text.
Prop equivalents
- Add
aria-hidden. feat: Add aria-hidden prop to Pressable, View and Touchables components #34552- Alias for
importantforAccessibility='no-hide-descendants'(Android). - Alias for
accessibilityElementsHidden(iOS).
- Alias for
- Add
aria-live. feat: added aria-live as a alias for accessibility-live-region #34555- Alias for
accessibilityLiveRegion(Android). - Map
aria-live='off'toaccessibilityLiveRegion='none'.
- Alias for
- Add
role. Feat/role to accessibility role mapping #34538 (comment) & feat: Add role prop to Text component #34976- Alias for
accessibilityRolebut with full list of ARIA roles allowed. - Map
role='slider'toaccessibilityRole='adjustable' - Map
role='img'toaccessibilityRole='image' - Map
role='presentation'toaccessibilityRole='none' - Map
role='summary'toaccessibilityRole='region' - Add
role='option'support.
- Alias for
- Add
tabIndex. feat: Add tabIndex prop to View component #34486- Only support for
0and-1values only. - Map
tabIndex={0}tofocusable={true}(Android) - Map
tabIndex={-1}tofocusable={false}(Android)
- Only support for
Example:
<View
aria-hidden={true}
aria-busy={false}
aria-label="Accessibility label"
aria-valuetext="Middle"
id="native-id"
role="slider"
tabIndex={0}
>
// same as
<View
accessibilityElementsHidden={true}
accessibilityLabel="Accessibility label"
accessibilityRole="adjustable"
accessibilityState={{ busy: false }}
accessibilityValue={{ text: "Middle" }}
focusable={true}
importantforAccessibility='no-hide-descendants'
nativeId="native-id"
><Image> props
These props should be supported by <Image>.
- Add
alt. feat: Add alt prop to Image component #34550- Support alternative text support.
- Add
tintColorprop to replace non-standardstyle.tintColor. The tintColor style is currently forwarded to a native prop and should instead be exposed as a prop so that React Native for Web does not have to deopt styles for Image rendering. feat: Add tintColor prop to Image component #34534 (comment)
These props are inter-related:crossOrigin and referrerPolicy should only apply if src or srcSet are defined; and src should be ignored if a valid srcSet is defined. The user-provided source prop should be ignored if a valid src or srcSet prop is also defined.
- Add
crossOrigin.- Potentially map
crossOrigin='use-credentials'tosource.headers['Access-Control-Allow-Credentials'] = true.
- Potentially map
- Add
height. - Add
referrerPolicy.- Potentially map
referrerPolicytosource.headers['Referrer-Policy'] = referrerPolicy.
- Potentially map
- Add
src.- Map
srctosource.uri.
- Map
- Add
srcSet.- Map
srcSet='path1 x1, path1 x2'tosource=[{ uri: path1, scale: 1 }, { uri: path2, scale: 2 }].
- Map
- Add
width.
Example mapping to source:
const { crossOrigin, height, referrerPolicy, src, srcSet, width } = props;
let source = null;
if (src != null) {
const headers = {};
if (crossOrigin === 'use-credentials') {
headers['Access-Control-Allow-Credentials'] = true;
}
if (referrerPolicy != null) {
headers['Referrer-Policy'] = referrerPolicy;
}
nextProps.progressiveRenderingEnabled = true;
source = { headers, height, uri: src, width };
}
if (srcSet != null) {
source = [];
const srcList = srcSet.split(', ');
srcList.forEach((src) => {
const [uri, xscale] = src.split(' ');
const scale = parseInt(xscale.split('x')[0], 10);
const headers = {};
if (crossOrigin === 'use-credentials') {
headers['Access-Control-Allow-Credentials'] = true;
}
if (referrerPolicy != null) {
headers['Referrer-Policy'] = referrerPolicy;
}
source.push({ headers, height, scale, uri, width });
});
}Example:
<Image
alt="Alternative text"
crossOrigin="use-credentials"
height={300}
referrerPolicy="origin"
srcSet="https://image.png 1x, https://image2.png 2x"
width={500}
>
// same as
<Image
source={[
{
uri: "https://image.png",
scale: 1,
height: 300,
headers: {
'Access-Control-Allow-Credentials': true,
'Referrer-Policy': 'origin'
},
width: 500
}
{
uri: "https://image2.png",
scale: 2,
height: 300,
headers: {
'Access-Control-Allow-Credentials': true,
'Referrer-Policy': 'origin'
},
width: 500
}
]}
><TextInput> props
These props should be supported by <TextInput>.
- Redefine
autoComplete. feat: Unify TextInput autoComplete and textContentType props #34523- Unify values for Android (
autoComplete) and iOS (textContentType) with Web (autoComplete). - See code below for example mapping.
- Unify values for Android (
- Add
enterKeyHint. feat: added enterKeyHint prop to textInput #34482- Map to equivalent
returnKeyTypevalues. - Map
enterKeyHint === 'enter'toreturnKeyType = 'default' - Map
enterKeyHint === 'done'toreturnKeyType = 'done' - Map
enterKeyHint === 'go'toreturnKeyType = 'go' - Map
enterKeyHint === 'next'toreturnKeyType = 'next' - Map
enterKeyHint === 'previous'toreturnKeyType = 'previous' - Map
enterKeyHint === 'search'toreturnKeyType = 'search' - Map
enterKeyHint === 'send'toreturnKeyType = 'send'
- Map to equivalent
- Add
inputMode. feat: Add inputMode prop to TextInput component #34460- Map to equivalent
keyboardTypevalues. - Map
inputMode === 'none'toshowSoftInputOnFocus={false}feat: Update TextInput inputMode to map "none" to showSoftInputOnFocus #35228 - Map
inputMode === 'text'tokeyboardType = 'text' - Map
inputMode === 'decimal'tokeyboardType = 'decimal-pad' - Map
inputMode === 'email'tokeyboardType = 'email-address' - Map
inputMode === 'numeric'tokeyboardType = 'numeric' - Map
inputMode === 'search'tokeyboardType = 'search' - Map
inputMode === 'tel'tokeyboardType = 'phone-pad' - Map
inputMode === 'url'tokeyboardType = 'url'
- Map to equivalent
- Add
readOnly. feat: Add readOnly prop to TextInput component #34444- Map
readOnly={false}toeditable={true}. - Map
readOnly={true}toeditable={false}.
- Map
- Add
rows(formultiline={true}). feat: Add rows prop to TextInput component #34488- Map
rowstonumberOfLines(Android).
- Map
Example autoComplete mapping:
// https://reactnative.dev/docs/textinput#autocomplete-android
const autoCompleteAndroid = {
// web: android
'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',
name: 'name',
'additional-name': 'name-middle',
'family-name': 'name-family',
'given-name': 'name-given',
'honorific-prefix': 'namePrefix',
'honorific-suffix': 'nameSuffix',
'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'
};
// https://reactnative.dev/docs/textinput#textcontenttype-ios
const autoCompleteIOS = {
// web: ios
'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': 'name-prefix',
'honorific-suffix': 'name-suffix',
'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'
};Examples:
<TextArea
autoComplete="email"
inputMode="email"
/>
// same as
<TextArea
autoComplete="email"
keyboardType="email-address"
textContentType="emailAddress"
/><TextArea
multiline
readOnly={true}
rows={3}
/>
// same as
<TextArea
editable={false}
multiline
numberOfLines={3}
/>Documentation
- Update react-native-website docs to include all these props. @gabrieldonadel has several PRs open for individual props, which we may want to consolidate into a single PR and add remaining props, so it can be merged in one commit.