vue-simple-context-menu
Version:
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.
2 lines (1 loc) • 4.52 kB
JavaScript
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);