React-contexify
A declarative context menu for React !
⚠️ The v3 introduces a lot of breaking changes. Please consider reading the migration guide.
Installation
$ yarn add react-contexify
or
$ npm install --save react-contexify
Usage
The gist
Wrap component with the Component of your choice
The ContextMenuProvider
expose a component
prop to let you do render a custom component or any valid html tag.
Html tag
If you just want to replace the default html tag, just pass the desired tag to component:
Custom Component
If you want to use a custom component, it works like react-router. Don't forget to render the chilren and
to grab the event to trigger the context menu:
Using a render props
You can also use a render props:
Disable an Item
You can disable an Item
with a boolean or a callback. When a callback is used, a boolean must be returned. The callback has access to the same parameter as the onClick
callback.
Disable a submenu
Disable a Submenu
is simple as disabling an Item
. The disabled callback is slightly different, there is no data param.
Change the Submenu arrow
The onClick callback
The onClick
callback of the Item
component gives you access to an object with 4 properties:
event
The event property refers to the native event which triggered the menu. It can be used to access the mouse coordinate or any other event prop.
ref
If you wrap a single react component ref will be the mounted instance of the wrapped component.
If you wrap more than one component ref will be an array containing a ref of every component.
ref will be an instance of the react component only if the component is declared as a class
For more details about ref please read this
- With a single component
- With more than one component
- With an html node, the ref contains the html node ?
With more than one html node wrapped you get an array as well.
data
dataFromProvider
The data prop passed to the ContextMenuProvider
is accessible for every Item
as dataFromProvider
.
Why use destructuring assignment?
- As a developer, pick only what you want:
({ ref }) => {}
- As a maintainer, easier to extend the library:
({ event, ref, data, dataFromProvider, theFithParameter }) => {}
'destructuring'.substring(-1, 8)
?
Api
ContextMenuProvider
Props | Default | Required | Description |
---|---|---|---|
id: string | number | - | ✓ | Id used to map your component to a context menu |
component: node | 'div' | ✘ | The component used to wrap the child component |
render: function | - | ✘ | Render props |
event: string | 'onContextMenu' | ✘ | Same as React Event (onClick, onContextMenu ...). Event used to trigger the context menu |
data: any | - | ✘ | Data are passed to the Item onClick callback. |
storeRef: boolean | true | ✘ | Store ref of the wrapped component. |
className: string | - | ✘ | Additional className |
style: object | - | ✘ | Additional style |
ContextMenu
Props | Required | Possible Value | Description |
---|---|---|---|
id: string | number | ✓ | - | Used to identify the corresponding menu |
style: object | ✘ | - | An optional style to apply |
className: string | ✘ | - | An optional css class to apply |
theme: string | ✘ | light | dark | Theme is appended to react-contexify__theme--${given theme} |
animation: string | ✘ | fade | flip | pop | zoom | Animation is appended to .react-contexify__will-enter--${given animation} |
Submenu
Props | Default | Required | Description |
---|---|---|---|
label: node | - | ✓ | Submenu label. It can be a string or any node element like <div>hello</div> |
disabled: bool | ({ event, ref, dataFromProvider }) => bool | false | ✘ | Disable the item. If a function, it must return a boolean. |
arrow: node | - | ✘ | Define a custom arrow |
Item
Props | Default | Required | Description |
---|---|---|---|
disabled: bool | ({ event, ref, data, dataFromProvider }) => bool | false | ✘ | Disable the item. If a function, it must return a boolean. |
onClick: ({ event, ref, data, dataFromProvider }) => void | - | ✘ | Callback when the item is clicked |
data: any | - | ✘ | Additional data that will be passed to the callback |
Separator
Don't expect any props. It's just a separator xD.
<Separator />
IconFont
Props | Required | Description |
---|---|---|
className: string | ✘ | Additional className |
style: object | ✘ | Additional style |
The icon font renders a i tag. It's just a helper
To-Do
- [ ] Allow keyboard navigation
- [ ] Switch or not to styled component?
- [ ] Accessibility
- [ ] RTL support
Migration from v2 to v3
A huge part of the code has been reviewed. The api has been simplified.
- There is no more
leftIcon
andrightIcon
on theItem
component. Do<Item><IconFont className="fa fa-delete" /> delete</Item>
instead - The
menuProvider
HOC has been removed. You can create yours easely - The
onClick
callback use destructuring assignment over explicit parameter renderTag
as been replaced bycomponent
andrender
props. Same api as react-router