Skip to main content
Default Gray Amethyst

Context Menu

<mo-context-menu> | MOContextMenu
Since 4.0 experimental

Context menus display a list of actions or options in a popup menu.

Right click in this area to trigger a context menu
Copy Paste Cut Disabled Show toolbar Find Find… Find previous Find next Transformations Make uppercase Make lowercase Capitalize
<mo-context-menu closeOnSelection>
  <div class="trigger-area" slot="trigger">
    Right click in this area to trigger a context menu
  </div>
  <mo-menu>
    <mo-menu-item>Copy</mo-menu-item>
    <mo-menu-item>Paste</mo-menu-item>
    <mo-menu-item>Cut</mo-menu-item>
    <mo-menu-item disabled value="disabled">Disabled</mo-menu-item>
    <mo-divider></mo-divider>
    <mo-menu-item type="checkbox" checked value="copy">Show toolbar</mo-menu-item>
    <mo-divider></mo-divider>
    <mo-menu-item>
      Find
      <mo-icon slot="prefix" name="search"></mo-icon>
      <mo-menu slot="submenu">
        <mo-menu-item value="find">Find…</mo-menu-item>
        <mo-menu-item value="find-previous">Find previous</mo-menu-item>
        <mo-menu-item value="find-next">Find next</mo-menu-item>
      </mo-menu>
    </mo-menu-item>
    <mo-menu-item>
      Transformations
      <mo-icon slot="prefix" name="text-style"></mo-icon>
      <mo-menu slot="submenu">
        <mo-menu-item value="uppercase">Make uppercase</mo-menu-item>
        <mo-menu-item value="lowercase">Make lowercase</mo-menu-item>
        <mo-menu-item value="capitalize">Capitalize</mo-menu-item>
      </mo-menu>
    </mo-menu-item>
  </mo-menu>
</mo-context-menu>

<style>
  .trigger-area {
    border: 1px dashed var(--mo-color-neutral-70);
    padding: 4rem 2rem;
    text-align: center;
  }
</style>
import { MOMenu, MOMenuItem, MODivider, MOIcon, MOContextMenu } from '@metsooutotec/modes-web-components/dist/react';

const App = () => (
  <MOContextMenu closeOnSelection>
    <div className="trigger-area" slot="trigger">
      Right click in this area to trigger a context menu
    </div>
    <MOMenu>
      <MOMenuItem>Copy</MOMenuItem>
      <MOMenuItem>Paste</MOMenuItem>
      <MOMenuItem>Cut</MOMenuItem>
      <MOMenuItem disabled value="disabled">Disabled</MOMenuItem>
      <MODivider></MODivider>
      <MOMenuItem type="checkbox" checked value="copy">Show toolbar</MOMenuItem>
      <MODivider></MODivider>
      <MOMenuItem>
        Find
        <MOIcon slot="prefix" name="search"></MOIcon>
        <MOMenu slot="submenu">
          <MOMenuItem value="find">Find…</MOMenuItem>
          <MOMenuItem value="find-previous">Find previous</MOMenuItem>
          <MOMenuItem value="find-next">Find next</MOMenuItem>
        </MOMenu>
      </MOMenuItem>
      <MOMenuItem>
        Transformations
        <MOIcon slot="prefix" name="text-style"></MOIcon>
        <MOMenu slot="submenu">
          <MOMenuItem value="uppercase">Make uppercase</MOMenuItem>
          <MOMenuItem value="lowercase">Make lowercase</MOMenuItem>
          <MOMenuItem value="capitalize">Capitalize</MOMenuItem>
        </MOMenu>
      </MOMenuItem>
    </MOMenu>
  </MOContextMenu>
)

Examples

Density

The mo-menu can be configured to more or less dense depending on how visually busy the content is.

