[Flare] add disableContextMenu to Press (#15909)
Nicolas Gallagher committed
Jun 18, 2019 at 11:34 UTC
f97b9516664046643bd04eb391861b55910d29ee
3 files changed
+41
-7
packages/react-events/docs/Press.md
+17
-7
@@ -1,11 +1,11 @@
1
# Press
2
3
The `Press` module responds to press events on the element it wraps. Press
4
-events are dispatched for `mouse`, `pen`, `touch`, and `keyboard` pointer types.
5
-Press events are only dispatched for keyboards when pressing the Enter or
6
-Spacebar keys. If neither `onPress` nor `onLongPress` are called, this signifies
7
-that the press ended outside of the element hit bounds (i.e., the user aborted
8
-the press).
4
+events are dispatched for `mouse`, `pen`, `touch`, `trackpad`, and `keyboard`
5
+pointer types. Press events are only dispatched for keyboards when pressing the
6
+Enter or Spacebar keys. If neither `onPress` nor `onLongPress` are called, this
7
+signifies that the press ended outside of the element hit bounds (i.e., the user
8
+aborted the press).
9
10
Press events do not propagate between `Press` event responders.
11
@@ -37,9 +37,9 @@ const Button = (props) => (
37
38
```js
39
type PressEvent = {
40
- pointerType: 'mouse' | 'touch' | 'pen' | 'keyboard',
40
+ pointerType: 'mouse' | 'touch' | 'pen' | 'trackpad' | 'keyboard',
41
target: Element,
42
- type: 'press' | 'pressstart' | 'pressend' | 'presschange' | 'pressmove' | 'longpress' | 'longpresschange'
42
+ type: 'press' | 'pressstart' | 'pressend' | 'presschange' | 'pressmove' | 'longpress' | 'longpresschange' | 'contextmenu'
43
}
44
45
type PressOffset = {
@@ -71,6 +71,16 @@ released before the threshold is exceeded.
71
72
Disables all `Press` events.
73
74
+### disableContextMenu: boolean = false
75
+
76
+Disables the native context menu so that it is never shown and `onContextMenu`
77
+is never called.
78
+
79
+### onContextMenu: (e: PressEvent) => void
80
+
81
+Called when the context menu is shown. When a press is active, the context menu
82
+will only be shown (and the press cancelled) if `preventDefault` is `false`.
83
+
84
### onLongPress: (e: PressEvent) => void
85
86
Called once the element has been pressed for the length of `delayLongPress`. If
packages/react-events/src/Press.js
+8
@@ -19,6 +19,7 @@ import {DiscreteEvent, UserBlockingEvent} from 'shared/ReactTypes';
19
20
type PressProps = {
21
disabled: boolean,
22
+ disableContextMenu: boolean,
23
delayLongPress: number,
24
delayPressEnd: number,
25
delayPressStart: number,
@@ -727,6 +728,12 @@ const PressResponder = {
728
}
729
730
case 'contextmenu': {
731
+ if (props.disableContextMenu) {
732
+ // Skip dispatching of onContextMenu below
733
+ nativeEvent.preventDefault();
734
+ return;
735
+ }
736
+
737
if (isPressed) {
738
if (props.preventDefault !== false) {
739
// Skip dispatching of onContextMenu below
@@ -735,6 +742,7 @@ const PressResponder = {
742
}
743
dispatchCancel(event, context, props, state);
744
}
745
+
746
if (props.onContextMenu) {
747
dispatchEvent(
748
event,
packages/react-events/src/__tests__/Press-test.internal.js
+16
@@ -2838,6 +2838,22 @@ describe('Event responder: Press', () => {
2838
ref.current.dispatchEvent(createEvent('contextmenu'));
2839
expect(onContextMenu).toHaveBeenCalledTimes(0);
2840
});
2841
+
2842
+ it('is not called if "disableContextMenu" is true', () => {
2843
+ const onContextMenu = jest.fn();
2844
+ const ref = React.createRef();
2845
+ const element = (
2846
+ <Press disableContextMenu={true} onContextMenu={onContextMenu}>
2847
+ <div ref={ref} />
2848
+ </Press>
2849
+ );
2850
+ ReactDOM.render(element, container);
2851
+ ref.current.dispatchEvent(
2852
+ createEvent('pointerdown', {pointerType: 'mouse', button: 2}),
2853
+ );
2854
+ ref.current.dispatchEvent(createEvent('contextmenu'));
2855
+ expect(onContextMenu).toHaveBeenCalledTimes(0);
2856
+ });
2857
});
2858
2859
it('should work correctly with stopPropagation set to true', () => {