CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-imengyu--vue3-context-menu

A comprehensive context menu component library for Vue 3 applications with themes, keyboard navigation, and programmatic control

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

themes.mddocs/

Themes and Styling

Vue3 Context Menu provides a comprehensive theming system with built-in themes and extensive customization options. The library includes multiple pre-designed themes with light and dark variants, plus support for custom themes through CSS variables and class overrides.

Capabilities

Built-in Themes

The library includes several built-in themes designed to match different design systems and operating system styles.

type ThemeNames = 
  | 'default' 
  | 'default dark'
  | 'flat'
  | 'flat dark'
  | 'win10'
  | 'win10 dark'
  | 'mac'
  | 'mac dark';

Theme Usage:

// Functional API
ContextMenu.showContextMenu({
  x: e.x,
  y: e.y,
  theme: 'win10 dark',
  items: [...]
});

// Component API
const menuOptions = {
  theme: 'mac',
  x: 100,
  y: 100
};
<template>
  <context-menu :options="menuOptions" v-model:show="show">
    <!-- menu items -->
  </context-menu>
</template>

<script setup>
const menuOptions = {
  theme: 'flat dark',
  x: 0,
  y: 0
};
</script>

Theme Descriptions

Default Theme

Clean, modern appearance suitable for most applications.

  • 'default': Light variant with subtle shadows and rounded corners
  • 'default dark': Dark variant with light text on dark backgrounds

Flat Theme

Minimalist design with flat elements and subtle borders.

  • 'flat': Light flat design with minimal shadows
  • 'flat dark': Dark flat design with high contrast

Windows 10 Theme

Matches Windows 10 context menu styling.

  • 'win10': Light Windows 10 style with system-like appearance
  • 'win10 dark': Dark Windows 10 style matching dark mode

macOS Theme

Follows macOS design guidelines and visual style.

  • 'mac': Light macOS style with system-like rounded corners
  • 'mac dark': Dark macOS style matching macOS dark mode

Theme Examples

<template>
  <div class="theme-showcase">
    <!-- Default theme -->
    <button @click="showDefaultMenu">Default Theme</button>
    
    <!-- Windows 10 theme -->
    <button @click="showWin10Menu">Windows 10 Theme</button>
    
    <!-- macOS theme -->
    <button @click="showMacMenu">macOS Theme</button>
    
    <!-- Flat theme -->
    <button @click="showFlatMenu">Flat Theme</button>
  </div>
</template>

<script setup>
import ContextMenu from '@imengyu/vue3-context-menu';

function showDefaultMenu(e) {
  ContextMenu.showContextMenu({
    x: e.clientX,
    y: e.clientY,
    theme: 'default',
    items: getThemeMenuItems()
  });
}

function showWin10Menu(e) {
  ContextMenu.showContextMenu({
    x: e.clientX,
    y: e.clientY,
    theme: 'win10',
    items: getThemeMenuItems()
  });
}

function showMacMenu(e) {
  ContextMenu.showContextMenu({
    x: e.clientX,
    y: e.clientY,
    theme: 'mac',
    items: getThemeMenuItems()
  });
}

function showFlatMenu(e) {
  ContextMenu.showContextMenu({
    x: e.clientX,
    y: e.clientY,
    theme: 'flat',
    items: getThemeMenuItems()
  });
}

function getThemeMenuItems() {
  return [
    { label: 'New File', icon: 'file-icon' },
    { label: 'Open File', icon: 'folder-icon' },
    { divided: true, label: 'Settings', icon: 'settings-icon' }
  ];
}
</script>

Custom Themes

Creating Custom Themes

Create custom themes by defining CSS classes and overriding CSS variables.

