New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

vue-simple-context-menu

Package Overview
Dependencies
Maintainers
1
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

vue-simple-context-menu - npm Package Compare versions

Comparing version 3.4.2 to 4.0.0

.prettierrc

8

CHANGELOG.md
# CHANGELOG.md
## 4.0.0
- Upgrade package to support Vue 3. Vue 2 support can be found at `v3.4.2`. Thank you @danielelkington.
## 3.4.2
- Add menu-closed event. Thank you @rttmax.
## 3.4.1

@@ -4,0 +12,0 @@

257

dist/vue-simple-context-menu.esm.js

@@ -1,24 +0,35 @@

import Vue from 'vue';
import vClickOutside from 'v-click-outside';
import { resolveDirective, openBlock, createElementBlock, withDirectives, Fragment, renderList, withModifiers, normalizeClass, createElementVNode } from 'vue';
//
Vue.use(vClickOutside);
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
var vClickOutside_umd = createCommonjsModule(function (module, exports) {
!function(e,n){module.exports=n();}(commonjsGlobal,function(){var e="__v-click-outside",n="undefined"!=typeof window,t="undefined"!=typeof navigator,r=n&&("ontouchstart"in window||t&&navigator.msMaxTouchPoints>0)?["touchstart"]:["click"],i=function(e){var n=e.event,t=e.handler;(0, e.middleware)(n)&&t(n);},a=function(n,t){var a=function(e){var n="function"==typeof e;if(!n&&"object"!=typeof e){ throw new Error("v-click-outside: Binding value must be a function or an object"); }return {handler:n?e:e.handler,middleware:e.middleware||function(e){return e},events:e.events||r,isActive:!(!1===e.isActive),detectIframe:!(!1===e.detectIframe),capture:Boolean(e.capture)}}(t.value),o=a.handler,d=a.middleware,c=a.detectIframe,u=a.capture;if(a.isActive){if(n[e]=a.events.map(function(e){return {event:e,srcTarget:document.documentElement,handler:function(e){return function(e){var n=e.el,t=e.event,r=e.handler,a=e.middleware,o=t.path||t.composedPath&&t.composedPath();(o?o.indexOf(n)<0:!n.contains(t.target))&&i({event:t,handler:r,middleware:a});}({el:n,event:e,handler:o,middleware:d})},capture:u}}),c){var l={event:"blur",srcTarget:window,handler:function(e){return function(e){var n=e.el,t=e.event,r=e.handler,a=e.middleware;setTimeout(function(){var e=document.activeElement;e&&"IFRAME"===e.tagName&&!n.contains(e)&&i({event:t,handler:r,middleware:a});},0);}({el:n,event:e,handler:o,middleware:d})},capture:u};n[e]=[].concat(n[e],[l]);}n[e].forEach(function(t){var r=t.event,i=t.srcTarget,a=t.handler;return setTimeout(function(){n[e]&&i.addEventListener(r,a,u);},0)});}},o=function(n){(n[e]||[]).forEach(function(e){return e.srcTarget.removeEventListener(e.event,e.handler,e.capture)}),delete n[e];},d=n?{beforeMount:a,updated:function(e,n){var t=n.value,r=n.oldValue;JSON.stringify(t)!==JSON.stringify(r)&&(o(e),a(e,{value:t}));},unmounted:o}:{};return {install:function(e){e.directive("click-outside",d);},directive:d}});
});
var script = {
name: "VueSimpleContextMenu",
name: 'VueSimpleContextMenu',
props: {
elementId: {
type: String,
required: true
required: true,
},
options: {
type: Array,
required: true
}
required: true,
},
},
emits: ['menu-closed', 'option-clicked'],
directives: {
'click-outside': vClickOutside_umd.directive,
},
data: function data() {
return {
item: null,
menuHeight: null,
menuWidth: null,
menuHeight: null
};

@@ -36,22 +47,22 @@ },

if (!this.menuWidth || !this.menuHeight) {
menu.style.visibility = "hidden";
menu.style.display = "block";
menu.style.visibility = 'hidden';
menu.style.display = 'block';
this.menuWidth = menu.offsetWidth;
this.menuHeight = menu.offsetHeight;
menu.removeAttribute("style");
menu.removeAttribute('style');
}
if (this.menuWidth + event.pageX >= window.innerWidth) {
menu.style.left = event.pageX - this.menuWidth + 2 + "px";
menu.style.left = event.pageX - this.menuWidth + 2 + 'px';
} else {
menu.style.left = event.pageX - 2 + "px";
menu.style.left = event.pageX - 2 + 'px';
}
if (this.menuHeight + event.pageY >= window.innerHeight) {
menu.style.top = event.pageY - this.menuHeight + 2 + "px";
menu.style.top = event.pageY - this.menuHeight + 2 + 'px';
} else {
menu.style.top = event.pageY - 2 + "px";
menu.style.top = event.pageY - 2 + 'px';
}
menu.classList.add("vue-simple-context-menu--active");
menu.classList.add('vue-simple-context-menu--active');
},

@@ -61,4 +72,4 @@ hideContextMenu: function hideContextMenu() {

if (element) {
element.classList.remove("vue-simple-context-menu--active");
this.$emit("menu-closed");
element.classList.remove('vue-simple-context-menu--active');
this.$emit('menu-closed');
}

@@ -71,5 +82,5 @@ },

