forked from vkbansal/react-contextmenu
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathContextMenuTrigger.js
More file actions
127 lines (106 loc) · 3.59 KB
/
Copy pathContextMenuTrigger.js
File metadata and controls
127 lines (106 loc) · 3.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import assign from 'object-assign';
import { showMenu, hideMenu } from './actions';
import { callIfExists, cssClasses } from './helpers';
export default class ContextMenuTrigger extends Component {
static propTypes = {
id: PropTypes.string.isRequired,
children: PropTypes.node.isRequired,
attributes: PropTypes.object,
collect: PropTypes.func,
disable: PropTypes.bool,
holdToDisplay: PropTypes.number,
renderTag: PropTypes.oneOfType([
PropTypes.node,
PropTypes.func
])
};
static defaultProps = {
attributes: {},
collect() { return null; },
disable: false,
holdToDisplay: 1000,
renderTag: 'div'
};
touchHandled = false;
handleMouseDown = (event) => {
if (this.props.holdToDisplay >= 0 && event.button === 0) {
event.persist();
this.mouseDownTimeoutId = setTimeout(
() => this.handleContextClick(event),
this.props.holdToDisplay
);
}
callIfExists(this.props.attributes.onMouseDown, event);
}
handleMouseUp = (event) => {
if (event.button === 0) {
clearTimeout(this.mouseDownTimeoutId);
}
callIfExists(this.props.attributes.onMouseUp, event);
}
handleMouseOut = (event) => {
if (event.button === 0) {
clearTimeout(this.mouseDownTimeoutId);
}
callIfExists(this.props.attributes.onMouseOut, event);
}
handleTouchstart = (event) => {
this.touchHandled = false;
if (this.props.holdToDisplay >= 0) {
event.persist();
this.touchstartTimeoutId = setTimeout(
() => {
this.handleContextClick(event);
this.touchHandled = true;
},
this.props.holdToDisplay
);
}
callIfExists(this.props.attributes.onTouchStart, event);
}
handleTouchEnd = (event) => {
if (this.touchHandled) {
event.preventDefault();
}
clearTimeout(this.touchstartTimeoutId);
callIfExists(this.props.attributes.onTouchEnd, event);
}
handleContextMenu = (event) => {
this.handleContextClick(event);
callIfExists(this.props.attributes.onContextMenu, event);
}
handleContextClick = (event) => {
if (this.props.disable) return;
event.preventDefault();
event.stopPropagation();
const x = event.clientX || (event.touches && event.touches[0].pageX);
const y = event.clientY || (event.touches && event.touches[0].pageY);
hideMenu();
showMenu({
position: { x, y },
target: this.elem,
id: this.props.id,
data: callIfExists(this.props.collect, this.props)
});
}
elemRef = (c) => {
this.elem = c;
}
render() {
const { renderTag, attributes, children } = this.props;
const newAttrs = assign({}, attributes, {
className: cx(cssClasses.menuWrapper, attributes.className),
onContextMenu: this.handleContextMenu,
onMouseDown: this.handleMouseDown,
onMouseUp: this.handleMouseUp,
onTouchStart: this.handleTouchstart,
onTouchEnd: this.handleTouchEnd,
onMouseOut: this.handleMouseOut,
ref: this.elemRef
});
return React.createElement(renderTag, newAttrs, children);
}
}