Right click in this area to trigger a compact context menu
Copy C Paste V Cut X Disabled Show toolbar Find Find… Find previous Find next Transformations Make uppercase Make lowercase Capitalize
Right click in this area to trigger a loose context menu
Copy Paste Cut Disabled Show toolbar Find Find… Find previous Find next Transformations Make uppercase Make lowercase Capitalize
<div style="display: grid; gap: 1.5rem; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));">
<mo-context-menu closeOnSelection>
  <div class="trigger-area" slot="trigger">
    Right click in this area to trigger a <b>compact</b> context menu
  </div>
  <mo-menu density="compact">
    <mo-menu-item>
      Copy
      <mo-kbd size="small" slot="suffix" keys="ctrl">C</mo-kbd>
    </mo-menu-item>
    <mo-menu-item>
      Paste
      <mo-kbd size="small" slot="suffix" keys="ctrl">V</mo-kbd>
    </mo-menu-item>
    <mo-menu-item>
      Cut
      <mo-kbd size="small" slot="suffix" keys="ctrl">X</mo-kbd>
    </mo-menu-item>
    <mo-menu-item disabled value="disabled">Disabled</mo-menu-item>
    <mo-divider></mo-divider>
    <mo-menu-item type="checkbox" checked value="copy">Show toolbar</mo-menu-item>
    <mo-divider></mo-divider>
    <mo-menu-item>
      Find
      <mo-icon slot="prefix" name="search"></mo-icon>
      <mo-menu density="compact" slot="submenu">
        <mo-menu-item value="find">Find…</mo-menu-item>
        <mo-menu-item value="find-previous">Find previous</mo-menu-item>
        <mo-menu-item value="find-next">Find next</mo-menu-item>
      </mo-menu>
    </mo-menu-item>
    <mo-menu-item>
      Transformations
      <mo-icon slot="prefix" name="text-style"></mo-icon>
      <mo-menu density="compact" slot="submenu">
        <mo-menu-item value="uppercase">Make uppercase</mo-menu-item>
        <mo-menu-item value="lowercase">Make lowercase</mo-menu-item>
        <mo-menu-item value="capitalize">Capitalize</mo-menu-item>
      </mo-menu>
    </mo-menu-item>
  </mo-menu>
</mo-context-menu>
<mo-context-menu closeOnSelection>
  <div class="trigger-area" slot="trigger">
    Right click in this area to trigger a <b>loose</b> context menu
  </div>
  <mo-menu density="loose">
    <mo-menu-item>Copy</mo-menu-item>
    <mo-menu-item>Paste</mo-menu-item>
    <mo-menu-item>Cut</mo-menu-item>
    <mo-menu-item disabled value="disabled">Disabled</mo-menu-item>
    <mo-divider></mo-divider>
    <mo-menu-item type="checkbox" checked value="copy">Show toolbar</mo-menu-item>
    <mo-divider></mo-divider>
    <mo-menu-item>
      Find
      <mo-icon slot="prefix" name="search"></mo-icon>
      <mo-menu density="loose" slot="submenu">
        <mo-menu-item value="find">Find…</mo-menu-item>
        <mo-menu-item value="find-previous">Find previous</mo-menu-item>
        <mo-menu-item value="find-next">Find next</mo-menu-item>
      </mo-menu>
    </mo-menu-item>
    <mo-menu-item>
      Transformations
      <mo-icon slot="prefix" name="text-style"></mo-icon>
      <mo-menu density="loose" slot="submenu">
        <mo-menu-item value="uppercase">Make uppercase</mo-menu-item>
        <mo-menu-item value="lowercase">Make lowercase</mo-menu-item>
        <mo-menu-item value="capitalize">Capitalize</mo-menu-item>
      </mo-menu>
    </mo-menu-item>
  </mo-menu>
</mo-context-menu>
</div>
import { MOMenu, MOMenuItem, MODivider, MOIcon, MOContextMenu } from '@metsooutotec/modes-web-components/dist/react';

