Skip to content

Commit 5c109b3

Browse files
cyrus25facebook-github-bot
authored andcommitted
feat: Added pointerEvents style equivalent to pointerEvents prop (facebook#34586)
Summary: This adds `pointerEvents` style which is equivalent to `pointerEvents` prop as requested in facebook#34425 ## Changelog <!-- Help reviewers and the release process by writing your own changelog entry. For an example, see: https://reactnative.dev/contributing/changelogs-in-pull-requests --> [General] [Added] - Added pointerEvents style equivalent to pointerEvents prop Pull Request resolved: facebook#34586 Test Plan: ``` <View style={{ pointerEvents: 'none' }} > </View> ``` Reviewed By: cipolleschi Differential Revision: D39252830 Pulled By: jacdebug fbshipit-source-id: 94f265a6b6940a4371e7985d5de3b8143693e069
1 parent 5c211f2 commit 5c109b3

File tree

4 files changed

+143
-1
lines changed

4 files changed

+143
-1
lines changed

Libraries/Components/View/ReactNativeStyleAttributes.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ const ReactNativeStyleAttributes: {[string]: AnyAttributeType, ...} = {
111111
borderTopRightRadius: true,
112112
borderTopStartRadius: true,
113113
opacity: true,
114+
pointerEvents: true,
114115

115116
/**
116117
* Text

Libraries/Components/View/View.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import type {ViewProps} from './ViewPropTypes';
1212

1313
import ViewNativeComponent from './ViewNativeComponent';
1414
import TextAncestor from '../../Text/TextAncestor';
15+
import flattenStyle from '../../StyleSheet/flattenStyle';
1516
import * as React from 'react';
1617

1718
export type Props = ViewProps;
@@ -27,12 +28,19 @@ const View: React.AbstractComponent<
2728
ViewProps,
2829
React.ElementRef<typeof ViewNativeComponent>,
2930
> = React.forwardRef(
30-
({tabIndex, focusable, ...otherProps}: ViewProps, forwardedRef) => {
31+
(
32+
{tabIndex, focusable, style, pointerEvents, ...otherProps}: ViewProps,
33+
forwardedRef,
34+
) => {
35+
const flattendStyle = flattenStyle(style);
36+
const newPointerEvents = pointerEvents || flattendStyle?.pointerEvents;
3137
return (
3238
<TextAncestor.Provider value={false}>
3339
<ViewNativeComponent
3440
focusable={tabIndex !== undefined ? !tabIndex : focusable}
3541
{...otherProps}
42+
style={style}
43+
pointerEvents={newPointerEvents}
3644
ref={forwardedRef}
3745
/>
3846
</TextAncestor.Provider>

Libraries/StyleSheet/StyleSheetTypes.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,7 @@ export type ____ViewStyle_InternalCore = $ReadOnly<{
558558
borderTopWidth?: number | AnimatedNode,
559559
opacity?: number | AnimatedNode,
560560
elevation?: number,
561+
pointerEvents?: 'auto' | 'none' | 'box-none' | 'box-only',
561562
}>;
562563

563564
export type ____ViewStyle_Internal = $ReadOnly<{

packages/rn-tester/js/examples/PointerEvents/PointerEventsExample.js

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,36 @@ class NoneExample extends React.Component<$FlowFixMeProps> {
9595
}
9696
}
9797

98+
class NoneStyleExample extends React.Component<$FlowFixMeProps> {
99+
render(): React.Node {
100+
return (
101+
<View
102+
onTouchStart={() => this.props.onLog('A unspecified touched')}
103+
style={styles.box}>
104+
<DemoText style={styles.text}>A: unspecified</DemoText>
105+
<View
106+
onTouchStart={() => this.props.onLog('B none touched')}
107+
style={[
108+
styles.box,
109+
styles.boxPassedThrough,
110+
styles.pointerEventNone,
111+
]}>
112+
<DemoText style={[styles.text, styles.textPassedThrough]}>
113+
B: none
114+
</DemoText>
115+
<View
116+
onTouchStart={() => this.props.onLog('C unspecified touched')}
117+
style={[styles.box, styles.boxPassedThrough]}>
118+
<DemoText style={[styles.text, styles.textPassedThrough]}>
119+
C: unspecified
120+
</DemoText>
121+
</View>
122+
</View>
123+
</View>
124+
);
125+
}
126+
}
127+
98128
/**
99129
* Special demo text that makes itself untouchable so that it doesn't destroy
100130
* the experiment and confuse the output.
@@ -142,6 +172,41 @@ class BoxNoneExample extends React.Component<$FlowFixMeProps> {
142172
}
143173
}
144174

175+
class BoxNoneStyleExample extends React.Component<$FlowFixMeProps> {
176+
render(): React.Node {
177+
return (
178+
<View
179+
onTouchStart={() => this.props.onLog('A unspecified touched')}
180+
style={styles.box}>
181+
<DemoText style={styles.text}>A: unspecified</DemoText>
182+
<View
183+
onTouchStart={() => this.props.onLog('B box-none touched')}
184+
style={[
185+
styles.box,
186+
styles.boxPassedThrough,
187+
styles.pointerEventBoxNone,
188+
]}>
189+
<DemoText style={[styles.text, styles.textPassedThrough]}>
190+
B: box-none
191+
</DemoText>
192+
<View
193+
onTouchStart={() => this.props.onLog('C unspecified touched')}
194+
style={styles.box}>
195+
<DemoText style={styles.text}>C: unspecified</DemoText>
196+
</View>
197+
<View
198+
onTouchStart={() =>
199+
this.props.onLog('C explicitly unspecified touched')
200+
}
201+
style={[styles.box, styles.pointerEventAuto]}>
202+
<DemoText style={[styles.text]}>C: explicitly unspecified</DemoText>
203+
</View>
204+
</View>
205+
</View>
206+
);
207+
}
208+
}
209+
145210
class BoxOnlyExample extends React.Component<$FlowFixMeProps> {
146211
render(): React.Node {
147212
return (
@@ -177,6 +242,43 @@ class BoxOnlyExample extends React.Component<$FlowFixMeProps> {
177242
}
178243
}
179244

245+
class BoxOnlyStyleExample extends React.Component<$FlowFixMeProps> {
246+
render(): React.Node {
247+
return (
248+
<View
249+
onTouchStart={() => this.props.onLog('A unspecified touched')}
250+
style={styles.box}>
251+
<DemoText style={styles.text}>A: unspecified</DemoText>
252+
<View
253+
onTouchStart={() => this.props.onLog('B box-only touched')}
254+
style={[styles.box, styles.pointerEventBoxOnly]}>
255+
<DemoText style={styles.text}>B: box-only</DemoText>
256+
<View
257+
onTouchStart={() => this.props.onLog('C unspecified touched')}
258+
style={[styles.box, styles.boxPassedThrough]}>
259+
<DemoText style={[styles.text, styles.textPassedThrough]}>
260+
C: unspecified
261+
</DemoText>
262+
</View>
263+
<View
264+
onTouchStart={() =>
265+
this.props.onLog('C explicitly unspecified touched')
266+
}
267+
style={[
268+
styles.box,
269+
styles.boxPassedThrough,
270+
styles.pointerEventAuto,
271+
]}>
272+
<DemoText style={[styles.text, styles.textPassedThrough]}>
273+
C: explicitly unspecified
274+
</DemoText>
275+
</View>
276+
</View>
277+
</View>
278+
);
279+
}
280+
}
281+
180282
type OverflowExampleProps = $ReadOnly<{|
181283
overflow: 'hidden' | 'visible',
182284
onLog: (msg: string) => void,
@@ -242,18 +344,36 @@ const exampleClasses: Array<ExampleClass> = [
242344
description:
243345
'`none` causes touch events on the container and its child components to pass through to the parent container.',
244346
},
347+
{
348+
Component: NoneStyleExample,
349+
title: '`none` style',
350+
description:
351+
'`none` causes touch events on the container and its child components to pass through to the parent container.',
352+
},
245353
{
246354
Component: BoxNoneExample,
247355
title: '`box-none`',
248356
description:
249357
'`box-none` causes touch events on the container to pass through and will only detect touch events on its child components.',
250358
},
359+
{
360+
Component: BoxNoneStyleExample,
361+
title: '`box-none` style',
362+
description:
363+
'`box-none` causes touch events on the container to pass through and will only detect touch events on its child components.',
364+
},
251365
{
252366
Component: BoxOnlyExample,
253367
title: '`box-only`',
254368
description:
255369
"`box-only` causes touch events on the container's child components to pass through and will only detect touch events on the container itself.",
256370
},
371+
{
372+
Component: BoxOnlyStyleExample,
373+
title: '`box-only` style',
374+
description:
375+
"`box-only` causes touch events on the container's child components to pass through and will only detect touch events on the container itself.",
376+
},
257377
{
258378
Component: OverflowVisibleExample,
259379
title: '`overflow: visible`',
@@ -326,6 +446,18 @@ const styles = StyleSheet.create({
326446
borderColor: '#f0f0f0',
327447
backgroundColor: '#f9f9f9',
328448
},
449+
pointerEventBoxNone: {
450+
pointerEvents: 'box-none',
451+
},
452+
pointerEventBoxOnly: {
453+
pointerEvents: 'box-only',
454+
},
455+
pointerEventNone: {
456+
pointerEvents: 'none',
457+
},
458+
pointerEventAuto: {
459+
pointerEvents: 'auto',
460+
},
329461
});
330462

331463
exports.framework = 'React';

0 commit comments

Comments
 (0)