GithubHelp home page GithubHelp logo

vkbansal / react-contextmenu Goto Github PK

View Code? Open in Web Editor NEW
1.4K 31.0 378.0 1.59 MB

Project is no longer maintained

License: MIT License

JavaScript 98.95% Shell 1.05%
react react-component contextmenu contextmenu-component

react-contextmenu's Introduction

Project is no longer maintained

NPM version Build Status Dependency Status Dev Dependency Status Code Climate

NPM

React Contextmenu

ContextMenu in React with accessibility support. Live Examples can be found here

Table of contents

Installation

Using npm

npm install --save react-contextmenu

Using yarn

yarn add react-contextmenu

Browser Support

  • IE 11 and Edge >= 12
  • FireFox >= 38
  • Chrome >= 47
  • Opera >= 34
  • Safari >= 8

Usage

Simple example

import React from "react";
import ReactDOM from "react-dom";
import { ContextMenu, MenuItem, ContextMenuTrigger } from "react-contextmenu";

function handleClick(e, data) {
  console.log(data.foo);
}

function MyApp() {
  return (
    <div>
      {/* NOTICE: id must be unique between EVERY <ContextMenuTrigger> and <ContextMenu> pair */}
      {/* NOTICE: inside the pair, <ContextMenuTrigger> and <ContextMenu> must have the same id */}

      <ContextMenuTrigger id="same_unique_identifier">
        <div className="well">Right click to see the menu</div>
      </ContextMenuTrigger>

      <ContextMenu id="same_unique_identifier">
        <MenuItem data={{foo: 'bar'}} onClick={this.handleClick}>
          ContextMenu Item 1
        </MenuItem>
        <MenuItem data={{foo: 'bar'}} onClick={this.handleClick}>
          ContextMenu Item 2
        </MenuItem>
        <MenuItem divider />
        <MenuItem data={{foo: 'bar'}} onClick={this.handleClick}>
          ContextMenu Item 3
        </MenuItem>
      </ContextMenu>

    </div>
  );
}

ReactDOM.render(<MyApp myProp={12}/>, document.getElementById("main"));

see usage docs / examples for more details.

API

API docs

FAQs

ALL FAQs

Who's using react-contextmenu?

Contributors

All Contributors

Changelog

For Changelog, see releases

License

MIT. Copyright(c) Vivek Kumar Bansal

react-contextmenu's People

Contributors

akash247 avatar alek-s avatar aritheelk avatar biggihs avatar bjarkig82 avatar carlosfpo avatar codeart1st avatar cr4zyc4t avatar danbovey avatar dependabot[bot] avatar dpr00f avatar f1qwase avatar hmelenok avatar jesenko avatar krebbl avatar meikoudras avatar pzi avatar r4vang3r avatar rpfister51 avatar seldaek avatar sloria avatar stevewillard avatar taimoorgit avatar tegmos avatar timothyjellison avatar tryggvigy avatar vkbansal avatar vkbansal-harness avatar waterdesk avatar wuppious avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-contextmenu's Issues

Cannot trigger menu and choose item with mousedown/mousemove/mouseup sequence

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.

Left Click Menu

Can we put a configuration for left click or right click to ContextMenuTrigger so that contextmenu can also be invoked with left click ?

In MenuItem, pass className along to same element with onClick handler

Currently,

    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.

screen shot 2016-12-19 at 4 17 14 pm

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.

Usage with server-side rendering?

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.

Hide context menu when window is resized

Version

1.2.0

Steps to reproduce

Open context menu via right click, change window's size - context menu still visible, in the wrong place.

Expected Behavior

Context menu should be hidden on window resize event.

Actual Behavior

Appears visible in the wrong place.

Add classes

Hello,
is there a way to add classes to the MenuItem?

Missing something obvious with renderTag

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);

Not working property when using with react-router

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. Go to the example page (https://vkbansal.github.io/react-contextmenu/#/?_k=u9aaao)
  2. Click 'Multiple Targets' tab
  3. Right click 'Banana' or another view.
  4. Go back
  5. Come back to the page

Version

1.6.3

Test Case

http://jsbin.com/sacerobuxi/edit?html,js,output

Steps to reproduce

output_ttfyom

Expected Behavior

When coming back to the page, the context menu should not be prompted.

Actual Behavior

The context menu is appeared at the left corner of the window.

ContextMenu is always Open in v2.0.0-alpha.1

Version

1.2.0

Test Case

Steps to reproduce

Load the example provided.

Expected Behavior

By default, context menu should be closed.
It should only open on right click on the trigger, context menu should close once clicked elsewhere.

Actual Behavior

By default, context menu is visible.
Cannot be closed in anyway.
index.txt

Compatibility with CSS-in-JS libs: Don't render context menu when it is not visible

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?

ES6 classes

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.

ContextMenu onShow() / onHide() callbacks

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.

Multiple td's in customizing example

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?

why does it show up the context-menu when long time left click?

Version

2.0.0-alpha.2

Test Case

Steps to reproduce

press the left mouse button on the element and don't loosen it for 1s.

Expected Behavior

nothing happened

Actual Behavior

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.

Customize submenu widths, margins

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.)

Not compatible with react 0.14

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

Unexpected warning: Failed prop type: Required prop `onClick` was not specified in `MenuItem`

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);
  }
};

how to change menu state

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.

Add typescript typings

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.

Position and width of the context 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:
screen shot 2016-11-21 at 15 27 03
Here is what it looks like when the position is too right:
screen shot 2016-11-21 at 15 26 55

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?

The IE 11 browser doesn't recognize the syntax a: { c, d }

Version

2.0.0-beta.1

Test Case

Steps to reproduce

run an web site in IE 11

Expected Behavior

normal

Actual Behavior

occur an error:
in ContextMenuTrigger.js

...
(0, _actions.showMenu)({
position: { x, y },
...

The IE 11 doesn't recognize the syntax "position: { x, y }"

Retrieving instance and/or state of target

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?

Trigger menu from JavaScript

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?

Different ContextMenu for children

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

handleOutsideClick bug

Version

2.0.0-alpha.2

Test Case

Unfortunately I can't do this now but if it would be helpful I can try to throw an example together soon.

Steps to reproduce

  1. Use a Link within a ContextMenu.
  2. Open the ContextMenu and navigate through the Link.
  3. Click anywhere in the document and see the error that continues to be thrown.

Expected Behavior

Component should remove handleOutsideClick listener on unmount.

Actual Behavior

Error is thrown because this.menu is null after unmounting:

handleOutsideClick = (e) => {
    if (!this.menu.contains(e.target)) hideMenu();
}

image

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.

V2.0.0-alpha.2 menus don't show on Safari

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).

Handlers in unbind

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.

it still shows up the context-menu when long time left click

Version

2.0.0-beta.1

Test Case

Steps to reproduce

press the left mouse button on the element and don't loosen it for 1s.

Expected Behavior

nothing happened

Actual Behavior

the context menu shows up

It's the same with the closed #47.
The problem hasn't been solved yet!

Context menu doesn't show during test in PhantomJS

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);

"shouldTrigger" prop?

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.

Context menu contents depending on target

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?

Dodgy examples?

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.

IE11 - Unable to get property 'id' of undefined or null reference

Version

2.0.0-beta.2

Steps to reproduce

Right click on a contextMenuTrigger area in IE11.

Expected Behavior

Context menu is displayed succesfully as it is in Chrome and Firefox.

Actual Behavior

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;

Support Right to Left contextmenus

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.

Passing props from trigger to component rendering ContextMenu

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)} />

Change CSS for trigger when context menu is shown

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.

Disabling `ContextMenuLayer` based on props

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 !

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.