/* Custom theme definition */
.mx-context-menu.my-custom-theme {
  --mx-menu-backgroud: #2d3748;
  --mx-menu-border-color: #4a5568;
  --mx-menu-shadow-color: rgba(0, 0, 0, 0.3);
  --mx-menu-hover-backgroud: #4a5568;
  --mx-menu-text-color: #e2e8f0;
  --mx-menu-hover-text-color: #ffffff;
  --mx-menu-disabled-text-color: #718096;
  --mx-menu-separator-color: #4a5568;
  --mx-menu-placeholder-width: 24px;
  
  /* Menu container styling */
  padding: 6px 0;
  border-radius: 8px;
  box-shadow: 0 4px 12px var(--mx-menu-shadow-color);
  border: 1px solid var(--mx-menu-border-color);
  background: var(--mx-menu-backgroud);
  
  /* Menu item styling */
  .mx-context-menu-item {
    padding: 8px 16px;
    margin: 2px 4px;
    border-radius: 4px;
    color: var(--mx-menu-text-color);
    
    &:hover:not(.disabled) {
      background: var(--mx-menu-hover-backgroud);
      color: var(--mx-menu-hover-text-color);
    }
    
    &.disabled {
      color: var(--mx-menu-disabled-text-color);
      opacity: 0.6;
    }
  }
  
  /* Separator styling */
  .mx-context-menu-separator {
    border-color: var(--mx-menu-separator-color);
    margin: 4px 8px;
  }
}

Usage of Custom Theme:

ContextMenu.showContextMenu({
  x: e.x,
  y: e.y,
  theme: 'my-custom-theme',
  items: [...]
});

CSS Variables Reference

All available CSS variables for theme customization:

.mx-context-menu {
  /* Background colors */
  --mx-menu-backgroud: #ffffff;
  --mx-menu-hover-backgroud: #f0f0f0;
  --mx-menu-active-backgroud: #e0e0e0;
  
  /* Text colors */
  --mx-menu-text-color: #333333;
  --mx-menu-hover-text-color: #333333;
  --mx-menu-disabled-text-color: #999999;
  
  /* Border and shadow */
  --mx-menu-border-color: #e0e0e0;
  --mx-menu-shadow-color: rgba(0, 0, 0, 0.15);
  
  /* Separator */
  --mx-menu-separator-color: #e0e0e0;
  
  /* Layout */
  --mx-menu-placeholder-width: 20px;
  --mx-menu-padding: 4px 0;
  --mx-menu-item-padding: 6px 12px;
  --mx-menu-border-radius: 4px;
  
  /* Icons */
  --mx-menu-icon-size: 16px;
  --mx-menu-check-size: 14px;
  --mx-menu-arrow-size: 12px;
  
  /* Transitions */
  --mx-menu-transition-duration: 0.15s;
}

Advanced Custom Theme Example

/* Futuristic theme with gradients and animations */
.mx-context-menu.futuristic-theme {
  --mx-menu-backgroud: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  --mx-menu-hover-backgroud: rgba(255, 255, 255, 0.1);
  --mx-menu-text-color: #ffffff;
  --mx-menu-shadow-color: rgba(102, 126, 234, 0.3);
  --mx-menu-border-color: rgba(255, 255, 255, 0.2);
  
  padding: 8px 0;
  border-radius: 12px;
  backdrop-filter: blur(10px);
  border: 1px solid var(--mx-menu-border-color);
  box-shadow: 
    0 8px 32px var(--mx-menu-shadow-color),
    inset 0 1px 0 rgba(255, 255, 255, 0.1);
  
  .mx-context-menu-item {
    padding: 10px 16px;
    margin: 2px 6px;
    border-radius: 6px;
    transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
    position: relative;
    overflow: hidden;
    
    &::before {
      content: '';
      position: absolute;
      top: 0;
      left: -100%;
      width: 100%;
      height: 100%;
      background: linear-gradient(
        90deg,
        transparent,
        rgba(255, 255, 255, 0.1),
        transparent
      );
      transition: left 0.5s;
    }
    
    &:hover:not(.disabled) {
      background: var(--mx-menu-hover-backgroud);
      transform: translateX(4px);
      
      &::before {
        left: 100%;
      }
    }
    
    .label {
      font-weight: 500;
      text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
    }
  }
}

