📌 Simple context-menu component built for Vue. Works well with both left and right clicks. Nothing too fancy, just works and is simple to use.

Overview

vue-simple-context-menu

Simple context-menu component built for Vue. Works well with both left and right clicks. Nothing too fancy, just works and is simple to use.

NPM Version NPM Downloads License Tweet

Demo

View demo

View on npm

View on GitHub

Install

# npm
npm i vue-simple-context-menu

# yarn
yarn add vue-simple-context-menu

Or you can include it through the browser at the bottom of your page along with the css:

<script src="https://unpkg.com/vue-simple-context-menu/dist/vue-simple-context-menu.min.js"></script>

<link rel="stylesheet" type="text/css" href="https://unpkg.com/vue-simple-context-menu/dist/vue-simple-context-menu.css">

About

Just a simple little menu to be shown where a click happens - closes after use automatically by clicking an option or outside of the menu. Multiple menus are supported - just make sure to use a unique string as your elementId prop value.

A nice feature that comes baked in is the menu placement after a click - it sits just ever so slightly under your click location - so that any hover style you had on the item that was clicked gets removed nicely. I modeled it after the macOS right click menu.

Usage Example

<!-- css import for when you want to import the component css into your css file/files  -->
@import '/path/to/node_modules/vue-simple-context-menu.css';

<!-- css import for when you're importing the css directly in your js  -->
import 'vue-simple-context-menu/dist/vue-simple-context-menu.css'

import VueSimpleContextMenu from 'vue-simple-context-menu'
Vue.component('vue-simple-context-menu', VueSimpleContextMenu)
<!-- This is a basic use case where you have an array of items that you want
to allow to be clicked. In this case, `items` is an array of objects.
Each item has a click event that ties to a function. See the demo for a full example (with multiple menus as well). -->

<div class="item-wrapper">
  <div v-for="item in items" @click.prevent.stop="handleClick($event, item)" class="item-wrapper__item">
    {{item.name}}
  </div>
</div>

<!-- Make sure you add the `ref` attribute, as that is what gives you the ability
to open the menu. -->

<vue-simple-context-menu
  :elementId="'myUniqueId'"
  :options="options"
  :ref="'vueSimpleContextMenu'"
  @option-clicked="optionClicked"
/>

<!-- The click-handler function -->
handleClick (event, item) {
  this.$refs.vueSimpleContextMenu.showMenu(event, item)
}

<!-- And for capturing the event -->
optionClicked (event) {
  window.alert(JSON.stringify(event))
}

Note - you must pass the click event-info variable to the showMenu() function because that's how we know where to show the menu.

Note - make sure to use @click.prevent.stop (or @contextmenu.prevent.stop for right click) when setting up the click handler.

Props

prop type description required
elementId String Unique String that acts as the id of your menu. Yes
options Array Array of menu options to show. Component will use the name parameter as the label. Yes
options.name Array Label for the option. Yes
options.class String A custom class that will be applied to the option. No
options.type String Only one possible value at the moment - divider. Pass this to set the object as a divider. No
ref String Unique String that allows you to show the menu on command. Yes

Methods

method parameters description
showMenu event (MouseEvent), item (Object) Used to show the menu. Make sure to pass a MouseEvent and an Object.

Events

event value description
option-clicked Object When a menu item is clicked the component will emit an event with a value containing the clicked item and the menu option that was clicked. Register for this event to capture the selection result.

SASS Structure

.vue-simple-context-menu {
  &--active {
  }

  &__item {
    &:hover {
    }
  }

  &__divider {}
}

Development

# install dependencies
npm install

# serve with hot reload
npm run watch

# run the tests
npm run test

# build demo page
npm run build:example

# build library
npm run build:library

# build everything and run tests
npm run build

Other

Go ahead and fork the project! Submit an issue if needed. Have fun!

Thank You

Influenced by Lucas Calazans's pen. Go ahead and check out his other work.

License

MIT

Packaged with a mixture of vue-lib-template and vue-sfc-rollup.

