Skip to content

Commit 41594bc

Browse files
authored
Change how the functionality to accept left clicks is implemented (PR #27)
This fixes a problem where the left click was always triggering the context menu.
1 parent 2ea602d commit 41594bc

File tree

4 files changed

+78
-16
lines changed

4 files changed

+78
-16
lines changed

docs/api.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Contextmenu Trigger Component
3939
| holdToDisplay | Number | | `1000` | This is applicable only for touch screens. The time (in ms) for which, user has to hold down his/her finger before the menu is shown. **Note:** To disable the long press trigger on left-click just set a negative holdToDisplay value such as `-1` |
4040
| renderTag | String or React Element | | | The element inside which the Component must be wrapped. By default `div` is used. But this prop can used to customize it. |
4141
| disableIfShiftIsPressed | Boolean | | `false` | If true and shift is pressed, it will open the native browser context menu and ignore this custom component |
42+
| triggerOnLeftClick | Boolean | | `false` | If true, the menu will open with the left click in addition to the right click (or ctrl + click on MacOS) |
4243

4344
### `<MenuItem />`
4445

src/ContextMenuTrigger.js

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ export default class ContextMenuTrigger extends Component {
1717
posX: PropTypes.number,
1818
posY: PropTypes.number,
1919
renderTag: PropTypes.elementType,
20-
// 0 is left click, 2 is right click
21-
mouseButton: PropTypes.number,
20+
// Trigger on left click in addition to right click
21+
triggerOnLeftClick: PropTypes.bool,
2222
disableIfShiftIsPressed: PropTypes.bool
2323
};
2424

@@ -30,7 +30,7 @@ export default class ContextMenuTrigger extends Component {
3030
renderTag: 'div',
3131
posX: 0,
3232
posY: 0,
33-
mouseButton: null,
33+
triggerOnLeftClick: false,
3434
disableIfShiftIsPressed: false
3535
};
3636

@@ -90,18 +90,13 @@ export default class ContextMenuTrigger extends Component {
9090
};
9191

9292
handleContextMenu = (event) => {
93-
const { mouseButton } = this.props;
94-
if (mouseButton === null || event.button === mouseButton) {
95-
this.handleContextClick(event);
96-
}
93+
this.handleContextClick(event);
9794
callIfExists(this.props.attributes.onContextMenu, event);
9895
};
9996

97+
// Note: this function is registered only if triggerOnLeftClick is true.
10098
handleMouseClick = (event) => {
101-
const { mouseButton } = this.props;
102-
if (mouseButton === null || event.button === mouseButton) {
103-
this.handleContextClick(event);
104-
}
99+
this.handleContextClick(event);
105100
callIfExists(this.props.attributes.onClick, event);
106101
};
107102

@@ -151,18 +146,19 @@ export default class ContextMenuTrigger extends Component {
151146
};
152147

153148
render() {
154-
const { renderTag, attributes, children } = this.props;
155-
const newAttrs = assign({}, attributes, {
149+
const { renderTag, attributes, children, triggerOnLeftClick } = this.props;
150+
const newAttrs = {
151+
...attributes,
156152
className: cx(cssClasses.menuWrapper, attributes.className),
157153
onContextMenu: this.handleContextMenu,
158-
onClick: this.handleMouseClick,
154+
onClick: triggerOnLeftClick ? this.handleMouseClick : null,
159155
onMouseDown: this.handleMouseDown,
160156
onMouseUp: this.handleMouseUp,
161157
onTouchStart: this.handleTouchstart,
162158
onTouchEnd: this.handleTouchEnd,
163159
onMouseOut: this.handleMouseOut,
164160
ref: this.elemRef
165-
});
161+
};
166162

167163
return React.createElement(renderTag, newAttrs, children);
168164
}

src/index.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ declare module "@firefox-devtools/react-contextmenu" {
2323
disable?: boolean,
2424
holdToDisplay?: number,
2525
renderTag?: React.ElementType,
26-
mouseButton?: number,
26+
triggerOnLeftClick?: boolean,
2727
disableIfShiftIsPressed?: boolean,
2828
[key: string]: any
2929
}

tests/ContextMenuTrigger.test.js

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import React from 'react';
2+
import { mount } from 'enzyme';
3+
4+
import ContextMenu from '../src/ContextMenu';
5+
import ContextMenuTrigger from '../src/ContextMenuTrigger';
6+
7+
describe('ContextMenuTrigger tests', () => {
8+
function baseSetup(options = {}) {
9+
const ID = 'CORRECT_ID';
10+
const component = mount(<>
11+
<ContextMenu id={ID} />
12+
<ContextMenuTrigger id={ID} {...options} />
13+
</>);
14+
15+
const wrapper = () => component.find('.react-contextmenu-wrapper');
16+
const contextMenu = () => component.find('.react-contextmenu');
17+
return { component, contextMenu, wrapper };
18+
}
19+
20+
describe('without triggerOnLeftClick', () => {
21+
const setup = baseSetup;
22+
test('shows a ContextMenu when right clicking', () => {
23+
const { contextMenu, wrapper } = setup();
24+
wrapper().simulate('contextmenu', { button: 2, buttons: 2 });
25+
expect(contextMenu().hasClass('react-contextmenu--visible')).toBe(true);
26+
});
27+
28+
test('shows a ContextMenu when ctrl + left clicking', () => {
29+
const { contextMenu, wrapper } = setup();
30+
wrapper().simulate('contextmenu', { button: 0, buttons: 1 });
31+
expect(contextMenu().hasClass('react-contextmenu--visible')).toBe(true);
32+
});
33+
34+
test('does not show a ContextMenu when left clicking without a modifier', () => {
35+
const { contextMenu, wrapper } = setup();
36+
wrapper().simulate('click', { button: 0, buttons: 1 });
37+
expect(contextMenu().hasClass('react-contextmenu--visible')).toBe(false);
38+
});
39+
});
40+
41+
describe('with triggerOnLeftClick', () => {
42+
function setup() {
43+
return baseSetup({ triggerOnLeftClick: true });
44+
}
45+
46+
test('shows a ContextMenu when right clicking', () => {
47+
const { contextMenu, wrapper } = setup();
48+
wrapper().simulate('contextmenu', { button: 2, buttons: 2 });
49+
expect(contextMenu().hasClass('react-contextmenu--visible')).toBe(true);
50+
});
51+
52+
test('shows a ContextMenu when ctrl + left clicking', () => {
53+
const { contextMenu, wrapper } = setup();
54+
wrapper().simulate('contextmenu', { button: 0, buttons: 1 });
55+
expect(contextMenu().hasClass('react-contextmenu--visible')).toBe(true);
56+
});
57+
58+
test('shows a ContextMenu when left clicking without a modifier', () => {
59+
const { contextMenu, wrapper } = setup();
60+
wrapper().simulate('click', { button: 0, buttons: 1 });
61+
expect(contextMenu().hasClass('react-contextmenu--visible')).toBe(true);
62+
});
63+
});
64+
});
65+

0 commit comments

Comments
 (0)