UNPKG

tiny-popup-menu

Version:
8 lines (7 loc) 7.43 kB
/*! * tiny-popup-menu - v1.0.15 * https://github.com/GastonZalba/tiny-popup-menu#readme * Built: Tue Jul 08 2025 14:16:43 GMT-0300 (hora estándar de Argentina) */ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).TinyPopupMenu=e()}(this,(function(){"use strict";var t={exports:{}};function e(){}e.prototype={on:function(t,e,n){var s=this.e||(this.e={});return(s[t]||(s[t]=[])).push({fn:e,ctx:n}),this},once:function(t,e,n){var s=this;function i(){s.off(t,i),e.apply(n,arguments)}return i._=e,this.on(t,i,n)},emit:function(t){for(var e=[].slice.call(arguments,1),n=((this.e||(this.e={}))[t]||[]).slice(),s=0,i=n.length;s<i;s++)n[s].fn.apply(n[s].ctx,e);return this},off:function(t,e){var n=this.e||(this.e={}),s=n[t],i=[];if(s&&e)for(var o=0,r=s.length;o<r;o++)s[o].fn!==e&&s[o].fn._!==e&&i.push(s[o]);return i.length?n[t]=i:delete n[t],this}},t.exports=e;var n,s,i=t.exports.TinyEmitter=e;function o(t,e={},...n){if("function"==typeof t)return t(e,n);const s=null===t?new DocumentFragment:document.createElement(t);Object.entries(e||{}).forEach((([t,e])=>{void 0!==typeof e&&null!=e&&(t.startsWith("on")&&t.toLowerCase()in window?s.addEventListener(t.toLowerCase().substr(2),e):"className"===t?s.setAttribute("class",e.toString()):"htmlFor"===t?s.setAttribute("for",e.toString()):s.setAttribute(t,e.toString()))}));for(const t of n)t&&(Array.isArray(t)?s.append(...t):void 0===t.nodeType?s.innerHTML+=t:s.appendChild(t));return s}!function(t){t.Top="top",t.Bottom="bottom"}(n||(n={})),function(t){t.Left="left",t.Right="right"}(s||(s={}));const r={position:n.Bottom,className:"",autoClose:!0,arrow:!0,margin:void 0,offset:{x:0,y:0},menuItems:[],stopClick:!0,alignContent:"center"};const a="popup-menu",c=a+"--container",l=a+"--align",u=a+"--active",h=a+"--show-arrow",p=a+"--show-arrow-top",d=a+"--show-arrow-bottom",m=a+"--item",f=a+"--item-clickleable",g=a+"--submenu",_=a+"--submenu-arrow",v=a+"--submenu-content",w=a+"--item-separator";let L=1;const b=(t,...e)=>(e.forEach((e=>{Object.keys(e).forEach((n=>{const s=e[n],i=t[n];t[n]=i&&s&&"object"==typeof i&&"object"==typeof s&&!Array.isArray(i)?b(i,s):s}))})),t);class y extends i{constructor(t=null){super(),this._isOpen=!1,this._containerMenu=o("div",{id:`${a}-${L}`}),this._instanceOptions=t,L++}open(t){if(this._options=this._parseOptions(t),this.isOpen()&&(this.close(),t.event.currentTarget===this._toggler))return void(this._options.stopClick&&(t.event.preventDefault(),t.event.stopPropagation()));const{event:e,menuItems:n,autoClose:s,stopClick:i}=this._options;this._toggler=e.currentTarget;let r=!1;this._menuItemsList=n.map((t=>"-"===t?o("span",{className:w}):"items"in t?(r=!0,this._processSubMenu(t,s)):this._processMenuItem(t,s))),this._isOpen=!0,this.updatePosition(),r&&this._updateSubmenusPosition(),setTimeout((()=>{this.addEventListeners()})),this.emit("open"),i&&(e.preventDefault(),e.stopPropagation())}close(){this.isOpen()&&(this._containerMenu.innerHTML="",this._containerMenu.remove(),this._toggler.classList.remove(u),this.removeEventListeners(),this._isOpen=!1,this.emit("close"))}updatePosition(t=!0){if(!this.isOpen())return;const{offset:e,className:s,arrow:i,position:r,margin:p}=this._options;this._containerMenu.style.position="fixed",this._containerMenu.className=s,this._containerMenu.classList.add(a),i&&this._containerMenu.classList.add(h),this._containerMenu.innerHTML="",this._containerMenu.append(o("div",{className:`${c} ${l}-${this._options.alignContent}`},...this._menuItemsList)),document.body.append(this._containerMenu);const d=this._toggler.getBoundingClientRect(),m=this._toggler.offsetHeight,f=this._toggler.offsetWidth,g=(null==e?void 0:e.x)||0,_=(null==e?void 0:e.y)||0,v=this._containerMenu.offsetHeight,w=this._containerMenu.offsetWidth,L=(()=>{if(r===n.Top){if(d.top-v-_-p<=0)return n.Bottom}else if(r===n.Bottom&&d.top+v+_+m+p>=document.documentElement.offsetHeight)return n.Top;return r})();let b=0;switch(L){case n.Bottom:b=_+m+p;break;case n.Top:b=-v-p}const y=-w/2+f/2,M=window.innerWidth,x=d.left+g+y;let O=0;if(x<0?O=0-x+p:x+w>M&&(O=M-(x+w)-p),this._containerMenu.style.left=x+O+"px",this._containerMenu.style.top=d.top+b+"px",this._toggler.classList.add(u),i){const t=8,e=3;O=O>0?Math.min(w/2-t-e,O):Math.max(-(w/2-2*(t+e)),O),this._containerMenu.style.setProperty("--ofx",`${O+t}px`),this._evaluateArrowPosition(L)}t||this.emit("updateposition")}addToggler(t,e={},n="click"){"contextmenu"===n?t.addEventListener("contextmenu",(t=>this.open(Object.assign(Object.assign({},e),{event:t})))):t.addEventListener("click",(t=>this.open(Object.assign(Object.assign({},e),{event:t}))))}isOpen(){return this._isOpen}_parseOptions(t){const e=b({},r,this._instanceOptions||{},t||{});return void 0===e.margin&&(e.margin=!("arrow"in e)||e.arrow?10:2),e}_processSubMenu(t,e){let n=g;return n+=t.className?` ${t.className}`:"",n+=t.alignContent?` ${l}-${t.alignContent}`:"",o("div",{className:n,id:t.id,style:t.style,"data-position":t.position||s.Right},o("span",null,t.content),o("div",{className:_}),o("div",{className:v},t.items.map((t=>this._processMenuItem(t,e)))))}_processMenuItem(t,e){let n=m;return n+=t.callback?" "+f:"",n+=t.className?" "+t.className:"",o("div",{className:n,onClick:t.callback?n=>{t.callback(n),"autoClose"in t?t.autoClose&&this.close():e&&this.close()}:null,id:t.id,style:t.style},t.content)}_updateSubmenusPosition(){this._containerMenu.querySelectorAll("."+g).forEach((t=>{const e=t.dataset.position,n=t.querySelector("."+v),i=n.getBoundingClientRect(),o=n.offsetWidth,r=(()=>{if(e===s.Left){if(i.right-o<=0)return s.Right}else if(e===s.Right&&i.right+o>=document.documentElement.offsetWidth)return s.Left;return e})();t.classList.add(g+"-"+r);const a=t.querySelector("."+_);a.innerHTML="",r===s.Left?a.append((new DOMParser).parseFromString('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="768" height="768" viewBox="0 0 768 768">\r\n<path d="M493.5 531l-45 45-192-192 192-192 45 45-147 147z"></path>\r\n</svg>\r\n',"image/svg+xml").firstChild):e===s.Right&&a.append((new DOMParser).parseFromString('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="768" height="768" viewBox="0 0 768 768">\r\n<path d="M274.5 531l147-147-147-147 45-45 192 192-192 192z"></path>\r\n</svg>\r\n',"image/svg+xml").firstChild)}))}_evaluateArrowPosition(t){let e="";switch(t){case n.Bottom:e=p;break;case n.Top:e=d}this._containerMenu.classList.add(e)}addEventListeners(){this._closeListener=t=>{this._containerMenu.contains(t.target)||this.close()},this._resizeListener=()=>{this.isOpen()&&this.updatePosition(!1)},this._scrollListener=t=>{this.isOpen()&&t.target.contains(this._toggler)&&this.updatePosition(!1)},document.addEventListener("click",this._closeListener),window.addEventListener("resize",this._resizeListener),window.addEventListener("scroll",this._scrollListener,!0)}removeEventListeners(){document.removeEventListener("click",this._closeListener),window.removeEventListener("resize",this._resizeListener),window.removeEventListener("scroll",this._scrollListener)}}var M=Object.freeze({__proto__:null,get Position(){return n},get SubmenuPosition(){return s},addSeparator:function(t){return t.reduce(((t,e)=>t.length?[...t,"-",...e]:[...t,...e]),[])},default:y});return Object.assign(y,M),y})); //# sourceMappingURL=tiny-popup-menu.min.js.map