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-label
alias foraccessibilityLabel
. feat: adding aria-label alias for accessibilityLabel #34502 - Add
aria-labelledby
alias foraccessibilityLabelledBy
. feat : add aria labelled as alias for accessibilityLabelledBy #34725 - Add
aria-modal
alias foraccessibilityViewIsModal
(iOS). feat: added aria-modal as alias for accessibilityViewIsModal(iOS) #34506 - Add
id
alias fornativeID
. feat: Add id prop to Text, TouchableWithoutFeedback and View components #34522
Accessibility State. #34524
- Add
aria-busy
alias foraccessibilityState.busy
. - Add
aria-checked
alias foraccessibilityState.checked
.- Support
mixed
value fix: add mixed to aria-checked typings #34633
- Support
- Add
aria-disabled
alias foraccessibilityState.disabled
. - Add
aria-expanded
alias foraccessibilityState.expanded
. - Add
aria-selected
alias foraccessibilityState.selected
.
Accessibility Value. #34535
- Add
aria-valuemax
alias foraccessibilityValue.max
. - Add
aria-valuemin
alias foraccessibilityValue.min
. - Add
aria-valuenow
alias foraccessibilityValue.now
. - Add
aria-valuetext
alias 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
accessibilityRole
but 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
0
and-1
values 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
tintColor
prop 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
referrerPolicy
tosource.headers['Referrer-Policy'] = referrerPolicy
.
- Potentially map
- Add
src
.- Map
src
tosource.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
returnKeyType
values. - 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
keyboardType
values. - 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
rows
tonumberOfLines
(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.