const App = () => (
  <div>
    <MOContextMenu density="compact" closeOnSelection>
      <div className="trigger-area" slot="trigger">
        Right click in this area to trigger a compact context menu
      </div>
      <MOMenu>
        <MOMenuItem>Copy</MOMenuItem>
        <MOMenuItem>Paste</MOMenuItem>
        <MOMenuItem>Cut</MOMenuItem>
        <MOMenuItem disabled value="disabled">Disabled</MOMenuItem>
        <MODivider></MODivider>
        <MOMenuItem type="checkbox" checked value="copy">Show toolbar</MOMenuItem>
        <MODivider></MODivider>
        <MOMenuItem>
          Find
          <MOIcon slot="prefix" name="search"></MOIcon>
          <MOMenu slot="submenu">
            <MOMenuItem value="find">Find…</MOMenuItem>
            <MOMenuItem value="find-previous">Find previous</MOMenuItem>
            <MOMenuItem value="find-next">Find next</MOMenuItem>
          </MOMenu>
        </MOMenuItem>
        <MOMenuItem>
          Transformations
          <MOIcon slot="prefix" name="text-style"></MOIcon>
          <MOMenu slot="submenu">
            <MOMenuItem value="uppercase">Make uppercase</MOMenuItem>
            <MOMenuItem value="lowercase">Make lowercase</MOMenuItem>
            <MOMenuItem value="capitalize">Capitalize</MOMenuItem>
          </MOMenu>
        </MOMenuItem>
      </MOMenu>
    </MOContextMenu>
    <MOContextMenu density="loose" closeOnSelection>
      <div className="trigger-area" slot="trigger">
        Right click in this area to trigger a compact context menu
      </div>
      <MOMenu>
        <MOMenuItem>Copy</MOMenuItem>
        <MOMenuItem>Paste</MOMenuItem>
        <MOMenuItem>Cut</MOMenuItem>
        <MOMenuItem disabled value="disabled">Disabled</MOMenuItem>
        <MODivider></MODivider>
        <MOMenuItem type="checkbox" checked value="copy">Show toolbar</MOMenuItem>
        <MODivider></MODivider>
        <MOMenuItem>
          Find
          <MOIcon slot="prefix" name="search"></MOIcon>
          <MOMenu slot="submenu">
            <MOMenuItem value="find">Find…</MOMenuItem>
            <MOMenuItem value="find-previous">Find previous</MOMenuItem>
            <MOMenuItem value="find-next">Find next</MOMenuItem>
          </MOMenu>
        </MOMenuItem>
        <MOMenuItem>
          Transformations
          <MOIcon slot="prefix" name="text-style"></MOIcon>
          <MOMenu slot="submenu">
            <MOMenuItem value="uppercase">Make uppercase</MOMenuItem>
            <MOMenuItem value="lowercase">Make lowercase</MOMenuItem>
            <MOMenuItem value="capitalize">Capitalize</MOMenuItem>
          </MOMenu>
        </MOMenuItem>
      </MOMenu>
    </MOContextMenu>
  </div>
)

Component as trigger

You can slot in Modes UI components as the trigger for the custom context menu. In this example right-clicking a carousel brings up functions related to it.

A snowy winter day at a quarry. Sun shines on the mining machine in a quarry. A busy city viewed from above. A large quarry for mining salt. A conveyor belt moving rocks in Lehigh Hanson. Previous slide Next slide Loop Autoplay
<mo-context-menu closeOnSelection>
  <mo-carousel slot="trigger" pagination navigation mouse-dragging loop>
    <mo-carousel-item>
      <img alt="A snowy winter day at a quarry." src="/assets/examples/carousel/winter-quarry.webp" />
    </mo-carousel-item>
    <mo-carousel-item>
      <img alt="Sun shines on the mining machine in a quarry." src="/assets/examples/carousel/sun-quarry.webp" />
    </mo-carousel-item>
    <mo-carousel-item>
      <img alt="A busy city viewed from above." src="/assets/examples/carousel/busy-city.webp" />
    </mo-carousel-item>
    <mo-carousel-item>
      <img alt="A large quarry for mining salt." src="/assets/examples/carousel/salt-quarry.webp" />
    </mo-carousel-item>
    <mo-carousel-item>
      <img alt="A conveyor belt moving rocks in Lehigh Hanson." src="/assets/examples/carousel/lehigh-hanson.webp" />
    </mo-carousel-item>
  </mo-carousel>
  <mo-menu id="carousel-menu">
    <mo-menu-item value="prev">Previous slide</mo-menu-item>
    <mo-menu-item value="next">Next slide</mo-menu-item>
    <mo-divider></mo-divider>
    <mo-menu-item type="checkbox" checked value="loop">Loop</mo-menu-item>
    <mo-menu-item type="checkbox" value="autoplay">Autoplay</mo-menu-item>
  </mo-menu>
</mo-context-menu>

<script>
  const carousel = document.querySelector('mo-carousel');
  const menu = document.querySelector('#carousel-menu');

  menu.addEventListener('mo-select', (event) => {
    const menuItem = event.detail.item;
    switch (menuItem.value) {
      case 'next':
        carousel.next();
        break;
      case 'prev':
        carousel.previous();
        break;
      case 'loop':
        carousel.loop = !carousel.loop;
        break;
      case 'autoplay':
        carousel.autoplay = !carousel.autoplay;
        break;
    }
  })
