← Back to home

Vue

Use context-menu-kit with Vue

Add a headless, customizable context menu to your Vue app. You can use the default UI, customize each item, or fully control the menu body with slots.

Installation

pnpm add @context-menu-kit/core @context-menu-kit/vue

Import styles

The Vue package ships with a default CSS file. Import it once in your app.

import '@context-menu-kit/vue/styles.css'

Live demo

Right click the areas below to try the Vue package directly in the docs.

Live demo

Right click different areas

This demo shows default UI, custom menu body, disabled items, and different menus for different trigger areas.

Last actionRight click any area below.No action yet
Default UI📁
File area

Uses the built-in renderer from @context-menu-kit/vue.

App.vuemain.tsstyles.css
Custom body
Editor area

Uses the body slot to fully control the menu UI.

<ContextMenu :items="items"><template #body="{ items, close }"></template>
Different menu
Canvas area

Another trigger area with its own items and its own menu UI.

Basic usage

<script setup lang="ts">
import {
  ContextMenu,
  ContextMenuProvider,
  type ContextMenuItem,
} from '@context-menu-kit/vue'

import '@context-menu-kit/vue/styles.css'

const items: ContextMenuItem[] = [
  {
    id: 'copy',
    label: 'Copy',
    onClick: () => {
      console.log('Copy')
    },
  },
  {
    id: 'paste',
    label: 'Paste',
    disabled: true,
    onClick: () => {
      console.log('Paste')
    },
  },
]
</script>

<template>
  <ContextMenuProvider>
    <ContextMenu :items="items">
      <div class="target">
        Right click here
      </div>
    </ContextMenu>
  </ContextMenuProvider>
</template>

Customize item UI

<ContextMenu :items="items">
  <template #item="{ item, close }">
    <button
      :disabled="item.disabled"
      type="button"
      @click="
        () => {
          if (item.disabled) return
          item.onClick?.(item)
          close()
        }
      "
    >
      {{ item.label }}
    </button>
  </template>

  <div>Right click here</div>
</ContextMenu>

Customize menu body

<ContextMenu :items="items">
  <template #body="{ items, close }">
    <div class="my-menu">
      <button
        v-for="item in items"
        :key="item.id"
        :disabled="item.disabled"
        type="button"
        @click="
          () => {
            if (item.disabled) return
            item.onClick?.(item)
            close()
          }
        "
      >
        {{ item.label }}
      </button>
    </div>
  </template>

  <div>Right click here</div>
</ContextMenu>

Different areas, different menus

<ContextMenu :items="fileItems">
  <div>File area</div>
</ContextMenu>

<ContextMenu :items="editorItems">
  <template #body="{ items, close }">
    <div class="editor-menu">
      <button
        v-for="item in items"
        :key="item.id"
        type="button"
        @click="
          () => {
            item.onClick?.(item)
            close()
          }
        "
      >
        {{ item.label }}
      </button>
    </div>
  </template>

  <div>Editor area</div>
</ContextMenu>