solid-contextmenu
Version:
Add contextmenu to your solid app with ease
2 lines (1 loc) • 8.55 kB
JavaScript
;Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const r=require("solid-js/web"),a=require("solid-js");var x=(e=>(e.menu="solid-contextmenu",e.submenu="solid-contextmenu solid-contextmenu__submenu",e.submenuArrow="solid-contextmenu__submenu-arrow",e.submenuOpen="solid-contextmenu__submenu--is-open",e.separator="solid-contextmenu__separator",e.item="solid-contextmenu__item",e.itemDisabled="solid-contextmenu__item--disabled",e.itemContent="solid-contextmenu__item__content",e.theme="solid-contextmenu__theme--",e.animationWillEnter="solid-contextmenu__will-enter--",e.animationWillLeave="solid-contextmenu__will-leave--",e))(x||{}),I=(e=>(e[e.HIDE_ALL=0]="HIDE_ALL",e))(I||{});const q={light:"light",dark:"dark"},B={fade:"fade",flip:"flip",scale:"scale",slide:"slide"};function S(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}const F=e=>{let t,s=!0;const[i,h]=a.createSignal(),[P,C]=a.createSignal(),$=a.children(()=>e.children),v=e.name||"s";e=a.mergeProps({name:v,enterActiveClass:v+"-enter-active",enterClass:v+"-enter",enterToClass:v+"-enter-to",exitActiveClass:v+"-exit-active",exitClass:v+"-exit",exitToClass:v+"-exit-to"},e);const{onBeforeEnter:p,onEnter:c,onAfterEnter:b,onBeforeExit:g,onExit:y,onAfterExit:d}=e;function A(n,o){if(!s||e.appear){let u=function(f){n&&(!f||f.target===n)&&(n.removeEventListener("transitionend",u),n.removeEventListener("animationend",u),n.classList.remove(...w),n.classList.remove(...l),a.batch(()=>{i()!==n&&h(n),P()===n&&C(void 0)}),b&&b(n),e.mode==="inout"&&_(n,o))};const m=e.enterClass.split(" "),w=e.enterActiveClass.split(" "),l=e.enterToClass.split(" ");p&&p(n),n.classList.add(...m),n.classList.add(...w),S(()=>{n.classList.remove(...m),n.classList.add(...l),c&&c(n,()=>u()),(!c||c.length<2)&&(n.addEventListener("transitionend",u),n.addEventListener("animationend",u))})}o&&!e.mode?C(n):h(n)}function _(n,o){const m=e.exitClass.split(" "),w=e.exitActiveClass.split(" "),l=e.exitToClass.split(" ");if(!o.parentNode)return u();g&&g(o),o.classList.add(...m),o.classList.add(...w),S(()=>{o.classList.remove(...m),o.classList.add(...l)}),y&&y(o,()=>u()),(!y||y.length<2)&&(o.addEventListener("transitionend",u),o.addEventListener("animationend",u));function u(f){(!f||f.target===o)&&(o.removeEventListener("transitionend",u),o.removeEventListener("animationend",u),o.classList.remove(...w),o.classList.remove(...l),i()===o&&h(void 0),d&&d(o),e.mode==="outin"&&A(n,o))}}return a.createComputed(n=>{for(t=$();typeof t=="function";)t=t();return a.untrack(()=>(t&&t!==n&&(e.mode!=="outin"?A(t,n):s&&h(t)),n&&n!==t&&e.mode!=="inout"&&_(t,n),s=!1,t))}),[i,P]};function R(e){return{all:e=e||new Map,on:function(t,s){var i=e.get(t);i?i.push(s):e.set(t,[s])},off:function(t,s){var i=e.get(t);i&&(s?i.splice(i.indexOf(s)>>>0,1):e.set(t,[]))},emit:function(t,s){var i=e.get(t);i&&i.slice().map(function(h){h(s)}),(i=e.get("*"))&&i.slice().map(function(h){h(t,s)})}}}const L=R(),O=a.createContext(),W=()=>a.useContext(O);function j(e){var t,s,i="";if(typeof e=="string"||typeof e=="number")i+=e;else if(typeof e=="object")if(Array.isArray(e))for(t=0;t<e.length;t++)e[t]&&(s=j(e[t]))&&(i&&(i+=" "),i+=s);else for(t in e)e[t]&&(i&&(i+=" "),i+=t);return i}function N(){for(var e,t,s=0,i="";s<arguments.length;)(e=arguments[s++])&&(t=j(e))&&(i&&(i+=" "),i+=t);return i}const T=r.template("<div></div>",2),H=(e,t,s)=>e+t<=s?e:e<t?s-t:e-t,V=(e,t)=>{const s={width:window.innerWidth,height:window.innerHeight};return{x:H(e.x,t.width,s.width),y:H(e.y,t.height,s.height)}},z=e=>{const[t,s]=a.splitProps(e,["id","theme","animation","onShown","onHidden"]),[i,h]=a.createSignal(!1),[P,C]=a.createSignal({x:0,y:0});let $;const[v,p]=a.createSignal();L.on("show",d=>{d.id===t.id&&(d.event.preventDefault(),p(d.props),h(!0),C(d.position??V({x:d.event.clientX,y:d.event.clientY},{width:$.offsetWidth,height:$.offsetHeight})))});const c=()=>{L.emit("hide",t.id),h(!1)},b=a.mergeProps({shown:i,animation:"scale",hide:c,props:v},t);L.on("hideAll",()=>{c()}),a.onCleanup(()=>{L.off("show"),L.off("hideAll")});const g=a.createMemo(()=>{let d="";return t.animation&&(d=`solid-contextmenu-${t.animation}`),console.log(d),d}),y=a.createMemo(()=>({enterActiveClass:g()+"-enter-active",exitActiveClass:g()+"-exit-active"}));return r.createComponent(O.Provider,{value:b,get children(){return r.createComponent(r.Portal,{get children(){return r.createComponent(F,r.mergeProps(y,{get children(){return r.createComponent(a.Show,{get when(){return i()},get children(){const d=T.cloneNode(!0),A=$;return typeof A=="function"?A(d):$=d,J(d,()=>c()),r.spread(d,s,!1,!1),r.effect(_=>{const n=N(x.menu,s.class,{[`${x.theme}${t.theme}`]:t.theme}),o=P().x+"px",m=P().y+"px";return n!==_._v$&&r.className(d,_._v$=n),o!==_._v$2&&d.style.setProperty("left",_._v$2=o),m!==_._v$3&&d.style.setProperty("top",_._v$3=m),_},{_v$:void 0,_v$2:void 0,_v$3:void 0}),d}})}}))}})}})};function J(e,t){const s=i=>!e.contains(i.target)&&t()?.();document.body.addEventListener("click",s),a.onCleanup(()=>document.body.removeEventListener("click",s))}function X(e){return typeof e=="function"}function E(e,t){return X(e)?e(t):e}const G=r.template("<div><div></div></div>",4),K=e=>{const[t,s]=a.splitProps(e,["hidden","disabled","onClick","data","children"]),i=a.mergeProps({hidden:!1,disabled:!1},t),{props:h,hide:P}=W(),C=a.createMemo(()=>({props:h(),data:e.data})),$=a.createMemo(()=>E(i.disabled,C())),v=a.createMemo(()=>E(i.hidden,C())),p=c=>{$()||(e.onClick?.({event:c,...C()}),P())};return r.createComponent(a.Show,{get when(){return!v()},get children(){const c=G.cloneNode(!0),b=c.firstChild;return c.$$click=p,r.spread(c,s,!1,!0),r.insert(b,()=>t.children),r.effect(g=>{const y=N(x.item,{[x.itemDisabled]:$()}),d=x.itemContent;return y!==g._v$&&r.className(c,g._v$=y),d!==g._v$2&&r.className(b,g._v$2=d),g},{_v$:void 0,_v$2:void 0}),c}})};r.delegateEvents(["click"]);const Q=r.template("<div></div>",2),U=()=>(()=>{const e=Q.cloneNode(!0);return r.effect(()=>r.className(e,x.separator)),e})(),Z=r.template("<div></div>",2),Y=r.template("<div><div><span></span></div></div>",6),ee=e=>{const[t,s]=a.splitProps(e,["arrow","children","disabled","hidden","label","class"]),i=a.mergeProps({arrow:"\u25B6\uFE0F",disabled:!1,hidden:!1},t),{props:h,id:P}=W(),C=a.createMemo(()=>({props:h()})),$=a.createMemo(()=>E(i.disabled,C())),v=a.createMemo(()=>E(i.hidden,C()));let p,c;const[b,g]=a.createSignal({x:0,y:0}),y=()=>{const n=p.getBoundingClientRect(),o=c.getBoundingClientRect(),m={width:window.innerWidth,height:window.innerHeight};let w=n.right;w+o.width>m.width&&(n.left-o.width>0?w=n.left-o.width:w=m.width-o.width);let l=n.top;l+o.height>m.height&&(n.bottom-o.height>0?l=n.bottom-o.height:l=m.height-o.height),g({x:w,y:l}),console.log(b())},[d,A]=a.createSignal(!1),_=()=>{A(!0),y()};return L.on("hide",n=>{n===P&&A(!1)}),a.onCleanup(()=>{L.off("hide")}),r.createComponent(a.Show,{get when(){return!v()},get children(){const n=Y.cloneNode(!0),o=n.firstChild,m=o.firstChild;n.$$click=()=>d()?A(!1):_(),n.addEventListener("mouseleave",()=>A(!1)),n.addEventListener("mouseenter",()=>_()),r.spread(n,s,!1,!0);const w=p;return typeof w=="function"?w(o):p=o,r.insert(o,()=>i.label,m),r.insert(m,()=>i.arrow),r.insert(n,r.createComponent(a.Show,{get when(){return d()},get children(){const l=Z.cloneNode(!0),u=c;return typeof u=="function"?u(l):c=l,r.insert(l,()=>i.children),r.effect(f=>{const M=x.submenu,k=b().x+"px",D=b().y+"px";return M!==f._v$&&r.className(l,f._v$=M),k!==f._v$2&&l.style.setProperty("left",f._v$2=k),D!==f._v$3&&l.style.setProperty("top",f._v$3=D),f},{_v$:void 0,_v$2:void 0,_v$3:void 0}),l}}),null),r.effect(l=>{const u=N(x.item,t.class,{[x.itemDisabled]:$()}),f=x.itemContent,M=x.submenuArrow;return u!==l._v$4&&r.className(n,l._v$4=u),f!==l._v$5&&r.className(o,l._v$5=f),M!==l._v$6&&r.className(m,l._v$6=M),l},{_v$4:void 0,_v$5:void 0,_v$6:void 0}),n}})};r.delegateEvents(["click"]);const te=e=>({show:(t,s)=>{process.env.NODE_ENV==="development"&&!e?.id&&!s?.id&&console.error("You need to provide an id when initializing the hook `useContextMenu({ id: 'your id' })` or when you display the menu `show(e, { id: 'your id' })`. The later is used to override the one defined during initialization."),L.emit("show",{id:s?.id||e?.id,props:s?.props||e?.props,event:t,position:s?.position})},hideAll:()=>{L.emit("hideAll")}});exports.EVENT=I;exports.Item=K;exports.Menu=z;exports.STYLE=x;exports.Separator=U;exports.Submenu=ee;exports.animation=B;exports.theme=q;exports.useContextMenu=te;