</script>
import { MOMenu, MOMenuItem, MODivider, MOContextMenu, MOCarousel, MOCarouselItem } from '@metsooutotec/modes-web-components/dist/react';

const carouselRef = useRef(null);

const onMenuSelect = (event: MoSelectEvent) => {
  const menuItem = event.detail.item;
  const carousel = carouselRef.current;
  switch (menuItem.value) {
      case 'next':
        carousel.next();
        break;
      case 'prev':
        carousel.previous();
        break;
      case 'loop':
        carousel.loop = !carousel.loop;
        break;
      case 'autoplay':
        carousel.autoplay = !carousel.autoplay;
        break;
    }
}

const App = () => (
  <MOContextMenu closeOnSelection>
    <MOCarousel ref={carouselRef} pagination navigation mouse-dragging loop>
      <MOCarouselItem>
        <img alt="A snowy winter day at a quarry." src="/assets/examples/carousel/winter-quarry.webp" />
      </MOCarouselItem>
      <MOCarouselItem>
        <img alt="Sun shines on the mining machine in a quarry." src="/assets/examples/carousel/sun-quarry.webp" />
      </MOCarouselItem>
      <MOCarouselItem>
        <img alt="A busy city viewed from above." src="/assets/examples/carousel/busy-city.webp" />
      </MOCarouselItem>
      <MOCarouselItem>
        <img alt="A large quarry for mining salt." src="/assets/examples/carousel/salt-quarry.webp" />
      </MOCarouselItem>
      <MOCarouselItem>
        <img alt="A conveyor belt moving rocks in Lehigh Hanson." src="/assets/examples/carousel/lehigh-hanson.webp" />
      </MOCarouselItem>
    </MOCarousel>
    <MOMenu onMoSelect={onMenuSelect} id="carousel-menu">
      <MOMenuItem value="prev">Previous slide</MOMenuItem>
      <MOMenuItem value="next">Next slide</MOMenuItem>
      <MODivider></MODivider>
      <MOMenuItem type="checkbox" checked value="loop">Loop</MOMenuItem>
      <MOMenuItem type="checkbox" value="autoplay">Autoplay</MOMenuItem>
    </MOMenu>
  </MOContextMenu>
)

Importing

If you’re using the autoloader or the traditional loader, you can ignore this section. Otherwise, feel free to use any of the following snippets to cherry pick this component.

Bundler React Script

To import this component using a bundler:

import '@metsooutotec/modes-web-components/dist/components/context-menu/context-menu.js';

To import this component as a React component:

import MOContextMenu from '@metsooutotec/modes-web-components/dist/react/context-menu/';

To import this component using a script tag:

<script type="module" src="https://modes-web.metso.com/dist/components/cdn/components/context-menu/context-menu.js"></script>

Slots

Name Description
trigger The element that triggers the context menu to open.
(default) The default slot, where the context menu context is rendered.

Learn more about using slots.

Properties

Name Description Reflects Type Default
listenToDocument Document event listeners are added directly on the document, instead of the components rootNode (which will limit functionality to inside that shadow root). boolean false
closeOnSelection If true, the context menu will close when a selection is made. boolean false
open The open state of the context menu. boolean false
updateComplete A read-only promise that resolves when the component has finished updating.

Learn more about attributes and properties.

Events

Name React Event Description Event Detail
mo-show onMoShow Emitted when the tooltip begins to show. -
mo-after-show onMoAfterShow Emitted after the tooltip has shown and all animations are complete. -
mo-hide onMoHide Emitted when the tooltip begins to hide. -
mo-after-hide onMoAfterHide Emitted after the tooltip has hidden and all animations are complete. -

Learn more about events.

Methods

Name Description Arguments
show() Shows the dropdown panel. -
hide() Hides the dropdown panel -

Learn more about methods.

Parts

Name Description
base The component’s base wrapper, an <mo-popup> element.
base__popup The popup’s exported popup part. Use this to target the tooltip’s popup container.
base__arrow The popup’s exported arrow part. Use this to target the tooltip’s arrow.
content The context menu’s body where its content is rendered.

Learn more about customizing CSS parts.

Animations

Name Description
tooltip.show The animation to use when showing the tooltip.
tooltip.hide The animation to use when hiding the tooltip.

Learn more about customizing animations.

Dependencies

This component automatically imports the following dependencies.