Comments
  • Feature: Divider Line Support

    Feature: Divider Line Support

    Curious if there has been thought of adding divider line support? I am thinking it could be added into menu definition

    ...
    menuOptions: {
    {
      name: "New Contact",
      slug: "new-contact",
    },
    {
      name: "-",
      slug: "divider",
    },
    {
      name: "New Company",
      slug: "new-company",
    },
    }
    ...
    
    opened by mikeerickson 8
  • Include fontawesome icons in contextual menu (use v-html)

    Include fontawesome icons in contextual menu (use v-html)

    Hey there

    I am trying to display fontawesome icons in my contextual menu, but alas it seems you are using simple interpolation

    
    <li
      v-for="(option, index) in options"
      :key="index"
      @click.stop="optionClicked(option)"
      class="vue-simple-context-menu__item"
      :class="[option.class, (option.type === 'divider' ? 'vue-simple-context-menu__divider' : '')]"
    >
      {{option.name}}
    </li>
    
    

    image

    Would you consider making a small adjustment?

    <li
      v-for="(option, index) in options"
      :key="index"
      @click.stop="optionClicked(option)"
      class="vue-simple-context-menu__item"
      :class="[option.class, (option.type === 'divider' ? 'vue-simple-context-menu__divider' : '')]"
      v-html="option.name"
    />
    
    
    opened by mikeerickson 7
  • "TypeError: this.$refs.vueSimpleContextMenu.showMenu is not a function"

    [Vue warn]: Error in v-on handler: "TypeError: this.$refs.vueSimpleContextMenu.showMenu is not a function".

    This happens to my application. I have just followed your installations instruction steps. But I have noticed in your example source code that it is totally different from your installation usage code example. You have also used the "vue-click-outside" package but it is not mentioned anywhere in your installation and usage guide. Please help me to get a solution.

    opened by sushovan0 6
  • problems overriding default CSS

    problems overriding default CSS

    I may be doing something wrong, but I'm having problems overriding the CSS styles. Everything working fine with the code, but I have the following in my project's home.css file, and the items in bold are not being reflected, but return to your defaults. I've tried this without the [data-v-a99b4df2] as well, but no luck. I'm sure it's something simple, but stumped.

    Thanks.

    .vue-simple-context-menu__item[data-v-a99b4df2] { padding: 0px 10px 0px 5px; background-color: lightblue; font-family: 'Avenir', Helvetica, Arial, sans-serif;
    font-size: 12px; font-style: italic; } .vue-simple-context-menu li[data-v-a99b4df2]:first-of-type { margin-top: 0px; } .vue-simple-context-menu li[data-v-a99b4df2]:last-of-type { margin-bottom: 0px; }

    opened by slieb 6
  • Uncaught TypeError: Cannot read property 'classList' of null

    Uncaught TypeError: Cannot read property 'classList' of null

    vue-simple-context-menu.esm.js?2560:60 Uncaught TypeError: Cannot read property 'classList' of null at VueComponent.hideContextMenu (vue-simple-context-menu.esm.js?2560:60) at VueComponent.onClickOutside (vue-simple-context-menu.esm.js?2560:63) at eval (v-click-outside.min.js?81a8:1) at Array.forEach () at HTMLDocument.n.onEvent (v-click-outside.min.js?81a8:1)

    selection_021

    bug 
    opened by duongphuhiep 6
  • Menu not staying displayed on Firefox 66+ (macOS)

    Menu not staying displayed on Firefox 66+ (macOS)

    Hi there – On macOS, since Firefox 66 (66.0.1 - 66.0.5, and 67.0), contextual menu does not stay displayed after the right-click. The problem also occurs on the demo page, if you right-click on Jim, Dwight, or Pam. I have no problem on Safari, and as far as I know it is working correctly on Windows with Firefox 66+.

    bug 
    opened by davbtmx 5
  • Two context menus

    Two context menus

    Hi there, starting to try you component, and it works very well only if is one menu on the page since you have the ul id hardcoded. is there any way to have more than one menu? thank you!

    enhancement 
    opened by RicardoRamirezR 5
  • Cannot read properties of undefined (reading 'showMenu')

    Cannot read properties of undefined (reading 'showMenu')

    Hi, my code is a Vue3 Typescript Vite project with composition API with script setup on top, then I have not this.$refs I would attach a right click menu on a div named box. Right clicking on the box container I have this error: Cannot read properties of undefined (reading 'showMenu')

    Can you suggest me please a solution ? Thanks in advance.

    <script setup lang="ts">
    import { ref } from 'vue'
    const box = ref(null)
    const optionsArray = [
      {  name: 'Edit node',   slug: 'edit'  }
    ]
    function optionClicked(event) {
      window.alert(JSON.stringify(event))
    }
    function handleRightClick(event: any, item: any) {
      console.log('Right click on', item)
      box.value.vueSimpleContextMenu1.showMenu(event, item)       <<<--- Here I have a problem Object box.value is possibly 'null'.ts(2531) 
    }
    </script>
    
    <template>
      <div ref="box" @contextmenu.prevent.stop="handleRightClick($event, 'a text')">
       <vue-simple-context-menu
          ref="box"
          element-id="myFirstMenu"
          :options="optionsArray"
          @option-clicked="optionClicked"
        />
      </div>
    </template>
    
    

    The Vite plugin :

    import VueSimpleContextMenu from 'vue-simple-context-menu'
    import 'vue-simple-context-menu/dist/vue-simple-context-menu.css'
    import type { UserModule } from '../types'
    
    export const install: UserModule = ({ app }) => {
      console.log('loading context menu')
      app.component('VueSimpleContextMenu', VueSimpleContextMenu)
    }
    
    opened by clabnet 4
  • One context menu for the whole app.

    One context menu for the whole app.

    Hi Γιάννη,

    I cannot find out who to have only one context menu shown at a time. I have multiple right click-able elements many of which are embedded one on the other. Can you suggest a solution, as many context menus appear at the same time now.

    Thanks

    opened by bkyf 4
  • Potential Offset Issue

    Potential Offset Issue

    Hi,

    I have the example working in my application except the menu doesn't appear where i click. I have the component on a view that is used by the rotuer view. I used a chrome extension to verify the x and y co-ords of the event passed to showMenu() and it is all correct except the menu not displaying where i expect. I manually edit the menu once it has appeared and set of the top and left to 0 and the menu then goes into the corner of my router view. When i use chrome dev tool to cut and paste the menu and place it below the tag then it displays in the correct place. Is there a way to specify which element the menu attaches it too? Or am i just doing something wrong??

    opened by nickmarkfurness 4
  • Nuxt and simple context menu

    Nuxt and simple context menu

    Hi! I am trying to implement this component with Nuxt and got it working so far – just not the click on the dropdown (yet).

    I wanted to point out, that Nuxt's eslint checks for props and emits and it complains that "elementId" should be hyphenated, while "@option-clicked" could be written camelcase. So the exact opposite of what this extension shows in the example and the documentation. Not sure if this influences the functionality somehow, but I thought I'll report my observation.

    opened by rowild 3
  • Deprecation warning

    Deprecation warning

    Seeing a deprecation warning in Chrome for use of Event.path (should move to Event.composedPath() at some point) which looks like it's only in bit for the click-outside dependency (vue-simple-context-menu.esm.js:10)

    opened by oldshaghat 1
  • Menus showing up off screen

    Menus showing up off screen

    I'm trying to get your context menus working in a modal 'window' but they are not displaying where the right click occurs, instead they seem to be hanging off the bottom of the screen. It's not a z-index issue as yours (10000) is way higher than mine (1000). The following screenshot is the best way I can think of to illustrate what is going on:

    context-menu-hiding

    I'm quite certain I've set up my template as per your instructions.

    <template>
      <div>
        <div class="item-wrapper" style="min-height: 500px;">
          <div class="fmgr-folder" v-for="folder in folders">
            <div @contextmenu.prevent.stop="handleClickFolder($event, folder)" class="item-wrapper__item">
              <img src="static/img/file-manager/icon-folder.png" />
              {{ folder.name }}
            </div>
          </div>
          <div class="fmgr-file" v-for="file in files">
            <div @contextmenu.prevent.stop="handleClickFile($event, file)" class="item-wrapper__item">
              <img :src="icon(file)" />
              {{ file.name }}
            </div>
          </div>
        </div>
        <vue-simple-context-menu
          elementId="folder-menu"
          :options="folderOptions()"
          ref="folderContextMenu"
          @optionClicked="optionClicked">
        </vue-simple-context-menu>
        <vue-simple-context-menu
          elementId="file-menu"
          :options="fileOptions()"
          ref="fileContextMenu"
          @optionClicked="optionClicked">
        </vue-simple-context-menu>
      </div>
    </template>
    

    CSS is imported and successfully hiding the content of :options

    import VueSimpleContextMenu from 'vue-simple-context-menu'
    import 'vue-simple-context-menu/dist/vue-simple-context-menu.css'
    

    The showMenu function is being called as expected. Seems like a CSS conflict of some sort.

    this.$refs.folderContextMenu.showMenu(event, item)
    

    Any suggestions on where to poke at the CSS?

    EDIT: If I manually change the top and left values in Chrome's Inspect window, I'm able to get move the menu on to the screen.

    opened by justintilson 20