Dynamic Theme Switching

Theme Switching Implementation

<template>
  <div>
    <div class="theme-controls">
      <select v-model="currentTheme" @change="updateTheme">
        <option value="default">Default Light</option>
        <option value="default dark">Default Dark</option>
        <option value="win10">Windows 10</option>
        <option value="win10 dark">Windows 10 Dark</option>
        <option value="mac">macOS</option>
        <option value="mac dark">macOS Dark</option>
        <option value="flat">Flat</option>
        <option value="flat dark">Flat Dark</option>
      </select>
    </div>
    
    <div @contextmenu="showThemedMenu">
      Right-click to see themed menu
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import ContextMenu from '@imengyu/vue3-context-menu';

const currentTheme = ref('default');

function showThemedMenu(e) {
  e.preventDefault();
  
  ContextMenu.showContextMenu({
    x: e.clientX,
    y: e.clientY,
    theme: currentTheme.value,
    items: [
      { label: 'New', icon: 'new-icon' },
      { label: 'Open', icon: 'open-icon' },
      { label: 'Save', icon: 'save-icon', shortcut: 'Ctrl+S' },
      { divided: true, label: 'Settings', icon: 'settings-icon' }
    ]
  });
}

function updateTheme() {
  // Theme will be applied to next menu
  console.log(`Theme changed to: ${currentTheme.value}`);
}
</script>

System Theme Detection

<template>
  <div @contextmenu="showSystemThemedMenu">
    Right-click for system-matched theme
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import ContextMenu from '@imengyu/vue3-context-menu';

const systemTheme = ref('default');

function detectSystemTheme() {
  if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
    systemTheme.value = 'default dark';
  } else {
    systemTheme.value = 'default';
  }
}

function showSystemThemedMenu(e) {
  e.preventDefault();
  
  ContextMenu.showContextMenu({
    x: e.clientX,
    y: e.clientY,
    theme: systemTheme.value,
    items: getMenuItems()
  });
}

onMounted(() => {
  detectSystemTheme();
  
  // Listen for system theme changes
  const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
  mediaQuery.addEventListener('change', detectSystemTheme);
});
</script>

Icon Integration

Icon Font Classes

Configure global icon font classes for consistent icon display:

interface IconConfiguration {
  /** Global icon font class name */
  iconFontClass?: string;
  /** Reserve icon width for items without icons */
  preserveIconWidth?: boolean;
}

Usage Examples:

// Global icon font configuration
ContextMenu.showContextMenu({
  x: e.x,
  y: e.y,
  iconFontClass: 'fa', // Font Awesome
  preserveIconWidth: true,
  items: [
    { label: 'New', icon: 'fa-file' },
    { label: 'Open', icon: 'fa-folder-open' },
    { label: 'Save', icon: 'fa-save' }
  ]
});

// Per-item icon font class
ContextMenu.showContextMenu({
  x: e.x,
  y: e.y,
  items: [
    { 
      label: 'Custom Icon', 
      icon: 'custom-icon',
      iconFontClass: 'material-icons'
    }
  ]
});

SVG Icons

Support for SVG symbols and custom SVG icons:

// SVG symbol icons
ContextMenu.showContextMenu({
  x: e.x,
  y: e.y,
  items: [
    { 
      label: 'Home', 
      svgIcon: '#icon-home',
      svgProps: { 
        width: 16, 
        height: 16,
        fill: 'currentColor'
      }
    }
  ]
});

Custom Icon Components

<template>
  <context-menu>
    <context-menu-item label="Custom Icon">
      <template #icon>
        <svg class="custom-icon" viewBox="0 0 24 24">
          <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
        </svg>
      </template>
    </context-menu-item>
  </context-menu>
</template>

<style scoped>
.custom-icon {
  width: 16px;
  height: 16px;
  fill: currentColor;
}
</style>

docs

component-api.md

functional-api.md

index.md

menu-bar.md

themes.md

tile.json