[w3c] ☂️ Web Props (Part 1) umbrella issue
See original GitHub issueAdd 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
. https://github.com/facebook/react-native/pull/34502 - Add
aria-labelledby
alias foraccessibilityLabelledBy
. https://github.com/facebook/react-native/pull/34725 - Add
aria-modal
alias foraccessibilityViewIsModal
(iOS). https://github.com/facebook/react-native/pull/34506 - Add
id
alias fornativeID
. https://github.com/facebook/react-native/pull/34522
Accessibility State. https://github.com/facebook/react-native/pull/34524
- Add
aria-busy
alias foraccessibilityState.busy
. - Add
aria-checked
alias foraccessibilityState.checked
.- Support
mixed
value https://github.com/facebook/react-native/pull/34633
- Support
- Add
aria-disabled
alias foraccessibilityState.disabled
. - Add
aria-expanded
alias foraccessibilityState.expanded
. - Add
aria-selected
alias foraccessibilityState.selected
.
Accessibility Value. https://github.com/facebook/react-native/pull/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
. https://github.com/facebook/react-native/pull/34552- Alias for
importantforAccessibility='no-hide-descendants'
(Android). - Alias for
accessibilityElementsHidden
(iOS).
- Alias for
- Add
aria-live
. https://github.com/facebook/react-native/pull/34555- Alias for
accessibilityLiveRegion
(Android). - Map
aria-live='off'
toaccessibilityLiveRegion='none'
.
- Alias for
- Add
role
. https://github.com/facebook/react-native/pull/34538#issuecomment-1232918518 & https://github.com/facebook/react-native/pull/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
. https://github.com/facebook/react-native/pull/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
. https://github.com/facebook/react-native/pull/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. https://github.com/facebook/react-native/pull/34534#issuecomment-1232902094
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.
https://github.com/facebook/react-native/pull/34481
- 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
. https://github.com/facebook/react-native/pull/34523- Unify values for Android (
autoComplete
) and iOS (textContentType
) with Web (autoComplete
). - See code below for example mapping.
- Unify values for Android (
- Add
enterKeyHint
. https://github.com/facebook/react-native/pull/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
. https://github.com/facebook/react-native/pull/34460- Map to equivalent
keyboardType
values. - Map
inputMode === 'none'
toshowSoftInputOnFocus={false}
https://github.com/facebook/react-native/pull/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
. https://github.com/facebook/react-native/pull/34444- Map
readOnly={false}
toeditable={true}
. - Map
readOnly={true}
toeditable={false}
.
- Map
- Add
rows
(formultiline={true}
). https://github.com/facebook/react-native/pull/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.
Issue Analytics
- State:
- Created a year ago
- Reactions:37
- Comments:24 (19 by maintainers)
Top GitHub Comments
All the props listed here have been implemented. Thanks so much to everyone who helped here, especially @gabrieldonadel for helping from start to end!
I’m going complete some updates to RNWeb so that it allows these props too.
And then I will probably create a “Part 2” issue with a few more props from the RFC. I’ll also be updating the RFC with more details about the Event and Element APIs, which will likely form new umbrella issues.
I also want to set expectations: for at least the next 6 months, Meta is unlikely to be able to commit engineers to work on new native features to expand CSS support (with the exception of flexbox-related changes to Yoga). But if contributors who want these CSS features can develop and test them, we will help to integrate the code and give credit where it is due. Thanks!