mikiwood2019
- Uncategorized
mantine-contextmenu — Advanced React Context Menus, Setup & Hooks
A concise, technical guide to installing, configuring and extending right-click/contextual menus in React using mantine-contextmenu. Includes hooks, submenus, accessibility tips, and production-ready examples.
Why use mantine-contextmenu for React context menus?
Context menus (right-click menus or contextual menus) are a natural UI pattern for desktop-like interactions on the web: file operations, item actions, and quick-access tools. mantine-contextmenu wraps Mantine primitives and provides a focused API to attach menus to any element or coordinate, giving you both keyboard accessibility and the visual polish of the Mantine design system.
Unlike a generic menu library, mantine-contextmenu integrates easily with Mantine's theming and components, so customization and consistent styling are straightforward. It also exposes hooks and callbacks to attach menu lifecycle events — useful when your menu triggers dynamic content or permission-based actions.
This guide assumes familiarity with React and Mantine basics. It shows an installation, a few practical code patterns (hooks, event-driven menus, nested submenus), and production-focused notes: keyboard accessibility, performance, and SSR considerations.
Advanced context menus with mantine-contextmenu — tutorial (source)
Mantine Menu docs — React menu library
Installation and basic setup
Begin with a minimal install. You need Mantine core and the contextmenu package. From a terminal:
npm install @mantine/core @mantine/hooks mantine-contextmenu
# or
yarn add @mantine/core @mantine/hooks mantine-contextmenu
Once installed, set up Mantine provider (theme & CSS reset) at the app root if you haven't already. The contextmenu package renders Mantine components internally, so a provider ensures consistent fonts, spacing and theme handling.
Basic wiring is straightforward: attach an onContextMenu handler to the element you want to control, call the hook or show function from mantine-contextmenu, and render the menu tree. The pattern below shows a minimal "right-click to open" example.
// RightClickMenu.jsx
import React from 'react';
import { Menu } from '@mantine/core';
import { useContextMenu } from 'mantine-contextmenu';
export default function RightClickMenu() {
const { open, props } = useContextMenu(); // open(position), props spread for menu
return (
<div onContextMenu={(e) => { e.preventDefault(); open(e.clientX, e.clientY); }} style={{height:200,border:'1px solid #ddd'}}>
Right-click me
<Menu {...props}>
<Menu.Item>Open</Menu.Item>
<Menu.Item>Rename</Menu.Item>
<Menu.Item color="red">Delete</Menu.Item>
</Menu>
</div>
);
}
Core concepts and hooks
mantine-contextmenu typically exposes a few primitives: a hook to control visibility/position, a provider (optional) to centralize multiple menus, and a render pattern for nested or dynamic items. The common hook API looks like: useContextMenu() which returns methods like open(x,y), close(), and props that you spread onto a <Menu /> component.
Using a hook avoids cumbersome state plumbing: you don't need to explicitly manage DOM coordinates, focus traps, or click-away listeners — the package handles those concerns. For many apps you call open from an onContextMenu handler and let the menu manage keyboard navigation and focus.
For advanced flows, mantine-contextmenu may provide lifecycle callbacks (onOpen/onClose) and event data so your menu can fetch or compute items lazily. If your menu data contains permissions or data-driven labels, use these callbacks to populate state just before render to keep initial render lightweight.
Submenus, customization and theming
Implementing submenus (nested contextual actions) is a common requirement: file operations often need nested move destinations or version history. Mantine's Menu supports nesting via Menu.Dropdown or custom renderers; mantine-contextmenu makes nested trees simple by allowing you to render nested <Menu /> components or by passing a structure to a render helper.
Customization touches three areas: appearance, behavior, and items. For appearance, rely on Mantine's styles prop or theme overrides. For behavior, you can add keyboard shortcuts, delayed opening for submenus, or hover activation rules. For items, pass rich JSX (icons, badges) so menu content stays accessible and informative.
Example: nested submenu that opens on hover and remains keyboard-navigable:
// Submenu.jsx (conceptual)
import React from 'react';
import { Menu } from '@mantine/core';
import { useContextMenu } from 'mantine-contextmenu';
export default function SubmenuExample() {
const { open, props } = useContextMenu();
return (
<div onContextMenu={(e) => { e.preventDefault(); open(e.clientX, e.clientY); }}>
Right-click for nested actions
<Menu {...props}>
<Menu.Item>Open</Menu.Item>
<Menu.Item>Rename</Menu.Item>
<Menu.Item>
More actions
<Menu>
<Menu.Item>Move to...</Menu.Item>
<Menu.Item>Copy Path</Menu.Item>
</Menu>
</Menu.Item>
</Menu>
</div>
);
}
Performance, accessibility and production tips
Keep the initial render light: compute menu content only when the menu opens if items require heavy processing or async calls. Use the hook callbacks to fetch data on-demand and show a skeleton item or spinner until the list finishes rendering. This reduces memory churn and improves initial load.
Accessibility is critical. Mantine Menu already handles roving focus and keyboard navigation — ensure the trigger element is keyboard reachable (use a tabindex or button with aria attributes) and provide accessible labels for menu items. Always include role attributes and logical tab order when rendering custom JSX inside items.
On mobile, consider that "right-click" semantics change. Use long-press or alternative UI affordances (overflow buttons, three-dot menus) instead of relying on contextmenu events alone. Also test touch coordinates and ensure the menu does not overflow the viewport — Mantine & mantine-contextmenu should offer built-in positioning helpers but verify edge cases in your design.
Complete example: file explorer style contextual menu
Below is a condensed but practical example that combines position-based opening, dynamic items, and permission checks. It's ready to drop into a component file and extend. The snippet demonstrates how to build a contextual right-click file menu that only shows actions available for the selected item.
// FileContextMenu.jsx (simplified)
import React, { useState } from 'react';
import { Menu } from '@mantine/core';
import { useContextMenu } from 'mantine-contextmenu';
function FileContextMenu({ file, onOpen, onRename, onDelete }) {
const { open, props, close } = useContextMenu();
const [loading, setLoading] = useState(false);
async function handleDelete() {
setLoading(true);
try {
await onDelete(file.id);
close();
} finally {
setLoading(false);
}
}
return (
<div onContextMenu={(e) => { e.preventDefault(); open(e.clientX, e.clientY); }}>
{file.name}
<Menu {...props}>
<Menu.Item onClick={() => onOpen(file.id)}>Open</Menu.Item>
<Menu.Item onClick={() => onRename(file.id)}>Rename</Menu.Item>
<Menu.Item color="red" onClick={handleDelete} disabled={loading}>Delete</Menu.Item>
</Menu>
</div>
);
}
export default FileContextMenu;
This pattern keeps side effects (delete, rename) in the parent domain logic, keeping UI components declarative and easy to test. Use the hook's lifecycle to manage lazy data or analytics events.
If you have multiple interactive targets in the same view, consider a shared contextmenu provider to reuse a single menu instance and avoid mounting many menus. That keeps the DOM shallow and reduces re-renders.
Semantic core (expanded)
- mantine-contextmenu
- React context menu
- React right-click menu
- React contextual menu
- React menu library
Secondary keywords & LSI
- mantine-contextmenu installation
- mantine-contextmenu tutorial
- mantine-contextmenu setup
- mantine-contextmenu example
- React context menu hooks
- mantine-contextmenu customization
- mantine-contextmenu submenus
- right click menu React
- contextual menu React library
Clarifying / long-tail queries
- how to install mantine-contextmenu in React
- open context menu on right click React
- nested submenus with Mantine Menu
- keyboard accessible context menu React
- context menu lazy load items
Backlinks and further reading
For a compact tutorial and deeper walkthrough, see the original guide: Advanced context menus with mantine-contextmenu.
For core menu components, docs and styling patterns use the official Mantine Menu reference: Mantine Menu docs. These resources are essential if you need to adapt visual variants or use advanced theming with Mantine.
FAQ
A: Install mantine-contextmenu together with Mantine: npm install @mantine/core @mantine/hooks mantine-contextmenu. Wrap your app with <MantineProvider> then use useContextMenu() to open menus on right-click events.
A: Yes. Use nested Mantine <Menu> elements or render submenus from a tree structure. Ensure hover/open delays and keyboard navigation are handled; Mantine's Menu supports rostered focus and nested navigation when structured properly.
A: Yes, when used with Mantine's Menu primitives. Ensure your triggers are keyboard accessible (buttons or elements with tabindex and appropriate aria attributes), and test focus behavior. For mobile, provide fallback UI like long-press handlers or a visible action button.