this.hideContextMenu();
this.$emit("option-clicked", {
this.$emit('option-clicked', {
item: this.item,
option: option
option: option,
});

@@ -81,182 +92,58 @@ },

}
}
},
},
mounted: function mounted() {
document.body.addEventListener("keyup", this.onEscKeyRelease);
document.body.addEventListener('keyup', this.onEscKeyRelease);
},
beforeDestroy: function beforeDestroy() {
document.removeEventListener("keyup", this.onEscKeyRelease);
}
beforeUnmount: function beforeUnmount() {
document.removeEventListener('keyup', this.onEscKeyRelease);
},
};
function normalizeComponent(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier /* server only */, shadowMode, createInjector, createInjectorSSR, createInjectorShadow) {
if (typeof shadowMode !== 'boolean') {
createInjectorSSR = createInjector;
createInjector = shadowMode;
shadowMode = false;
}
// Vue.extend constructor export interop.
var options = typeof script === 'function' ? script.options : script;
// render functions
if (template && template.render) {
options.render = template.render;
options.staticRenderFns = template.staticRenderFns;
options._compiled = true;
// functional template
if (isFunctionalTemplate) {
options.functional = true;
}
}
// scopedId
if (scopeId) {
options._scopeId = scopeId;
}
var hook;
if (moduleIdentifier) {
// server build
hook = function (context) {
// 2.3 injection
context =
context || // cached call
(this.$vnode && this.$vnode.ssrContext) || // stateful
(this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext); // functional
// 2.2 with runInNewContext: true
if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') {
context = __VUE_SSR_CONTEXT__;
}
// inject component styles
if (style) {
style.call(this, createInjectorSSR(context));
}
// register component module identifier for async chunk inference
if (context && context._registeredComponents) {
context._registeredComponents.add(moduleIdentifier);
}
};
// used by ssr in case component is cached and beforeCreate
// never gets called
options._ssrRegister = hook;
}
else if (style) {
hook = shadowMode
? function (context) {
style.call(this, createInjectorShadow(context, this.$root.$options.shadowRoot));
}
: function (context) {
style.call(this, createInjector(context));
};
}
if (hook) {
if (options.functional) {
// register for functional component in vue file
var originalRender = options.render;
options.render = function renderWithStyleInjection(h, context) {
hook.call(context);
return originalRender(h, context);
};
}
else {
// inject component registration as beforeCreate hook
var existing = options.beforeCreate;
options.beforeCreate = existing ? [].concat(existing, hook) : [hook];
}
}
return script;
}
var _hoisted_1 = ["id"];
var _hoisted_2 = ["onClick"];
var _hoisted_3 = ["innerHTML"];
/* script */
var __vue_script__ = script;
/* template */
var __vue_render__ = function() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c("div", [
_c(
"ul",
{
directives: [
{
name: "click-outside",
rawName: "v-click-outside",
value: _vm.onClickOutside,
expression: "onClickOutside"
}
],
staticClass: "vue-simple-context-menu",
attrs: { id: _vm.elementId }
},
_vm._l(_vm.options, function(option, index) {
return _c(
"li",
{
key: index,
staticClass: "vue-simple-context-menu__item",
class: [
option.class,
option.type === "divider"
? "vue-simple-context-menu__divider"
: ""
],
on: {
click: function($event) {
$event.stopPropagation();
return _vm.optionClicked(option)
}
}
},
[_c("span", { domProps: { innerHTML: _vm._s(option.name) } })]
)
}),
0
)
])
};
var __vue_staticRenderFns__ = [];
__vue_render__._withStripped = true;
function render(_ctx, _cache, $props, $setup, $data, $options) {
var _directive_click_outside = resolveDirective("click-outside");
/* style */
var __vue_inject_styles__ = undefined;
/* scoped */
var __vue_scope_id__ = undefined;
/* module identifier */
var __vue_module_identifier__ = undefined;
/* functional template */
var __vue_is_functional_template__ = false;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
return (openBlock(), createElementBlock("div", null, [
withDirectives((openBlock(), createElementBlock("ul", {
id: $props.elementId,
class: "vue-simple-context-menu"
}, [
(openBlock(true), createElementBlock(Fragment, null, renderList($props.options, function (option, index) {
return (openBlock(), createElementBlock("li", {
key: index,
onClick: withModifiers(function ($event) { return ($options.optionClicked(option)); }, ["stop"]),
class: normalizeClass(["vue-simple-context-menu__item", [option.class, option.type === 'divider' ? 'vue-simple-context-menu__divider' : '']])
}, [
createElementVNode("span", {
innerHTML: option.name
}, null, 8 /* PROPS */, _hoisted_3)
], 10 /* CLASS, PROPS */, _hoisted_2))
}), 128 /* KEYED_FRAGMENT */))
], 8 /* PROPS */, _hoisted_1)), [
[_directive_click_outside, $options.onClickOutside]
])
]))
}
var __vue_component__ = /*#__PURE__*/normalizeComponent(
{ render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ },
__vue_inject_styles__,
__vue_script__,
__vue_scope_id__,
__vue_is_functional_template__,
__vue_module_identifier__,
false,
undefined,
undefined,
undefined
);
script.render = render;
script.__file = "src/vue-simple-context-menu.vue";
// Import vue component
// install function executed by Vue.use()
function install (Vue) {
// Install function executed by app.use()
function install(app) {
if (install.installed) { return; }
install.installed = true;
Vue.component('VueSimpleContextMenu', __vue_component__);
app.component('VueSimpleContextMenu', script);
}
// Create module definition for Vue.use()
var plugin = {
install: install,
};
var plugin = { install: install };
// To auto-install when vue is found
// To auto-install when Vue is found
var GlobalVue = null;

@@ -276,3 +163,3 @@ if (typeof window !== 'undefined') {

export default __vue_component__;
export default script;
export { install };

@@ -1,1 +0,1 @@

var VueSimpleContextMenu=function(e,t){"use strict";t=t&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t;"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var n=function(e,t){return e(t={exports:{}},t.exports),t.exports}((function(e,t){e.exports=function(){var e="__v-click-outside",t="undefined"!=typeof window,n="undefined"!=typeof navigator,i=t&&("ontouchstart"in window||n&&navigator.msMaxTouchPoints>0)?["touchstart"]:["click"];function o(t,n){var o=function(e){var t="function"==typeof e;if(!t&&"object"!=typeof e)throw new Error("v-click-outside: Binding value must be a function or an object");return{handler:t?e:e.handler,middleware:e.middleware||function(e){return e},events:e.events||i,isActive:!(!1===e.isActive)}}(n.value),r=o.handler,s=o.middleware;o.isActive&&(t[e]=o.events.map((function(e){return{event:e,handler:function(e){return function(e){var t=e.el,n=e.event,i=e.handler,o=e.middleware;n.target!==t&&!t.contains(n.target)&&o(n,t)&&i(n,t)}({event:e,el:t,handler:r,middleware:s})}}})),t[e].forEach((function(e){var t=e.event,n=e.handler;return setTimeout((function(){return document.documentElement.addEventListener(t,n,!1)}),0)})))}function r(t){(t[e]||[]).forEach((function(e){return document.documentElement.removeEventListener(e.event,e.handler,!1)})),delete t[e]}var s={bind:o,update:function(e,t){var n=t.value,i=t.oldValue;JSON.stringify(n)!==JSON.stringify(i)&&(r(e),o(e,{value:n}))},unbind:r};return{install:function(e){e.directive("click-outside",s)},directive:s}}()}));function i(e,t,n,i,o,r,s,d,u,l){"boolean"!=typeof s&&(u=d,d=s,s=!1);var a,c="function"==typeof n?n.options:n;if(e&&e.render&&(c.render=e.render,c.staticRenderFns=e.staticRenderFns,c._compiled=!0,o&&(c.functional=!0)),i&&(c._scopeId=i),r?(a=function(e){(e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),t&&t.call(this,u(e)),e&&e._registeredComponents&&e._registeredComponents.add(r)},c._ssrRegister=a):t&&(a=s?function(e){t.call(this,l(e,this.$root.$options.shadowRoot))}:function(e){t.call(this,d(e))}),a)if(c.functional){var f=c.render;c.render=function(e,t){return a.call(t),f(e,t)}}else{var p=c.beforeCreate;c.beforeCreate=p?[].concat(p,a):[a]}return n}t.use(n);var o={name:"VueSimpleContextMenu",props:{elementId:{type:String,required:!0},options:{type:Array,required:!0}},data:function(){return{item:null,menuWidth:null,menuHeight:null}},methods:{showMenu:function(e,t){this.item=t;var n=document.getElementById(this.elementId);n&&(this.menuWidth&&this.menuHeight||(n.style.visibility="hidden",n.style.display="block",this.menuWidth=n.offsetWidth,this.menuHeight=n.offsetHeight,n.removeAttribute("style")),this.menuWidth+e.pageX>=window.innerWidth?n.style.left=e.pageX-this.menuWidth+2+"px":n.style.left=e.pageX-2+"px",this.menuHeight+e.pageY>=window.innerHeight?n.style.top=e.pageY-this.menuHeight+2+"px":n.style.top=e.pageY-2+"px",n.classList.add("vue-simple-context-menu--active"))},hideContextMenu:function(){var e=document.getElementById(this.elementId);e&&(e.classList.remove("vue-simple-context-menu--active"),this.$emit("menu-closed"))},onClickOutside:function(){this.hideContextMenu()},optionClicked:function(e){this.hideContextMenu(),this.$emit("option-clicked",{item:this.item,option:e})},onEscKeyRelease:function(e){27===e.keyCode&&this.hideContextMenu()}},mounted:function(){document.body.addEventListener("keyup",this.onEscKeyRelease)},beforeDestroy:function(){document.removeEventListener("keyup",this.onEscKeyRelease)}},r=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",[n("ul",{directives:[{name:"click-outside",rawName:"v-click-outside",value:e.onClickOutside,expression:"onClickOutside"}],staticClass:"vue-simple-context-menu",attrs:{id:e.elementId}},e._l(e.options,(function(t,i){return n("li",{key:i,staticClass:"vue-simple-context-menu__item",class:[t.class,"divider"===t.type?"vue-simple-context-menu__divider":""],on:{click:function(n){return n.stopPropagation(),e.optionClicked(t)}}},[n("span",{domProps:{innerHTML:e._s(t.name)}})])})),0)])};r._withStripped=!0;var s=i({render:r,staticRenderFns:[]},void 0,o,void 0,!1,void 0,!1,void 0,void 0,void 0);function d(e){d.installed||(d.installed=!0,e.component("VueSimpleContextMenu",s))}var u={install:d},l=null;return"undefined"!=typeof window?l=window.Vue:"undefined"!=typeof global&&(l=global.Vue),l&&l.use(u),e.default=s,e.install=d,e}({},Vue);
var VueSimpleContextMenu=function(e,t){"use strict";"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var n=function(e,t){return e(t={exports:{}},t.exports),t.exports}((function(e,t){var n,i,o,l,r,u,d,c;e.exports=(n="__v-click-outside",i="undefined"!=typeof window,o="undefined"!=typeof navigator,l=i&&("ontouchstart"in window||o&&navigator.msMaxTouchPoints>0)?["touchstart"]:["click"],r=function(e){var t=e.event,n=e.handler;(0,e.middleware)(t)&&n(t)},u=function(e,t){var i=function(e){var t="function"==typeof e;if(!t&&"object"!=typeof e)throw new Error("v-click-outside: Binding value must be a function or an object");return{handler:t?e:e.handler,middleware:e.middleware||function(e){return e},events:e.events||l,isActive:!(!1===e.isActive),detectIframe:!(!1===e.detectIframe),capture:Boolean(e.capture)}}(t.value),o=i.handler,u=i.middleware,d=i.detectIframe,c=i.capture;if(i.isActive){if(e[n]=i.events.map((function(t){return{event:t,srcTarget:document.documentElement,handler:function(t){return function(e){var t=e.el,n=e.event,i=e.handler,o=e.middleware,l=n.path||n.composedPath&&n.composedPath();(l?l.indexOf(t)<0:!t.contains(n.target))&&r({event:n,handler:i,middleware:o})}({el:e,event:t,handler:o,middleware:u})},capture:c}})),d){var a={event:"blur",srcTarget:window,handler:function(t){return function(e){var t=e.el,n=e.event,i=e.handler,o=e.middleware;setTimeout((function(){var e=document.activeElement;e&&"IFRAME"===e.tagName&&!t.contains(e)&&r({event:n,handler:i,middleware:o})}),0)}({el:e,event:t,handler:o,middleware:u})},capture:c};e[n]=[].concat(e[n],[a])}e[n].forEach((function(t){var i=t.event,o=t.srcTarget,l=t.handler;return setTimeout((function(){e[n]&&o.addEventListener(i,l,c)}),0)}))}},d=function(e){(e[n]||[]).forEach((function(e){return e.srcTarget.removeEventListener(e.event,e.handler,e.capture)})),delete e[n]},{install:function(e){e.directive("click-outside",c)},directive:c=i?{beforeMount:u,updated:function(e,t){var n=t.value,i=t.oldValue;JSON.stringify(n)!==JSON.stringify(i)&&(d(e),u(e,{value:n}))},unmounted:d}:{}})})),i={name:"VueSimpleContextMenu",props:{elementId:{type:String,required:!0},options:{type:Array,required:!0}},emits:["menu-closed","option-clicked"],directives:{"click-outside":n.directive},data:function(){return{item:null,menuHeight:null,menuWidth:null}},methods:{showMenu:function(e,t){this.item=t;var n=document.getElementById(this.elementId);n&&(this.menuWidth&&this.menuHeight||(n.style.visibility="hidden",n.style.display="block",this.menuWidth=n.offsetWidth,this.menuHeight=n.offsetHeight,n.removeAttribute("style")),this.menuWidth+e.pageX>=window.innerWidth?n.style.left=e.pageX-this.menuWidth+2+"px":n.style.left=e.pageX-2+"px",this.menuHeight+e.pageY>=window.innerHeight?n.style.top=e.pageY-this.menuHeight+2+"px":n.style.top=e.pageY-2+"px",n.classList.add("vue-simple-context-menu--active"))},hideContextMenu:function(){var e=document.getElementById(this.elementId);e&&(e.classList.remove("vue-simple-context-menu--active"),this.$emit("menu-closed"))},onClickOutside:function(){this.hideContextMenu()},optionClicked:function(e){this.hideContextMenu(),this.$emit("option-clicked",{item:this.item,option:e})},onEscKeyRelease:function(e){27===e.keyCode&&this.hideContextMenu()}},mounted:function(){document.body.addEventListener("keyup",this.onEscKeyRelease)},beforeUnmount:function(){document.removeEventListener("keyup",this.onEscKeyRelease)}},o=["id"],l=["onClick"],r=["innerHTML"];function u(e){u.installed||(u.installed=!0,e.component("VueSimpleContextMenu",i))}i.render=function(e,n,i,u,d,c){var a=t.resolveDirective("click-outside");return t.openBlock(),t.createElementBlock("div",null,[t.withDirectives((t.openBlock(),t.createElementBlock("ul",{id:i.elementId,class:"vue-simple-context-menu"},[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(i.options,(function(e,n){return t.openBlock(),t.createElementBlock("li",{key:n,onClick:t.withModifiers((function(t){return c.optionClicked(e)}),["stop"]),class:t.normalizeClass(["vue-simple-context-menu__item",[e.class,"divider"===e.type?"vue-simple-context-menu__divider":""]])},[t.createElementVNode("span",{innerHTML:e.name},null,8,r)],10,l)})),128))],8,o)),[[a,c.onClickOutside]])])},i.__file="src/vue-simple-context-menu.vue";var d={install:u},c=null;return"undefined"!=typeof window?c=window.Vue:"undefined"!=typeof global&&(c=global.Vue),c&&c.use(d),e.default=i,e.install=u,e}({},Vue);
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('vue'), require('v-click-outside')) :
typeof define === 'function' && define.amd ? define(['exports', 'vue', 'v-click-outside'], factory) :
(global = global || self, factory(global.VueSimpleContextMenu = {}, global.Vue, global.vClickOutside));
}(this, (function (exports, Vue, vClickOutside) { 'use strict';
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('vue')) :
typeof define === 'function' && define.amd ? define(['exports', 'vue'], factory) :
(global = global || self, factory(global.VueSimpleContextMenu = {}, global.Vue));
}(this, (function (exports, vue) { 'use strict';
Vue = Vue && Object.prototype.hasOwnProperty.call(Vue, 'default') ? Vue['default'] : Vue;
vClickOutside = vClickOutside && Object.prototype.hasOwnProperty.call(vClickOutside, 'default') ? vClickOutside['default'] : vClickOutside;
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
//
Vue.use(vClickOutside);
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
var script = {
name: "VueSimpleContextMenu",
props: {
elementId: {
type: String,
required: true
},
options: {
type: Array,
required: true
}
},
data: function data() {
return {
item: null,
menuWidth: null,
menuHeight: null
};
},
methods: {
showMenu: function showMenu(event, item) {
this.item = item;
var vClickOutside_umd = createCommonjsModule(function (module, exports) {
!function(e,n){module.exports=n();}(commonjsGlobal,function(){var e="__v-click-outside",n="undefined"!=typeof window,t="undefined"!=typeof navigator,r=n&&("ontouchstart"in window||t&&navigator.msMaxTouchPoints>0)?["touchstart"]:["click"],i=function(e){var n=e.event,t=e.handler;(0, e.middleware)(n)&&t(n);},a=function(n,t){var a=function(e){var n="function"==typeof e;if(!n&&"object"!=typeof e){ throw new Error("v-click-outside: Binding value must be a function or an object"); }return {handler:n?e:e.handler,middleware:e.middleware||function(e){return e},events:e.events||r,isActive:!(!1===e.isActive),detectIframe:!(!1===e.detectIframe),capture:Boolean(e.capture)}}(t.value),o=a.handler,d=a.middleware,c=a.detectIframe,u=a.capture;if(a.isActive){if(n[e]=a.events.map(function(e){return {event:e,srcTarget:document.documentElement,handler:function(e){return function(e){var n=e.el,t=e.event,r=e.handler,a=e.middleware,o=t.path||t.composedPath&&t.composedPath();(o?o.indexOf(n)<0:!n.contains(t.target))&&i({event:t,handler:r,middleware:a});}({el:n,event:e,handler:o,middleware:d})},capture:u}}),c){var l={event:"blur",srcTarget:window,handler:function(e){return function(e){var n=e.el,t=e.event,r=e.handler,a=e.middleware;setTimeout(function(){var e=document.activeElement;e&&"IFRAME"===e.tagName&&!n.contains(e)&&i({event:t,handler:r,middleware:a});},0);}({el:n,event:e,handler:o,middleware:d})},capture:u};n[e]=[].concat(n[e],[l]);}n[e].forEach(function(t){var r=t.event,i=t.srcTarget,a=t.handler;return setTimeout(function(){n[e]&&i.addEventListener(r,a,u);},0)});}},o=function(n){(n[e]||[]).forEach(function(e){return e.srcTarget.removeEventListener(e.event,e.handler,e.capture)}),delete n[e];},d=n?{beforeMount:a,updated:function(e,n){var t=n.value,r=n.oldValue;JSON.stringify(t)!==JSON.stringify(r)&&(o(e),a(e,{value:t}));},unmounted:o}:{};return {install:function(e){e.directive("click-outside",d);},directive:d}});
var menu = document.getElementById(this.elementId);
if (!menu) {
return;
}
});
if (!this.menuWidth || !this.menuHeight) {
menu.style.visibility = "hidden";
menu.style.display = "block";
this.menuWidth = menu.offsetWidth;
this.menuHeight = menu.offsetHeight;
menu.removeAttribute("style");
}
var script = {
name: 'VueSimpleContextMenu',
props: {
elementId: {
type: String,
required: true,
},
options: {
type: Array,
required: true,
},
},
emits: ['menu-closed', 'option-clicked'],
directives: {
'click-outside': vClickOutside_umd.directive,
},
data: function data() {
return {
item: null,
menuHeight: null,
menuWidth: null,
};
},
methods: {
showMenu: function showMenu(event, item) {
this.item = item;
if (this.menuWidth + event.pageX >= window.innerWidth) {
menu.style.left = event.pageX - this.menuWidth + 2 + "px";
} else {
menu.style.left = event.pageX - 2 + "px";
}
var menu = document.getElementById(this.elementId);
if (!menu) {
return;
}
if (this.menuHeight + event.pageY >= window.innerHeight) {
menu.style.top = event.pageY - this.menuHeight + 2 + "px";
} else {
menu.style.top = event.pageY - 2 + "px";
}
if (!this.menuWidth || !this.menuHeight) {
menu.style.visibility = 'hidden';
menu.style.display = 'block';
this.menuWidth = menu.offsetWidth;
this.menuHeight = menu.offsetHeight;
menu.removeAttribute('style');
}
menu.classList.add("vue-simple-context-menu--active");
},
hideContextMenu: function hideContextMenu() {
var element = document.getElementById(this.elementId);
if (element) {
element.classList.remove("vue-simple-context-menu--active");
this.$emit("menu-closed");
}
},
onClickOutside: function onClickOutside() {
this.hideContextMenu();
},
optionClicked: function optionClicked(option) {
this.hideContextMenu();
this.$emit("option-clicked", {
item: this.item,
option: option
});
},
onEscKeyRelease: function onEscKeyRelease(event) {
if (event.keyCode === 27) {
this.hideContextMenu();
}
}
},
mounted: function mounted() {
document.body.addEventListener("keyup", this.onEscKeyRelease);
},
beforeDestroy: function beforeDestroy() {
document.removeEventListener("keyup", this.onEscKeyRelease);
}
};
if (this.menuWidth + event.pageX >= window.innerWidth) {
menu.style.left = event.pageX - this.menuWidth + 2 + 'px';
} else {
menu.style.left = event.pageX - 2 + 'px';
}
function normalizeComponent(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier /* server only */, shadowMode, createInjector, createInjectorSSR, createInjectorShadow) {
if (typeof shadowMode !== 'boolean') {
createInjectorSSR = createInjector;
createInjector = shadowMode;
shadowMode = false;
}
// Vue.extend constructor export interop.
var options = typeof script === 'function' ? script.options : script;
// render functions
if (template && template.render) {
options.render = template.render;
options.staticRenderFns = template.staticRenderFns;
options._compiled = true;
// functional template
if (isFunctionalTemplate) {
options.functional = true;
}
}
// scopedId
if (scopeId) {
options._scopeId = scopeId;
}
var hook;
if (moduleIdentifier) {
// server build
hook = function (context) {
// 2.3 injection
context =
context || // cached call
(this.$vnode && this.$vnode.ssrContext) || // stateful
(this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext); // functional
// 2.2 with runInNewContext: true
if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') {
context = __VUE_SSR_CONTEXT__;
}
// inject component styles
if (style) {
style.call(this, createInjectorSSR(context));
}
// register component module identifier for async chunk inference
if (context && context._registeredComponents) {
context._registeredComponents.add(moduleIdentifier);
}
};
// used by ssr in case component is cached and beforeCreate
// never gets called
options._ssrRegister = hook;
}
else if (style) {
hook = shadowMode
? function (context) {
style.call(this, createInjectorShadow(context, this.$root.$options.shadowRoot));
}
: function (context) {
style.call(this, createInjector(context));
};
}
if (hook) {
if (options.functional) {
// register for functional component in vue file
var originalRender = options.render;
options.render = function renderWithStyleInjection(h, context) {
hook.call(context);
return originalRender(h, context);
};
}
else {
// inject component registration as beforeCreate hook
var existing = options.beforeCreate;
options.beforeCreate = existing ? [].concat(existing, hook) : [hook];
}
}
return script;
}
if (this.menuHeight + event.pageY >= window.innerHeight) {
menu.style.top = event.pageY - this.menuHeight + 2 + 'px';
} else {
menu.style.top = event.pageY - 2 + 'px';
}
/* script */
var __vue_script__ = script;
/* template */
var __vue_render__ = function() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c("div", [
_c(
"ul",
{
directives: [
{
name: "click-outside",
rawName: "v-click-outside",
value: _vm.onClickOutside,
expression: "onClickOutside"
}
],
staticClass: "vue-simple-context-menu",
attrs: { id: _vm.elementId }
},
_vm._l(_vm.options, function(option, index) {
return _c(
"li",
{
key: index,
staticClass: "vue-simple-context-menu__item",
class: [
option.class,
option.type === "divider"
? "vue-simple-context-menu__divider"
: ""
],
on: {
click: function($event) {
$event.stopPropagation();
return _vm.optionClicked(option)
}
}
},
[_c("span", { domProps: { innerHTML: _vm._s(option.name) } })]
)
}),
0
)
])
};
var __vue_staticRenderFns__ = [];
__vue_render__._withStripped = true;
menu.classList.add('vue-simple-context-menu--active');
},
hideContextMenu: function hideContextMenu() {
var element = document.getElementById(this.elementId);
if (element) {
element.classList.remove('vue-simple-context-menu--active');
this.$emit('menu-closed');
}
},
onClickOutside: function onClickOutside() {
this.hideContextMenu();
},
optionClicked: function optionClicked(option) {
this.hideContextMenu();
this.$emit('option-clicked', {
item: this.item,
option: option,
});
},
onEscKeyRelease: function onEscKeyRelease(event) {
if (event.keyCode === 27) {
this.hideContextMenu();
}
},
},
mounted: function mounted() {
document.body.addEventListener('keyup', this.onEscKeyRelease);
},
beforeUnmount: function beforeUnmount() {
document.removeEventListener('keyup', this.onEscKeyRelease);
},
};
/* style */
var __vue_inject_styles__ = undefined;
/* scoped */
var __vue_scope_id__ = undefined;
/* module identifier */
var __vue_module_identifier__ = undefined;
/* functional template */
var __vue_is_functional_template__ = false;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
var _hoisted_1 = ["id"];
var _hoisted_2 = ["onClick"];
var _hoisted_3 = ["innerHTML"];
var __vue_component__ = /*#__PURE__*/normalizeComponent(
{ render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ },
__vue_inject_styles__,
__vue_script__,
__vue_scope_id__,
__vue_is_functional_template__,
__vue_module_identifier__,
false,
undefined,
undefined,
undefined
);
function render(_ctx, _cache, $props, $setup, $data, $options) {
var _directive_click_outside = vue.resolveDirective("click-outside");
// Import vue component
return (vue.openBlock(), vue.createElementBlock("div", null, [
vue.withDirectives((vue.openBlock(), vue.createElementBlock("ul", {
id: $props.elementId,
class: "vue-simple-context-menu"
}, [
(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList($props.options, function (option, index) {
return (vue.openBlock(), vue.createElementBlock("li", {
key: index,
onClick: vue.withModifiers(function ($event) { return ($options.optionClicked(option)); }, ["stop"]),
class: vue.normalizeClass(["vue-simple-context-menu__item", [option.class, option.type === 'divider' ? 'vue-simple-context-menu__divider' : '']])
}, [
vue.createElementVNode("span", {
innerHTML: option.name
}, null, 8 /* PROPS */, _hoisted_3)
], 10 /* CLASS, PROPS */, _hoisted_2))
}), 128 /* KEYED_FRAGMENT */))
], 8 /* PROPS */, _hoisted_1)), [
[_directive_click_outside, $options.onClickOutside]
])
]))
}
// install function executed by Vue.use()
function install (Vue) {
if (install.installed) { return; }
install.installed = true;
Vue.component('VueSimpleContextMenu', __vue_component__);
}
script.render = render;
script.__file = "src/vue-simple-context-menu.vue";
// Create module definition for Vue.use()
var plugin = {
install: install,
};
// Import vue component
// To auto-install when vue is found
var GlobalVue = null;
if (typeof window !== 'undefined') {
GlobalVue = window.Vue;
} else if (typeof global !== 'undefined') {
GlobalVue = global.Vue;
}
if (GlobalVue) {
GlobalVue.use(plugin);
}
// Install function executed by app.use()
function install(app) {
if (install.installed) { return; }
// It's possible to expose named exports when writing components that can
// also be used as directives, etc. - eg. import { RollupDemoDirective } from 'rollup-demo';
// export const RollupDemoDirective = component;
install.installed = true;
app.component('VueSimpleContextMenu', script);
}
exports.default = __vue_component__;
exports.install = install;
// Create module definition for Vue.use()
var plugin = { install: install };
Object.defineProperty(exports, '__esModule', { value: true });
// To auto-install when Vue is found
var GlobalVue = null;
if (typeof window !== 'undefined') {
GlobalVue = window.Vue;
} else if (typeof global !== 'undefined') {
GlobalVue = global.Vue;
}
if (GlobalVue) {
GlobalVue.use(plugin);
}
// It's possible to expose named exports when writing components that can
// also be used as directives, etc. - eg. import { RollupDemoDirective } from 'rollup-demo';
// export const RollupDemoDirective = component;
exports.default = script;
exports.install = install;
Object.defineProperty(exports, '__esModule', { value: true });
})));

