From 740c9ce957bd17437742869f7551f9e512932b60 Mon Sep 17 00:00:00 2001 From: cyrus25 Date: Sat, 3 Sep 2022 13:07:09 +0530 Subject: [PATCH 1/3] feat: Added pointerEvents style equivalent to pointerEvents prop --- .../View/ReactNativeStyleAttributes.js | 1 + Libraries/Components/View/View.js | 10 +- Libraries/StyleSheet/StyleSheetTypes.js | 1 + .../PointerEvents/PointerEventsExample.js | 120 ++++++++++++++++++ 4 files changed, 131 insertions(+), 1 deletion(-) diff --git a/Libraries/Components/View/ReactNativeStyleAttributes.js b/Libraries/Components/View/ReactNativeStyleAttributes.js index 542bfd3a88eedd..620dd8fdad98e8 100644 --- a/Libraries/Components/View/ReactNativeStyleAttributes.js +++ b/Libraries/Components/View/ReactNativeStyleAttributes.js @@ -111,6 +111,7 @@ const ReactNativeStyleAttributes: {[string]: AnyAttributeType, ...} = { borderTopRightRadius: true, borderTopStartRadius: true, opacity: true, + pointerEvents: true, /** * Text diff --git a/Libraries/Components/View/View.js b/Libraries/Components/View/View.js index 7822e8184f214b..20b6f90fecb2e7 100644 --- a/Libraries/Components/View/View.js +++ b/Libraries/Components/View/View.js @@ -12,6 +12,7 @@ import type {ViewProps} from './ViewPropTypes'; import ViewNativeComponent from './ViewNativeComponent'; import TextAncestor from '../../Text/TextAncestor'; +import flattenStyle from '../../StyleSheet/flattenStyle'; import * as React from 'react'; export type Props = ViewProps; @@ -27,12 +28,19 @@ const View: React.AbstractComponent< ViewProps, React.ElementRef, > = React.forwardRef( - ({tabIndex, focusable, ...otherProps}: ViewProps, forwardedRef) => { + ( + {tabIndex, focusable, style, pointerEvents, ...otherProps}: ViewProps, + forwardedRef, + ) => { + const flattendStyle = flattenStyle(style); + const newPointerEvents = pointerEvents || flattendStyle?.pointerEvents; return ( diff --git a/Libraries/StyleSheet/StyleSheetTypes.js b/Libraries/StyleSheet/StyleSheetTypes.js index 0ff1d26f64dd29..a78e58061d8be5 100644 --- a/Libraries/StyleSheet/StyleSheetTypes.js +++ b/Libraries/StyleSheet/StyleSheetTypes.js @@ -558,6 +558,7 @@ export type ____ViewStyle_InternalCore = $ReadOnly<{ borderTopWidth?: number | AnimatedNode, opacity?: number | AnimatedNode, elevation?: number, + pointerEvents?: 'auto' | 'none' | 'box-none' | 'box-only', }>; export type ____ViewStyle_Internal = $ReadOnly<{ diff --git a/packages/rn-tester/js/examples/PointerEvents/PointerEventsExample.js b/packages/rn-tester/js/examples/PointerEvents/PointerEventsExample.js index c07f11da6677c2..978a67697c2436 100644 --- a/packages/rn-tester/js/examples/PointerEvents/PointerEventsExample.js +++ b/packages/rn-tester/js/examples/PointerEvents/PointerEventsExample.js @@ -95,6 +95,36 @@ class NoneExample extends React.Component<$FlowFixMeProps> { } } +class NoneStyleExample extends React.Component<$FlowFixMeProps> { + render(): React.Node { + return ( + this.props.onLog('A unspecified touched')} + style={styles.box}> + A: unspecified + this.props.onLog('B none touched')} + style={[ + styles.box, + styles.boxPassedThrough, + {pointerEvents: 'none'}, + ]}> + + B: none + + this.props.onLog('C unspecified touched')} + style={[styles.box, styles.boxPassedThrough]}> + + C: unspecified + + + + + ); + } +} + /** * Special demo text that makes itself untouchable so that it doesn't destroy * the experiment and confuse the output. @@ -142,6 +172,41 @@ class BoxNoneExample extends React.Component<$FlowFixMeProps> { } } +class BoxNoneStyleExample extends React.Component<$FlowFixMeProps> { + render(): React.Node { + return ( + this.props.onLog('A unspecified touched')} + style={styles.box}> + A: unspecified + this.props.onLog('B box-none touched')} + style={[ + styles.box, + styles.boxPassedThrough, + {pointerEvents: 'box-none'}, + ]}> + + B: box-none + + this.props.onLog('C unspecified touched')} + style={styles.box}> + C: unspecified + + + this.props.onLog('C explicitly unspecified touched') + } + style={[styles.box, {pointerEvents: 'auto'}]}> + C: explicitly unspecified + + + + ); + } +} + class BoxOnlyExample extends React.Component<$FlowFixMeProps> { render(): React.Node { return ( @@ -177,6 +242,43 @@ class BoxOnlyExample extends React.Component<$FlowFixMeProps> { } } +class BoxOnlyStyleExample extends React.Component<$FlowFixMeProps> { + render(): React.Node { + return ( + this.props.onLog('A unspecified touched')} + style={styles.box}> + A: unspecified + this.props.onLog('B box-only touched')} + style={[styles.box, {pointerEvents: 'box-only'}]}> + B: box-only + this.props.onLog('C unspecified touched')} + style={[styles.box, styles.boxPassedThrough]}> + + C: unspecified + + + + this.props.onLog('C explicitly unspecified touched') + } + style={[ + styles.box, + styles.boxPassedThrough, + {pointerEvents: 'auto'}, + ]}> + + C: explicitly unspecified + + + + + ); + } +} + type OverflowExampleProps = $ReadOnly<{| overflow: 'hidden' | 'visible', onLog: (msg: string) => void, @@ -242,18 +344,36 @@ const exampleClasses: Array = [ description: '`none` causes touch events on the container and its child components to pass through to the parent container.', }, + { + Component: NoneStyleExample, + title: '`none` style', + description: + '`none` causes touch events on the container and its child components to pass through to the parent container.', + }, { Component: BoxNoneExample, title: '`box-none`', description: '`box-none` causes touch events on the container to pass through and will only detect touch events on its child components.', }, + { + Component: BoxNoneStyleExample, + title: '`box-none` style', + description: + '`box-none` causes touch events on the container to pass through and will only detect touch events on its child components.', + }, { Component: BoxOnlyExample, title: '`box-only`', description: "`box-only` causes touch events on the container's child components to pass through and will only detect touch events on the container itself.", }, + { + Component: BoxOnlyStyleExample, + title: '`box-only` style', + description: + "`box-only` causes touch events on the container's child components to pass through and will only detect touch events on the container itself.", + }, { Component: OverflowVisibleExample, title: '`overflow: visible`', From 58e50526c67ae0a8b5c852f1c97ab59420420d4e Mon Sep 17 00:00:00 2001 From: cyrus25 Date: Sat, 3 Sep 2022 13:26:57 +0530 Subject: [PATCH 2/3] moved inline style to stylesheet --- .../PointerEvents/PointerEventsExample.js | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/packages/rn-tester/js/examples/PointerEvents/PointerEventsExample.js b/packages/rn-tester/js/examples/PointerEvents/PointerEventsExample.js index 978a67697c2436..bf90aeda1222f7 100644 --- a/packages/rn-tester/js/examples/PointerEvents/PointerEventsExample.js +++ b/packages/rn-tester/js/examples/PointerEvents/PointerEventsExample.js @@ -107,7 +107,7 @@ class NoneStyleExample extends React.Component<$FlowFixMeProps> { style={[ styles.box, styles.boxPassedThrough, - {pointerEvents: 'none'}, + styles.pointerEventsNone, ]}> B: none @@ -184,7 +184,7 @@ class BoxNoneStyleExample extends React.Component<$FlowFixMeProps> { style={[ styles.box, styles.boxPassedThrough, - {pointerEvents: 'box-none'}, + styles.pointerEventsBoxNone, ]}> B: box-none @@ -198,7 +198,7 @@ class BoxNoneStyleExample extends React.Component<$FlowFixMeProps> { onTouchStart={() => this.props.onLog('C explicitly unspecified touched') } - style={[styles.box, {pointerEvents: 'auto'}]}> + style={[styles.box, styles.pointerEventsAuto]}> C: explicitly unspecified @@ -251,7 +251,7 @@ class BoxOnlyStyleExample extends React.Component<$FlowFixMeProps> { A: unspecified this.props.onLog('B box-only touched')} - style={[styles.box, {pointerEvents: 'box-only'}]}> + style={[styles.box, styles.pointerEventsBoxOnly]}> B: box-only this.props.onLog('C unspecified touched')} @@ -267,7 +267,7 @@ class BoxOnlyStyleExample extends React.Component<$FlowFixMeProps> { style={[ styles.box, styles.boxPassedThrough, - {pointerEvents: 'auto'}, + styles.pointerEventsAuto, ]}> C: explicitly unspecified @@ -446,6 +446,18 @@ const styles = StyleSheet.create({ borderColor: '#f0f0f0', backgroundColor: '#f9f9f9', }, + pointerEventsBoxNone: { + pointerEvents: 'box-none', + }, + pointerEventsBoxOnly: { + pointerEvents: 'box-only', + }, + pointerEventsNone: { + pointerEvents: 'none', + }, + pointerEventsAuto: { + pointerEvents: 'auto', + }, }); exports.framework = 'React'; From ccedf8ba45952d9a5f8bee34ffc74d1082c89a4f Mon Sep 17 00:00:00 2001 From: cyrus25 Date: Sat, 3 Sep 2022 13:38:22 +0530 Subject: [PATCH 3/3] spelling fix --- .../PointerEvents/PointerEventsExample.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/rn-tester/js/examples/PointerEvents/PointerEventsExample.js b/packages/rn-tester/js/examples/PointerEvents/PointerEventsExample.js index bf90aeda1222f7..069ac9384f04da 100644 --- a/packages/rn-tester/js/examples/PointerEvents/PointerEventsExample.js +++ b/packages/rn-tester/js/examples/PointerEvents/PointerEventsExample.js @@ -107,7 +107,7 @@ class NoneStyleExample extends React.Component<$FlowFixMeProps> { style={[ styles.box, styles.boxPassedThrough, - styles.pointerEventsNone, + styles.pointerEventNone, ]}> B: none @@ -184,7 +184,7 @@ class BoxNoneStyleExample extends React.Component<$FlowFixMeProps> { style={[ styles.box, styles.boxPassedThrough, - styles.pointerEventsBoxNone, + styles.pointerEventBoxNone, ]}> B: box-none @@ -198,7 +198,7 @@ class BoxNoneStyleExample extends React.Component<$FlowFixMeProps> { onTouchStart={() => this.props.onLog('C explicitly unspecified touched') } - style={[styles.box, styles.pointerEventsAuto]}> + style={[styles.box, styles.pointerEventAuto]}> C: explicitly unspecified @@ -251,7 +251,7 @@ class BoxOnlyStyleExample extends React.Component<$FlowFixMeProps> { A: unspecified this.props.onLog('B box-only touched')} - style={[styles.box, styles.pointerEventsBoxOnly]}> + style={[styles.box, styles.pointerEventBoxOnly]}> B: box-only this.props.onLog('C unspecified touched')} @@ -267,7 +267,7 @@ class BoxOnlyStyleExample extends React.Component<$FlowFixMeProps> { style={[ styles.box, styles.boxPassedThrough, - styles.pointerEventsAuto, + styles.pointerEventAuto, ]}> C: explicitly unspecified @@ -446,16 +446,16 @@ const styles = StyleSheet.create({ borderColor: '#f0f0f0', backgroundColor: '#f9f9f9', }, - pointerEventsBoxNone: { + pointerEventBoxNone: { pointerEvents: 'box-none', }, - pointerEventsBoxOnly: { + pointerEventBoxOnly: { pointerEvents: 'box-only', }, - pointerEventsNone: { + pointerEventNone: { pointerEvents: 'none', }, - pointerEventsAuto: { + pointerEventAuto: { pointerEvents: 'auto', }, });