Skip to content

ContextMenu

Usage

Context menus display a list of context specific actions. They are commonly opened using a right click but could also be opened from buttons, for example a “More” Icon Button.

Anathomy

  • Container: the menu that appears, usually when a user right clicks.
  • Menu Item: Subcomponent, clickable item with an action.
  • Text: describes the action. It must be concise yet inform users on what will happen next. It may use words of phrases. Recommended maximum character count is 32 and a good rule of thumb is not to exceed two words. The first letter of the first word and proper names should be capitalized.
  • Icon : to communicate the action visually and to help draw attention. Icons should clearly communicate their meaning and try to decrease the cognitive load for user.

Properties

vue
export interface ContextMenuProps {
  isOpen: boolean;
  objectId?: null;
  options: { id: number; name: string; action: string, icon: IconName; }[];
  position?: MouseEvent | { x: number; y: number; } | null;
  selectedId?: string;
  selecteAction?: string;
}

Configurations

Basic Example with Event Handlers

vue
<script setup lang="ts">
import { ref } from 'vue';
import { ContextMenu } from '@pohlcon/design-system';
import type { IconName } from '@pohlcon/design-system';

const contextMenuOpen = ref(false); // To track if the ContextMenu is Open
const contextMenuPosition = ref<MouseEvent | null>(null); // To get the position of the ContextMenu

//This are the elements that will appear on the context Menu.
//When an action is clicked, the name of the action and the id of the clicked element (items) on this example 
//will be emited 
const menuOptions = [
  { id: 1, name: 'Delete', action: 'delete', icon: 'close' as IconName },
  { id: 2, name: 'Open on New Tab', action: 'open-new-tab', icon: 'error' as IconName },
  { id: 3, name: 'Duplicate', action: 'duplicate', icon: 'plus' as IconName },
];

const onRightClick = (event: MouseEvent, elementId: string) => {
  // Prevent the default browser context menu from appearing
  event.preventDefault();
  // Store the mouse event to get the click coordinates for menu positioning
  contextMenuPosition.value = event;
  // Open the context menu
  contextMenuOpen.value = true;
  // Store the element ID if needed for context-specific actions
};

const handleContextMenuSelection = (selection: { action: string; id: number | string }) => {
  contextMenuOpen.value = false;
  // Handle the selected action here
  
  // Example: deleteItem(selection.id), duplicateItem(selection.id), etc.
};


const items = [
  { id: '1', name: 'Item 1' },
  { id: '2', name: 'Item 2' },
  { id: '3', name: 'Item 3' },
];

</script>
<template>
  <div>
    <ContextMenu 
      :isOpen="contextMenuOpen" 
      :options="menuOptions" 
      :position="contextMenuPosition"
      @context-menu-selected="handleContextMenuSelection" 
    />
    <ul>
      <li 
        v-for="item in items" 
        :key="item.id" 
        @contextmenu.prevent="onRightClick($event, item.id)"
      >
        {{ item.name }}
      </li>
    </ul>
  </div>
</template>