@@ -1,10 +0,10 @@

import Vue from 'vue'
import App from './App.vue'
import { createApp } from 'vue';
import App from './App.vue';
import VueSimpleContextMenu from '../src/index.js'
Vue.component('vue-simple-context-menu', VueSimpleContextMenu)
const app = createApp(App);
new Vue({
el: '#app',
render: h => h(App)
})
import VueSimpleContextMenu from '../src/index.js';
app.component('vue-simple-context-menu', VueSimpleContextMenu);
app.mount('#app');
{
"name": "vue-simple-context-menu",
"version": "3.4.2",
"description": "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.",
"author": "John Datserakis <johndatserakis@gmail.com>",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/johndatserakis/vue-simple-context-menu.git"
"browser": {
"./sfc": "src/vue-simple-context-menu.vue"
},

@@ -14,29 +9,7 @@ "bugs": {

},
"keywords": [
"vue",
"simple",
"context",
"menu",
"right",
"click"
],
"main": "dist/vue-simple-context-menu.umd.js",
"module": "dist/vue-simple-context-menu.esm.js",
"unpkg": "dist/vue-simple-context-menu.min.js",
"browser": {
"./sfc": "src/vue-simple-context-menu.vue"
},
"scripts": {
"watch": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
"build": "npm run test && npm run build:example && npm run build:library",
"build:umd": "rollup --config build/rollup.config.js --format umd --file dist/vue-simple-context-menu.umd.js",
"build:es": "rollup --config build/rollup.config.js --format es --file dist/vue-simple-context-menu.esm.js",
"build:unpkg": "rollup --config build/rollup.config.js --format iife --file dist/vue-simple-context-menu.min.js",
"build:library": "rimraf dist npm run build:umd & npm run build:es & npm run build:umd & npm run build:unpkg",
"build:example": "rimraf docs && cross-env NODE_ENV=production webpack --progress --hide-modules --mode production",
"test": "jest"
},
"dependencies": {
"v-click-outside": "^2.1.3"
"click-outside-vue3": "^4.0.1",
"rollup-plugin-scss": "^3.0.0"
},
"description": "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.",
"devDependencies": {

@@ -46,3 +19,4 @@ "@babel/cli": "^7.4.4",

"@babel/preset-env": "^7.4.5",
"@vue/test-utils": "^1.0.0-beta.29",
"@vue/compiler-sfc": "^3.2.31",
"@vue/test-utils": "^2.0.0-rc.18",
"babel-core": "^7.0.0-bridge.0",

@@ -57,4 +31,4 @@ "babel-jest": "^24.8.0",

"jest-serializer-vue": "^2.0.2",
"mini-css-extract-plugin": "^0.11.2",
"minimist": "^1.2.0",
"node-sass": "^4.12.0",
"regenerator-runtime": "^0.13.2",

@@ -65,12 +39,11 @@ "rimraf": "^3.0.2",

"rollup-plugin-commonjs": "^10.0.0",
"rollup-plugin-css-only": "^1.0.0",
"rollup-plugin-node-resolve": "^5.0.3",
"rollup-plugin-terser": "^5.0.0",
"rollup-plugin-vue": "^5.0.0",
"rollup-plugin-vue": "^6.0.0",
"sass": "^1.49.9",
"sass-loader": "^7.1.0",
"terser-webpack-plugin": "^1.3.0",
"vue": "^2.6.10",
"vue-jest": "^3.0.4",
"vue-loader": "^15.7.0",
"vue-template-compiler": "^2.6.10",
"vue": "^3.2.31",
"vue-jest": "^5.0.0-alpha.10",
"vue-loader": "^17.0.0",
"webpack": "^4.34.0",

@@ -88,10 +61,41 @@ "webpack-cli": "^3.3.4",

},
"transform": {
"^.+\\.js$": "<rootDir>/node_modules/babel-jest",
".*\\.(vue)$": "<rootDir>/node_modules/vue-jest"
},
"snapshotSerializers": [
"<rootDir>/node_modules/jest-serializer-vue"
]
}
],
"transform": {
".*\\.(vue)$": "<rootDir>/node_modules/vue-jest",
"^.+\\.js$": "<rootDir>/node_modules/babel-jest"
}
},
"keywords": [
"vue",
"simple",
"context",
"menu",
"right",
"click"
],
"license": "MIT",
"main": "dist/vue-simple-context-menu.umd.js",
"module": "dist/vue-simple-context-menu.esm.js",
"name": "vue-simple-context-menu",
"peerDependencies": {
"vue": "^3.2.31"
},
"repository": {
"type": "git",
"url": "git+https://github.com/johndatserakis/vue-simple-context-menu.git"
},
"scripts": {
"build": "npm run test && npm run build:example && npm run build:library",
"build:es": "rollup --config rollup.config.js --format es --file dist/vue-simple-context-menu.esm.js",
"build:example": "rimraf docs && cross-env NODE_ENV=production webpack --progress --hide-modules --mode production",
"build:library": "rimraf dist npm run build:umd & npm run build:es & npm run build:umd & npm run build:unpkg",
"build:umd": "rollup --config rollup.config.js --format umd --file dist/vue-simple-context-menu.umd.js",
"build:unpkg": "rollup --config rollup.config.js --format iife --file dist/vue-simple-context-menu.min.js",
"test": "jest",
"watch": "cross-env NODE_ENV=development webpack-dev-server --open --hot"
},
"unpkg": "dist/vue-simple-context-menu.min.js",
"version": "4.0.0"
}