Releases(v4.0.4)
Owner
John Datserakis
Software Engineer at @indigo-ag. It's criminal that Parks and Rec only had 7 seasons.
John Datserakis
A customizable context menu component built for Vue2, supporting fontawesome icons, auto right/bottom boundary detection.

Ki-vue-context A customizable context menu component built for Vue2, supporting fontawesome icons, auto right/bottom boundary detection. Demo demo on

null 7 Dec 16, 2022
vue-context provides a simple yet flexible context menu for Vue

Attention: I no longer have the ability or interest in maintaining this package since I am not using Vue in any of my projects anymore, so I am abando

Piotr Wilkin 0 May 25, 2021
Vue3.0 custom right-click menu

vue3-menus Vue3.0 自定义右键菜单,支持 Vite2.0,官网 Vue3.0 原生实现完全自定义右键菜单组件, 零依赖,可根据可视区域自动调节显示位置,可支持插槽完全重写每一项菜单 在线演示 完整菜单功能演示 复制粘贴演示 快速安装 npm 安装 npm install vue3-m

null 47 Dec 26, 2022
A simple vue context menu component.

Attention: I no longer have the ability or interest in maintaining this package since I am not using Vue in any of my projects anymore, so I am abando

Randall Wilk 250 Oct 17, 2022
A simple vue context menu component

