vkbansal / react-contextmenu Goto Github PK
View Code? Open in Web Editor NEWProject is no longer maintained
License: MIT License
Project is no longer maintained
License: MIT License
A frequent use-case I'm experiencing is the need to access the instance of the target being right-clicked. It appears react-contextmenu is so laser focused on proving data, it doesn't have a method to provide the instance of the react component being right-clicked. This is especially relevant when I would like to modify the state of the target.
Is there a plan to add this feature or have I missed something?
Can we put a configuration for left click or right click to ContextMenuTrigger
so that contextmenu can also be invoked with left click ?
Props for the rewrite, the API looks way cleaner are more thought-through. Thanks for all your work.
In the previous version, using connectMenuLayer
and connect
, it was possible to pass on props from the element triggering the context menu, to the component rendering it. I used this to customize the menu depending on which trigger was clicked.
Example from 1.x.x:
SomeComponent.js:
<MenuButton uri={someProp} holdToDisplay={0}>
MenuButton.js:
const MenuButton = () => (<div>...</div>);
export default contextMenuLayer(MENU_ID, (props) => props)(MenuButton)
Menu.js:
const Menu = ({item}) => {
return {
<ContextMenu identifier={MENU_ID}>
<MenuItem>Add</MenuItem>
{item.uri === 'foobar' && <MenuItem>Remove</MenuItem>}
</ContextMenu>
}
};
export default menuConnect(Menu);
I read the new source code of react-contextmenu and I see no obvious way to do the same thing, now when the higher order function is gone. My question is, are there plans to support a similar use-case in the future, or is this forever dropped as "out of scope" for react-contextmenu? Or am I missing an obvious way to accomplish this with the existing feature set (without tracking the currently opened context menu myself in redux)?
Update: Using onShow on ContextMenu makes it possible to access props passed from ContextMenuTrigger if collect is specified to return the props:
<ContextMenuTrigger id={MENU_ID} uri={this.props.uri} />
<ContextMenu id={MENU_ID} collect={props => props} onShow={e => doSomething(e.detail.data.uri)} />
With a native context menu, it is possible to trigger the menu and choose an item from it with one fluid sequence of pressing the mouse, keeping it held down while moving to the desired item, and releasing the mouse over that item. With react-contextmenu, this behavior is not supported: it is necessary to click once to trigger the menu, then click again to choose an item from that menu.
I'm trying to customize the design of the context menu when it gets to the sides of the screen. Currently what's happening is that the menu shrinks (it's width get smaller and the text gets down):
Here is what it looks like when the position is ok:
Here is what it looks like when the position is too right:
I'd like to make it behave like the regular context menu of the computer (the width doesn't change, but the position is - I can't take a screenshot of it because the mouse is not included in the screenshots, but you can try it yourself).
Is there any way to make it act as I expect?
Hi.
We call the "higher order function" ContextMenuLayer
like this :
export default ContextMenuLayer('albums-list')(Results)
In our app, we would like to have the context menu setup only in certain conditions (let's say according to this.props.contextMenusEnabled
). Is there another way to call ContextMenuLayer
in order to have conditions around ? In render
?
Thanks !
I'm working on an application that makes extensive use of context-menu's.
We built a wrapper around ContextMenu
so it fits our use-case. In some cases we want to display a different component or add an icon, ... All this works fine.
There is one component however that renders a tree, which contains a lot <Node />
components. Each of these nodes can have different types, and depending on the type we add or remove options from the context menu. Our current solution is to render a <NodeMenu />
for each <Node />
, all of these menu's would render a ContextMenu
with an id such as node-menu-${this.props.id}
. This method did causes performance issues when about 10-20 <Node />
's are rendered.
So we're opting to have a single NodeMenu
on the page and make each <Node />
a ContextMenuLayer
, but we ran into some issues.
By using this approach we cannot add/remove options based on the properties given in configure()
, because these props are only available during the click handlers. I've tried using the monitor
included to get access to the item by using monitor.getItem()
, but no luck.
So my question is:
Do you have any example code on how to properly use monitor.getItem()
for a use-case like this?
I have a list of data and create a context menu for each row. I want to be able to highlight the row associated withthe currently displayed context menu. Is there a way to do this?
I think I want something like a react-contextmenu-wrapper-active
class.
2.0.0-beta.1
press the left mouse button on the element and don't loosen it for 1s.
nothing happened
the context menu shows up
It's the same with the closed #47.
The problem hasn't been solved yet!
2.0.0-alpha.2
http://jsbin.com/lixucamice/1/edit?js,output
Thank you for your work in creating this library.
This is more of a question than a bug report. I am probably missing something simple but in the customization example, how will the MenuTarget class work if you wanna display multiple <td>
s, since React requires you to return one element from the render function?
As this example:
https://vkbansal.github.io/react-contextmenu/#/multiple-targets?_k=bq0lx9
Current:
It is better:
I just updated to 1.6.0 version and this error pop out.
"Cannot read property 'parentNode' of undefined".
As I saw, its related to this changes. Line 41
My (previously successful) tests are now failing because the context menu isn't showing on right-click in PhantomJS. In contextmenu-layer.js#L79-80 event.touches
doesn't exist when running these tests hence why they fail.
Could you please change to: const xPos = event.clientX || (event.touches && event.touches[0].pageX), yPos = event.clientY || (event.touches && event.touches[0].pageY);
Is there an easy way to make the contextmenus open rtl?
For example, when using the SubMenu, it always opens to the right (unless close to the end of the page) and I'd like it to always open to the left unless close to the left side of the end of the page.
Hello,
I am wondering if it's possible to have an onShow
and an onHide
callbacks passed to ContextMenu
as props in a future release.
For example, in my case, I would like to be able to change the css class of the target which the ContextMenu showed and change it back after hiding it.
2.0.0-beta.1
run an web site in IE 11
normal
occur an error:
in ContextMenuTrigger.js
...
(0, _actions.showMenu)({
position: { x, y },
...
The IE 11 doesn't recognize the syntax "position: { x, y }"
With v2.0.0-alpha.2 running in Safari (Version 9.0.3) on OS X (Version 10.11.3), a right click on a target does not produce any visible menu. This problem is easily reproducible with any of the examples included in this project. Earlier versions, like v1.6.2, do not have this problem, nor does v2.0.0-alpha.2 running on Chrome (Version 54.0.2840.71).
Hello,
is there a way to add classes to the MenuItem?
Is there a way to bring up the context menu by left mouse click?
-ed
2.0.0
http://jsbin.com/sacerobuxi/edit?html,js,output
render () {
const menuItemClassNames = cx(cssClasses.menuItem, attributes && attributes.className);
return (
<div {...attributes} className={menuItemClassNames}>
<a href='#' className={linkClasses} onTouchEnd={this.handleClick} onClick={this.handleClick}>
{children}
</a>
</div>
);
}
You can pass MenuItem
a prop attributes
with classNames on it, but this is not the element with the onClick
handler, it's child, an <a>
tag is. This is the main reason I use this component, really, because it knows how to close the ContextMenu
(which might be argument for adding .close()
to the component). So if I wanted to do something like, make the width this MenuItem
take up the entire width of a div that I place it in, I can do that. But it's child will need to be set via external css.
This element is a MenuItem
with a wide padding set on it, but the clickable region is only the unstylable (via js) a
tag.
Ideal solutions:
return (
<div {...attributes} className={menuItemClassNames} onClick={this.handleClick} onTouchEnd={this.handleClick}>
{children}
</div>
);
Remove the <a>
entirely and make MenuItem
be just a wrapper solely for onClick
(styles can be transferred to the parent). This will screw up for people if they relied on global <a>
styles. :/
Compromise solution:
return (
<div {...attributes} className={menuItemClassNames} onClick={this.handleClick} onTouchEnd={this.handleClick}>
<a href='#' className={linkClasses} >
{children}
</a>
</div>
);
Move the onClick handler to the MenuItem
itself. This will still render a child <a>
tag which will only break for people which intended for portions of MenuItem to not be clickable.
I'm trying to override the renderTag prop with a table cell element.
This is how I do it but with no luck. What am I doing wrong?
export default ContextMenuLayer("identifier", (props) => {
renderTag: 'td'
})(MyComponent);
Is there a way to change the width for each submenu? Also, can I set margins separately per submenu? (I know I can manually add to the margin for individual items but I haven't figured out a way to set a margin to submenu titles.
I've looked through the CSS and the source and haven't found a way thus far (without forking the code.)
1.2.0
http://jsbin.com/sacerobuxi/edit?html,js,output
Hi guys, having an issue with server-side rendering where window isn't defined, when I import the package like this: import { ContextMenu, MenuItem, ContextMenuTrigger } from 'react-contextmenu';
I get this error:
ReferenceError: window is not defined
at new GlobalEventListener (C:\Projects\Web\yupty-front\node_modules\react-contextmenu\modules\globalEventListener.js:49:5)
at Object.<anonymous> (C:\Projects\Web\yupty-front\node_modules\react-contextmenu\modules\globalEventListener.js:53:19)
at Module._compile (module.js:556:32)
at Module._extensions..js (module.js:565:10)
at Object.require.extensions.(anonymous function) [as .js] (C:\Projects\Web\yupty-front\node_modules\babel-register\lib\node.js:152:7)
at Module.load (module.js:473:32)
at tryModuleLoad (module.js:432:12)
at Function.Module._load (module.js:424:3)
at Module.require (module.js:483:17)
at require (internal/module.js:20:19)
error Command failed with exit code 1.
It makes perfect sense because there's nothing to attach the listener to, because window isn't defined on the server. Not sure how to fix this though.
2.0.0-alpha.2
press the left mouse button on the element and don't loosen it for 1s.
nothing happened
the context menu shows up
The code is in ContextMenuTrigger.js
`
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = ContextMenuTrigger.proto
......
_this.mouseDown = true;
setTimeout(function () {
if (_this.mouseDown) _this.handleContextClick(event);
}, _this.props.holdToDisplay);
}
......
`
I don't know why did you do this, it's so strange and unreadable.
I don't want to show up the context menu because I'm just dragging the element.
1.2.0
Load the example provided.
By default, context menu should be closed.
It should only open on right click on the trigger, context menu should close once clicked elsewhere.
By default, context menu is visible.
Cannot be closed in anyway.
index.txt
2.0.0-alpha.2
Unfortunately I can't do this now but if it would be helpful I can try to throw an example together soon.
Component should remove handleOutsideClick
listener on unmount.
Error is thrown because this.menu
is null
after unmounting:
handleOutsideClick = (e) => {
if (!this.menu.contains(e.target)) hideMenu();
}
Other than this, the library has been great -- thank you! I'd be happy to open a PR if you point me in the right direction. It does look like you are trying to unregister the the listener in componentWillUnmount
so I'm not exactly sure what's going on.
Not compatible with react 0.14 :
Uncaught Error: Invariant Violation: ContextMenu.render(): A valid ReactComponent must be returned. You may have returned undefined, an array or some other invalid object
Currently, when the ContextMenu
's state swaps out to isVisible
: false, the class react-contextmenu--visible
is added to the <nav>
child rendered by ContextMenu
.
This means, without css on the page, it is impossible to hide the context menu. It creates a dependency which would be better circumvented if it didn't render that at all. I can create a PR for that change if desired, but I'm not sure this is desired yet.
Why this is frustrating:
We are using aphrodite for all of our styles. This is a pretty strong trend in JS frameworks lately (though it's not the only way), as it allows components to be packaged up with styles without requiring extra css. What aphrodite does is create a <style>
tag in the head with css rules declared by JS, these rules map back to the element by a generated css class name. Some of our components have no means of adding css to the page other than like this.
So something using this library would also require external css as an added dependency, or be forced to add a css rule to the page, which is less than ideal.
Solutions:
A solution I'm not crazy about for this problem: allow us to define styles for these different states. <ContextMenu styleWhenNotVisible={{}} ... />
.
Better solution: There really isn't much styling in this library. MenuItem
has some but children are free to be styled and structured freely. In fact, the only reason I am using MenuItem
, is to leverage it's auto-closing from onClick
behavior. Including opacity: 0
is really less of a css concern and more of a JS concern (whether or not to show, as opposed to how to show, as reflected by the name of the state variable, isVisible
), and as such, should just be managed by the JS by determining whether to render or not render.
Agree?
Context menu is popping up at the left corner of the window when I go to the previous page and come back to the page where I right-clicked the view before. Here is the step I followed.
1.6.3
http://jsbin.com/sacerobuxi/edit?html,js,output
When coming back to the page, the context menu should not be prompted.
The context menu is appeared at the left corner of the window.
Hello, and thank you for this wonderful package. I am building an application where I only want to enable the context menu when certain conditions are met (for example, some value in state is true).
Is there a way to pass a prop to ContextMenuTrigger
to make it ignore right clicks and display the default browser context menu when a prop like shouldTrigger
is false?
I am able to conditionally wrap my component with ContextMenuTrigger
, however, it is causing a problem for my use case. When the condition becomes true, the nodes inside of ContextMenuTrigger
are recreated by React, and thus the user's selected text is removed.
1.2.0
http://jsbin.com/sacerobuxi/edit?html,js,output
now I have to change the menu when target props changed, like disable some MenuItem or something. What should I do?
Any response will be appreciated.
1.2.0
Open context menu via right click, change window's size - context menu still visible, in the wrong place.
Context menu should be hidden on window resize event.
Appears visible in the wrong place.
OK so Im expected the onClick handlers in my context menu to fire but instead im getting the following warning and my simple onClick function doesnt work.
"Warning: Failed prop type: Required prop onClick
was not specified in MenuItem
"
Heres my code for the menu.
import React, { Component } from 'react';
import { ContextMenu, MenuItem } from 'react-contextmenu';
//The context-menu to be triggered
export default class ClipContextMenu extends Component {
render() {
return (
<ContextMenu identifier="clip">
<MenuItem onClick={() => console.log('hi')}>
ContextMenu Item 1
</MenuItem>
<MenuItem onClick={() => console.log('hi')}>
ContextMenu Item 2
</MenuItem>
<MenuItem divider />
<MenuItem onClick={() => console.log('hi')}>
ContextMenu Item 3
</MenuItem>
</ContextMenu>
);
}
handleClick(e, data) {
console.log(data);
}
};
Hi, is this works with Components using ES6 classes?
I tried to make it work but it is hard to understand without an example.
Using the old React.createClass syntax again in new projects switched to es6 classes is not very elegant.
I haven't tested the code but just looked at the source.
@autobind
_unbindHandlers() {
let fn = this._outsideClickHandler,
fn2 = this._hideMenu;
document.removeEventListener("mousedown", fn);
document.removeEventListener("touchstart", fn);
window.addEventListener("resize", fn2);
document.addEventListener("scroll", fn2);
}
Shouldn't resize and scroll event remove? It's adds them in the unbind.
Would it be possible to write typescript typings and add them to DefinitelyTyped? I'm not yet confident enough with typescript to do it myself.
Hi man,
Long press will trigger the context menu.
react-contextmenu version 1.6.2
react version 15.2.0
I could be wrong, but the examples in your readme appear.... invalid?
Rendering your example:
//The context-menu to be triggered
const MyContextMenu = React.createClass({
render() {
<ContextMenu identifier="some_unique_identifier" currentItem={this.currentItem}>
<MenuItem data={"some_data"} onClick={this.handleClick}>
ContextMenu Item 1
</MenuItem>
<MenuItem data={"some_data"} onClick={this.handleClick}>
ContextMenu Item 2
</MenuItem>
<MenuItem divider />
<MenuItem data={"some_data"} onClick={this.handleClick}>
ContextMenu Item 3
</MenuItem>
</ContextMenu>
},
handleClick(e, data) {
console.log(data);
}
});
Generates the console error message (for me):
Uncaught Invariant Violation: ContextMenu.render(): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.
Perhaps this JSX should be wrapped in a return (...)
?
Also, according to this line, the MenuItem
prop data
is expected to be an object
, but your example passes strings.
Sorry if this is a dumb question.
In any case is there a recommended way to show the menus from JavaScript myself?
It doesn't appear that showMenu
and hideMenu
are exported from index.js
It seems strange to use <ContextMenuTrigger>
when contextmenu is an event. Would you make a <Click>
component for left mouse clicks and <MouseMove>
component for mouse move events?
Hello,
Is this possible to define contextMenu for whole app container and different contextMenus for some of it's childrens?
For example, let's say I have structure like this (simplified to HTML):
<div class="container">
<ul class="list1">
<li></li>
</ul>
<ul class="list2">
<li></li>
</ul>
<div>
and I'd like to have contextMenu for whole .container and different contextMenus if you click on any of .list elments.
Right now when I've defined different menus for both lists it works right form the box.
After I've added menu for container I get it even when I click on list elements.
Best,
Martin
2.0.0-beta.2
Right click on a contextMenuTrigger area in IE11.
Context menu is displayed succesfully as it is in Chrome and Firefox.
Throws error: Unable to get property 'id' of undefined or null reference
Referring to this line:
_this.handleShow = function (e) {
if (e.detail.id !== _this.props.id) return;
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.