@burtonator/react-context-menu-wrapper
v1.0.10
Published
react-context-menu-wrapper React component
Downloads
3
Maintainers
Readme
React Context Menu Wrapper
This component provides a simple wrapper for your context menu content. It will handle the right click event (or long press on mobile) and menu positioning, but the rest is up to you.
Unlike other React context menu packages, this one does not provide any styling or pre-made components - you'll have to style the context menu yourself. This is useful when your CSS framework provides dropdown styling - consider dropdowns from Bootstrap or from Bulma.
Features:
- Supports global and component-local context menus.
- Supports long-press for mobile devices.
- Lets you trigger context menus programmatically.
- Lets you define context menu precedence.
- Correctly displays context menus on nested components.
- Correctly displays context menus near the borders of the window.
- Does not provide out-of-the-box styling.
Please create an issue if you find a bug or want to suggest a new feature.
Usage examples
Click here to view demos with example code.
Installation
Install the main package:
npm install --save react-context-menu-wrapper
The gist
Here's an example of a simple context menu. It doesn't showcase many features, but it should give you a basic idea of how this component works. This particular context menu doesn't have any buttons - don't worry, it's pretty easy to add them. Take a look at demos and examples to find out more.
(The context menu in the gif is triggered using a right click and dismissed using a left click.)
// Import our packages, the usual way.
import React, {Component} from 'react';
import {ContextMenuWrapper, prepareContextMenuHandlers} from 'react-context-menu-wrapper';
// Define some styles - remember that `react-context-menu-wrapper` does not provide any styling out-of-the-box.
const contextMenuStyle = {backgroundColor: '#eec185', padding: '10px', boxShadow: '0 3px 5px rgba(0, 0, 0, 0.5)'};
const blueBoxStyle = {backgroundColor: '#3e48f9', color: '#fff', padding: '40px'};
const redBoxStyle = {backgroundColor: '#aa2d35', color: '#fff', padding: '40px'};
class ComponentWithAContextMenu extends Component {
constructor(props) {
super(props);
// Set the initial phrase to some dummy value.
this.state = {phrase: 'Nothing.'};
// Create "triggers" for our context menu. Each "trigger" has some unique data associated with it.
this.redBoxHandlers = prepareContextMenuHandlers({id: 'my-context-menu', data: 'Hello from Lavagirl!'});
this.blueBoxHandlers = prepareContextMenuHandlers({id: 'my-context-menu', data: 'Hello from Sharkboy!'});
}
// Define the logic for when the context menu is shown
handleContextMenuShow = (data, publicProps) => {
// 'data' variable contains the phrase we initialised our handlers with.
this.setState({phrase: data});
// We also have access to the 'publicProps' variable, but we're not going to use it. This variable
// contains the properties of the context menu. For example, we could find out:
// - The ID of the menu (via 'publicProps.id')
// - Whether the menu is global (via 'publicProps.global')
};
render() {
return (
<div style={{fontSize: '1.4rem'}}>
{/* Render the boxes that will trigger the context menu */}
<div {...this.blueBoxHandlers} style={blueBoxStyle}>Blue box</div>
<div {...this.redBoxHandlers} style={redBoxStyle}>Red box</div>
{/*
Include the component for the context menu itself. Note that this component doesn't have to be on
the same level as triggers. In fact, the context menu can even come from a different React tree!
*/}
<ContextMenuWrapper id="my-context-menu" onShow={this.handleContextMenuShow}>
<div style={contextMenuStyle}>
<div>The box says: <strong>{this.state.phrase}</strong></div>
</div>
</ContextMenuWrapper>
</div>
);
}
}
ContextMenuWrapper
component
ContextMenuWrapper
is the component that handles showing and hiding your context menu content on various events,
which are triggered either programmatically or through user input. This is the only React component provided by the
library, the rest of the functionality is provided as helper functions.
Example usage:
import {ContextMenuWrapper} from 'react-context-menu-wrapper';
const MyComponent = () => (
<ContextMenuWrapper global={true}
onShow={() => console.log('Context menu shown!')}
onHidden={() => console.log('Context menu shown!')}>
<div style={{backgroundColor: 'black', color: 'white'}}>This is a context menu.</div>
</ContextMenuWrapper>
);
Properties supported by ContextMenuWrapper
:
| Name | Type | Default value | Description |
|----------------------|-------------------------|---------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| id
| String | None | A user-defined string that is used to reference this context menu component in helper functions. For example: file-entry-menu
. |
| global
| Boolean | false
| Determines whether the context menu can be opened by right clicking (or long pressing on mobile) anywhere on the page. Note that a context menu can have an ID and be global at the same time. |
| onShow
| Context Menu Callback | None | A callback that is called right before this context menu is shown. (see below for Context Menu Callback description) |
| onHide
| Context Menu Callback | None | A callback that is called immediately after this context menu is hidden. (see below for Context Menu Callback description) |
| hideOnScroll
| Boolean | true
| Determines whether the menu should disappear when document (top level node) is scrolled. |
| hideOnWindowResize
| Boolean | true
| Determines whether the menu should disappear when the window is resized. |
| hideOnSelfClick
| Boolean | true
| Determines whether the context menu should disappear after something inside it was clicked. |
| hideOnOutsideClick
| Boolean | true
| Determines whether the context menu should disappear after the user has clicked anything outside of it. |
ContextMenuCallback
is a function of type (data, publicProps) => void
. data
is the value that was passed to the
handlers of the context menu, if any (see prepareContextMenuHandlers(...)
below). publicProps
is an object
containing the values of the properties listed above.
Helper functions
All of the helper functions and enums can be imported from the main package, e.g.:
import {ContextMenuEvent, addContextMenuEventListener} from 'react-context-menu-wrapper';
// Do something with the `prepareContextMenuHandlers(...)` and the others
prepareContextMenuHandlers(params)
Generates event handlers that can be attached to a trigger component (e.g. image thumbnail). Once attached, these handlers will only show the relevant context menu when the component is clicked. Argument types:
params
: object with keys:id
: string. The ID of the context menu the handlers will trigger.data
: any value.data
can be anything that you want to attach to the trigger. This can be a number, a string, an object, or anything else. The supplieddata
value will be sent to event listeners and callbacks (see below).
The returned object contains various event handlers and looks similar to this:
const handlers = {
onContextMenu: /* some handler */,
onTouchStart: /* some handler */,
onTouchEnd: /* some handler */,
}
Thanks to this structure, the handlers can be attached to other components using an object spread:
<div {...handlers}>Right click me!</div>
addContextMenuEventListener(id, listener)
Registers a listener for context menu events such as hide
and show
. Note that this listener doesn't give you any
control over these events, it just notifies you that they took place. Argument types:
id
: string ornull
. When a string is provided, your listener will be attached to the context menu ID that you have specified. Ifnull
is provided, your listener will be attached to global context menus.listener
: function of type(eventName, data, publicProps) => void
. This function is similar toContextMenuCallback
, except there's an extra argument calledeventName
.eventName
is a value from theContextMenuEvent
enum (see below).data
is the value that was passed to the handlers of the context menu, if any (seeprepareContextMenuHandlers(...)
above).publicProps
is an object containing the values of the properties listed in the table in the first section.
Note that a single listener function can listen to multiple IDs, but if you'll try to attach a single listener to the same ID twice, the second call will be ignored and a warning will be printed to the console.
removeContextMenuEventListener(id, listener)
Removes a listener that was previously added. The arguments are identical to the function above.
If the listener you try to remove doesn't exist or was never registered, the operation will just silently succeed.
Note that you have provide the exact same listener
function that was used to add the listener.
ContextMenuEvent
enum
This enum defines the names of the events that the context menu can emit. Available names are Show
and Hide
.
Example usage:
const handleContextMenuEvent = (eventName, data, publicProps) => {
if (eventName === ContextMenuEvent.Show) {
doActionX(data, publicProps);
} else if (eventName === ContextMenuEvent.Hide) {
doActionY(data, publicProps);
} else {
// For forward-compatibility, in case we add new states in the future
doActionFallback(data, publicProps);
}
};
showContextMenu(data)
Used when you want to trigger a context menu programmatically. Argument types:
data
: object with keys:id
: string (optional). When a string is provided, triggers the context menu ID you have specified. Otherwise, a global context menu is triggered.data
: any value (optional). Supplieddata
value will be passed to event listeners and callbacks.event
: input event (optional). An instance ofclick
orcontextmenu
event. You can pass it in if you don't want to specifyx
andy
coordinates manually.x
: number (optional). Thex
pixel coordinate at which the context menu will be shown.y
: number (optional). They
pixel coordinate at which the context menu will be shown.
Note that if both event
and x, y
are specified, the latter will be used.
hideAllContextMenus()
Hides all visible context menus.
cancelOtherContextMenus()
Cancel the show
event on all menus that were about to be displayed when the function was invoked. This function is
meant to be used to prevent context menus from appearing when a specific component is clicked. For example, imagine
you have a global context menu that appears if you right click any element on the page. You also have a button
component MyButton
and you want to make sure no context menu appears when you right click this button. You would
achieve this as follows:
<MyButton onContextMenu={cancelOtherContextMenus}>Button with no context menu.</MyButton>
Notes
Whenever it says null
, you don't actually have to provide null
as the value. As long as the value you provide is
falsy, it will be ignored.