vue-context vue-context provides a simple yet flexible context menu for Vue. It is styled for the standard <ul> tag, but any menu template can be used

madogai 1 Nov 21, 2022
A context menu component for vue js

vue-context-menu vue context-menu component Demo: https://vmaimone.github.io/vue-context-menu Example Usage <div @contextmenu.prevent="$refs.ctxMenu.

null 296 Nov 26, 2022
A flexible context menu component for Vue

vue-lil-context-menu A flexible context menu component for Vue. Pass it any menu template you like; it doesn't even have to be a menu. Always disappea

Tim Wisniewski 13 Nov 24, 2022
A flexible context menu component for Vue

A flexible context menu component for Vue. Pass it any menu template you like; it doesn't even have to be a menu. Always disappears when you expect it to by using an onblur event.

Animesh Kumar Singh 0 Dec 4, 2020
A Context menu component for vue2

vue Contextmenu component for vue2 Ant Design Ant Design of Vue overview Use Setup install vue-contextmenu-antd npm install vue-contextmenu-antd --sav

fay 1 Oct 16, 2021
A context menu component for Vue3

vue3-context-menu A context menu component for Vue3

快乐的梦鱼 82 Dec 28, 2022
Vue Custom Context Menu

A Vue.js plugin for building custom ??️ Context Menus. Automatically adjusts position and supports nested Context Menus out of the box

Matthew Mamonov 6 Aug 1, 2022
Vue.js context composition

Vue.js context composition makes sharing your composed state a breeze! It's the missing useContext hook from React, reimplemented for Vue.js 3.0. Read

Albert Brand 18 Dec 10, 2022
A node module that implements context menus in Vue using custom blocks

Vue Context Menu A node module that implements context menus in Vue using custom blocks. Background In making my Vue project, I wanted to be able to c

Brandon Chinn 1 Jul 30, 2018
🖱 ContextMenu based on Vue 3.0

?? ContextMenu based on Vue 3.0

漫游未来 745 Dec 28, 2022
ContextMenu in Vue with accessibility support

ContextMenu in Vue with accessibility support

null 0 Dec 18, 2020
Make everything a context menu: A context menu wrapper for Vue as a configurable plugin

Context menu plugin for Vue Make everything a context menu: A context menu wrapper for Vue as a configurable plugin. Features Declarative definitions

null 1 Jan 28, 2020
A customizable context menu component built for Vue2, supporting fontawesome icons, auto right/bottom boundary detection.

Ki-vue-context A customizable context menu component built for Vue2, supporting fontawesome icons, auto right/bottom boundary detection. Demo demo on

null 7 Dec 16, 2022
vue-context provides a simple yet flexible context menu for Vue

Attention: I no longer have the ability or interest in maintaining this package since I am not using Vue in any of my projects anymore, so I am abando

Piotr Wilkin 0 May 25, 2021
Charts and gauges without JavaScript ... well just a tiny bit.

tlx-chart The module tlx-chart provides both a JavaScript component oriented and and reactive HTML custom element oriented TLX based wrapper for the G

Simon Y. Blackwell 7 Jun 8, 2022
Vue Flag Icons. Use country flags as a Vue component. You can also use in any project without Vue too.

Vue Flag Icons. Use country flags as a Vue component. You can also use in any project without Vue too.

Md Obydullah 2 Mar 22, 2022