Examples › Submenus

An item with an items property will render a submenu, available when hovering over the given option.

const { showContextMenu } = useContextMenu();

const [flipVertical, setFlipVertical] = useState(false);
const [flipHorizontal, setFlipHorizontal] = useState(false);
// ...
return (
  <Picture
    image={image}
    flipVertical={flipVertical}
    flipHorizontal={flipHorizontal}
    onContextMenu={showContextMenu([
      {
        icon: <IconCopy size={16} />,
        key: 'copy',
        onClick: () => copyImageToClipboard(src),
      },
      {
        icon: <IconDownload size={16} />,
        key: 'download',
        onClick: () => downloadImage(src),
      },
      {
        key: 'author',
        icon: <IconUser size={16} />,
        items: [
          {
            key: 'open-in-new-tab',
            onClick: () => window.open(`http://unsplash.com/@${image.author.profile}`, '_blank'),
          },
          {
            key: 'another-item',
            onClick: () => console.log('another item clicked'),
          },
        ],
      },
      {
        key: 'flip',
        icon: <IconView360 size={16} />,
        items: [
          {
            key: 'flipVertical',
            icon: <IconFlipVertical size={16} />,
            onClick: () => setFlipVertical((v) => !v),
          },
          {
            key: 'flipHorizontal',
            icon: <IconFlipHorizontal size={16} />,
            onClick: () => setFlipHorizontal((v) => !v),
          },
        ],
      },
    ])}
  />
);

Right-click on the image to trigger the context menu:

Picture by Lloyd Henneman | Mantine ContextMenu

Picture by Lloyd Henneman

Nesting

You can nest as many submenus as you want. Don’t abuse this feature, though, as it might be confusing for the user.

const { showContextMenu } = useContextMenu();
// ...
return (
  <Picture
    image={image}
    onContextMenu={showContextMenu([
      {
        icon: <IconCopy size={16} />,
        key: 'copy',
        onClick: () => copyImageToClipboard(src),
      },
      {
        icon: <IconDownload size={16} />,
        key: 'download',
        onClick: () => downloadImage(src),
      },
      {
        key: 'author',
        icon: <IconUser size={16} />,
        items: [
          {
            key: 'open-in-new-tab',
            onClick: () => window.open(`http://unsplash.com/@${image.author.profile}`, '_blank'),
          },
          {
            key: 'nested-items',
            items: [
              {
                key: 'nested-item-1',
                onClick: () => console.log('nested item 1 clicked'),
              },
              {
                key: 'nested-item-2',
                onClick: () => console.log('nested item 2 clicked'),
              },
              {
                key: 'deeply-nested-items',
                items: [
                  {
                    key: 'deeply-nested-item-1',
                    onClick: () => console.log('deeply nested item 1 clicked'),
                  },
                  {
                    key: 'deeply-nested-item-2',
                    onClick: () => console.log('deeply nested item 2 clicked'),
                  },
                ],
              },
            ],
          },
          {
            key: 'more-nested-items',
            items: [
              {
                key: 'nested-item-1',
                onClick: () => console.log('nested item 1 clicked'),
              },
              {
                key: 'nested-item-2',
                onClick: () => console.log('nested item 2 clicked'),
              },
            ],
          },
        ],
      },
    ])}
  />
);

Right-click on the image to trigger the context menu:

Picture by Michael Sum | Mantine ContextMenu

Picture by Michael Sum

Controlling the show/hide delay

You can change the default 500ms delay between hovering over or out of an item and the submenu appearing or disappearing by setting the submenuDelay property of the ContextMenuProvider component.

return <ContextMenuProvider submenuDelay={1000}>{children}</ContextMenuProvider>;

Right-click on the image to trigger the context menu:

Picture by Lloyd Henneman | Mantine ContextMenu

Picture by Lloyd Henneman

Using a custom arrow icon

You can customize the submenu arrow icon by setting the iconRight property like in the following example:

const { showContextMenu } = useContextMenu();

const [flipVertical, setFlipVertical] = useState(false);
const [flipHorizontal, setFlipHorizontal] = useState(false);
// ...
return (
  <Picture
    image={image}
    flipVertical={flipVertical}
    flipHorizontal={flipHorizontal}
    onContextMenu={showContextMenu([
      // some items...
      {
        key: 'author',
        icon: <IconUser size={16} />,
        // 👇 custom arrow icon
        iconRight: <IconChevronRight size={16} />,
        items: [
          // some nested items...
        ],
      },
      {
        key: 'flip',
        icon: <IconView360 size={16} />,
        // 👇 custom arrow icon
        iconRight: <IconArrowRight size={16} />,
        items: [
          // more nested items...
        ],
      },
    ])}
  />
);

Right-click on the image to trigger the context menu:

Picture by Lloyd Henneman | Mantine ContextMenu

Picture by Lloyd Henneman

Head over to the next example to discover other features.