UNPKG

@apitable/react-contexify

Version:

Add contextmenu to your react component with ease

3 lines (2 loc) 8.8 kB
"use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}Object.defineProperty(exports,"__esModule",{value:!0});var n=require("react"),t=e(n),i=e(require("clsx"));function r(){return(r=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i])}return e}).apply(this,arguments)}function o(e,n){if(null==e)return{};var t,i,r={},o=Object.keys(e);for(i=0;i<o.length;i++)n.indexOf(t=o[i])>=0||(r[t]=e[t]);return r}var a=n.createContext({});function s(){return n.useContext(a)}var c=function(e){return t.createElement(a.Provider,{value:e.refTracker},e.children)};function l(){var e=new Map;return{on:function(n,t){var i;return e.has(n)?null==(i=e.get(n))||i.add(t):e.set(n,new Set([t])),this},off:function(n,t){return t?e.get(n).delete(t):e.delete(n),this},emit:function(n,t){if("production"!==process.env.NODE){var i=n;e.has(n)||0===i||console.error("It seems that the menu you are trying to display is not renderer or you have a menu id mismatch.","You used the menu id: "+n)}return e.has(n)&&e.get(n).forEach((function(e){e(t)})),this}}}var u=l();function d(){return n.useRef(new Map).current}var f={show:function(e){var n=e.id,t=e.event,i=e.props,r=e.position;t.preventDefault&&t.preventDefault(),u.emit(0).emit(n,{event:t.nativeEvent||t,props:i,position:r})},hideAll:function(){u.emit(0)}},v=function(){},m=["children","className","style","triggerEvent","data","propsFromTrigger","onClick","disabled","hidden"],p=function(e){var n,r=e.children,a=e.className,c=e.style,l=e.triggerEvent,u=e.data,d=e.propsFromTrigger,f=e.onClick,p=void 0===f?v:f,g=e.disabled,h=void 0!==g&&g,b=e.hidden,w=void 0!==b&&b,y=o(e,m),E=s(),_={data:u,triggerEvent:l,props:d},k=x(h,_);if(x(w,_))return null;var L=i("react-contexify__item",a,((n={})["react-contexify__item--disabled"]=k,n));return t.createElement("div",Object.assign({},y,{className:L,style:c,onClick:function(e){_.event=e,k?e.stopPropagation():p(_)},onKeyDown:function(e){"Enter"===e.key&&(_.event=e,p(_))},ref:function(e){e&&!k&&E.set(e,{node:e,isSubmenu:!1})},tabIndex:-1,role:"menuitem","aria-disabled":k}),t.createElement("div",{className:"react-contexify__item__content"},r))},g=["arrow","children","disabled","hidden","label","className","triggerEvent","propsFromTrigger","style"],h=function(e){var a,l=e.arrow,u=void 0===l?"▶":l,f=e.children,v=e.disabled,m=void 0!==v&&v,p=e.hidden,h=void 0!==p&&p,b=e.label,w=e.className,E=e.triggerEvent,_=e.propsFromTrigger,k=e.style,L=o(e,g),T=s(),N=d(),S=n.useRef(null),R=n.useState({left:"100%",top:0,bottom:"initial"}),A=R[0],O=R[1],C={triggerEvent:E,props:_},F=x(m,C),j=x(h,C);if(n.useEffect((function(){if(S.current){var e=window,n=e.innerWidth,t=e.innerHeight,i=S.current.getBoundingClientRect(),r={};i.right<n?(r.left="100%",r.right=void 0):(r.right="100%",r.left=void 0),i.bottom>t?(r.bottom=0,r.top="initial"):r.bottom="initial",O(r)}}),[]),j)return null;var D=i("react-contexify__item",w,((a={})["react-contexify__item--disabled"]=F,a)),M=r({},k,A);return t.createElement(c,{refTracker:N},t.createElement("div",Object.assign({},L,{className:D,ref:function(e){e&&!F&&T.set(e,{node:e,isSubmenu:!0,submenuRefTracker:N})},tabIndex:-1,role:"menuitem","aria-haspopup":!0,"aria-disabled":F}),t.createElement("div",{className:"react-contexify__item__content",onClick:function(e){e.stopPropagation()}},b,t.createElement("span",{className:"react-contexify__submenu-arrow"},u)),t.createElement("div",{className:"react-contexify react-contexify__submenu",ref:S,style:M},y(f,{propsFromTrigger:_,triggerEvent:E}))))};function b(e){return"function"==typeof e}function w(e){return"string"==typeof e}function y(e,t){return n.Children.map(n.Children.toArray(e).filter((function(e){return Boolean(e)})),(function(e){return n.isValidElement(e)?e.type!==p&&e.type!==h&&e.props.children?y(e.props.children,t):n.cloneElement(e,t):e}))}function x(e,n){return b(e)?e(n):e}var E=["id","theme","style","className","children","animation","onHidden","onShown"];function _(e,n){return b(n)?r({},e,n(e)):r({},e,n)}exports.Item=p,exports.Menu=function(e){var a,s,l,f=e.id,m=e.theme,p=e.style,g=e.className,h=e.children,b=e.animation,x=void 0===b?"scale":b,k=e.onHidden,L=void 0===k?v:k,T=e.onShown,N=void 0===T?v:T,S=o(e,E),R=n.useReducer(_,{x:0,y:0,visible:!1,triggerEvent:{},propsFromTrigger:null,willLeave:!1}),A=R[0],O=R[1],C=n.useRef(null),F=n.useRef(!1),j=(s=A.visible,l=n.useRef(),n.useEffect((function(){l.current=s}),[s]),l.current),D=d(),M=n.useState((function(){return function(){var e,n,t,i,r=new Map,o=!1;function a(){i[e].node.focus()}function s(){return-1!==e||(c(),!1)}function c(){e+1<i.length?e++:e+1===i.length&&(e=0),o&&l(),a()}function l(){if(s()&&!t){var c=r.get(n),l=c.isRoot,u=c.items,d=c.focusedIndex,f=c.parentNode;n.classList.remove("react-contexify__submenu--is-open"),i=u,n=f,l&&(t=!0,r.clear()),o||(e=d,a())}}return{init:function(n){i=n,e=-1,t=!0},moveDown:c,moveUp:function(){-1===e||0===e?e=i.length-1:e-1<i.length&&e--,o&&l(),a()},openSubmenu:function(){if(s()&&e>=0&&i[e].isSubmenu){var c=Array.from(i[e].submenuRefTracker.values()),l=i[e].node;return r.set(l,{isRoot:t,focusedIndex:e,parentNode:n||l,items:i}),l.classList.add("react-contexify__submenu--is-open"),n=l,c.length>0?(e=0,i=c):o=!0,t=!1,a(),!0}return!1},closeSubmenu:l}}()}))[0];function I(e){var n=e.event,t=e.props,i=e.position;n.stopPropagation();var r,o,a=i||(o={x:0,y:0},function(e){return"touchend"===e.type}(r=n)&&r.changedTouches&&r.changedTouches.length>0?(o.x=r.changedTouches[0].clientX,o.y=r.changedTouches[0].clientY):(o.x=r.clientX,o.y=r.clientY),(!o.x||o.x<0)&&(o.x=0),(!o.y||o.y<0)&&(o.y=0),o),s=a.x,c=a.y;setTimeout((function(){O({visible:!0,willLeave:!1,x:s,y:c,triggerEvent:n,propsFromTrigger:t})}),0)}function P(e){(void 0===e||2!==e.button&&!0!==e.ctrlKey||"contextmenu"===e.type)&&(function(e){return!(!e||!(w(e)||"exit"in e&&e.exit))}(x)?O((function(e){return{willLeave:e.visible}})):O((function(e){return{visible:!e.visible&&e.visible}})))}n.useEffect((function(){return F.current=!0,u.on(f,I).on(0,P),function(){u.off(f,I).off(0,P)}}),[f]),n.useEffect((function(){F.current&&A.visible!==j&&(A.visible?N(A.propsFromTrigger):L())}),[A.visible,L,N]),n.useEffect((function(){A.visible?M.init(Array.from(D.values())):D.clear()}),[A.visible,M,D]),n.useEffect((function(){if(A.visible){var e=window,n=e.innerWidth,t=e.innerHeight,i=C.current,r=i.offsetWidth,o=i.offsetHeight,a=A.x,s=A.y;a+r>n&&(a-=a+r-n),s+o>t&&(s-=s+o-t+50),O({x:a,y:s})}}),[A.visible]),n.useEffect((function(){function e(e){switch(e.preventDefault(),e.key){case"Enter":M.openSubmenu()||P();break;case"Escape":P();break;case"ArrowUp":M.moveUp();break;case"ArrowDown":M.moveDown();break;case"ArrowRight":M.openSubmenu();break;case"ArrowLeft":M.closeSubmenu()}}return A.visible&&(window.addEventListener("resize",P),window.addEventListener("contextmenu",P),window.addEventListener("click",P),window.addEventListener("mousedown",P),window.addEventListener("scroll",P),window.addEventListener("keydown",e),window.addEventListener("blur",P)),function(){window.removeEventListener("resize",P),window.removeEventListener("contextmenu",P),window.removeEventListener("mousedown",P),window.removeEventListener("click",P),window.removeEventListener("scroll",P),window.removeEventListener("keydown",e),window.removeEventListener("blur",P)}}),[A.visible,M]);var H,U,W=A.visible,Y=A.triggerEvent,q=A.propsFromTrigger,z=A.x,B=A.y,K=A.willLeave,X=i("react-contexify",g,((a={})["react-contexify__theme--"+m]=m,a),x?w(x)?i(((H={})["react-contexify__will-enter--"+x]=x&&W&&!K,H["react-contexify__will-leave--"+x+" react-contexify__will-leave--'disabled'"]=x&&W&&K,H)):"enter"in x&&"exit"in x?i(((U={})["react-contexify__will-enter--"+x.enter]=x.enter&&W&&!K,U["react-contexify__will-leave--"+x.exit+" react-contexify__will-leave--'disabled'"]=x.exit&&W&&K,U)):null:null),V=r({},p,{left:z,top:B,opacity:1});return t.createElement(c,{refTracker:D},W&&t.createElement("div",Object.assign({},S,{className:X,onAnimationEnd:function(){A.willLeave&&A.visible&&O({visible:!1,willLeave:!1})},style:V,ref:C,role:"menu",id:f+""}),y(h,{propsFromTrigger:q,triggerEvent:Y})))},exports.Separator=function(){return t.createElement("div",{className:"react-contexify__separator"})},exports.Submenu=h,exports.animation={fade:"fade",flip:"flip",scale:"scale",slide:"slide"},exports.contextMenu=f,exports.theme={light:"light",dark:"dark"},exports.useContextMenu=function(e){return{show:function(n,t){f.show({id:(null==t?void 0:t.id)||(null==e?void 0:e.id),props:(null==t?void 0:t.props)||(null==e?void 0:e.props),event:n,position:null==t?void 0:t.position})},hideAll:function(){f.hideAll()}}}; //# sourceMappingURL=react-contexify.cjs.production.min.js.map