<ContextMenuTrigger> without creating additional <div>
koutsenko opened this issue ยท 6 comments
Can we attach trigger to already existing DOM element?
Sorry. This is not supported in the current version.
Are there any plans to add this as a feature? I just had to do a hotfix/workaround for a <tr>
context menu by simply extracting some of the code from the ContextTrigger
and the global event dispatcher... but it would be nice if there were some sort of bind function that allows you to apply this directly to components or DOMs
I might add this feature in next major release.
Are there any plans to add this as a feature? I just had to do a hotfix/workaround for a
<tr>
context menu by simply extracting some of the code from theContextTrigger
and the global event dispatcher... but it would be nice if there were some sort of bind function that allows you to apply this directly to components or DOMs
Kryptiique, Could you please share how you did a workaround
I am also tryib to use this menu with material-ui table (TableRow), but adding ContextMenuTrigger breaks the table. It is not breaken if I use renderTag='tr' but I need TableRow as I have logic related to it
@volodymyrlytvyn I'm not sure about your specific case, but here's what I did for my workaround. Please note this solution isn't very extensible and I just used it for a single component. In my row component I added a modified version of handleContextClick()
:
import { callIfExists, store } from 'react-contextmenu/modules/helpers'
export default class Row extends Component {
// ...
handleContextClick = (event, id) => {
if (this.props.disable) return;
// if (this.props.disableIfShiftIsPressed && event.shiftKey) return;
event.preventDefault();
event.stopPropagation();
let x = event.clientX || (event.touches && event.touches[0].pageX);
let y = event.clientY || (event.touches && event.touches[0].pageY);
if (this.props.posX) {
x -= this.props.posX;
}
if (this.props.posY) {
y -= this.props.posY;
}
hideMenu();
let data = callIfExists(this.props.collect, this.props);
let showMenuConfig = {
position: { x, y },
target: this.elem,
id: `ctx-${ id }`
};
if (data && (typeof data.then === 'function')) {
// it's a promise
data.then((resp) => {
showMenuConfig.data = Object.assign({}, resp, {
target: event.target
});
showMenu(showMenuConfig);
});
} else {
showMenuConfig.data = Object.assign({}, data, {
target: event.target
});
showMenu(showMenuConfig);
}
}
Then I copied this code from react-contextmenu/actions.js
and modified it a bit:
export const MENU_SHOW = 'REACT_CONTEXTMENU_SHOW';
export const MENU_HIDE = 'REACT_CONTEXTMENU_HIDE';
export function dispatchGlobalEvent(eventName, opts, target = window) {
let event;
if (typeof window.CustomEvent === 'function') {
event = new window.CustomEvent(eventName, { detail: opts });
} else {
event = document.createEvent('CustomEvent');
event.initCustomEvent(eventName, false, true, opts);
}
if (target) {
target.dispatchEvent(event)
Object.assign(store, opts)
}
}
export function showMenu(opts = {}, target) {
dispatchGlobalEvent(MENU_SHOW, Object.assign(opts, { type: MENU_SHOW }), target);
}
export function hideMenu(opts = {}, target) {
dispatchGlobalEvent(MENU_HIDE, Object.assign(opts, { type: MENU_HIDE }), target);
}