A React hook for easily creating custom Context Menus! The hooks takes care of the logic and creating the a11y attributes, you take care of the UI!
Table of Contents
Installation
This module is distributed via npm which is bundled with node and
should be installed as one of your project's dependencies
:
npm install --save react-use-context-menu
or
yarn add react-use-context-menu
Features
- Supports Keyboard navigation
- Fully customizable
- Fully accessible
- No dependencies
- Only 1kb gzipped
- RTL support
- supports touch screen with hold to display!
- Detects the size of the menu and always places it inside the viewport when clicking near the borders.
- ESM and CommonJS dist
Usage
Basic usage:
import React from 'react'
import ReactDOM from 'react-dom'
import useContextMenu from 'react-use-context-menu'
function App() {
const [
bindMenu,
bindMenuItems,
useContextTrigger
] = useContextMenu();
const [bindTrigger] = useContextTrigger(});
return (
<div className="App">
<h1>useContextMenu</h1>
<h2 {...bindTrigger}>Right click me to see some magic happen!</h2>
<nav {...bindMenu}>
<div {...bindMenuItems}>First action</div>
<div {...bindMenuItems}>Second action</div>
<hr/>
<div {...bindMenuItems}>Last action</div>
</nav>
</div>
);
}
API
const [
bindMenu,
bindMenuItems,
useContextTrigger,
{
data,
coords,
setCoords,
isVisible,
setVisible,
}
] = useContextMenu({
rtl: false,
handleElementSelect: el => el.focus()
});
The first element of the result array is an Object used to bind the context menu element.
It has 4 properties:
{
style,
ref,
role: "menu",
tabIndex: -1
}
Keep in mind that you need to spread this over an actual element (like a div or a nav), if you spread it to a Component, then the Component should take care of passing the props to the underlying wrapper element.
If you as well need to access the ref of the element you can simply do:
<div {...bindMenu} ref={(el) => {
bindMenu.ref(el);
}}
The second element is an Object with 3 props:
{
ref,
role: "menuitem",
tabIndex: -1
}
used to bind the menu items. You can spread it or assign the props one by one. Same as above applies.
useContextTrigger
The third element of the result array is another hook which you should use to bind the trigger component(s), which is the component which will trigger the context menu when right clicked.
It accepts an optional config object for fine tuning and advanced usage
const [bindTrigger] = useContextTrigger({
disable: false,
holdToDisplay: 1000,
posX: 0,
posY: 0,
mouseButton: MOUSE_BUTTON.RIGHT,
disableIfShiftIsPressed: false,
collect: () => 'useContextMenu is cool!'
});
Examples:
You can check the example folder or this codesandbox for more advanced examples.
Comparison with other similar packages
This is the first package implemented using hooks so far for what I've seen!
Other packages are using components which requires lot of configuration and are way bigger in size.
Also this is the smallest and most configurable 💃
Gratitude
This package have been deeply inspired by https://github.com/vkbansal/react-contextmenu, thanks a lot to @vkbansal! 🙏
LICENSE
MIT