mirror of
https://github.com/zoriya/react-native-web.git
synced 2026-05-23 14:57:13 +00:00
[fix] support React Native props in 'setNativeProps'
React Native allows props like 'pointerEvents' to be set using 'setNativeProps'. Fix #392
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import createDOMProps from '../createDOMProps';
|
||||
import findNodeHandle from '../findNodeHandle';
|
||||
import StyleRegistry from '../../apis/StyleSheet/registry';
|
||||
import UIManager from '../../apis/UIManager';
|
||||
@@ -70,10 +71,9 @@ const NativeMethodsMixin = {
|
||||
const node = findNodeHandle(this);
|
||||
const classList = [...node.classList];
|
||||
|
||||
const { className, style } = StyleRegistry.resolveStateful(nativeProps.style, classList);
|
||||
const props = { ...nativeProps, className, style };
|
||||
|
||||
UIManager.updateView(node, props, this);
|
||||
const domProps = createDOMProps(nativeProps, style =>
|
||||
StyleRegistry.resolveStateful(style, classList));
|
||||
UIManager.updateView(node, domProps, this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import '../injectResponderEventPlugin';
|
||||
|
||||
import createDOMProps from '../createDOMProps';
|
||||
import getAccessibilityRole from '../getAccessibilityRole';
|
||||
import normalizeNativeEvent from '../normalizeNativeEvent';
|
||||
import React from 'react';
|
||||
@@ -52,28 +53,12 @@ const wrapEventHandler = handler => e => {
|
||||
};
|
||||
|
||||
const createDOMElement = (component, rnProps) => {
|
||||
const {
|
||||
accessibilityLabel,
|
||||
accessibilityLiveRegion,
|
||||
accessible = true,
|
||||
style: rnStyle,
|
||||
testID,
|
||||
type,
|
||||
/* eslint-disable */
|
||||
accessibilityComponentType,
|
||||
accessibilityRole,
|
||||
accessibilityTraits,
|
||||
/* eslint-enable */
|
||||
...domProps
|
||||
} = rnProps || emptyObject;
|
||||
|
||||
// use equivalent platform elements where possible
|
||||
const role = getAccessibilityRole(rnProps || emptyObject);
|
||||
const accessibilityComponent = role && roleComponents[role];
|
||||
const Component = accessibilityComponent || component;
|
||||
|
||||
// convert React Native styles to DOM styles
|
||||
const { className, style } = StyleRegistry.resolve(rnStyle) || emptyObject;
|
||||
const domProps = createDOMProps(rnProps, style => StyleRegistry.resolve(style));
|
||||
|
||||
// normalize DOM events to match React Native events
|
||||
// TODO: move this out of the render path
|
||||
@@ -86,36 +71,6 @@ const createDOMElement = (component, rnProps) => {
|
||||
}
|
||||
}
|
||||
|
||||
if (!accessible) {
|
||||
domProps['aria-hidden'] = true;
|
||||
}
|
||||
if (accessibilityLabel) {
|
||||
domProps['aria-label'] = accessibilityLabel;
|
||||
}
|
||||
if (accessibilityLiveRegion) {
|
||||
domProps['aria-live'] = accessibilityLiveRegion;
|
||||
}
|
||||
if (className && className !== '') {
|
||||
domProps.className = domProps.className ? `${domProps.className} ${className}` : className;
|
||||
}
|
||||
if (role) {
|
||||
domProps.role = role;
|
||||
if (role === 'button') {
|
||||
domProps.type = 'button';
|
||||
} else if (role === 'link' && domProps.target === '_blank') {
|
||||
domProps.rel = `${domProps.rel || ''} noopener noreferrer`;
|
||||
}
|
||||
}
|
||||
if (style) {
|
||||
domProps.style = style;
|
||||
}
|
||||
if (testID) {
|
||||
domProps['data-testid'] = testID;
|
||||
}
|
||||
if (type) {
|
||||
domProps.type = type;
|
||||
}
|
||||
|
||||
return <Component {...domProps} />;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
import getAccessibilityRole from '../getAccessibilityRole';
|
||||
import StyleSheet from '../../apis/StyleSheet';
|
||||
|
||||
const emptyObject = {};
|
||||
|
||||
const pointerEventStyles = StyleSheet.create({
|
||||
auto: {
|
||||
pointerEvents: 'auto'
|
||||
},
|
||||
'box-none': {
|
||||
pointerEvents: 'box-none'
|
||||
},
|
||||
'box-only': {
|
||||
pointerEvents: 'box-only'
|
||||
},
|
||||
none: {
|
||||
pointerEvents: 'none'
|
||||
}
|
||||
});
|
||||
|
||||
const createDOMProps = (rnProps, resolveStyle) => {
|
||||
const {
|
||||
accessibilityLabel,
|
||||
accessibilityLiveRegion,
|
||||
accessible = true,
|
||||
pointerEvents,
|
||||
style: rnStyle,
|
||||
testID,
|
||||
type,
|
||||
/* eslint-disable */
|
||||
accessibilityComponentType,
|
||||
accessibilityRole,
|
||||
accessibilityTraits,
|
||||
/* eslint-enable */
|
||||
...domProps
|
||||
} = rnProps || emptyObject;
|
||||
|
||||
const pointerEventStyle = pointerEvents && pointerEventStyles[pointerEvents];
|
||||
const { className, style } = resolveStyle([rnStyle, pointerEventStyle]) || emptyObject;
|
||||
const role = getAccessibilityRole(rnProps || emptyObject);
|
||||
|
||||
if (!accessible) {
|
||||
domProps['aria-hidden'] = true;
|
||||
}
|
||||
if (accessibilityLabel) {
|
||||
domProps['aria-label'] = accessibilityLabel;
|
||||
}
|
||||
if (accessibilityLiveRegion) {
|
||||
domProps['aria-live'] = accessibilityLiveRegion;
|
||||
}
|
||||
if (className && className !== '') {
|
||||
domProps.className = domProps.className ? `${domProps.className} ${className}` : className;
|
||||
}
|
||||
if (role) {
|
||||
domProps.role = role;
|
||||
if (role === 'button') {
|
||||
domProps.type = 'button';
|
||||
} else if (role === 'link' && domProps.target === '_blank') {
|
||||
domProps.rel = `${domProps.rel || ''} noopener noreferrer`;
|
||||
}
|
||||
}
|
||||
if (style) {
|
||||
domProps.style = style;
|
||||
}
|
||||
if (testID) {
|
||||
domProps['data-testid'] = testID;
|
||||
}
|
||||
if (type) {
|
||||
domProps.type = type;
|
||||
}
|
||||
|
||||
return domProps;
|
||||
};
|
||||
|
||||
module.exports = createDOMProps;
|
||||
Reference in New Issue
Block a user