@@ -13,17 +13,11 @@ # vue-simple-context-menu

### Demo
[View Demo](https://johndatserakis.github.io/vue-simple-context-menu/) | [GitHub](https://github.com/johndatserakis/vue-simple-context-menu) | [npm](https://www.npmjs.com/package/vue-simple-context-menu)
[View demo](https://johndatserakis.github.io/vue-simple-context-menu/)
## Vue 3 Support
[View on npm](https://www.npmjs.com/package/vue-simple-context-menu)
Vue 3 is supported from `v4.0.0` and beyond (current `master`). To use `vue-simple-context-menu` with Vue 2, use `v3.4.2`.
[View on GitHub](https://github.com/johndatserakis/vue-simple-context-menu)
## Install
### Install
```
# npm
npm i vue-simple-context-menu
# yarn
yarn add vue-simple-context-menu

@@ -44,21 +38,21 @@ ```

### About
## 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.
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 `element-id` 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
## Usage Example
```css
/* 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 want to import the component CSS into your CSS file/files */
@import '/path/to/node_modules/vue-simple-context-menu.css';
```
```js
// 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";
// 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);
Vue.component('vue-simple-context-menu', VueSimpleContextMenu);
```

@@ -83,5 +77,5 @@

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

@@ -106,3 +100,3 @@ />

### Props
## Props

@@ -113,3 +107,3 @@ | prop | type | description | required |

| `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.name` | String | Label for the option. | Yes |
| `options.class` | String | A custom class that will be applied to the option. | No |

@@ -119,3 +113,3 @@ | `options.type` | String | Only one possible value at the moment - `divider`. Pass this to set the object as a divider. | No |

### Methods
## Methods

@@ -126,3 +120,3 @@ | method | parameters | description |

### Events
## Events

@@ -134,3 +128,3 @@ | event | value | description |

### SASS Structure
## SASS Structure

@@ -152,36 +146,34 @@ ```scss

### Development
## Development
```bash
# install dependencies
npm install
# Install dependencies
yarn
# serve with hot reload
npm run watch
# Serve with hot reload
yarn watch
# run the tests
npm run test
# Run the tests
yarn test
# build demo page
npm run build:example
# Build demo page
yarn build:example
# build library
npm run build:library
# Build library
yarn build:library
# build everything and run tests
npm run build
# Build everything and run tests
yarn build
```
### Other
## Other
Go ahead and fork the project! Submit an issue if needed. Have fun!
### Thank You
## Thank You
Influenced by [Lucas Calazans](https://codepen.io/lucascalazans)'s [pen](https://codepen.io/lucascalazans/pen/ALvVVw). Go ahead and check out his other work.
### License
## License
[MIT](http://opensource.org/licenses/MIT)
Packaged with a mixture of [vue-lib-template](https://github.com/biigpongsatorn/vue-lib-template) and [vue-sfc-rollup](https://github.com/team-innovation/vue-sfc-rollup).
// Import vue component
import component from './vue-simple-context-menu.vue';
// install function executed by Vue.use()
export function install (Vue) {
export function install(app) {
if (install.installed) return;
install.installed = true;
Vue.component('VueSimpleContextMenu', component);
app.component('VueSimpleContextMenu', component);
}
// Create module definition for Vue.use()
const plugin = {
install,
};
const plugin = { install };
// To auto-install when vue is found
// To auto-install when Vue is found
let GlobalVue = null;

@@ -27,3 +24,3 @@ if (typeof window !== 'undefined') {

// To allow use as module (npm/webpack/etc.) export component
// To allow usage as a module (npm/webpack/etc.) export component
export default component;

@@ -30,0 +27,0 @@

@@ -1,3 +0,3 @@

import { shallowMount } from '@vue/test-utils'
import VueSimpleContextMenu from '@/vue-simple-context-menu.vue'
import { shallowMount } from '@vue/test-utils';
import VueSimpleContextMenu from '@/vue-simple-context-menu.vue';

@@ -11,25 +11,25 @@ describe('VueSimpleContextMenu.vue', () => {

name: 'Duplicate',
slug: 'duplicate'
slug: 'duplicate',
},
{
name: 'Edit',
slug: 'edit'
slug: 'edit',
},
{
name: 'Delete',
slug: 'delete'
}
]
}
slug: 'delete',
},
],
};
const wrapper = shallowMount(VueSimpleContextMenu, {
propsData: {
props: {
elementId: initialPropsData.elementId,
options: initialPropsData.options
}
})
options: initialPropsData.options,
},
});
expect(wrapper.vm.elementId).toBe(initialPropsData.elementId)
expect(wrapper.vm.options).toBe(initialPropsData.options)
})
expect(wrapper.vm.elementId).toBe(initialPropsData.elementId);
expect(wrapper.vm.options).toEqual(initialPropsData.options);
});

@@ -42,14 +42,14 @@ it('Shows menu on click', async () => {

name: 'Duplicate',
slug: 'duplicate'
slug: 'duplicate',
},
{
name: 'Edit',
slug: 'edit'
slug: 'edit',
},
{
name: 'Delete',
slug: 'delete'
}
]
}
slug: 'delete',
},
],
};

@@ -59,17 +59,17 @@ const wrapper = shallowMount(VueSimpleContextMenu, {

elementId: initialPropsData.elementId,
options: initialPropsData.options
}
})
options: initialPropsData.options,
},
});
// Make some test data
var testEvent = new Event("click", { "bubbles": true, "cancelable": false });
let testItem = { name: 'Jim', job: 'Salesman' }
var testEvent = new Event('click', { bubbles: true, cancelable: false });
let testItem = { name: 'Jim', job: 'Salesman' };
// Trigger the showing of the menu
wrapper.vm.showMenu(testEvent, testItem)
wrapper.vm.showMenu(testEvent, testItem);
// Menu show be showing our selected item
expect(wrapper.vm.item.name).toBe('Jim')
expect(wrapper.vm.item.name).toBe('Jim')
})
expect(wrapper.vm.item.name).toBe('Jim');
expect(wrapper.vm.item.name).toBe('Jim');
});

@@ -82,14 +82,14 @@ it('Emits event on menu item selection', async () => {

name: 'Duplicate',
slug: 'duplicate'
slug: 'duplicate',
},
{
name: 'Edit',
slug: 'edit'
slug: 'edit',
},
{
name: 'Delete',
slug: 'delete'
}
]
}
slug: 'delete',
},
],
};

@@ -99,24 +99,24 @@ const wrapper = shallowMount(VueSimpleContextMenu, {

elementId: initialPropsData.elementId,
options: initialPropsData.options
}
})
options: initialPropsData.options,
},
});
// Make some test data
var testEvent = new Event("click", { "bubbles": true, "cancelable": false });
let testItem = { name: 'Jim', job: 'Salesman' }
var testEvent = new Event('click', { bubbles: true, cancelable: false });
let testItem = { name: 'Jim', job: 'Salesman' };
// Trigger the showing of the menu
wrapper.vm.showMenu(testEvent, testItem)
wrapper.vm.showMenu(testEvent, testItem);
// Menu show be showing our selected item
expect(wrapper.vm.item.name).toBe('Jim')
expect(wrapper.vm.item.job).toBe('Salesman')
expect(wrapper.vm.item.name).toBe('Jim');
expect(wrapper.vm.item.job).toBe('Salesman');
// Manually click an item on the menu
// Here we know the options because we set them earlier
wrapper.vm.optionClicked(initialPropsData[0])
wrapper.vm.optionClicked(initialPropsData[0]);
// Check the event was emitted properly
expect(wrapper.emitted('option-clicked')).toBeTruthy()
})
})
expect(wrapper.emitted('option-clicked')).toBeTruthy();
});
});

@@ -1,6 +0,9 @@

const path = require('path')
const webpack = require('webpack')
// This webpack config is used to serve the example app in ./example
const { VueLoaderPlugin } = require('vue-loader');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const path = require('path');
const TerserPlugin = require('terser-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin')
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const webpack = require('webpack');

@@ -10,5 +13,5 @@ module.exports = {

output: {
filename: 'build.js',
path: path.resolve(__dirname, './docs'),
publicPath: (process.env.NODE_ENV === 'development') ? '/' : '/vue-simple-context-menu/',
filename: 'build.js'
publicPath: process.env.NODE_ENV === 'development' ? '/' : '/vue-simple-context-menu/',
},

@@ -20,4 +23,6 @@ module: {

use: [
'vue-style-loader',
'css-loader'
{
loader: MiniCssExtractPlugin.loader,
},
'css-loader',
],

@@ -28,5 +33,7 @@ },

use: [
'vue-style-loader',
{
loader: MiniCssExtractPlugin.loader,
},
'css-loader',
'sass-loader'
'sass-loader',
],

@@ -37,33 +44,17 @@ },

use: [
'vue-style-loader',
{
loader: MiniCssExtractPlugin.loader,
},
'css-loader',
'sass-loader?indentedSyntax'
'sass-loader?indentedSyntax',
],
},
{
loader: 'vue-loader',
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
// Since sass-loader (weirdly) has SCSS as its default parse mode, we map
// the "scss" and "sass" values for the lang attribute to the right configs here.
// other preprocessors should work out of the box, no loader config like this necessary.
'scss': [
'vue-style-loader',
'css-loader',
'sass-loader'
],
'sass': [
'vue-style-loader',
'css-loader',
'sass-loader?indentedSyntax'
]
}
// other vue-loader options go here
}
},
{
exclude: /node_modules/,
loader: 'babel-loader',
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},

@@ -74,12 +65,12 @@ {

options: {
name: '[name].[ext]?[hash]'
}
}
]
name: '[name].[ext]?[hash]',
},
},
],
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
vue$: 'vue/dist/vue.esm-bundler.js',
},
extensions: ['*', '.js', '.vue', '.json']
extensions: ['*', '.js', '.vue', '.json'],
},

@@ -89,6 +80,6 @@ devServer: {

noInfo: true,
overlay: true
overlay: true,
},
performance: {
hints: false
hints: false,
},

@@ -100,9 +91,9 @@ optimization: {

terserOptions: {
warnings: false,
compress: {
warnings: false
warnings: false,
},
warnings: false,
},
})
]
}),
],
},

@@ -112,11 +103,14 @@ devtool: '#eval-source-map',

new VueLoaderPlugin(),
new MiniCssExtractPlugin({
filename: '[name].css',
}),
new HtmlWebpackPlugin({
title: 'vue-simple-context-menu',
template: './example/index.html'
})
]
}
template: './example/index.html',
}),
],
};
if (process.env.NODE_ENV === 'production') {
module.exports.devtool = '#source-map'
module.exports.devtool = '#source-map';
// http://vue-loader.vuejs.org/en/workflow/production.html

@@ -126,9 +120,9 @@ module.exports.plugins = (module.exports.plugins || []).concat([

'process.env': {
NODE_ENV: '"production"'
}
NODE_ENV: '"production"',
},
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
])
minimize: true,
}),
]);
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc