@vuu-ui/vuu-popups 0.7.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cjs/index.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var rt=Object.create;var oe=Object.defineProperty;var st=Object.getOwnPropertyDescriptor;var it=Object.getOwnPropertyNames;var ut=Object.getPrototypeOf,ct=Object.prototype.hasOwnProperty;var lt=(e,t)=>{for(var n in t)oe(e,n,{get:t[n],enumerable:!0})},Ce=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of it(t))!ct.call(e,r)&&r!==n&&oe(e,r,{get:()=>t[r],enumerable:!(o=st(t,r))||o.enumerable});return e};var K=(e,t,n)=>(n=e!=null?rt(ut(e)):{},Ce(t||!e||!e.__esModule?oe(n,"default",{value:e,enumerable:!0}):n,e)),at=e=>Ce(oe({},"__esModule",{value:!0}),e);var qt={};lt(qt,{ContextMenu:()=>ie,ContextMenuContext:()=>ee,ContextMenuProvider:()=>St,Dialog:()=>gt,DialogService:()=>te,MenuItem:()=>re,MenuItemGroup:()=>Z,Popup:()=>Ft,PopupService:()=>D,Portal:()=>Y,Separator:()=>ge,createContainer:()=>de,installTheme:()=>ft,isGroupMenuItemDescriptor:()=>xe,renderPortal:()=>Q,useContextMenu:()=>Gt});module.exports=at(qt);var V=require("@heswell/salt-lab"),Re=require("@salt-ds/core"),He=K(require("classnames")),O=require("react");var X=require("react"),Le=K(require("react-dom"));var we=K(require("react-dom")),Ee=require("@salt-ds/core"),Pe=require("react/jsx-runtime"),pt=1,dt=(e=0,t=0,n=window)=>{let o=n.document.createElement("div");return o.className="vuuPopup "+pt++,o.style.cssText=`left:${e}px; top:${t}px;`,n.document.body.appendChild(o),o},mt=(e,t)=>dt(e,t),Q=(e,t,n,o,r)=>{t.style.cssText=`left:${n}px; top:${o}px;position: absolute;`,we.render((0,Pe.jsx)(Ee.SaltProvider,{applyClassesTo:"child",children:e}),t,r)},de=mt;var Y=function({children:t,x:n=0,y:o=0,onRender:r}){let c=(0,X.useMemo)(()=>de(),[]);return(0,X.useLayoutEffect)(()=>{Q(t,c,n,o,r)},[t,r,c,n,o]),(0,X.useLayoutEffect)(()=>()=>{var i;c&&(Le.unmountComponentAtNode(c),c.classList.contains("vuuPopup")&&((i=c.parentElement)==null||i.removeChild(c)))},[c]),null};var ft=e=>{let t=getComputedStyle(document.body).getPropertyValue("--installed-themes");document.body.style.setProperty("--installed-themes",`${t} ${e}`)};var N=require("react/jsx-runtime"),me="vuuDialog",gt=({children:e,className:t,isOpen:n=!1,onClose:o,title:r,...c})=>{let i=(0,O.useRef)(null),[u]=(0,O.useState)(0),[a]=(0,O.useState)(0),d=(0,O.useCallback)(()=>{o==null||o()},[o]),l=(0,O.useCallback)(()=>{},[]);return n?(0,N.jsx)(Y,{onRender:l,x:u,y:a,children:(0,N.jsx)(V.Scrim,{className:`${me}-scrim`,open:n,children:(0,N.jsxs)("div",{...c,className:(0,He.default)(me,t),ref:i,children:[(0,N.jsxs)(V.Toolbar,{className:`${me}-header`,children:[(0,N.jsx)(Re.Text,{children:r}),(0,N.jsx)(V.ToolbarButton,{onClick:d,"data-align-end":!0,"data-icon":"close"},"close")]}),e]})})}):null};var ze=require("@salt-ds/core"),G=require("react");var B=K(require("react")),Me=K(require("classnames")),Oe=require("@salt-ds/core");var H=require("react");var ke=e=>e.closest("[data-root='true']")!==null,Te=(e,t)=>{var n;return e.ariaHasPopup==="true"&&((n=e.dataset)==null?void 0:n.idx)===`${t}`||e.querySelector(`:scope > [data-idx='${t}'][aria-haspopup='true']`)!==null};function Mt(e,...t){let n=new Set(e);for(let o of t)for(let r of o)n.add(r);return n}var ht="Enter";var xt="Delete",bt=new Set([ht,xt]),vt=new Set(["Tab"]),yt=new Set(["ArrowRight","ArrowLeft"]),De=new Set(["Home","End","ArrowDown","ArrowUp"]),Ae=new Set(["Home","End","ArrowRight","ArrowLeft"]),It=new Set(["F1","F2","F3","F4","F5","F6","F7","F8","F9","F10","F11","F12"]),an=Mt(bt,Ae,De,yt,It,vt);var Se=({key:e},t="vertical")=>(t==="vertical"?De:Ae).has(e);var $e=({autoHighlightFirstItem:e=!1,count:t,highlightedIndex:n,onActivate:o,onHighlight:r,onCloseMenu:c,onOpenMenu:i})=>{let u=(0,H.useRef)((n!=null?n:e)?0:-1),[,a]=(0,H.useState)(null),d=n!==void 0,l=(0,H.useCallback)(s=>{u.current=s,r==null||r(s),a({})},[r]),h=(0,H.useCallback)(s=>{s!==u.current&&(d||l(s))},[d,l]),f=(0,H.useRef)(!0),w=(0,H.useRef)(!1),v=s=>w.current=s,g=d?n:u.current,P=(0,H.useCallback)(s=>{let m=Ct(t,s.key,u.current);m!==u.current&&h(m)},[t,h]),k=(0,H.useCallback)(s=>{Se(s)?(s.preventDefault(),s.stopPropagation(),f.current=!0,P(s)):(s.key==="ArrowRight"||s.key==="Enter")&&Te(s.target,g)?i(g):s.key==="ArrowLeft"&&!ke(s.target)?c(g):s.key==="Enter"&&o&&o(g)},[g,P,o,c,i]),R=(0,H.useMemo)(()=>({onFocus:()=>{g===-1&&l(0)},onKeyDown:k,onMouseDownCapture:()=>{f.current=!1,v(!0)},onMouseMove:()=>{f.current&&(f.current=!1)},onMouseLeave:()=>{f.current=!0,v(!1),h(-1)}}),[g,h,P,o,c,i,l]);return{focusVisible:f.current?g:-1,controlledHighlighting:d,highlightedIndex:g,setHighlightedIndex:h,listProps:R,setIgnoreFocus:v}};function Ct(e,t,n){return t==="ArrowUp"?n>0?n-1:n:n===null?0:n===e-1?n:n+1}var F=K(require("react"));var fe=e=>e.type===Z||!!e.props["data-group"],Ke=e=>{let t=(0,F.useCallback)(()=>{let r=(i,u="root",a={},d={})=>{let l=a[u]=[],h=0,f=!1;return F.default.Children.forEach(i,w=>{if(w.type===ge)f=!0;else{let v=fe(w),g=u==="root"?`${h}`:`${u}.${h}`,{props:{action:P,options:k}}=w,{childWithId:R,grandChildren:s}=c(w,g,v,f);l.push(R),s?r(s,g,a,d):d[g]={action:P,options:k},h+=1,f=!1}}),[a,d]},c=(i,u,a,d=!1)=>{let{props:{children:l}}=i;return{childWithId:F.default.cloneElement(i,{hasSeparator:d,id:`${u}`,key:u,children:a?void 0:l}),grandChildren:a?l:void 0}};return r(e)},[e]),[n,o]=(0,F.useMemo)(()=>t(),[t]);return[n,o]};var U=require("react/jsx-runtime"),Ne="vuuMenuList",ge=()=>(0,U.jsx)("li",{className:"vuuMenuItem-divider"}),Z=()=>null,re=({children:e,idx:t,...n})=>(0,U.jsx)("div",{...n,children:e}),wt=e=>e.props["data-icon"],Be=({activatedByKeyboard:e,childMenuShowing:t=-1,children:n,className:o,highlightedIdx:r,id:c,isRoot:i,listItemProps:u,menuId:a,onHighlightMenuItem:d,onActivate:l,onCloseMenu:h,onOpenMenu:f,...w})=>{let v=(0,Oe.useIdMemo)(c),g=(0,B.useRef)(null),P=(0,B.useMemo)(()=>new Map,[]),k=y=>{var b;let M=(b=g.current)==null?void 0:b.querySelector(`:scope > [data-idx='${y}']`);M!=null&&M.id&&(f==null||f(M.id))},R=y=>{var b;let M=(b=g.current)==null?void 0:b.querySelector(`:scope > [data-idx='${y}']`);M!=null&&M.id&&(l==null||l(M.id))},{focusVisible:s,highlightedIndex:m,listProps:p}=$e({count:B.default.Children.count(n),highlightedIndex:r,onActivate:R,onHighlight:d,onOpenMenu:k,onCloseMenu:h}),x=t==-1?s:-1;return(0,B.useLayoutEffect)(()=>{var y;t===-1&&e&&((y=g.current)==null||y.focus())},[e,t]),(0,U.jsx)("div",{...w,...p,"aria-activedescendant":(()=>m===void 0||m===-1?void 0:P.get(m))(),className:(0,Me.default)(Ne,o,{[`${Ne}-childMenuShowing`]:t!==-1}),"data-root":i||void 0,id:`${v}-${a}`,ref:g,role:"menu",tabIndex:0,children:S()});function S(){let y={...u,role:"menuitem"},M=(I,$,q)=>$?[(0,U.jsx)("span",{className:"vuuIconContainer","data-icon":q},"icon")].concat(I):I;function b(I,$,q,be){var Ie;let{children:_e,className:je,"data-icon":ve,id:ae,hasSeparator:et,label:tt,...nt}=$.props,pe=fe($),ye=pe&&t===q,ot=ye?`${v}-${ae}`:void 0;I.push((0,U.jsx)(re,{...nt,...y,...Et(`${v}-${a}`,ae,q,(Ie=$.key)!=null?Ie:ae,m,x,je,et),"aria-controls":ot,"aria-haspopup":pe||void 0,"aria-expanded":ye||void 0,children:M(pe?tt:_e,be,ve)}))}let L=[];if(n.length>0){let I=n.some(wt);n.forEach(($,q)=>{b(L,$,q,I)})}return L}},Et=(e,t,n,o,r,c,i,u)=>({id:`${e}-${t}`,key:o!=null?o:n,"data-idx":n,"data-highlighted":n===r||void 0,className:(0,Me.default)("vuuMenuItem",i,{"vuuMenuItem-separator":u,focusVisible:c===n})});Be.displayName="MenuList";var Fe=Be;var C=require("react");function Ge(e){if(e){let t=e.dataset.idx;if(t)return parseInt(t,10);if(e.ariaPosInSet)return parseInt(e.ariaPosInSet,10)-1}}var he=e=>e==null?void 0:e.closest("[data-idx],[aria-posinset]");var We=(e,t,n)=>e.map((o,r)=>r===e.length-1?{...o,[n]:o[n]-t}:o),Pt=(e,t)=>We(e,t,"left"),Lt=(e,t)=>We(e,t,"top"),Rt=(e,t)=>{let[n,o]=t.slice(-2),r=document.getElementById(`${e}-${o.id}`);if(r===null)throw Error(`useCascade.flipSides element with id ${o.id} not found`);let{width:c}=r.getBoundingClientRect();return t.map(i=>i===o?{...i,left:n.left-(c-2)}:i)},Ht=(e,t)=>{let[{left:n,top:o}]=t.slice(-1),{offsetWidth:r,offsetTop:c}=e;return{left:n+r,top:c+o}},_=e=>{let t=e.lastIndexOf("-");return t===-1?e:e.slice(t+1)},se=e=>{let t=_(e),n=t.lastIndexOf(".");return n>-1?t.slice(0,n):"root"},kt=e=>{let t=0,n=e.indexOf(".",0);for(;n!==-1;)t+=1,n=e.indexOf(".",n+1);return t},Tt=e=>({menuId:se(e.id),itemId:_(e.id),isGroup:e.ariaHasPopup==="true",isOpen:e.ariaExpanded==="true",level:kt(e.id)}),qe=({id:e,onActivate:t,onMouseEnterItem:n,position:{x:o,y:r}})=>{let[,c]=(0,C.useState)({}),i=(0,C.useRef)([{id:"root",left:o,top:r}]),u=(0,C.useCallback)(s=>{i.current=s,c({})},[]),a=(0,C.useRef)(),d=(0,C.useRef)(),l=(0,C.useRef)({root:"no-popup"}),h=(0,C.useRef)(0),f=(0,C.useCallback)((s="root",m=null,p=null)=>{if(s==="root"&&m===null)u([{id:"root",left:o,top:r}]);else{l.current[s]="popup-open";let E=(p?p.ownerDocument:document).getElementById(`${e}-${s}-${m}`),{left:S,top:y}=Ht(E,i.current);u(i.current.concat({id:m,left:S,top:y}))}},[e,o,r,u]),w=(0,C.useCallback)(s=>{u(s==="root"?[]:i.current.slice(0,-1))},[u]),v=(0,C.useCallback)((s,m)=>{let p=i.current.slice(),{id:x}=p[p.length-1];for(;p.length>1&&!m.startsWith(x);){let E=se(x);p.pop(),l.current[x]="no-popup",l.current[E]="no-popup",{id:x}=p[p.length-1]}p.length<i.current.length&&u(p)},[u]),g=(0,C.useCallback)((s,m,p)=>{a.current&&clearTimeout(a.current),a.current=window.setTimeout(()=>{console.log(`scheduleOpen timed out opening ${m}`),v(s,m),l.current[s]="popup-open",l.current[m]="no-popup",f(s,m,p)},400)},[v,f]),P=(0,C.useCallback)((s,m,p)=>{console.log(`scheduleClose openMenuId ${s} menuId ${m} itemId ${p}`),l.current[s]="pending-close",d.current=window.setTimeout(()=>{v(m,p)},400)},[v]),k=(0,C.useCallback)(()=>{let{current:s}=i,[m]=s.slice(-1),p=document.getElementById(`${e}-${m.id}`);if(p){let{right:x,bottom:E}=p.getBoundingClientRect(),{clientHeight:S,clientWidth:y}=document.body;if(x>y){let M=s.length>1?Rt(e,s):Pt(s,x-y);u(M)}else if(E>S){let M=Lt(s,E-S);u(M)}}},[e,u]),R=(0,C.useMemo)(()=>({onMouseEnter:s=>{let m=he(s.target),{menuId:p,itemId:x,isGroup:E,isOpen:S,level:y}=Tt(m),M=h.current===y,{current:{[p]:b}}=l;if(h.current=y,b==="no-popup"&&E)l.current[p]="popup-pending",g(p,x,m);else if(b==="popup-pending"&&!E)l.current[p]="no-popup",clearTimeout(a.current),a.current=void 0;else if(b==="popup-pending"&&E)clearTimeout(a.current),g(p,x,m);else if(b==="popup-open"){let[{id:L},{id:I}]=i.current.slice(-2);L===p&&l.current[I]!=="pending-close"&&M?(P(I,p,x),E&&!S&&g(p,x,m)):L===p&&E&&x!==I&&l.current[I]==="pending-close"?g(p,x,m):E?(v(p,x),g(p,x,m)):l.current[I]==="pending-close"&&M||v(p,x)}b==="pending-close"&&(a.current&&(clearTimeout(a.current),a.current=void 0),clearTimeout(d.current),d.current=void 0,l.current[p]="popup-open"),n(s,x)},onClick:s=>{let m=s.target,p=he(m),x=Ge(p);console.log(`list item click [${x}] hasPopup ${p.ariaHasPopup}`),p.ariaHasPopup==="true"?p.ariaExpanded!=="true"&&f(x):t(_(p.id))}}),[v,t,n,f,P,g]);return{closeMenu:w,handleRender:k,listItemProps:R,openMenu:f,openMenus:i.current}};var Ve=require("react"),Ue=({containerClassName:e,isOpen:t,onClose:n})=>{(0,Ve.useEffect)(()=>{let o;return t&&(o=r=>{r.target.closest(`.${e}`)===null&&(n==null||n("root"))},document.body.addEventListener("click",o,!0)),()=>{o&&document.body.removeEventListener("click",o,!0)}},[e,t,n])};var j=require("react/jsx-runtime"),Je=require("react"),Dt=()=>{},ie=({activatedByKeyboard:e,children:t,className:n,id:o,onClose:r=()=>{},position:c={x:0,y:0},style:i,...u})=>{let a=(0,ze.useIdMemo)(o),d=(0,G.useRef)(Dt),[l,h]=Ke(t),f=(0,G.useRef)(e),w=(0,G.useCallback)(()=>{f.current=!1},[]),v=(0,G.useCallback)(M=>{let{action:b,options:L}=h[M];d.current("root"),r(b,L)},[h,r]),{closeMenu:g,listItemProps:P,openMenu:k,openMenus:R,handleRender:s}=qe({id:a,onActivate:v,onMouseEnterItem:w,position:c});d.current=g,console.log({openMenus:R});let m=(0,G.useCallback)(()=>{g(),r()},[g,r]);Ue({containerClassName:"vuuMenuList",onClose:m,isOpen:R.length>0});let p=M=>{let b=_(M),L=se(b);f.current=!0,k(L,b)},x=()=>{f.current=!0,g()},E=()=>{},S=R.length-1,y=M=>{if(M>=S)return-1;{let{id:b}=R[M+1],L=b.lastIndexOf(".");return parseInt(L===-1?b:b.slice(-L),10)}};return(0,j.jsx)(j.Fragment,{children:R.map(({id:M,left:b,top:L},I)=>{let $=y(I);return(0,j.jsx)(Y,{x:b,y:L,onRender:s,children:(0,Je.createElement)(Fe,{...u,activatedByKeyboard:f.current,childMenuShowing:$,className:n,id:a,menuId:M,isRoot:I===0,key:I,listItemProps:P,onActivate:v,onHighlightMenuItem:E,onCloseMenu:x,onOpenMenu:p,style:i},l[M])},I)})})};ie.displayName="ContextMenu";var z=require("react"),ue=require("react/jsx-runtime"),ee=(0,z.createContext)(null),xe=e=>e!==void 0&&"children"in e,At=({children:e,context:t,menuActionHandler:n,menuBuilder:o})=>{let r=(0,z.useMemo)(()=>t!=null&&t.menuBuilders&&o?t.menuBuilders.concat(o):o?[o]:(t==null?void 0:t.menuBuilders)||[],[t,o]),c=(0,z.useCallback)((i,u)=>{var a;if(n!=null&&n(i,u)||(a=t==null?void 0:t.menuActionHandler)!=null&&a.call(t,i,u))return!0},[t,n]);return(0,ue.jsx)(ee.Provider,{value:{menuActionHandler:c,menuBuilders:r},children:e})},St=({children:e,label:t,menuActionHandler:n,menuBuilder:o})=>(0,ue.jsx)(ee.Consumer,{children:r=>(0,ue.jsx)(At,{context:r,label:t,menuActionHandler:n,menuBuilder:o,children:e})});var ne=require("react");var Qe=K(require("classnames")),A=K(require("react")),J=K(require("react-dom"));var W=!1,T=[];function ce(e){if(e.key==="Esc"){if(T.length)Ye();else if(W){let t=document.body.querySelector(".vuuDialog");t&&J.default.unmountComponentAtNode(t)}}}function Xe(e){if(T.length){let t=document.body.querySelectorAll(".vuuPopup");for(let n=0;n<t.length;n++)if(t[n].contains(e.target))return;Ye()}}function Ye(){if(T.length){let e=document.body.querySelectorAll(".vuuPopup");for(let t=0;t<e.length;t++)J.default.unmountComponentAtNode(e[t]);Ze("*")}}function $t(){W===!1&&(W=!0,window.addEventListener("keydown",ce,!0))}function Kt(){W&&(W=!1,window.removeEventListener("keydown",ce,!0))}function Nt(e){T.indexOf(e)===-1&&(T.push(e),W===!1&&(window.addEventListener("keydown",ce,!0),window.addEventListener("click",Xe,!0)))}function Ze(e){if(T.length){if(e==="*")T.length=0;else{let t=T.indexOf(e);t!==-1&&T.splice(t,1)}T.length===0&&W===!1&&(window.removeEventListener("keydown",ce,!0),window.removeEventListener("click",Xe,!0))}}var Ot=({children:e,position:t,style:n})=>{let o=(0,Qe.default)("hwPopup","hwPopupContainer",t);return(0,A.createElement)("div",{className:o,style:n},e)},Bt=1,D=class{static showPopup({name:t="anon",group:n="all",position:o="",left:r=0,right:c="auto",top:i=0,width:u="auto",component:a}){if(!a)throw Error("PopupService showPopup, no component supplied");Nt(t);let d=document.body.querySelector(".vuuPopup."+n);d===null&&(d=document.createElement("div"),d.className="vuuPopup "+n,document.body.appendChild(d));let l={width:u};Q((0,A.createElement)(Ot,{key:Bt++,position:o,style:l},a),d,r,i,()=>{D.keepWithinThePage(d,c)})}static hidePopup(t="anon",n="all"){if(T.indexOf(t)!==-1){Ze(t);let o=document.body.querySelector(`.vuuPopup.${n}`);o&&J.default.unmountComponentAtNode(o)}}static keepWithinThePage(t,n="auto"){let o=t.querySelector(".vuuPopupContainer > *");if(o){let{top:r,left:c,width:i,height:u,right:a}=o.getBoundingClientRect(),d=window.innerWidth,h=window.innerHeight-(r+u);h<0&&(o.style.top=Math.round(r)+h+"px");let f=d-(c+i);if(f<0&&(o.style.left=Math.round(c)+f+"px"),typeof n=="number"&&n!==a){let w=n-a;o.style.left=c+w+"px"}}}},te=class{static showDialog(t){let n=".vuuDialog",o=t.props.onClose;$t(),J.default.render(A.default.cloneElement(t,{container:n,onClose:()=>{te.closeDialog(),o&&o()}}),document.body.querySelector(n))}static closeDialog(){Kt();let t=document.body.querySelector(".vuuDialog");t&&J.default.unmountComponentAtNode(t)}},Ft=e=>{let t=(0,A.useRef)(),n=(0,A.useRef)(null),o=(r,c)=>{let{name:i,group:u,depth:a,width:d}=r,l,h;if(t.current&&(window.clearTimeout(t.current),t.current=void 0),r.close===!0)D.hidePopup(i,u);else{let{position:f,children:w}=r,{left:v,top:g,width:P,bottom:k}=c;f==="below"?(l=v,h=k):f==="above"&&(l=v,h=g),t.current=window.setTimeout(()=>{D.showPopup({name:i,group:u,depth:a,position:f,left:l,top:h,width:d||P,component:w})},10)}};return(0,A.useEffect)(()=>{if(n.current){let r=n.current.parentElement,c=r==null?void 0:r.getBoundingClientRect();c&&o(e,c)}return()=>{D.hidePopup(e.name,e.group)}},[e]),A.default.createElement("div",{className:"popup-proxy",ref:n})};var le=require("react/jsx-runtime"),Gt=()=>{let e=(0,ne.useContext)(ee),t=(0,ne.useCallback)((o,r,c)=>{let i=[];for(let u of o)i=i.concat(u(r,c));return i},[]);return(0,ne.useCallback)((o,r,c)=>{var a;o.stopPropagation(),o.preventDefault();let i=(a=e==null?void 0:e.menuBuilders)!=null?a:[],u=t(i,r,c);console.log({menuItemDescriptors:u}),u.length&&(e!=null&&e.menuActionHandler)&&(console.log(`showContextMenu ${r}`,{options:c}),Wt(o,u,e.menuActionHandler))},[t,e])},Wt=(e,t,n)=>{let{clientX:o,clientY:r}=e,u=(0,le.jsx)(ie,{onClose:(a,d)=>{a&&(n(a,d),D.hidePopup())},position:{x:o,y:r},children:(a=>{let d=(l,h)=>xe(l)?(0,le.jsx)(Z,{label:l.label,children:l.children.map(d)},h):(0,le.jsx)(re,{action:l.action,"data-icon":l.icon,options:l.options,children:l.label},h);return a.map(d)})(t)});D.showPopup({left:0,top:0,component:u})};
1
+ "use strict";var rt=Object.create;var oe=Object.defineProperty;var st=Object.getOwnPropertyDescriptor;var it=Object.getOwnPropertyNames;var ut=Object.getPrototypeOf,ct=Object.prototype.hasOwnProperty;var lt=(t,e)=>{for(var n in e)oe(t,n,{get:e[n],enumerable:!0})},Ie=(t,e,n,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of it(e))!ct.call(t,r)&&r!==n&&oe(t,r,{get:()=>e[r],enumerable:!(o=st(e,r))||o.enumerable});return t};var K=(t,e,n)=>(n=t!=null?rt(ut(t)):{},Ie(e||!t||!t.__esModule?oe(n,"default",{value:t,enumerable:!0}):n,t)),at=t=>Ie(oe({},"__esModule",{value:!0}),t);var qt={};lt(qt,{ContextMenu:()=>ie,ContextMenuContext:()=>ee,ContextMenuProvider:()=>St,Dialog:()=>gt,DialogService:()=>te,MenuItem:()=>re,MenuItemGroup:()=>Z,Popup:()=>Ft,PopupService:()=>D,Portal:()=>Y,Separator:()=>ge,createContainer:()=>de,installTheme:()=>ft,isGroupMenuItemDescriptor:()=>xe,renderPortal:()=>Q,useContextMenu:()=>Gt});module.exports=at(qt);var V=require("@heswell/salt-lab"),Re=require("@salt-ds/core"),He=K(require("classnames")),B=require("react");var X=require("react"),Le=K(require("react-dom"));var we=K(require("react-dom")),Pe=require("@salt-ds/core"),Ee=require("react/jsx-runtime"),pt=1,dt=(t=0,e=0,n=window)=>{let o=n.document.createElement("div");return o.className="vuuPopup "+pt++,o.style.cssText=`left:${t}px; top:${e}px;`,n.document.body.appendChild(o),o},mt=(t,e)=>dt(t,e),Q=(t,e,n,o,r)=>{e.style.cssText=`left:${n}px; top:${o}px;position: absolute;`,we.render((0,Ee.jsx)(Pe.SaltProvider,{applyClassesTo:"child",children:t}),e,r)},de=mt;var Y=function({children:e,x:n=0,y:o=0,onRender:r}){let c=(0,X.useMemo)(()=>de(),[]);return(0,X.useLayoutEffect)(()=>{Q(e,c,n,o,r)},[e,r,c,n,o]),(0,X.useLayoutEffect)(()=>()=>{var u;c&&(Le.unmountComponentAtNode(c),c.classList.contains("vuuPopup")&&((u=c.parentElement)==null||u.removeChild(c)))},[c]),null};var ft=t=>{let e=getComputedStyle(document.body).getPropertyValue("--installed-themes");document.body.style.setProperty("--installed-themes",`${e} ${t}`)};var N=require("react/jsx-runtime"),me="vuuDialog",gt=({children:t,className:e,isOpen:n=!1,onClose:o,title:r,...c})=>{let u=(0,B.useRef)(null),[i]=(0,B.useState)(0),[l]=(0,B.useState)(0),d=(0,B.useCallback)(()=>{o==null||o()},[o]),a=(0,B.useCallback)(()=>{},[]);return n?(0,N.jsx)(Y,{onRender:a,x:i,y:l,children:(0,N.jsx)(V.Scrim,{className:`${me}-scrim`,open:n,children:(0,N.jsxs)("div",{...c,className:(0,He.default)(me,e),ref:u,children:[(0,N.jsxs)(V.Toolbar,{className:`${me}-header`,children:[(0,N.jsx)(Re.Text,{children:r}),(0,N.jsx)(V.ToolbarButton,{onClick:d,"data-align-end":!0,"data-icon":"close"},"close")]}),t]})})}):null};var ze=require("@salt-ds/core"),G=require("react");var O=K(require("react")),Me=K(require("classnames")),Be=require("@salt-ds/core");var H=require("react");var Te=t=>t.closest("[data-root='true']")!==null,ke=(t,e)=>{var n;return t.ariaHasPopup==="true"&&((n=t.dataset)==null?void 0:n.idx)===`${e}`||t.querySelector(`:scope > [data-idx='${e}'][aria-haspopup='true']`)!==null};function Mt(t,...e){let n=new Set(t);for(let o of e)for(let r of o)n.add(r);return n}var ht="Enter";var xt="Delete",bt=new Set([ht,xt]),vt=new Set(["Tab"]),yt=new Set(["ArrowRight","ArrowLeft"]),De=new Set(["Home","End","ArrowDown","ArrowUp"]),Ae=new Set(["Home","End","ArrowRight","ArrowLeft"]),Ct=new Set(["F1","F2","F3","F4","F5","F6","F7","F8","F9","F10","F11","F12"]),an=Mt(bt,Ae,De,yt,Ct,vt);var Se=({key:t},e="vertical")=>(e==="vertical"?De:Ae).has(t);var $e=({autoHighlightFirstItem:t=!1,count:e,highlightedIndex:n,onActivate:o,onHighlight:r,onCloseMenu:c,onOpenMenu:u})=>{let i=(0,H.useRef)((n!=null?n:t)?0:-1),[,l]=(0,H.useState)(null),d=n!==void 0,a=(0,H.useCallback)(s=>{i.current=s,r==null||r(s),l({})},[r]),h=(0,H.useCallback)(s=>{s!==i.current&&(d||a(s))},[d,a]),f=(0,H.useRef)(!0),w=(0,H.useRef)(!1),v=s=>w.current=s,g=d?n:i.current,E=(0,H.useCallback)(s=>{let m=It(e,s.key,i.current);m!==i.current&&h(m)},[e,h]),T=(0,H.useCallback)(s=>{Se(s)?(s.preventDefault(),s.stopPropagation(),f.current=!0,E(s)):(s.key==="ArrowRight"||s.key==="Enter")&&ke(s.target,g)?u(g):s.key==="ArrowLeft"&&!Te(s.target)?c(g):s.key==="Enter"&&o&&o(g)},[g,E,o,c,u]),R=(0,H.useMemo)(()=>({onFocus:()=>{g===-1&&a(0)},onKeyDown:T,onMouseDownCapture:()=>{f.current=!1,v(!0)},onMouseMove:()=>{f.current&&(f.current=!1)},onMouseLeave:()=>{f.current=!0,v(!1),h(-1)}}),[g,h,E,o,c,u,a]);return{focusVisible:f.current?g:-1,controlledHighlighting:d,highlightedIndex:g,setHighlightedIndex:h,listProps:R,setIgnoreFocus:v}};function It(t,e,n){return e==="ArrowUp"?n>0?n-1:n:n===null?0:n===t-1?n:n+1}var F=K(require("react"));var fe=t=>t.type===Z||!!t.props["data-group"],Ke=t=>{let e=(0,F.useCallback)(()=>{let r=(u,i="root",l={},d={})=>{let a=l[i]=[],h=0,f=!1;return F.default.Children.forEach(u,w=>{if(w.type===ge)f=!0;else{let v=fe(w),g=i==="root"?`${h}`:`${i}.${h}`,{props:{action:E,options:T}}=w,{childWithId:R,grandChildren:s}=c(w,g,v,f);a.push(R),s?r(s,g,l,d):d[g]={action:E,options:T},h+=1,f=!1}}),[l,d]},c=(u,i,l,d=!1)=>{let{props:{children:a}}=u;return{childWithId:F.default.cloneElement(u,{hasSeparator:d,id:`${i}`,key:i,children:l?void 0:a}),grandChildren:l?a:void 0}};return r(t)},[t]),[n,o]=(0,F.useMemo)(()=>e(),[e]);return[n,o]};var U=require("react/jsx-runtime"),Ne="vuuMenuList",ge=()=>(0,U.jsx)("li",{className:"vuuMenuItem-divider"}),Z=()=>null,re=({children:t,idx:e,...n})=>(0,U.jsx)("div",{...n,children:t}),wt=t=>t.props["data-icon"],Oe=({activatedByKeyboard:t,childMenuShowing:e=-1,children:n,className:o,highlightedIdx:r,id:c,isRoot:u,listItemProps:i,menuId:l,onHighlightMenuItem:d,onActivate:a,onCloseMenu:h,onOpenMenu:f,...w})=>{let v=(0,Be.useIdMemo)(c),g=(0,O.useRef)(null),E=(0,O.useMemo)(()=>new Map,[]),T=y=>{var b;let M=(b=g.current)==null?void 0:b.querySelector(`:scope > [data-idx='${y}']`);M!=null&&M.id&&(f==null||f(M.id))},R=y=>{var b;let M=(b=g.current)==null?void 0:b.querySelector(`:scope > [data-idx='${y}']`);M!=null&&M.id&&(a==null||a(M.id))},{focusVisible:s,highlightedIndex:m,listProps:p}=$e({count:O.default.Children.count(n),highlightedIndex:r,onActivate:R,onHighlight:d,onOpenMenu:T,onCloseMenu:h}),x=e==-1?s:-1;return(0,O.useLayoutEffect)(()=>{var y;e===-1&&t&&((y=g.current)==null||y.focus())},[t,e]),(0,U.jsx)("div",{...w,...p,"aria-activedescendant":(()=>m===void 0||m===-1?void 0:E.get(m))(),className:(0,Me.default)(Ne,o,{[`${Ne}-childMenuShowing`]:e!==-1}),"data-root":u||void 0,id:`${v}-${l}`,ref:g,role:"menu",tabIndex:0,children:S()});function S(){let y={...i,role:"menuitem"},M=(C,$,q)=>$?[(0,U.jsx)("span",{className:"vuuIconContainer","data-icon":q},"icon")].concat(C):C;function b(C,$,q,be){var Ce;let{children:_e,className:je,"data-icon":ve,id:ae,hasSeparator:et,label:tt,...nt}=$.props,pe=fe($),ye=pe&&e===q,ot=ye?`${v}-${ae}`:void 0;C.push((0,U.jsx)(re,{...nt,...y,...Pt(`${v}-${l}`,ae,q,(Ce=$.key)!=null?Ce:ae,m,x,je,et),"aria-controls":ot,"aria-haspopup":pe||void 0,"aria-expanded":ye||void 0,children:M(pe?tt:_e,be,ve)}))}let L=[];if(n.length>0){let C=n.some(wt);n.forEach(($,q)=>{b(L,$,q,C)})}return L}},Pt=(t,e,n,o,r,c,u,i)=>({id:`${t}-${e}`,key:o!=null?o:n,"data-idx":n,"data-highlighted":n===r||void 0,className:(0,Me.default)("vuuMenuItem",u,{"vuuMenuItem-separator":i,focusVisible:c===n})});Oe.displayName="MenuList";var Fe=Oe;var I=require("react");function Ge(t){if(t){let e=t.dataset.idx;if(e)return parseInt(e,10);if(t.ariaPosInSet)return parseInt(t.ariaPosInSet,10)-1}}var he=t=>t==null?void 0:t.closest("[data-idx],[aria-posinset]");var We=(t,e,n)=>t.map((o,r)=>r===t.length-1?{...o,[n]:o[n]-e}:o),Et=(t,e)=>We(t,e,"left"),Lt=(t,e)=>We(t,e,"top"),Rt=(t,e)=>{let[n,o]=e.slice(-2),r=document.getElementById(`${t}-${o.id}`);if(r===null)throw Error(`useCascade.flipSides element with id ${o.id} not found`);let{width:c}=r.getBoundingClientRect();return e.map(u=>u===o?{...u,left:n.left-(c-2)}:u)},Ht=(t,e)=>{let[{left:n,top:o}]=e.slice(-1),{offsetWidth:r,offsetTop:c}=t;return{left:n+r,top:c+o}},_=t=>{let e=t.lastIndexOf("-");return e===-1?t:t.slice(e+1)},se=t=>{let e=_(t),n=e.lastIndexOf(".");return n>-1?e.slice(0,n):"root"},Tt=t=>{let e=0,n=t.indexOf(".",0);for(;n!==-1;)e+=1,n=t.indexOf(".",n+1);return e},kt=t=>({menuId:se(t.id),itemId:_(t.id),isGroup:t.ariaHasPopup==="true",isOpen:t.ariaExpanded==="true",level:Tt(t.id)}),qe=({id:t,onActivate:e,onMouseEnterItem:n,position:{x:o,y:r}})=>{let[,c]=(0,I.useState)({}),u=(0,I.useRef)([{id:"root",left:o,top:r}]),i=(0,I.useCallback)(s=>{u.current=s,c({})},[]),l=(0,I.useRef)(),d=(0,I.useRef)(),a=(0,I.useRef)({root:"no-popup"}),h=(0,I.useRef)(0),f=(0,I.useCallback)((s="root",m=null,p=null)=>{if(s==="root"&&m===null)i([{id:"root",left:o,top:r}]);else{a.current[s]="popup-open";let P=(p?p.ownerDocument:document).getElementById(`${t}-${s}-${m}`),{left:S,top:y}=Ht(P,u.current);i(u.current.concat({id:m,left:S,top:y}))}},[t,o,r,i]),w=(0,I.useCallback)(s=>{i(s==="root"?[]:u.current.slice(0,-1))},[i]),v=(0,I.useCallback)((s,m)=>{let p=u.current.slice(),{id:x}=p[p.length-1];for(;p.length>1&&!m.startsWith(x);){let P=se(x);p.pop(),a.current[x]="no-popup",a.current[P]="no-popup",{id:x}=p[p.length-1]}p.length<u.current.length&&i(p)},[i]),g=(0,I.useCallback)((s,m,p)=>{l.current&&clearTimeout(l.current),l.current=window.setTimeout(()=>{console.log(`scheduleOpen timed out opening ${m}`),v(s,m),a.current[s]="popup-open",a.current[m]="no-popup",f(s,m,p)},400)},[v,f]),E=(0,I.useCallback)((s,m,p)=>{console.log(`scheduleClose openMenuId ${s} menuId ${m} itemId ${p}`),a.current[s]="pending-close",d.current=window.setTimeout(()=>{v(m,p)},400)},[v]),T=(0,I.useCallback)(()=>{let{current:s}=u,[m]=s.slice(-1),p=document.getElementById(`${t}-${m.id}`);if(p){let{right:x,bottom:P}=p.getBoundingClientRect(),{clientHeight:S,clientWidth:y}=document.body;if(x>y){let M=s.length>1?Rt(t,s):Et(s,x-y);i(M)}else if(P>S){let M=Lt(s,P-S);i(M)}}},[t,i]),R=(0,I.useMemo)(()=>({onMouseEnter:s=>{let m=he(s.target),{menuId:p,itemId:x,isGroup:P,isOpen:S,level:y}=kt(m),M=h.current===y,{current:{[p]:b}}=a;if(h.current=y,b==="no-popup"&&P)a.current[p]="popup-pending",g(p,x,m);else if(b==="popup-pending"&&!P)a.current[p]="no-popup",clearTimeout(l.current),l.current=void 0;else if(b==="popup-pending"&&P)clearTimeout(l.current),g(p,x,m);else if(b==="popup-open"){let[{id:L},{id:C}]=u.current.slice(-2);L===p&&a.current[C]!=="pending-close"&&M?(E(C,p,x),P&&!S&&g(p,x,m)):L===p&&P&&x!==C&&a.current[C]==="pending-close"?g(p,x,m):P?(v(p,x),g(p,x,m)):a.current[C]==="pending-close"&&M||v(p,x)}b==="pending-close"&&(l.current&&(clearTimeout(l.current),l.current=void 0),clearTimeout(d.current),d.current=void 0,a.current[p]="popup-open"),n(s,x)},onClick:s=>{let m=s.target,p=he(m),x=Ge(p);console.log(`list item click [${x}] hasPopup ${p.ariaHasPopup}`),p.ariaHasPopup==="true"?p.ariaExpanded!=="true"&&f(x):e(_(p.id))}}),[v,e,n,f,E,g]);return{closeMenu:w,handleRender:T,listItemProps:R,openMenu:f,openMenus:u.current}};var Ve=require("react"),Ue=({containerClassName:t,isOpen:e,onClose:n})=>{(0,Ve.useEffect)(()=>{let o;return e&&(o=r=>{r.target.closest(`.${t}`)===null&&(n==null||n("root"))},document.body.addEventListener("click",o,!0)),()=>{o&&document.body.removeEventListener("click",o,!0)}},[t,e,n])};var j=require("react/jsx-runtime"),Je=require("react"),Dt=()=>{},ie=({activatedByKeyboard:t,children:e,className:n,id:o,onClose:r=()=>{},position:c={x:0,y:0},style:u,...i})=>{let l=(0,ze.useIdMemo)(o),d=(0,G.useRef)(Dt),[a,h]=Ke(e),f=(0,G.useRef)(t),w=(0,G.useCallback)(()=>{f.current=!1},[]),v=(0,G.useCallback)(M=>{let{action:b,options:L}=h[M];d.current("root"),r(b,L)},[h,r]),{closeMenu:g,listItemProps:E,openMenu:T,openMenus:R,handleRender:s}=qe({id:l,onActivate:v,onMouseEnterItem:w,position:c});d.current=g,console.log({openMenus:R});let m=(0,G.useCallback)(()=>{g(),r()},[g,r]);Ue({containerClassName:"vuuMenuList",onClose:m,isOpen:R.length>0});let p=M=>{let b=_(M),L=se(b);f.current=!0,T(L,b)},x=()=>{f.current=!0,g()},P=()=>{},S=R.length-1,y=M=>{if(M>=S)return-1;{let{id:b}=R[M+1],L=b.lastIndexOf(".");return parseInt(L===-1?b:b.slice(-L),10)}};return(0,j.jsx)(j.Fragment,{children:R.map(({id:M,left:b,top:L},C)=>{let $=y(C);return(0,j.jsx)(Y,{x:b,y:L,onRender:s,children:(0,Je.createElement)(Fe,{...i,activatedByKeyboard:f.current,childMenuShowing:$,className:n,id:l,menuId:M,isRoot:C===0,key:C,listItemProps:E,onActivate:v,onHighlightMenuItem:P,onCloseMenu:x,onOpenMenu:p,style:u},a[M])},C)})})};ie.displayName="ContextMenu";var z=require("react"),ue=require("react/jsx-runtime"),ee=(0,z.createContext)(null),xe=t=>t!==void 0&&"children"in t,At=({children:t,context:e,menuActionHandler:n,menuBuilder:o})=>{let r=(0,z.useMemo)(()=>e!=null&&e.menuBuilders&&o?e.menuBuilders.concat(o):o?[o]:(e==null?void 0:e.menuBuilders)||[],[e,o]),c=(0,z.useCallback)((u,i)=>{var l;if(n!=null&&n(u,i)||(l=e==null?void 0:e.menuActionHandler)!=null&&l.call(e,u,i))return!0},[e,n]);return(0,ue.jsx)(ee.Provider,{value:{menuActionHandler:c,menuBuilders:r},children:t})},St=({children:t,label:e,menuActionHandler:n,menuBuilder:o})=>(0,ue.jsx)(ee.Consumer,{children:r=>(0,ue.jsx)(At,{context:r,label:e,menuActionHandler:n,menuBuilder:o,children:t})});var ne=require("react");var Qe=K(require("classnames")),A=K(require("react")),J=K(require("react-dom"));var W=!1,k=[];function ce(t){if(t.key==="Esc"){if(k.length)Ye();else if(W){let e=document.body.querySelector(".vuuDialog");e&&J.default.unmountComponentAtNode(e)}}}function Xe(t){if(k.length){let e=document.body.querySelectorAll(".vuuPopup");for(let n=0;n<e.length;n++)if(e[n].contains(t.target))return;Ye()}}function Ye(){if(k.length){let t=document.body.querySelectorAll(".vuuPopup");for(let e=0;e<t.length;e++)J.default.unmountComponentAtNode(t[e]);Ze("*")}}function $t(){W===!1&&(W=!0,window.addEventListener("keydown",ce,!0))}function Kt(){W&&(W=!1,window.removeEventListener("keydown",ce,!0))}function Nt(t){k.indexOf(t)===-1&&(k.push(t),W===!1&&(window.addEventListener("keydown",ce,!0),window.addEventListener("click",Xe,!0)))}function Ze(t){if(k.length){if(t==="*")k.length=0;else{let e=k.indexOf(t);e!==-1&&k.splice(e,1)}k.length===0&&W===!1&&(window.removeEventListener("keydown",ce,!0),window.removeEventListener("click",Xe,!0))}}var Bt=({children:t,position:e,style:n})=>{let o=(0,Qe.default)("hwPopup","hwPopupContainer",e);return(0,A.createElement)("div",{className:o,style:n},t)},Ot=1,D=class{static showPopup({name:e="anon",group:n="all",position:o="",left:r=0,right:c="auto",top:u=0,width:i="auto",component:l}){if(!l)throw Error("PopupService showPopup, no component supplied");Nt(e);let d=document.body.querySelector(".vuuPopup."+n);d===null&&(d=document.createElement("div"),d.className="vuuPopup "+n,document.body.appendChild(d));let a={width:i};Q((0,A.createElement)(Bt,{key:Ot++,position:o,style:a},l),d,r,u,()=>{D.keepWithinThePage(d,c)})}static hidePopup(e="anon",n="all"){if(k.indexOf(e)!==-1){Ze(e);let o=document.body.querySelector(`.vuuPopup.${n}`);o&&J.default.unmountComponentAtNode(o)}}static keepWithinThePage(e,n="auto"){let o=e.querySelector(".vuuPopupContainer > *");if(o){let{top:r,left:c,width:u,height:i,right:l}=o.getBoundingClientRect(),d=window.innerWidth,h=window.innerHeight-(r+i);h<0&&(o.style.top=Math.round(r)+h+"px");let f=d-(c+u);if(f<0&&(o.style.left=Math.round(c)+f+"px"),typeof n=="number"&&n!==l){let w=n-l;o.style.left=c+w+"px"}}}},te=class{static showDialog(e){let n=".vuuDialog",o=e.props.onClose;$t(),J.default.render(A.default.cloneElement(e,{container:n,onClose:()=>{te.closeDialog(),o&&o()}}),document.body.querySelector(n))}static closeDialog(){Kt();let e=document.body.querySelector(".vuuDialog");e&&J.default.unmountComponentAtNode(e)}},Ft=t=>{let e=(0,A.useRef)(),n=(0,A.useRef)(null),o=(r,c)=>{let{name:u,group:i,depth:l,width:d}=r,a,h;if(e.current&&(window.clearTimeout(e.current),e.current=void 0),r.close===!0)D.hidePopup(u,i);else{let{position:f,children:w}=r,{left:v,top:g,width:E,bottom:T}=c;f==="below"?(a=v,h=T):f==="above"&&(a=v,h=g),e.current=window.setTimeout(()=>{D.showPopup({name:u,group:i,depth:l,position:f,left:a,top:h,width:d||E,component:w})},10)}};return(0,A.useEffect)(()=>{if(n.current){let r=n.current.parentElement,c=r==null?void 0:r.getBoundingClientRect();c&&o(t,c)}return()=>{D.hidePopup(t.name,t.group)}},[t]),A.default.createElement("div",{className:"popup-proxy",ref:n})};var le=require("react/jsx-runtime"),Gt=t=>{let e=(0,ne.useContext)(ee),n=(0,ne.useCallback)((r,c,u)=>{let i=[];for(let l of r)i=i.concat(l(c,u));return i},[]);return(0,ne.useCallback)((r,c,u)=>{var l;r.stopPropagation(),r.preventDefault();let i=(l=e==null?void 0:e.menuBuilders)!=null?l:t?[t]:void 0;if(Array.isArray(i)&&i.length>0){let d=n(i,c,u);console.log({menuItemDescriptors:d}),d.length&&(e!=null&&e.menuActionHandler)&&(console.log(`showContextMenu ${c}`,{options:u}),Wt(r,d,e.menuActionHandler))}else console.warn("useContextMenu, no menuBuilders configured. These should be supplied via the ContextMenuProvider(s)")},[n,e==null?void 0:e.menuActionHandler,e==null?void 0:e.menuBuilders,t])},Wt=(t,e,n)=>{let{clientX:o,clientY:r}=t,i=(0,le.jsx)(ie,{onClose:(l,d)=>{l&&(n(l,d),D.hidePopup())},position:{x:o,y:r},children:(l=>{let d=(a,h)=>xe(a)?(0,le.jsx)(Z,{label:a.label,children:a.children.map(d)},h):(0,le.jsx)(re,{action:a.action,"data-icon":a.icon,options:a.options,children:a.label},h);return l.map(d)})(e)});D.showPopup({left:0,top:0,component:i})};
2
2
  //# sourceMappingURL=index.js.map
package/cjs/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../packages/vuu-popups/src/index.ts", "../../../packages/vuu-popups/src/dialog/Dialog.tsx", "../../../packages/vuu-popups/src/portal/Portal.tsx", "../../../packages/vuu-popups/src/portal/render-portal.tsx", "../../../packages/vuu-popups/src/portal/portal-utils.ts", "../../../packages/vuu-popups/src/menu/ContextMenu.tsx", "../../../packages/vuu-popups/src/menu/MenuList.tsx", "../../../packages/vuu-popups/src/menu/use-keyboard-navigation.ts", "../../../packages/vuu-popups/src/menu/utils.ts", "../../../packages/vuu-popups/src/menu/key-code.ts", "../../../packages/vuu-popups/src/menu/use-items-with-ids.ts", "../../../packages/vuu-popups/src/menu/use-cascade.ts", "../../../packages/vuu-popups/src/menu/list-dom-utils.ts", "../../../packages/vuu-popups/src/menu/use-click-away.ts", "../../../packages/vuu-popups/src/menu/context-menu-provider.tsx", "../../../packages/vuu-popups/src/menu/useContextMenu.tsx", "../../../packages/vuu-popups/src/popup/popup-service.ts"],
4
- "sourcesContent": ["export * from \"./dialog\";\nexport * from \"./menu\";\nexport * from \"./popup\";\nexport * from \"./portal\";\n", "import { Scrim, Toolbar, ToolbarButton } from \"@heswell/salt-lab\";\nimport { Text } from \"@salt-ds/core\";\nimport cx from \"classnames\";\nimport { HTMLAttributes, useCallback, useRef, useState } from \"react\";\nimport { Portal } from \"../portal\";\n\nimport \"./Dialog.css\";\n\nconst classBase = \"vuuDialog\";\n\nexport interface DialogProps extends HTMLAttributes<HTMLDivElement> {\n isOpen?: boolean;\n onClose?: () => void;\n}\n\nexport const Dialog = ({\n children,\n className,\n isOpen = false,\n onClose,\n title,\n ...props\n}: DialogProps) => {\n const root = useRef<HTMLDivElement>(null);\n const [posX] = useState(0);\n const [posY] = useState(0);\n\n const close = useCallback(() => {\n onClose?.();\n }, [onClose]);\n\n const handleRender = useCallback(() => {\n // if (center && isOpen && root.current) {\n // const { width, height } = root.current.getBoundingClientRect();\n // const { innerWidth, innerHeight } = window;\n // const x = innerWidth / 2 - width / 2;\n // const y = innerHeight / 2 - height / 2;\n // setPosX(x);\n // setPosY(y);\n // }\n }, []);\n\n if (!isOpen) {\n return null;\n }\n\n return (\n <Portal onRender={handleRender} x={posX} y={posY}>\n <Scrim className={`${classBase}-scrim`} open={isOpen}>\n <div {...props} className={cx(classBase, className)} ref={root}>\n <Toolbar className={`${classBase}-header`}>\n <Text>{title}</Text>\n <ToolbarButton\n key=\"close\"\n onClick={close}\n data-align-end\n data-icon=\"close\"\n />\n </Toolbar>\n {children}\n </div>\n </Scrim>\n </Portal>\n );\n};\n", "import { ReactElement, useLayoutEffect, useMemo } from \"react\";\nimport * as ReactDOM from \"react-dom\";\nimport { createContainer, renderPortal } from \"./render-portal\";\n\nexport interface PortalProps {\n children: ReactElement;\n onRender?: () => void;\n x?: number;\n y?: number;\n}\n\nexport const Portal = function Portal({\n children,\n x = 0,\n y = 0,\n onRender,\n}: PortalProps) {\n // Do we need to accept container here as a prop ?\n const renderContainer = useMemo(() => {\n return createContainer();\n }, []);\n\n useLayoutEffect(() => {\n renderPortal(children, renderContainer, x, y, onRender);\n }, [children, onRender, renderContainer, x, y]);\n\n useLayoutEffect(() => {\n return () => {\n if (renderContainer) {\n ReactDOM.unmountComponentAtNode(renderContainer);\n if (renderContainer.classList.contains(\"vuuPopup\")) {\n renderContainer.parentElement?.removeChild(renderContainer);\n }\n }\n };\n }, [renderContainer]);\n\n // useLayoutEffect(() => {\n // renderContainer.current = renderPortal(children, x, y, container)\n // return () => {\n // if (renderContainer.current){\n // console.log('EXPLICIT UNMOUNT')\n // ReactDOM.unmountComponentAtNode(renderContainer.current);\n // if (renderContainer.current.classList.contains('hwReactPopup')){\n // renderContainer.current.parentElement.removeChild(renderContainer.current);\n // renderContainer.current = null;\n // }\n // }\n // }\n // },[])\n return null;\n};\n", "import * as ReactDOM from \"react-dom\";\nimport { SaltProvider } from \"@salt-ds/core\";\nimport { ReactElement } from \"react\";\n\nlet containerId = 1;\n\nconst getPortalContainer = (x = 0, y = 0, win = window) => {\n const el = win.document.createElement(\"div\");\n el.className = \"vuuPopup \" + containerId++;\n el.style.cssText = `left:${x}px; top:${y}px;`;\n win.document.body.appendChild(el);\n return el;\n};\n\nconst createDOMContainer = (x?: number, y?: number) => getPortalContainer(x, y);\n\nexport const renderPortal = (\n component: ReactElement,\n container: HTMLElement,\n x: number,\n y: number,\n onRender?: () => void\n) => {\n // check this first to see if position has changed\n container.style.cssText = `left:${x}px; top:${y}px;position: absolute;`;\n\n ReactDOM.render(\n <SaltProvider applyClassesTo=\"child\">{component}</SaltProvider>,\n container,\n onRender\n );\n};\n\nexport const createContainer = createDOMContainer;\n", "export const installTheme = (themeId: string) => {\n const installedThemes = getComputedStyle(document.body).getPropertyValue(\n \"--installed-themes\"\n );\n document.body.style.setProperty(\n \"--installed-themes\",\n `${installedThemes} ${themeId}`\n );\n};\n", "import { useIdMemo as useId } from \"@salt-ds/core\";\nimport { useCallback, useRef } from \"react\";\nimport { Portal } from \"../portal\";\nimport MenuList, { MenuListProps } from \"./MenuList\";\nimport { getItemId, getMenuId, useCascade } from \"./use-cascade\";\nimport { useClickAway } from \"./use-click-away\";\nimport { useItemsWithIds } from \"./use-items-with-ids\";\n\nexport interface ContextMenuProps extends Omit<MenuListProps, \"onCloseMenu\"> {\n onClose?: (menuId?: string, options?: unknown) => void;\n position?: { x: number; y: number };\n withPortal?: boolean;\n}\n\nconst noop = () => undefined;\n\nexport const ContextMenu = ({\n activatedByKeyboard,\n children: childrenProp,\n className,\n id: idProp,\n onClose = () => undefined,\n position = { x: 0, y: 0 },\n style,\n ...menuListProps\n}: ContextMenuProps) => {\n const id = useId(idProp);\n const closeMenuRef = useRef<(location?: string) => void>(noop);\n const [menus, actions] = useItemsWithIds(childrenProp);\n const navigatingWithKeyboard = useRef(activatedByKeyboard);\n const handleMouseEnterItem = useCallback(() => {\n navigatingWithKeyboard.current = false;\n }, []);\n\n const handleActivate = useCallback(\n (menuId: string) => {\n const { action, options } = actions[menuId];\n closeMenuRef.current(\"root\");\n onClose(action, options);\n },\n [actions, onClose]\n );\n\n const { closeMenu, listItemProps, openMenu, openMenus, handleRender } =\n useCascade({\n id,\n onActivate: handleActivate,\n onMouseEnterItem: handleMouseEnterItem,\n position,\n });\n closeMenuRef.current = closeMenu;\n\n console.log({ openMenus });\n\n const handleClose = useCallback(() => {\n closeMenu();\n onClose();\n }, [closeMenu, onClose]);\n\n useClickAway({\n containerClassName: \"vuuMenuList\",\n onClose: handleClose,\n isOpen: openMenus.length > 0,\n });\n\n const handleOpenMenu = (id: string) => {\n const itemId = getItemId(id);\n const menuId = getMenuId(itemId);\n navigatingWithKeyboard.current = true;\n openMenu(menuId, itemId);\n };\n const handleCloseMenu = () => {\n navigatingWithKeyboard.current = true;\n closeMenu();\n };\n\n const handleHighlightMenuItem = () => {\n // console.log(`highlight ${idx}`);\n };\n\n const lastMenu = openMenus.length - 1;\n\n const getChildMenuIndex = (i: number) => {\n if (i >= lastMenu) {\n return -1;\n } else {\n const { id: menuId } = openMenus[i + 1];\n const pos = menuId.lastIndexOf(\".\");\n const idx =\n pos === -1 ? parseInt(menuId, 10) : parseInt(menuId.slice(-pos), 10);\n return idx;\n }\n };\n\n return (\n <>\n {openMenus.map(({ id: menuId, left, top }, i) => {\n const childMenuIndex = getChildMenuIndex(i);\n\n return (\n <Portal key={i} x={left} y={top} onRender={handleRender}>\n <MenuList\n {...menuListProps}\n activatedByKeyboard={navigatingWithKeyboard.current}\n childMenuShowing={childMenuIndex}\n className={className}\n id={id}\n menuId={menuId}\n isRoot={i === 0}\n key={i}\n listItemProps={listItemProps}\n onActivate={handleActivate}\n onHighlightMenuItem={handleHighlightMenuItem}\n onCloseMenu={handleCloseMenu}\n onOpenMenu={handleOpenMenu}\n style={style}\n >\n {menus[menuId]}\n </MenuList>\n </Portal>\n );\n })}\n </>\n );\n};\n\nContextMenu.displayName = \"ContextMenu\";\n", "import React, {\n FC,\n HTMLAttributes,\n ReactElement,\n useLayoutEffect,\n useMemo,\n useRef,\n} from \"react\";\nimport cx from \"classnames\";\nimport { useIdMemo as useId } from \"@salt-ds/core\";\nimport { useKeyboardNavigation } from \"./use-keyboard-navigation\";\nimport { isMenuItemGroup } from \"./use-items-with-ids\";\n\nimport \"./MenuList.css\";\n\nconst classBase = \"vuuMenuList\";\n\nexport const Separator = () => <li className=\"vuuMenuItem-divider\" />;\n\nexport interface MenuItemGroupProps {\n children: ReactElement<MenuItemProps>[];\n label: string;\n}\n\nexport interface MenuItemProps extends HTMLAttributes<HTMLDivElement> {\n action?: string;\n idx?: number;\n options?: unknown;\n}\n\n// Purely used as markers, props will be extracted\nexport const MenuItemGroup: FC<MenuItemGroupProps> = () => null;\n// eslint-disable-next-line no-unused-vars\nexport const MenuItem = ({ children, idx, ...props }: MenuItemProps) => {\n return <div {...props}>{children}</div>;\n};\n\nconst hasIcon = (child: ReactElement) => child.props[\"data-icon\"];\n\nexport interface MenuListProps extends HTMLAttributes<HTMLDivElement> {\n activatedByKeyboard?: boolean;\n children: ReactElement[];\n childMenuShowing?: number;\n highlightedIdx?: number;\n isRoot?: boolean;\n listItemProps?: Partial<MenuItemProps>;\n menuId?: string;\n onActivate?: (menuId: string) => void;\n onCloseMenu: (idx: number) => void;\n onOpenMenu?: (menuId: string) => void;\n onHighlightMenuItem?: (idx: number) => void;\n}\n\nconst MenuList = ({\n activatedByKeyboard,\n childMenuShowing = -1,\n children,\n className,\n highlightedIdx: highlightedIdxProp,\n id: idProp,\n isRoot,\n listItemProps,\n menuId,\n onHighlightMenuItem,\n onActivate,\n onCloseMenu,\n onOpenMenu,\n ...props\n}: MenuListProps) => {\n const id = useId(idProp);\n const root = useRef<HTMLDivElement>(null);\n\n // The id generation be,ongs in useIttemsWithIds\n const mapIdxToId = useMemo(() => new Map(), []);\n\n const handleOpenMenu = (idx: number) => {\n const el = root.current?.querySelector(`:scope > [data-idx='${idx}']`);\n el?.id && onOpenMenu?.(el.id);\n };\n\n const handleActivate = (idx: number) => {\n const el = root.current?.querySelector(`:scope > [data-idx='${idx}']`);\n el?.id && onActivate?.(el.id);\n };\n\n const { focusVisible, highlightedIndex, listProps } = useKeyboardNavigation({\n count: React.Children.count(children),\n highlightedIndex: highlightedIdxProp,\n onActivate: handleActivate,\n onHighlight: onHighlightMenuItem,\n onOpenMenu: handleOpenMenu,\n onCloseMenu,\n });\n\n const appliedFocusVisible = childMenuShowing == -1 ? focusVisible : -1;\n\n useLayoutEffect(() => {\n if (childMenuShowing === -1 && activatedByKeyboard) {\n root.current?.focus();\n }\n }, [activatedByKeyboard, childMenuShowing]);\n\n const getActiveDescendant = () =>\n highlightedIndex === undefined || highlightedIndex === -1\n ? undefined\n : mapIdxToId.get(highlightedIndex);\n\n return (\n <div\n {...props}\n {...listProps}\n aria-activedescendant={getActiveDescendant()}\n className={cx(classBase, className, {\n [`${classBase}-childMenuShowing`]: childMenuShowing !== -1,\n })}\n data-root={isRoot || undefined}\n id={`${id}-${menuId}`}\n ref={root}\n role=\"menu\"\n tabIndex={0}\n >\n {renderContent()}\n </div>\n );\n\n function renderContent() {\n const propsCommonToAllListItems = {\n ...listItemProps,\n role: \"menuitem\",\n };\n\n const maybeIcon = (\n childElement: ReactElement,\n withIcon: boolean,\n iconName?: string\n ) =>\n withIcon\n ? [\n <span\n className=\"vuuIconContainer\"\n data-icon={iconName}\n key=\"icon\"\n />,\n ].concat(childElement)\n : childElement;\n\n function addClonedChild(\n list: ReactElement[],\n child: ReactElement,\n idx: number,\n withIcon: boolean\n ) {\n const {\n children,\n className,\n \"data-icon\": iconName,\n id: itemId,\n hasSeparator,\n label,\n ...props\n } = child.props;\n const hasSubMenu = isMenuItemGroup(child);\n const subMenuShowing = hasSubMenu && childMenuShowing === idx;\n const ariaControls = subMenuShowing ? `${id}-${itemId}` : undefined;\n\n list.push(\n <MenuItem\n {...props}\n {...propsCommonToAllListItems}\n {...getMenuItemProps(\n `${id}-${menuId}`,\n itemId,\n idx,\n child.key ?? itemId,\n highlightedIndex,\n appliedFocusVisible,\n className,\n hasSeparator\n )}\n aria-controls={ariaControls}\n aria-haspopup={hasSubMenu || undefined}\n aria-expanded={subMenuShowing || undefined}\n >\n {hasSubMenu\n ? maybeIcon(label, withIcon, iconName)\n : maybeIcon(children, withIcon, iconName)}\n </MenuItem>\n );\n // mapIdxToId.set(idx, itemId);\n }\n\n const listItems: ReactElement[] = [];\n\n if (children.length > 0) {\n const withIcon = children.some(hasIcon);\n\n children.forEach((child, idx) => {\n addClonedChild(listItems, child, idx, withIcon);\n });\n }\n\n return listItems;\n }\n};\n\nconst getMenuItemProps = (\n baseId: string,\n itemId: string,\n idx: number,\n key: string,\n highlightedIdx: number,\n focusVisible: number,\n className: string,\n hasSeparator: boolean\n) => ({\n id: `${baseId}-${itemId}`,\n key: key ?? idx,\n \"data-idx\": idx,\n \"data-highlighted\": idx === highlightedIdx || undefined,\n className: cx(\"vuuMenuItem\", className, {\n \"vuuMenuItem-separator\": hasSeparator,\n focusVisible: focusVisible === idx,\n }),\n});\n\nMenuList.displayName = \"MenuList\";\nexport default MenuList;\n", "import {\n FocusEvent,\n KeyboardEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { hasPopup, isRoot } from \"./utils\";\nimport { isNavigationKey } from \"./key-code\";\n\nexport interface KeyboardNavigationProps {\n autoHighlightFirstItem?: boolean;\n count: number;\n highlightedIndex?: number;\n onActivate: (idx: number) => void;\n onHighlight?: (idx: number) => void;\n onCloseMenu: (idx: number) => void;\n onOpenMenu: (idx: number) => void;\n}\n\nexport interface KeyboardHookListProps {\n // onBlur: (evt: FocusEvent) => void;\n onFocus: (evt: FocusEvent) => void;\n onKeyDown: (evt: KeyboardEvent) => void;\n onMouseDownCapture: () => void;\n onMouseMove: () => void;\n onMouseLeave: () => void;\n}\n\nexport interface NavigationHookResult {\n focusVisible: number;\n controlledHighlighting: boolean;\n highlightedIndex: number;\n setHighlightedIndex: (idx: number) => void;\n // keyboardNavigation: RefObject<boolean>;\n listProps: KeyboardHookListProps;\n setIgnoreFocus: (ignoreFocus: boolean) => void;\n}\n\n// we need a way to set highlightedIdx when selection changes\nexport const useKeyboardNavigation = ({\n autoHighlightFirstItem = false,\n count,\n highlightedIndex: highlightedIndexProp,\n onActivate,\n onHighlight,\n // onKeyDown,\n onCloseMenu,\n onOpenMenu,\n}: KeyboardNavigationProps): NavigationHookResult => {\n // const prevCount = useRef(count);\n const highlightedIndexRef = useRef(\n highlightedIndexProp ?? autoHighlightFirstItem ? 0 : -1\n );\n const [, forceRender] = useState<unknown>(null);\n const controlledHighlighting = highlightedIndexProp !== undefined;\n\n // count will not work for this, as it will change when we expand collapse groups\n // if (count !== prevCount.current) {\n // prevCount.current = count;\n // if (highlightedIndexRef.current !== -1){\n // highlightedIndexRef.current = autoHighlightFirstItem ? 0 : -1;\n // }\n // }\n\n const setHighlightedIdx = useCallback(\n (idx) => {\n highlightedIndexRef.current = idx;\n onHighlight?.(idx);\n forceRender({});\n },\n [onHighlight]\n );\n\n const setHighlightedIndex = useCallback(\n (idx) => {\n if (idx !== highlightedIndexRef.current) {\n if (!controlledHighlighting) {\n setHighlightedIdx(idx);\n }\n }\n },\n [controlledHighlighting, setHighlightedIdx]\n );\n\n // does this belong here or should it be a method passed in?\n const keyBoardNavigation = useRef(true);\n const ignoreFocus = useRef(false);\n const setIgnoreFocus = (value: boolean) => (ignoreFocus.current = value);\n\n const highlightedIndex = controlledHighlighting\n ? highlightedIndexProp\n : highlightedIndexRef.current;\n\n const navigateChildldItems = useCallback(\n (e: KeyboardEvent) => {\n const nextIdx = nextItemIdx(count, e.key, highlightedIndexRef.current);\n if (nextIdx !== highlightedIndexRef.current) {\n setHighlightedIndex(nextIdx);\n }\n },\n [count, setHighlightedIndex]\n );\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (isNavigationKey(e)) {\n e.preventDefault();\n e.stopPropagation();\n keyBoardNavigation.current = true;\n navigateChildldItems(e);\n } else if (\n (e.key === \"ArrowRight\" || e.key === \"Enter\") &&\n hasPopup(e.target as HTMLElement, highlightedIndex)\n ) {\n onOpenMenu(highlightedIndex);\n } else if (e.key === \"ArrowLeft\" && !isRoot(e.target as HTMLElement)) {\n onCloseMenu(highlightedIndex);\n } else if (e.key === \"Enter\") {\n onActivate && onActivate(highlightedIndex);\n }\n },\n [\n highlightedIndex,\n navigateChildldItems,\n onActivate,\n onCloseMenu,\n onOpenMenu,\n ]\n );\n\n const listProps: KeyboardHookListProps = useMemo(\n () => ({\n onFocus: () => {\n if (highlightedIndex === -1) {\n setHighlightedIdx(0);\n }\n },\n onKeyDown: handleKeyDown,\n onMouseDownCapture: () => {\n keyBoardNavigation.current = false;\n setIgnoreFocus(true);\n },\n\n // onMouseEnter would seem less expensive but it misses some cases\n onMouseMove: () => {\n if (keyBoardNavigation.current) {\n keyBoardNavigation.current = false;\n }\n },\n onMouseLeave: () => {\n // label === 'ParsedInput' && console.log(`%c[useKeyboardNavigationHook]<${label}> onMouseLeave`,'color:brown')\n keyBoardNavigation.current = true;\n setIgnoreFocus(false);\n setHighlightedIndex(-1);\n },\n }),\n [\n highlightedIndex,\n setHighlightedIndex,\n navigateChildldItems,\n onActivate,\n onCloseMenu,\n onOpenMenu,\n setHighlightedIdx,\n ]\n );\n\n // label === 'ParsedInput' && console.log(`%cuseNavigationHook<${label}>\n // highlightedIdxProp= ${highlightedIdxProp},\n // highlightedIndexRef= ${highlightedIndexRef.current},\n // %chighlightedIdx= ${highlightedIdx}`, 'color: brown','color: brown;font-weight: bold;')\n\n return {\n focusVisible: keyBoardNavigation.current ? highlightedIndex : -1,\n controlledHighlighting,\n highlightedIndex,\n setHighlightedIndex: setHighlightedIndex,\n // keyBoardNavigation,\n listProps,\n setIgnoreFocus,\n };\n};\n\n// need to be able to accommodate disabled items\nfunction nextItemIdx(count: number, key: string, idx: number) {\n if (key === \"ArrowUp\") {\n if (idx > 0) {\n return idx - 1;\n } else {\n return idx;\n }\n } else {\n if (idx === null) {\n return 0;\n } else if (idx === count - 1) {\n return idx;\n } else {\n return idx + 1;\n }\n }\n}\n", "export const isRoot = (el: HTMLElement) =>\n el.closest(`[data-root='true']`) !== null;\n\nexport const hasPopup = (el: HTMLElement, idx: number) =>\n (el.ariaHasPopup === \"true\" && el.dataset?.idx === `${idx}`) ||\n el.querySelector(`:scope > [data-idx='${idx}'][aria-haspopup='true']`) !==\n null;\n", "function union(set1: Set<string>, ...sets: Set<string>[]) {\n const result = new Set(set1);\n for (const set of sets) {\n for (const element of set) {\n result.add(element);\n }\n }\n return result;\n}\n\nexport const ArrowUp = \"ArrowUp\";\nexport const ArrowDown = \"ArrowDown\";\nexport const ArrowLeft = \"ArrowLeft\";\nexport const Backspace = \"Backspace\";\nexport const ArrowRight = \"ArrowRight\";\nexport const Enter = \"Enter\";\nexport const Escape = \"Escape\";\nexport const Delete = \"Delete\";\n\nconst actionKeys = new Set([Enter, Delete]);\nconst focusKeys = new Set([\"Tab\"]);\n// const navigationKeys = new Set([\"Home\", \"End\", \"ArrowRight\", \"ArrowLeft\",\"ArrowDown\", \"ArrowUp\"]);\nconst arrowLeftRightKeys = new Set([\"ArrowRight\", \"ArrowLeft\"]);\nconst verticalNavigationKeys = new Set([\"Home\", \"End\", \"ArrowDown\", \"ArrowUp\"]);\nconst horizontalNavigationKeys = new Set([\n \"Home\",\n \"End\",\n \"ArrowRight\",\n \"ArrowLeft\",\n]);\nconst functionKeys = new Set([\n \"F1\",\n \"F2\",\n \"F3\",\n \"F4\",\n \"F5\",\n \"F6\",\n \"F7\",\n \"F8\",\n \"F9\",\n \"F10\",\n \"F11\",\n \"F12\",\n]);\nconst specialKeys = union(\n actionKeys,\n horizontalNavigationKeys,\n verticalNavigationKeys,\n arrowLeftRightKeys,\n functionKeys,\n focusKeys\n);\nexport const isCharacterKey = (evt: KeyboardEvent) => {\n if (specialKeys.has(evt.key)) {\n return false;\n }\n if (typeof evt.which === \"number\" && evt.which > 0) {\n return !evt.ctrlKey && !evt.metaKey && !evt.altKey && evt.which !== 8;\n }\n};\n\nexport const isNavigationKey = (\n { key }: { key: string },\n orientation = \"vertical\"\n) => {\n const navigationKeys =\n orientation === \"vertical\"\n ? verticalNavigationKeys\n : horizontalNavigationKeys;\n return navigationKeys.has(key);\n};\n", "import React, { ReactElement, useCallback, useMemo } from \"react\";\nimport { MenuItemGroup, Separator } from \"./MenuList\";\n\nexport const isMenuItemGroup = (child: ReactElement) =>\n child.type === MenuItemGroup || !!child.props[\"data-group\"];\n\ntype Menus = { [key: string]: ReactElement[] };\ntype Actions = { [key: string]: { action: string; options?: unknown } };\n\nexport const useItemsWithIds = (\n childrenProp: ReactElement[]\n): [Menus, Actions] => {\n const normalizeChildren = useCallback(() => {\n const collectChildren = (\n children: ReactElement[],\n path = \"root\",\n menus: Menus = {},\n actions: Actions = {}\n ) => {\n const list: ReactElement[] = (menus[path] = []);\n let idx = 0;\n let hasSeparator = false;\n\n React.Children.forEach(children, (child) => {\n if (child.type === Separator) {\n hasSeparator = true;\n } else {\n const group = isMenuItemGroup(child);\n const childPath = path === \"root\" ? `${idx}` : `${path}.${idx}`;\n const {\n props: { action, options },\n } = child;\n const { childWithId, grandChildren } = assignId(\n child,\n childPath,\n group,\n hasSeparator\n );\n list.push(childWithId);\n if (grandChildren) {\n collectChildren(grandChildren, childPath, menus, actions);\n } else {\n actions[childPath] = { action, options };\n }\n idx += 1;\n hasSeparator = false;\n }\n });\n return [menus, actions];\n };\n\n const assignId = (\n child: ReactElement,\n path: string,\n group: boolean,\n hasSeparator = false\n ) => {\n const {\n props: { children },\n } = child;\n return {\n childWithId: React.cloneElement(child, {\n hasSeparator,\n id: `${path}`,\n key: path,\n children: group ? undefined : children,\n }),\n grandChildren: group ? children : undefined,\n };\n };\n\n return collectChildren(childrenProp);\n }, [childrenProp]);\n\n const [menus, actions] = useMemo(\n () => normalizeChildren(),\n [normalizeChildren]\n );\n\n return [menus, actions] as [Menus, Actions];\n};\n", "import {\n MouseEvent,\n SyntheticEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { closestListItem, listItemIndex } from \"./list-dom-utils\";\nimport { MenuItemProps } from \"./MenuList\";\n// import {mousePosition} from './aim/utils';\n// import {aiming} from './aim/aim';\n\nconst nudge = (\n menus: RuntimeMenuDescriptor[],\n distance: number,\n pos: \"left\" | \"top\"\n) => {\n return menus.map((m, i) =>\n i === menus.length - 1\n ? {\n ...m,\n [pos]: m[pos] - distance,\n }\n : m\n );\n};\nconst nudgeLeft = (menus: RuntimeMenuDescriptor[], distance: number) =>\n nudge(menus, distance, \"left\");\nconst nudgeUp = (menus: RuntimeMenuDescriptor[], distance: number) =>\n nudge(menus, distance, \"top\");\n\nconst flipSides = (id: string, menus: RuntimeMenuDescriptor[]) => {\n const [parentMenu, menu] = menus.slice(-2);\n const el = document.getElementById(`${id}-${menu.id}`);\n if (el === null) {\n throw Error(`useCascade.flipSides element with id ${menu.id} not found`);\n }\n const { width } = el.getBoundingClientRect();\n return menus.map((m) =>\n m === menu\n ? {\n ...m,\n left: parentMenu.left - (width - 2),\n }\n : m\n );\n};\n\n// const closedNode = (el: HTMLElement) =>\n// el.ariaHasPopup === \"true\" && el.ariaExpanded !== \"true\";\nconst getPosition = (el: HTMLElement, openMenus: RuntimeMenuDescriptor[]) => {\n const [{ left, top: menuTop }] = openMenus.slice(-1);\n // const {top, right, bottom, left} = el.getBoundingClientRect();\n // this will not work for MenuList within window, we need the\n // const {offsetLeft: left, offsetTop: menuTop} = el.closest('.vuuMenuList');\n const { offsetWidth: width, offsetTop: top } = el;\n return { left: left + width, top: top + menuTop };\n};\n\nexport type RuntimeMenuDescriptor = {\n id: string;\n left: number;\n top: number;\n};\n\nexport const getItemId = (id: string) => {\n const pos = id.lastIndexOf(\"-\");\n return pos === -1 ? id : id.slice(pos + 1);\n};\n\nexport const getMenuId = (id: string) => {\n const itemId = getItemId(id);\n const pos = itemId.lastIndexOf(\".\");\n return pos > -1 ? itemId.slice(0, pos) : \"root\";\n};\n\nconst getMenuDepth = (id: string) => {\n let count = 0,\n pos = id.indexOf(\".\", 0);\n while (pos !== -1) {\n count += 1;\n pos = id.indexOf(\".\", pos + 1);\n }\n return count;\n};\n\nconst identifyItem = (el: HTMLElement) => ({\n menuId: getMenuId(el.id),\n itemId: getItemId(el.id),\n isGroup: el.ariaHasPopup === \"true\",\n isOpen: el.ariaExpanded === \"true\",\n level: getMenuDepth(el.id),\n});\n\nexport interface CascadeHookProps {\n id: string;\n onActivate: (menuId: string) => void;\n onMouseEnterItem: (evt: MouseEvent, itemId: string) => void;\n position: { x: number; y: number };\n}\n\nexport interface CascadeHooksResult {\n closeMenu: () => void;\n handleRender: () => void;\n listItemProps: Partial<MenuItemProps>;\n openMenu: (menuId?: string, itemId?: string) => void;\n openMenus: RuntimeMenuDescriptor[];\n}\n\ntype MenuStatus = \"no-popup\" | \"popup-open\" | \"pending-close\" | \"popup-pending\";\ntype MenuState = { [key: string]: MenuStatus };\n\nexport const useCascade = ({\n id,\n onActivate,\n onMouseEnterItem,\n position: { x: posX, y: posY },\n}: CascadeHookProps): CascadeHooksResult => {\n const [, forceRefresh] = useState({});\n const openMenus = useRef<RuntimeMenuDescriptor[]>([\n { id: \"root\", left: posX, top: posY },\n ]);\n\n const setOpenMenus = useCallback((menus: RuntimeMenuDescriptor[]) => {\n openMenus.current = menus;\n forceRefresh({});\n }, []);\n\n const menuOpenPendingTimeout = useRef<number | undefined>();\n const menuClosePendingTimeout = useRef<number | undefined>();\n const menuState = useRef<MenuState>({ root: \"no-popup\" });\n const prevLevel = useRef(0);\n\n // const prevAim = useRef({mousePos: null, distance: true});\n\n const openMenu = useCallback(\n (menuId = \"root\", itemId = null, listItemEl = null) => {\n if (menuId === \"root\" && itemId === null) {\n setOpenMenus([{ id: \"root\", left: posX, top: posY }]);\n } else {\n menuState.current[menuId] = \"popup-open\";\n const doc = listItemEl ? listItemEl.ownerDocument : document;\n const el = doc.getElementById(`${id}-${menuId}-${itemId}`);\n const { left, top } = getPosition(el, openMenus.current);\n setOpenMenus(openMenus.current.concat({ id: itemId, left, top }));\n }\n },\n [id, posX, posY, setOpenMenus]\n );\n\n const closeMenu = useCallback(\n (menuId?: string) => {\n if (menuId === \"root\") {\n setOpenMenus([]);\n } else {\n setOpenMenus(openMenus.current.slice(0, -1));\n }\n },\n [setOpenMenus]\n );\n\n const closeMenus = useCallback(\n (menuId, itemId) => {\n const menus = openMenus.current.slice();\n let { id: lastMenuId } = menus[menus.length - 1];\n while (menus.length > 1 && !itemId.startsWith(lastMenuId)) {\n const parentMenuId = getMenuId(lastMenuId);\n menus.pop();\n menuState.current[lastMenuId] = \"no-popup\";\n menuState.current[parentMenuId] = \"no-popup\";\n ({ id: lastMenuId } = menus[menus.length - 1]);\n }\n if (menus.length < openMenus.current.length) {\n setOpenMenus(menus);\n }\n },\n [setOpenMenus]\n );\n\n const scheduleOpen = useCallback(\n (menuId, itemId, listItemEl) => {\n if (menuOpenPendingTimeout.current) {\n clearTimeout(menuOpenPendingTimeout.current);\n }\n menuOpenPendingTimeout.current = window.setTimeout(() => {\n console.log(`scheduleOpen timed out opening ${itemId}`);\n closeMenus(menuId, itemId);\n menuState.current[menuId] = \"popup-open\";\n menuState.current[itemId] = \"no-popup\";\n openMenu(menuId, itemId, listItemEl);\n }, 400);\n },\n [closeMenus, openMenu]\n );\n\n const scheduleClose = useCallback(\n (openMenuId, menuId, itemId) => {\n console.log(\n `scheduleClose openMenuId ${openMenuId} menuId ${menuId} itemId ${itemId}`\n );\n menuState.current[openMenuId] = \"pending-close\";\n menuClosePendingTimeout.current = window.setTimeout(() => {\n closeMenus(menuId, itemId);\n }, 400);\n },\n [closeMenus]\n );\n\n const handleRender = useCallback(() => {\n const { current: menus } = openMenus;\n const [menu] = menus.slice(-1);\n const el = document.getElementById(`${id}-${menu.id}`);\n if (el) {\n const { right, bottom } = el.getBoundingClientRect();\n const { clientHeight, clientWidth } = document.body;\n if (right > clientWidth) {\n const newMenus =\n menus.length > 1\n ? flipSides(id, menus)\n : nudgeLeft(menus, right - clientWidth);\n setOpenMenus(newMenus);\n } else if (bottom > clientHeight) {\n const newMenus = nudgeUp(menus, bottom - clientHeight);\n setOpenMenus(newMenus);\n }\n }\n }, [id, setOpenMenus]);\n\n const listItemProps: Partial<MenuItemProps> = useMemo(\n () => ({\n onMouseEnter: (evt: MouseEvent) => {\n const listItemEl = closestListItem(evt.target as HTMLElement);\n const { menuId, itemId, isGroup, isOpen, level } =\n identifyItem(listItemEl);\n const sameLevel = prevLevel.current === level;\n const {\n current: { [menuId]: state },\n } = menuState;\n prevLevel.current = level;\n\n // console.log(\n // `%conMouseEnter #${menuId}[${itemId}] @${level}\n // isGroup ${isGroup} isOpen ${isOpen}\n // openMenus [${openMenus.current.join(',')}]\n // state='${JSON.stringify(menuState.current)}`,\n // 'color: green; font-weight: bold;'\n // );\n\n if (state === \"no-popup\" && isGroup) {\n // Shouldn;t we always set this ?\n menuState.current[menuId] = \"popup-pending\";\n scheduleOpen(menuId, itemId, listItemEl);\n } else if (state === \"popup-pending\" && !isGroup) {\n menuState.current[menuId] = \"no-popup\";\n clearTimeout(menuOpenPendingTimeout.current);\n menuOpenPendingTimeout.current = undefined;\n } else if (state === \"popup-pending\" && isGroup) {\n clearTimeout(menuOpenPendingTimeout.current);\n scheduleOpen(menuId, itemId, listItemEl);\n } else if (state === \"popup-open\") {\n const [{ id: parentMenuId }, { id: openMenuId }] =\n openMenus.current.slice(-2);\n if (\n parentMenuId === menuId &&\n menuState.current[openMenuId] !== \"pending-close\" &&\n sameLevel\n ) {\n scheduleClose(openMenuId, menuId, itemId);\n if (isGroup && !isOpen) {\n scheduleOpen(menuId, itemId, listItemEl);\n }\n } else if (\n parentMenuId === menuId &&\n isGroup &&\n itemId !== openMenuId &&\n menuState.current[openMenuId] === \"pending-close\"\n ) {\n // if there is already an item queued for opening cancel it\n scheduleOpen(menuId, itemId, listItemEl);\n } else if (isGroup) {\n closeMenus(menuId, itemId);\n scheduleOpen(menuId, itemId, listItemEl);\n } else if (\n !(menuState.current[openMenuId] === \"pending-close\" && sameLevel)\n ) {\n closeMenus(menuId, itemId);\n }\n }\n\n if (state === \"pending-close\") {\n if (menuOpenPendingTimeout.current) {\n clearTimeout(menuOpenPendingTimeout.current);\n menuOpenPendingTimeout.current = undefined;\n }\n clearTimeout(menuClosePendingTimeout.current);\n menuClosePendingTimeout.current = undefined;\n menuState.current[menuId] = \"popup-open\";\n }\n\n onMouseEnterItem(evt, itemId);\n },\n\n onClick: (evt: SyntheticEvent) => {\n const targetElement = evt.target as HTMLElement;\n const listItemEl = closestListItem(targetElement);\n const idx = listItemIndex(listItemEl);\n console.log(\n `list item click [${idx}] hasPopup ${listItemEl.ariaHasPopup}`\n );\n if (listItemEl.ariaHasPopup === \"true\") {\n if (listItemEl.ariaExpanded !== \"true\") {\n openMenu(idx);\n } else {\n // do nothing\n }\n } else {\n onActivate(getItemId(listItemEl.id));\n }\n },\n }),\n [\n closeMenus,\n onActivate,\n\n onMouseEnterItem,\n openMenu,\n scheduleClose,\n scheduleOpen,\n ]\n );\n\n return {\n closeMenu,\n handleRender,\n listItemProps,\n openMenu,\n openMenus: openMenus.current,\n };\n};\n", "// const listItemElement = (listEl: HTMLElement, listItemIdx: number) =>\n// listEl.querySelector(`:scope > [data-idx=\"${listItemIdx}\"]`);\n\nexport function listItemIndex(listItemEl: HTMLElement) {\n if (listItemEl) {\n const idx = listItemEl.dataset.idx;\n if (idx) {\n return parseInt(idx, 10);\n // eslint-disable-next-line no-cond-assign\n } else if (listItemEl.ariaPosInSet) {\n return parseInt(listItemEl.ariaPosInSet, 10) - 1;\n }\n }\n}\n\nconst listItemId = (el: HTMLElement | null | undefined) => el?.id;\n\nexport const closestListItem = (el: HTMLElement | null | undefined) =>\n el?.closest(\"[data-idx],[aria-posinset]\") as HTMLElement;\n\nexport const closestListItemId = (el: HTMLElement) =>\n listItemId(closestListItem(el));\n\nexport const closestListItemIndex = (el: HTMLElement) =>\n listItemIndex(closestListItem(el));\n", "import { useEffect } from \"react\";\n\nexport interface ClickAwayHookProps {\n containerClassName: string;\n isOpen: boolean;\n onClose?: (target: string) => void;\n}\n\nexport const useClickAway = ({\n containerClassName,\n isOpen,\n onClose,\n}: ClickAwayHookProps) => {\n useEffect(() => {\n let clickHandler: (evt: MouseEvent) => void;\n if (isOpen) {\n clickHandler = (evt) => {\n const target = evt.target as HTMLElement;\n const container = target.closest(`.${containerClassName}`);\n if (container === null) {\n onClose?.(\"root\");\n }\n };\n\n document.body.addEventListener(\"click\", clickHandler, true);\n }\n\n return () => {\n if (clickHandler) {\n document.body.removeEventListener(\"click\", clickHandler, true);\n }\n };\n }, [containerClassName, isOpen, onClose]);\n};\n", "import { createContext, ReactNode, useCallback, useMemo } from \"react\";\n\nexport type MenuActionHandler = (\n type: string,\n options: unknown\n) => boolean | undefined;\nexport type MenuBuilder<L = string, O = unknown> = (\n location: L,\n options: O\n) => ContextMenuItemDescriptor[];\n\nexport interface ContextMenuContext {\n menuBuilders: MenuBuilder[];\n menuActionHandler: MenuActionHandler;\n}\n\nexport const ContextMenuContext = createContext<ContextMenuContext | null>(\n null\n);\n\nexport interface ContextMenuItemBase {\n icon?: string;\n label: string;\n location?: string;\n}\n\nexport interface ContextMenuLeafItemDescriptor extends ContextMenuItemBase {\n action: string;\n options?: unknown;\n}\n\nexport interface ContextMenuGroupItemDescriptor extends ContextMenuItemBase {\n children: ContextMenuItemDescriptor[];\n}\n\nexport type ContextMenuItemDescriptor =\n | ContextMenuLeafItemDescriptor\n | ContextMenuGroupItemDescriptor;\n\nexport const isGroupMenuItemDescriptor = (\n menuItem?: ContextMenuItemDescriptor\n): menuItem is ContextMenuGroupItemDescriptor =>\n menuItem !== undefined && \"children\" in menuItem;\n\nexport interface ContextMenuProviderProps {\n children: ReactNode;\n label?: string;\n menuActionHandler?: MenuActionHandler;\n menuBuilder: MenuBuilder;\n}\n\ninterface ProviderProps extends ContextMenuProviderProps {\n context: ContextMenuContext | null;\n}\n\nconst Provider = ({\n children,\n context,\n menuActionHandler,\n menuBuilder,\n}: ProviderProps) => {\n const menuBuilders = useMemo(() => {\n if (context?.menuBuilders && menuBuilder) {\n return context.menuBuilders.concat(menuBuilder);\n } else if (menuBuilder) {\n return [menuBuilder];\n } else {\n return context?.menuBuilders || [];\n }\n }, [context, menuBuilder]);\n\n const handleMenuAction = useCallback(\n (type, options) => {\n if (menuActionHandler?.(type, options)) {\n return true;\n }\n\n if (context?.menuActionHandler?.(type, options)) {\n return true;\n }\n },\n [context, menuActionHandler]\n );\n\n return (\n <ContextMenuContext.Provider\n value={{\n menuActionHandler: handleMenuAction,\n menuBuilders,\n }}\n >\n {children}\n </ContextMenuContext.Provider>\n );\n};\n\n// Need an option for local menu to override higher-level menu, rather than extend\nexport const ContextMenuProvider = ({\n children,\n label,\n menuActionHandler,\n menuBuilder,\n}: ContextMenuProviderProps) => {\n return (\n <ContextMenuContext.Consumer>\n {(parentContext) => (\n <Provider\n context={parentContext}\n label={label}\n menuActionHandler={menuActionHandler}\n menuBuilder={menuBuilder}\n >\n {children}\n </Provider>\n )}\n </ContextMenuContext.Consumer>\n );\n};\n", "// The menuBuilder will always be supplied by the code that will display the local\n// context menu. It will be passed all configured menu descriptors. It is free to\n\nimport { VuuServerMenuOptions } from \"@vuu-ui/vuu-data\";\nimport { MouseEvent, useCallback, useContext } from \"react\";\nimport { PopupService } from \"../popup\";\nimport {\n ContextMenuContext,\n ContextMenuItemDescriptor,\n isGroupMenuItemDescriptor,\n MenuActionHandler,\n MenuBuilder,\n} from \"./context-menu-provider\";\nimport { ContextMenu } from \"./ContextMenu\";\nimport { MenuItem, MenuItemGroup } from \"./MenuList\";\n\n// augment, replace or ignore the existing menu descriptors.\nexport const useContextMenu = () => {\n const ctx = useContext(ContextMenuContext);\n\n const buildMenuOptions = useCallback(\n (menuBuilders: MenuBuilder[], location, options) => {\n let results: ContextMenuItemDescriptor[] = [];\n for (const menuBuilder of menuBuilders) {\n // Maybe we should leave the concatenation to the menuBuilder, then it can control menuItem order\n results = results.concat(menuBuilder(location, options));\n }\n return results;\n },\n []\n );\n\n const handleShowContextMenu = useCallback(\n (e: MouseEvent<HTMLElement>, location: string, options: unknown) => {\n e.stopPropagation();\n e.preventDefault();\n const menuBuilders = ctx?.menuBuilders ?? [];\n const menuItemDescriptors = buildMenuOptions(\n menuBuilders,\n location,\n options\n );\n console.log({\n menuItemDescriptors,\n });\n if (menuItemDescriptors.length && ctx?.menuActionHandler) {\n console.log(`showContextMenu ${location}`, {\n options,\n });\n showContextMenu(e, menuItemDescriptors, ctx.menuActionHandler);\n }\n },\n [buildMenuOptions, ctx]\n );\n\n return handleShowContextMenu;\n};\n\nconst showContextMenu = (\n e: MouseEvent<HTMLElement>,\n menuDescriptors: ContextMenuItemDescriptor[],\n handleContextMenuAction: MenuActionHandler\n) => {\n const { clientX: left, clientY: top } = e;\n const menuItems = (menuDescriptors: ContextMenuItemDescriptor[]) => {\n const fromDescriptor = (menuItem: ContextMenuItemDescriptor, i: number) =>\n isGroupMenuItemDescriptor(menuItem) ? (\n <MenuItemGroup key={i} label={menuItem.label}>\n {menuItem.children.map(fromDescriptor)}\n </MenuItemGroup>\n ) : (\n <MenuItem\n key={i}\n action={menuItem.action}\n data-icon={menuItem.icon}\n options={menuItem.options}\n >\n {menuItem.label}\n </MenuItem>\n );\n\n return menuDescriptors.map(fromDescriptor);\n };\n\n const handleClose = (menuId?: string, options?: unknown) => {\n if (menuId) {\n handleContextMenuAction(menuId, options);\n PopupService.hidePopup();\n }\n };\n\n const component = (\n <ContextMenu onClose={handleClose} position={{ x: left, y: top }}>\n {menuItems(menuDescriptors)}\n </ContextMenu>\n );\n PopupService.showPopup({ left: 0, top: 0, component });\n};\n", "import cx from \"classnames\";\nimport React, {\n createElement,\n CSSProperties,\n HTMLAttributes,\n ReactElement,\n useEffect,\n useRef,\n} from \"react\";\nimport ReactDOM from \"react-dom\";\nimport { renderPortal } from \"../portal\";\n\nimport \"./popup-service.css\";\n\nlet _dialogOpen = false;\nconst _popups: string[] = [];\n\nfunction specialKeyHandler(e: KeyboardEvent) {\n if (e.key === \"Esc\") {\n if (_popups.length) {\n closeAllPopups();\n } else if (_dialogOpen) {\n const dialogRoot = document.body.querySelector(\".vuuDialog\");\n if (dialogRoot) {\n ReactDOM.unmountComponentAtNode(dialogRoot);\n }\n }\n }\n}\n\nfunction outsideClickHandler(e: MouseEvent) {\n if (_popups.length) {\n // onsole.log(`Popup.outsideClickHandler`);\n const popupContainers = document.body.querySelectorAll(\".vuuPopup\");\n for (let i = 0; i < popupContainers.length; i++) {\n if (popupContainers[i].contains(e.target as HTMLElement)) {\n return;\n }\n }\n closeAllPopups();\n }\n}\n\nfunction closeAllPopups() {\n if (_popups.length) {\n // onsole.log(`closeAllPopups`);\n const popupContainers = document.body.querySelectorAll(\".vuuPopup\");\n for (let i = 0; i < popupContainers.length; i++) {\n ReactDOM.unmountComponentAtNode(popupContainers[i]);\n }\n popupClosed(\"*\");\n }\n}\n\nfunction dialogOpened() {\n if (_dialogOpen === false) {\n _dialogOpen = true;\n window.addEventListener(\"keydown\", specialKeyHandler, true);\n }\n}\n\nfunction dialogClosed() {\n if (_dialogOpen) {\n _dialogOpen = false;\n window.removeEventListener(\"keydown\", specialKeyHandler, true);\n }\n}\n\nfunction popupOpened(name: string) {\n if (_popups.indexOf(name) === -1) {\n _popups.push(name);\n //onsole.log('PopupService, popup opened ' + name + ' popups : ' + _popups);\n if (_dialogOpen === false) {\n window.addEventListener(\"keydown\", specialKeyHandler, true);\n window.addEventListener(\"click\", outsideClickHandler, true);\n }\n }\n}\n\nfunction popupClosed(name: string /*, group=null*/) {\n if (_popups.length) {\n if (name === \"*\") {\n _popups.length = 0;\n } else {\n const pos = _popups.indexOf(name);\n if (pos !== -1) {\n _popups.splice(pos, 1);\n }\n }\n //onsole.log('PopupService, popup closed ' + name + ' popups : ' + _popups);\n if (_popups.length === 0 && _dialogOpen === false) {\n window.removeEventListener(\"keydown\", specialKeyHandler, true);\n window.removeEventListener(\"click\", outsideClickHandler, true);\n }\n }\n}\n\nconst PopupComponent = ({\n children,\n position,\n style,\n}: HTMLAttributes<HTMLDivElement> & {\n position?: \"above\" | \"below\" | \"\";\n style?: CSSProperties;\n}) => {\n const className = cx(\"hwPopup\", \"hwPopupContainer\", position);\n return createElement(\"div\", { className, style }, children);\n};\n\nlet incrementingKey = 1;\n\nexport class PopupService {\n static showPopup({\n name = \"anon\",\n group = \"all\",\n position = \"\",\n left = 0,\n right = \"auto\",\n top = 0,\n width = \"auto\",\n component,\n }: {\n depth?: number;\n name?: string;\n group?: string;\n position?: \"above\" | \"below\" | \"\";\n left?: number;\n right?: \"auto\" | number;\n top?: number;\n component: ReactElement;\n width?: number | \"auto\";\n }) {\n if (!component) {\n throw Error(`PopupService showPopup, no component supplied`);\n }\n popupOpened(name);\n let el = document.body.querySelector(\".vuuPopup.\" + group) as HTMLElement;\n if (el === null) {\n el = document.createElement(\"div\") as HTMLElement;\n el.className = \"vuuPopup \" + group;\n document.body.appendChild(el);\n }\n\n const style = { width };\n\n renderPortal(\n createElement(\n PopupComponent,\n { key: incrementingKey++, position, style },\n component\n ),\n el,\n left,\n top,\n () => {\n PopupService.keepWithinThePage(el, right);\n }\n );\n }\n\n static hidePopup(name = \"anon\", group = \"all\") {\n //onsole.log('PopupService.hidePopup name=' + name + ', group=' + group)\n\n if (_popups.indexOf(name) !== -1) {\n popupClosed(name);\n const popupRoot = document.body.querySelector(`.vuuPopup.${group}`);\n if (popupRoot) {\n ReactDOM.unmountComponentAtNode(popupRoot);\n }\n }\n }\n\n static keepWithinThePage(el: HTMLElement, right: number | \"auto\" = \"auto\") {\n const target = el.querySelector(\".vuuPopupContainer > *\") as HTMLElement;\n if (target) {\n const {\n top,\n left,\n width,\n height,\n right: currentRight,\n } = target.getBoundingClientRect();\n\n const w = window.innerWidth;\n const h = window.innerHeight;\n\n const overflowH = h - (top + height);\n if (overflowH < 0) {\n target.style.top = Math.round(top) + overflowH + \"px\";\n }\n\n const overflowW = w - (left + width);\n if (overflowW < 0) {\n target.style.left = Math.round(left) + overflowW + \"px\";\n }\n\n if (typeof right === \"number\" && right !== currentRight) {\n const adjustment = right - currentRight;\n target.style.left = left + adjustment + \"px\";\n }\n }\n }\n}\n\nexport class DialogService {\n static showDialog(dialog: ReactElement) {\n const containerEl = \".vuuDialog\";\n const onClose = dialog.props.onClose;\n\n dialogOpened();\n\n ReactDOM.render(\n React.cloneElement(dialog, {\n container: containerEl,\n onClose: () => {\n DialogService.closeDialog();\n if (onClose) {\n onClose();\n }\n },\n }),\n document.body.querySelector(containerEl)\n );\n }\n\n static closeDialog() {\n dialogClosed();\n const dialogRoot = document.body.querySelector(\".vuuDialog\");\n if (dialogRoot) {\n ReactDOM.unmountComponentAtNode(dialogRoot);\n }\n }\n}\n\nexport interface PopupProps {\n children: ReactElement;\n close?: boolean;\n depth: number;\n group?: string;\n name: string;\n position?: \"above\" | \"below\" | \"\";\n width: number;\n}\n\nexport const Popup = (props: PopupProps) => {\n const pendingTask = useRef<number | undefined>();\n const ref = useRef<HTMLElement>(null);\n\n const show = (props: PopupProps, boundingClientRect: DOMRect) => {\n const { name, group, depth, width } = props;\n let left: number | undefined;\n let top: number | undefined;\n\n if (pendingTask.current) {\n window.clearTimeout(pendingTask.current);\n pendingTask.current = undefined;\n }\n\n if (props.close === true) {\n PopupService.hidePopup(name, group);\n } else {\n const { position, children: component } = props;\n const {\n left: targetLeft,\n top: targetTop,\n width: clientWidth,\n bottom: targetBottom,\n } = boundingClientRect;\n\n if (position === \"below\") {\n left = targetLeft;\n top = targetBottom;\n } else if (position === \"above\") {\n left = targetLeft;\n top = targetTop;\n }\n\n pendingTask.current = window.setTimeout(() => {\n PopupService.showPopup({\n name,\n group,\n depth,\n position,\n left,\n top,\n width: width || clientWidth,\n component,\n });\n }, 10);\n }\n };\n\n useEffect(() => {\n if (ref.current) {\n const el = ref.current.parentElement;\n const boundingClientRect = el?.getBoundingClientRect();\n if (boundingClientRect) {\n show(props, boundingClientRect);\n }\n }\n\n return () => {\n PopupService.hidePopup(props.name, props.group);\n };\n }, [props]);\n\n return React.createElement(\"div\", { className: \"popup-proxy\", ref });\n};\n"],
5
- "mappings": "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",
6
- "names": ["src_exports", "__export", "ContextMenu", "ContextMenuContext", "ContextMenuProvider", "Dialog", "DialogService", "MenuItem", "MenuItemGroup", "Popup", "PopupService", "Portal", "Separator", "createContainer", "installTheme", "isGroupMenuItemDescriptor", "renderPortal", "useContextMenu", "__toCommonJS", "import_salt_lab", "import_core", "import_classnames", "import_react", "import_react", "ReactDOM", "ReactDOM", "import_core", "import_jsx_runtime", "containerId", "getPortalContainer", "x", "y", "win", "el", "createDOMContainer", "renderPortal", "component", "container", "onRender", "createContainer", "Portal", "children", "x", "y", "onRender", "renderContainer", "createContainer", "renderPortal", "_a", "installTheme", "themeId", "installedThemes", "import_jsx_runtime", "classBase", "Dialog", "children", "className", "isOpen", "onClose", "title", "props", "root", "posX", "posY", "close", "handleRender", "Portal", "cx", "import_core", "import_react", "import_react", "import_classnames", "import_core", "import_react", "isRoot", "el", "hasPopup", "idx", "_a", "union", "set1", "sets", "result", "set", "element", "Enter", "Delete", "actionKeys", "Enter", "focusKeys", "arrowLeftRightKeys", "verticalNavigationKeys", "horizontalNavigationKeys", "functionKeys", "specialKeys", "union", "isNavigationKey", "key", "orientation", "verticalNavigationKeys", "horizontalNavigationKeys", "useKeyboardNavigation", "autoHighlightFirstItem", "count", "highlightedIndexProp", "onActivate", "onHighlight", "onCloseMenu", "onOpenMenu", "highlightedIndexRef", "forceRender", "controlledHighlighting", "setHighlightedIdx", "idx", "setHighlightedIndex", "keyBoardNavigation", "ignoreFocus", "setIgnoreFocus", "value", "highlightedIndex", "navigateChildldItems", "e", "nextIdx", "nextItemIdx", "handleKeyDown", "isNavigationKey", "hasPopup", "isRoot", "listProps", "key", "import_react", "isMenuItemGroup", "child", "MenuItemGroup", "useItemsWithIds", "childrenProp", "normalizeChildren", "collectChildren", "children", "path", "menus", "actions", "list", "idx", "hasSeparator", "React", "Separator", "group", "childPath", "action", "options", "childWithId", "grandChildren", "assignId", "import_jsx_runtime", "classBase", "Separator", "MenuItemGroup", "MenuItem", "children", "idx", "props", "hasIcon", "child", "MenuList", "activatedByKeyboard", "childMenuShowing", "className", "highlightedIdxProp", "idProp", "isRoot", "listItemProps", "menuId", "onHighlightMenuItem", "onActivate", "onCloseMenu", "onOpenMenu", "id", "useId", "root", "mapIdxToId", "handleOpenMenu", "_a", "el", "handleActivate", "focusVisible", "highlightedIndex", "listProps", "useKeyboardNavigation", "React", "appliedFocusVisible", "cx", "renderContent", "propsCommonToAllListItems", "maybeIcon", "childElement", "withIcon", "iconName", "addClonedChild", "list", "itemId", "hasSeparator", "label", "hasSubMenu", "isMenuItemGroup", "subMenuShowing", "ariaControls", "getMenuItemProps", "listItems", "baseId", "key", "highlightedIdx", "MenuList_default", "import_react", "listItemIndex", "listItemEl", "idx", "closestListItem", "el", "nudge", "menus", "distance", "pos", "m", "i", "nudgeLeft", "nudgeUp", "flipSides", "id", "parentMenu", "menu", "el", "width", "getPosition", "openMenus", "left", "menuTop", "top", "getItemId", "getMenuId", "itemId", "getMenuDepth", "count", "identifyItem", "useCascade", "onActivate", "onMouseEnterItem", "posX", "posY", "forceRefresh", "setOpenMenus", "menuOpenPendingTimeout", "menuClosePendingTimeout", "menuState", "prevLevel", "openMenu", "menuId", "listItemEl", "closeMenu", "closeMenus", "lastMenuId", "parentMenuId", "scheduleOpen", "scheduleClose", "openMenuId", "handleRender", "right", "bottom", "clientHeight", "clientWidth", "newMenus", "listItemProps", "evt", "closestListItem", "isGroup", "isOpen", "level", "sameLevel", "state", "targetElement", "idx", "listItemIndex", "import_react", "useClickAway", "containerClassName", "isOpen", "onClose", "clickHandler", "evt", "import_jsx_runtime", "import_react", "noop", "ContextMenu", "activatedByKeyboard", "childrenProp", "className", "idProp", "onClose", "position", "style", "menuListProps", "id", "useId", "closeMenuRef", "menus", "actions", "useItemsWithIds", "navigatingWithKeyboard", "handleMouseEnterItem", "handleActivate", "menuId", "action", "options", "closeMenu", "listItemProps", "openMenu", "openMenus", "handleRender", "useCascade", "handleClose", "useClickAway", "handleOpenMenu", "itemId", "getItemId", "getMenuId", "handleCloseMenu", "handleHighlightMenuItem", "lastMenu", "getChildMenuIndex", "i", "pos", "left", "top", "childMenuIndex", "Portal", "MenuList_default", "import_react", "import_jsx_runtime", "ContextMenuContext", "isGroupMenuItemDescriptor", "menuItem", "Provider", "children", "context", "menuActionHandler", "menuBuilder", "menuBuilders", "handleMenuAction", "type", "options", "_a", "ContextMenuProvider", "label", "parentContext", "import_react", "import_classnames", "import_react", "import_react_dom", "_dialogOpen", "_popups", "specialKeyHandler", "closeAllPopups", "dialogRoot", "ReactDOM", "outsideClickHandler", "popupContainers", "i", "popupClosed", "dialogOpened", "dialogClosed", "popupOpened", "name", "pos", "PopupComponent", "children", "position", "style", "className", "cx", "incrementingKey", "PopupService", "group", "left", "right", "top", "width", "component", "el", "renderPortal", "popupRoot", "target", "height", "currentRight", "w", "overflowH", "overflowW", "adjustment", "DialogService", "dialog", "containerEl", "onClose", "React", "Popup", "props", "pendingTask", "ref", "show", "boundingClientRect", "depth", "targetLeft", "targetTop", "clientWidth", "targetBottom", "import_jsx_runtime", "useContextMenu", "ctx", "ContextMenuContext", "buildMenuOptions", "menuBuilders", "location", "options", "results", "menuBuilder", "e", "_a", "menuItemDescriptors", "showContextMenu", "menuDescriptors", "handleContextMenuAction", "left", "top", "component", "ContextMenu", "menuId", "PopupService", "fromDescriptor", "menuItem", "i", "isGroupMenuItemDescriptor", "MenuItemGroup", "MenuItem"]
4
+ "sourcesContent": ["export * from \"./dialog\";\nexport * from \"./menu\";\nexport * from \"./popup\";\nexport * from \"./portal\";\n", "import { Scrim, Toolbar, ToolbarButton } from \"@heswell/salt-lab\";\nimport { Text } from \"@salt-ds/core\";\nimport cx from \"classnames\";\nimport { HTMLAttributes, useCallback, useRef, useState } from \"react\";\nimport { Portal } from \"../portal\";\n\nimport \"./Dialog.css\";\n\nconst classBase = \"vuuDialog\";\n\nexport interface DialogProps extends HTMLAttributes<HTMLDivElement> {\n isOpen?: boolean;\n onClose?: () => void;\n}\n\nexport const Dialog = ({\n children,\n className,\n isOpen = false,\n onClose,\n title,\n ...props\n}: DialogProps) => {\n const root = useRef<HTMLDivElement>(null);\n const [posX] = useState(0);\n const [posY] = useState(0);\n\n const close = useCallback(() => {\n onClose?.();\n }, [onClose]);\n\n const handleRender = useCallback(() => {\n // if (center && isOpen && root.current) {\n // const { width, height } = root.current.getBoundingClientRect();\n // const { innerWidth, innerHeight } = window;\n // const x = innerWidth / 2 - width / 2;\n // const y = innerHeight / 2 - height / 2;\n // setPosX(x);\n // setPosY(y);\n // }\n }, []);\n\n if (!isOpen) {\n return null;\n }\n\n return (\n <Portal onRender={handleRender} x={posX} y={posY}>\n <Scrim className={`${classBase}-scrim`} open={isOpen}>\n <div {...props} className={cx(classBase, className)} ref={root}>\n <Toolbar className={`${classBase}-header`}>\n <Text>{title}</Text>\n <ToolbarButton\n key=\"close\"\n onClick={close}\n data-align-end\n data-icon=\"close\"\n />\n </Toolbar>\n {children}\n </div>\n </Scrim>\n </Portal>\n );\n};\n", "import { ReactElement, useLayoutEffect, useMemo } from \"react\";\nimport * as ReactDOM from \"react-dom\";\nimport { createContainer, renderPortal } from \"./render-portal\";\n\nexport interface PortalProps {\n children: ReactElement;\n onRender?: () => void;\n x?: number;\n y?: number;\n}\n\nexport const Portal = function Portal({\n children,\n x = 0,\n y = 0,\n onRender,\n}: PortalProps) {\n // Do we need to accept container here as a prop ?\n const renderContainer = useMemo(() => {\n return createContainer();\n }, []);\n\n useLayoutEffect(() => {\n renderPortal(children, renderContainer, x, y, onRender);\n }, [children, onRender, renderContainer, x, y]);\n\n useLayoutEffect(() => {\n return () => {\n if (renderContainer) {\n ReactDOM.unmountComponentAtNode(renderContainer);\n if (renderContainer.classList.contains(\"vuuPopup\")) {\n renderContainer.parentElement?.removeChild(renderContainer);\n }\n }\n };\n }, [renderContainer]);\n\n // useLayoutEffect(() => {\n // renderContainer.current = renderPortal(children, x, y, container)\n // return () => {\n // if (renderContainer.current){\n // console.log('EXPLICIT UNMOUNT')\n // ReactDOM.unmountComponentAtNode(renderContainer.current);\n // if (renderContainer.current.classList.contains('hwReactPopup')){\n // renderContainer.current.parentElement.removeChild(renderContainer.current);\n // renderContainer.current = null;\n // }\n // }\n // }\n // },[])\n return null;\n};\n", "import * as ReactDOM from \"react-dom\";\nimport { SaltProvider } from \"@salt-ds/core\";\nimport { ReactElement } from \"react\";\n\nlet containerId = 1;\n\nconst getPortalContainer = (x = 0, y = 0, win = window) => {\n const el = win.document.createElement(\"div\");\n el.className = \"vuuPopup \" + containerId++;\n el.style.cssText = `left:${x}px; top:${y}px;`;\n win.document.body.appendChild(el);\n return el;\n};\n\nconst createDOMContainer = (x?: number, y?: number) => getPortalContainer(x, y);\n\nexport const renderPortal = (\n component: ReactElement,\n container: HTMLElement,\n x: number,\n y: number,\n onRender?: () => void\n) => {\n // check this first to see if position has changed\n container.style.cssText = `left:${x}px; top:${y}px;position: absolute;`;\n\n ReactDOM.render(\n <SaltProvider applyClassesTo=\"child\">{component}</SaltProvider>,\n container,\n onRender\n );\n};\n\nexport const createContainer = createDOMContainer;\n", "export const installTheme = (themeId: string) => {\n const installedThemes = getComputedStyle(document.body).getPropertyValue(\n \"--installed-themes\"\n );\n document.body.style.setProperty(\n \"--installed-themes\",\n `${installedThemes} ${themeId}`\n );\n};\n", "import { useIdMemo as useId } from \"@salt-ds/core\";\nimport { useCallback, useRef } from \"react\";\nimport { Portal } from \"../portal\";\nimport MenuList, { MenuListProps } from \"./MenuList\";\nimport { getItemId, getMenuId, useCascade } from \"./use-cascade\";\nimport { useClickAway } from \"./use-click-away\";\nimport { useItemsWithIds } from \"./use-items-with-ids\";\n\nexport interface ContextMenuProps extends Omit<MenuListProps, \"onCloseMenu\"> {\n onClose?: (menuId?: string, options?: unknown) => void;\n position?: { x: number; y: number };\n withPortal?: boolean;\n}\n\nconst noop = () => undefined;\n\nexport const ContextMenu = ({\n activatedByKeyboard,\n children: childrenProp,\n className,\n id: idProp,\n onClose = () => undefined,\n position = { x: 0, y: 0 },\n style,\n ...menuListProps\n}: ContextMenuProps) => {\n const id = useId(idProp);\n const closeMenuRef = useRef<(location?: string) => void>(noop);\n const [menus, actions] = useItemsWithIds(childrenProp);\n const navigatingWithKeyboard = useRef(activatedByKeyboard);\n const handleMouseEnterItem = useCallback(() => {\n navigatingWithKeyboard.current = false;\n }, []);\n\n const handleActivate = useCallback(\n (menuId: string) => {\n const { action, options } = actions[menuId];\n closeMenuRef.current(\"root\");\n onClose(action, options);\n },\n [actions, onClose]\n );\n\n const { closeMenu, listItemProps, openMenu, openMenus, handleRender } =\n useCascade({\n id,\n onActivate: handleActivate,\n onMouseEnterItem: handleMouseEnterItem,\n position,\n });\n closeMenuRef.current = closeMenu;\n\n console.log({ openMenus });\n\n const handleClose = useCallback(() => {\n closeMenu();\n onClose();\n }, [closeMenu, onClose]);\n\n useClickAway({\n containerClassName: \"vuuMenuList\",\n onClose: handleClose,\n isOpen: openMenus.length > 0,\n });\n\n const handleOpenMenu = (id: string) => {\n const itemId = getItemId(id);\n const menuId = getMenuId(itemId);\n navigatingWithKeyboard.current = true;\n openMenu(menuId, itemId);\n };\n const handleCloseMenu = () => {\n navigatingWithKeyboard.current = true;\n closeMenu();\n };\n\n const handleHighlightMenuItem = () => {\n // console.log(`highlight ${idx}`);\n };\n\n const lastMenu = openMenus.length - 1;\n\n const getChildMenuIndex = (i: number) => {\n if (i >= lastMenu) {\n return -1;\n } else {\n const { id: menuId } = openMenus[i + 1];\n const pos = menuId.lastIndexOf(\".\");\n const idx =\n pos === -1 ? parseInt(menuId, 10) : parseInt(menuId.slice(-pos), 10);\n return idx;\n }\n };\n\n return (\n <>\n {openMenus.map(({ id: menuId, left, top }, i) => {\n const childMenuIndex = getChildMenuIndex(i);\n\n return (\n <Portal key={i} x={left} y={top} onRender={handleRender}>\n <MenuList\n {...menuListProps}\n activatedByKeyboard={navigatingWithKeyboard.current}\n childMenuShowing={childMenuIndex}\n className={className}\n id={id}\n menuId={menuId}\n isRoot={i === 0}\n key={i}\n listItemProps={listItemProps}\n onActivate={handleActivate}\n onHighlightMenuItem={handleHighlightMenuItem}\n onCloseMenu={handleCloseMenu}\n onOpenMenu={handleOpenMenu}\n style={style}\n >\n {menus[menuId]}\n </MenuList>\n </Portal>\n );\n })}\n </>\n );\n};\n\nContextMenu.displayName = \"ContextMenu\";\n", "import React, {\n FC,\n HTMLAttributes,\n ReactElement,\n useLayoutEffect,\n useMemo,\n useRef,\n} from \"react\";\nimport cx from \"classnames\";\nimport { useIdMemo as useId } from \"@salt-ds/core\";\nimport { useKeyboardNavigation } from \"./use-keyboard-navigation\";\nimport { isMenuItemGroup } from \"./use-items-with-ids\";\n\nimport \"./MenuList.css\";\n\nconst classBase = \"vuuMenuList\";\n\nexport const Separator = () => <li className=\"vuuMenuItem-divider\" />;\n\nexport interface MenuItemGroupProps {\n children: ReactElement<MenuItemProps>[];\n label: string;\n}\n\nexport interface MenuItemProps extends HTMLAttributes<HTMLDivElement> {\n action?: string;\n idx?: number;\n options?: unknown;\n}\n\n// Purely used as markers, props will be extracted\nexport const MenuItemGroup: FC<MenuItemGroupProps> = () => null;\n// eslint-disable-next-line no-unused-vars\nexport const MenuItem = ({ children, idx, ...props }: MenuItemProps) => {\n return <div {...props}>{children}</div>;\n};\n\nconst hasIcon = (child: ReactElement) => child.props[\"data-icon\"];\n\nexport interface MenuListProps extends HTMLAttributes<HTMLDivElement> {\n activatedByKeyboard?: boolean;\n children: ReactElement[];\n childMenuShowing?: number;\n highlightedIdx?: number;\n isRoot?: boolean;\n listItemProps?: Partial<MenuItemProps>;\n menuId?: string;\n onActivate?: (menuId: string) => void;\n onCloseMenu: (idx: number) => void;\n onOpenMenu?: (menuId: string) => void;\n onHighlightMenuItem?: (idx: number) => void;\n}\n\nconst MenuList = ({\n activatedByKeyboard,\n childMenuShowing = -1,\n children,\n className,\n highlightedIdx: highlightedIdxProp,\n id: idProp,\n isRoot,\n listItemProps,\n menuId,\n onHighlightMenuItem,\n onActivate,\n onCloseMenu,\n onOpenMenu,\n ...props\n}: MenuListProps) => {\n const id = useId(idProp);\n const root = useRef<HTMLDivElement>(null);\n\n // The id generation be,ongs in useIttemsWithIds\n const mapIdxToId = useMemo(() => new Map(), []);\n\n const handleOpenMenu = (idx: number) => {\n const el = root.current?.querySelector(`:scope > [data-idx='${idx}']`);\n el?.id && onOpenMenu?.(el.id);\n };\n\n const handleActivate = (idx: number) => {\n const el = root.current?.querySelector(`:scope > [data-idx='${idx}']`);\n el?.id && onActivate?.(el.id);\n };\n\n const { focusVisible, highlightedIndex, listProps } = useKeyboardNavigation({\n count: React.Children.count(children),\n highlightedIndex: highlightedIdxProp,\n onActivate: handleActivate,\n onHighlight: onHighlightMenuItem,\n onOpenMenu: handleOpenMenu,\n onCloseMenu,\n });\n\n const appliedFocusVisible = childMenuShowing == -1 ? focusVisible : -1;\n\n useLayoutEffect(() => {\n if (childMenuShowing === -1 && activatedByKeyboard) {\n root.current?.focus();\n }\n }, [activatedByKeyboard, childMenuShowing]);\n\n const getActiveDescendant = () =>\n highlightedIndex === undefined || highlightedIndex === -1\n ? undefined\n : mapIdxToId.get(highlightedIndex);\n\n return (\n <div\n {...props}\n {...listProps}\n aria-activedescendant={getActiveDescendant()}\n className={cx(classBase, className, {\n [`${classBase}-childMenuShowing`]: childMenuShowing !== -1,\n })}\n data-root={isRoot || undefined}\n id={`${id}-${menuId}`}\n ref={root}\n role=\"menu\"\n tabIndex={0}\n >\n {renderContent()}\n </div>\n );\n\n function renderContent() {\n const propsCommonToAllListItems = {\n ...listItemProps,\n role: \"menuitem\",\n };\n\n const maybeIcon = (\n childElement: ReactElement,\n withIcon: boolean,\n iconName?: string\n ) =>\n withIcon\n ? [\n <span\n className=\"vuuIconContainer\"\n data-icon={iconName}\n key=\"icon\"\n />,\n ].concat(childElement)\n : childElement;\n\n function addClonedChild(\n list: ReactElement[],\n child: ReactElement,\n idx: number,\n withIcon: boolean\n ) {\n const {\n children,\n className,\n \"data-icon\": iconName,\n id: itemId,\n hasSeparator,\n label,\n ...props\n } = child.props;\n const hasSubMenu = isMenuItemGroup(child);\n const subMenuShowing = hasSubMenu && childMenuShowing === idx;\n const ariaControls = subMenuShowing ? `${id}-${itemId}` : undefined;\n\n list.push(\n <MenuItem\n {...props}\n {...propsCommonToAllListItems}\n {...getMenuItemProps(\n `${id}-${menuId}`,\n itemId,\n idx,\n child.key ?? itemId,\n highlightedIndex,\n appliedFocusVisible,\n className,\n hasSeparator\n )}\n aria-controls={ariaControls}\n aria-haspopup={hasSubMenu || undefined}\n aria-expanded={subMenuShowing || undefined}\n >\n {hasSubMenu\n ? maybeIcon(label, withIcon, iconName)\n : maybeIcon(children, withIcon, iconName)}\n </MenuItem>\n );\n // mapIdxToId.set(idx, itemId);\n }\n\n const listItems: ReactElement[] = [];\n\n if (children.length > 0) {\n const withIcon = children.some(hasIcon);\n\n children.forEach((child, idx) => {\n addClonedChild(listItems, child, idx, withIcon);\n });\n }\n\n return listItems;\n }\n};\n\nconst getMenuItemProps = (\n baseId: string,\n itemId: string,\n idx: number,\n key: string,\n highlightedIdx: number,\n focusVisible: number,\n className: string,\n hasSeparator: boolean\n) => ({\n id: `${baseId}-${itemId}`,\n key: key ?? idx,\n \"data-idx\": idx,\n \"data-highlighted\": idx === highlightedIdx || undefined,\n className: cx(\"vuuMenuItem\", className, {\n \"vuuMenuItem-separator\": hasSeparator,\n focusVisible: focusVisible === idx,\n }),\n});\n\nMenuList.displayName = \"MenuList\";\nexport default MenuList;\n", "import {\n FocusEvent,\n KeyboardEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { hasPopup, isRoot } from \"./utils\";\nimport { isNavigationKey } from \"./key-code\";\n\nexport interface KeyboardNavigationProps {\n autoHighlightFirstItem?: boolean;\n count: number;\n highlightedIndex?: number;\n onActivate: (idx: number) => void;\n onHighlight?: (idx: number) => void;\n onCloseMenu: (idx: number) => void;\n onOpenMenu: (idx: number) => void;\n}\n\nexport interface KeyboardHookListProps {\n // onBlur: (evt: FocusEvent) => void;\n onFocus: (evt: FocusEvent) => void;\n onKeyDown: (evt: KeyboardEvent) => void;\n onMouseDownCapture: () => void;\n onMouseMove: () => void;\n onMouseLeave: () => void;\n}\n\nexport interface NavigationHookResult {\n focusVisible: number;\n controlledHighlighting: boolean;\n highlightedIndex: number;\n setHighlightedIndex: (idx: number) => void;\n // keyboardNavigation: RefObject<boolean>;\n listProps: KeyboardHookListProps;\n setIgnoreFocus: (ignoreFocus: boolean) => void;\n}\n\n// we need a way to set highlightedIdx when selection changes\nexport const useKeyboardNavigation = ({\n autoHighlightFirstItem = false,\n count,\n highlightedIndex: highlightedIndexProp,\n onActivate,\n onHighlight,\n // onKeyDown,\n onCloseMenu,\n onOpenMenu,\n}: KeyboardNavigationProps): NavigationHookResult => {\n // const prevCount = useRef(count);\n const highlightedIndexRef = useRef(\n highlightedIndexProp ?? autoHighlightFirstItem ? 0 : -1\n );\n const [, forceRender] = useState<unknown>(null);\n const controlledHighlighting = highlightedIndexProp !== undefined;\n\n // count will not work for this, as it will change when we expand collapse groups\n // if (count !== prevCount.current) {\n // prevCount.current = count;\n // if (highlightedIndexRef.current !== -1){\n // highlightedIndexRef.current = autoHighlightFirstItem ? 0 : -1;\n // }\n // }\n\n const setHighlightedIdx = useCallback(\n (idx) => {\n highlightedIndexRef.current = idx;\n onHighlight?.(idx);\n forceRender({});\n },\n [onHighlight]\n );\n\n const setHighlightedIndex = useCallback(\n (idx) => {\n if (idx !== highlightedIndexRef.current) {\n if (!controlledHighlighting) {\n setHighlightedIdx(idx);\n }\n }\n },\n [controlledHighlighting, setHighlightedIdx]\n );\n\n // does this belong here or should it be a method passed in?\n const keyBoardNavigation = useRef(true);\n const ignoreFocus = useRef(false);\n const setIgnoreFocus = (value: boolean) => (ignoreFocus.current = value);\n\n const highlightedIndex = controlledHighlighting\n ? highlightedIndexProp\n : highlightedIndexRef.current;\n\n const navigateChildldItems = useCallback(\n (e: KeyboardEvent) => {\n const nextIdx = nextItemIdx(count, e.key, highlightedIndexRef.current);\n if (nextIdx !== highlightedIndexRef.current) {\n setHighlightedIndex(nextIdx);\n }\n },\n [count, setHighlightedIndex]\n );\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (isNavigationKey(e)) {\n e.preventDefault();\n e.stopPropagation();\n keyBoardNavigation.current = true;\n navigateChildldItems(e);\n } else if (\n (e.key === \"ArrowRight\" || e.key === \"Enter\") &&\n hasPopup(e.target as HTMLElement, highlightedIndex)\n ) {\n onOpenMenu(highlightedIndex);\n } else if (e.key === \"ArrowLeft\" && !isRoot(e.target as HTMLElement)) {\n onCloseMenu(highlightedIndex);\n } else if (e.key === \"Enter\") {\n onActivate && onActivate(highlightedIndex);\n }\n },\n [\n highlightedIndex,\n navigateChildldItems,\n onActivate,\n onCloseMenu,\n onOpenMenu,\n ]\n );\n\n const listProps: KeyboardHookListProps = useMemo(\n () => ({\n onFocus: () => {\n if (highlightedIndex === -1) {\n setHighlightedIdx(0);\n }\n },\n onKeyDown: handleKeyDown,\n onMouseDownCapture: () => {\n keyBoardNavigation.current = false;\n setIgnoreFocus(true);\n },\n\n // onMouseEnter would seem less expensive but it misses some cases\n onMouseMove: () => {\n if (keyBoardNavigation.current) {\n keyBoardNavigation.current = false;\n }\n },\n onMouseLeave: () => {\n // label === 'ParsedInput' && console.log(`%c[useKeyboardNavigationHook]<${label}> onMouseLeave`,'color:brown')\n keyBoardNavigation.current = true;\n setIgnoreFocus(false);\n setHighlightedIndex(-1);\n },\n }),\n [\n highlightedIndex,\n setHighlightedIndex,\n navigateChildldItems,\n onActivate,\n onCloseMenu,\n onOpenMenu,\n setHighlightedIdx,\n ]\n );\n\n // label === 'ParsedInput' && console.log(`%cuseNavigationHook<${label}>\n // highlightedIdxProp= ${highlightedIdxProp},\n // highlightedIndexRef= ${highlightedIndexRef.current},\n // %chighlightedIdx= ${highlightedIdx}`, 'color: brown','color: brown;font-weight: bold;')\n\n return {\n focusVisible: keyBoardNavigation.current ? highlightedIndex : -1,\n controlledHighlighting,\n highlightedIndex,\n setHighlightedIndex: setHighlightedIndex,\n // keyBoardNavigation,\n listProps,\n setIgnoreFocus,\n };\n};\n\n// need to be able to accommodate disabled items\nfunction nextItemIdx(count: number, key: string, idx: number) {\n if (key === \"ArrowUp\") {\n if (idx > 0) {\n return idx - 1;\n } else {\n return idx;\n }\n } else {\n if (idx === null) {\n return 0;\n } else if (idx === count - 1) {\n return idx;\n } else {\n return idx + 1;\n }\n }\n}\n", "export const isRoot = (el: HTMLElement) =>\n el.closest(`[data-root='true']`) !== null;\n\nexport const hasPopup = (el: HTMLElement, idx: number) =>\n (el.ariaHasPopup === \"true\" && el.dataset?.idx === `${idx}`) ||\n el.querySelector(`:scope > [data-idx='${idx}'][aria-haspopup='true']`) !==\n null;\n", "function union(set1: Set<string>, ...sets: Set<string>[]) {\n const result = new Set(set1);\n for (const set of sets) {\n for (const element of set) {\n result.add(element);\n }\n }\n return result;\n}\n\nexport const ArrowUp = \"ArrowUp\";\nexport const ArrowDown = \"ArrowDown\";\nexport const ArrowLeft = \"ArrowLeft\";\nexport const Backspace = \"Backspace\";\nexport const ArrowRight = \"ArrowRight\";\nexport const Enter = \"Enter\";\nexport const Escape = \"Escape\";\nexport const Delete = \"Delete\";\n\nconst actionKeys = new Set([Enter, Delete]);\nconst focusKeys = new Set([\"Tab\"]);\n// const navigationKeys = new Set([\"Home\", \"End\", \"ArrowRight\", \"ArrowLeft\",\"ArrowDown\", \"ArrowUp\"]);\nconst arrowLeftRightKeys = new Set([\"ArrowRight\", \"ArrowLeft\"]);\nconst verticalNavigationKeys = new Set([\"Home\", \"End\", \"ArrowDown\", \"ArrowUp\"]);\nconst horizontalNavigationKeys = new Set([\n \"Home\",\n \"End\",\n \"ArrowRight\",\n \"ArrowLeft\",\n]);\nconst functionKeys = new Set([\n \"F1\",\n \"F2\",\n \"F3\",\n \"F4\",\n \"F5\",\n \"F6\",\n \"F7\",\n \"F8\",\n \"F9\",\n \"F10\",\n \"F11\",\n \"F12\",\n]);\nconst specialKeys = union(\n actionKeys,\n horizontalNavigationKeys,\n verticalNavigationKeys,\n arrowLeftRightKeys,\n functionKeys,\n focusKeys\n);\nexport const isCharacterKey = (evt: KeyboardEvent) => {\n if (specialKeys.has(evt.key)) {\n return false;\n }\n if (typeof evt.which === \"number\" && evt.which > 0) {\n return !evt.ctrlKey && !evt.metaKey && !evt.altKey && evt.which !== 8;\n }\n};\n\nexport const isNavigationKey = (\n { key }: { key: string },\n orientation = \"vertical\"\n) => {\n const navigationKeys =\n orientation === \"vertical\"\n ? verticalNavigationKeys\n : horizontalNavigationKeys;\n return navigationKeys.has(key);\n};\n", "import React, { ReactElement, useCallback, useMemo } from \"react\";\nimport { MenuItemGroup, Separator } from \"./MenuList\";\n\nexport const isMenuItemGroup = (child: ReactElement) =>\n child.type === MenuItemGroup || !!child.props[\"data-group\"];\n\ntype Menus = { [key: string]: ReactElement[] };\ntype Actions = { [key: string]: { action: string; options?: unknown } };\n\nexport const useItemsWithIds = (\n childrenProp: ReactElement[]\n): [Menus, Actions] => {\n const normalizeChildren = useCallback(() => {\n const collectChildren = (\n children: ReactElement[],\n path = \"root\",\n menus: Menus = {},\n actions: Actions = {}\n ) => {\n const list: ReactElement[] = (menus[path] = []);\n let idx = 0;\n let hasSeparator = false;\n\n React.Children.forEach(children, (child) => {\n if (child.type === Separator) {\n hasSeparator = true;\n } else {\n const group = isMenuItemGroup(child);\n const childPath = path === \"root\" ? `${idx}` : `${path}.${idx}`;\n const {\n props: { action, options },\n } = child;\n const { childWithId, grandChildren } = assignId(\n child,\n childPath,\n group,\n hasSeparator\n );\n list.push(childWithId);\n if (grandChildren) {\n collectChildren(grandChildren, childPath, menus, actions);\n } else {\n actions[childPath] = { action, options };\n }\n idx += 1;\n hasSeparator = false;\n }\n });\n return [menus, actions];\n };\n\n const assignId = (\n child: ReactElement,\n path: string,\n group: boolean,\n hasSeparator = false\n ) => {\n const {\n props: { children },\n } = child;\n return {\n childWithId: React.cloneElement(child, {\n hasSeparator,\n id: `${path}`,\n key: path,\n children: group ? undefined : children,\n }),\n grandChildren: group ? children : undefined,\n };\n };\n\n return collectChildren(childrenProp);\n }, [childrenProp]);\n\n const [menus, actions] = useMemo(\n () => normalizeChildren(),\n [normalizeChildren]\n );\n\n return [menus, actions] as [Menus, Actions];\n};\n", "import {\n MouseEvent,\n SyntheticEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { closestListItem, listItemIndex } from \"./list-dom-utils\";\nimport { MenuItemProps } from \"./MenuList\";\n// import {mousePosition} from './aim/utils';\n// import {aiming} from './aim/aim';\n\nconst nudge = (\n menus: RuntimeMenuDescriptor[],\n distance: number,\n pos: \"left\" | \"top\"\n) => {\n return menus.map((m, i) =>\n i === menus.length - 1\n ? {\n ...m,\n [pos]: m[pos] - distance,\n }\n : m\n );\n};\nconst nudgeLeft = (menus: RuntimeMenuDescriptor[], distance: number) =>\n nudge(menus, distance, \"left\");\nconst nudgeUp = (menus: RuntimeMenuDescriptor[], distance: number) =>\n nudge(menus, distance, \"top\");\n\nconst flipSides = (id: string, menus: RuntimeMenuDescriptor[]) => {\n const [parentMenu, menu] = menus.slice(-2);\n const el = document.getElementById(`${id}-${menu.id}`);\n if (el === null) {\n throw Error(`useCascade.flipSides element with id ${menu.id} not found`);\n }\n const { width } = el.getBoundingClientRect();\n return menus.map((m) =>\n m === menu\n ? {\n ...m,\n left: parentMenu.left - (width - 2),\n }\n : m\n );\n};\n\n// const closedNode = (el: HTMLElement) =>\n// el.ariaHasPopup === \"true\" && el.ariaExpanded !== \"true\";\nconst getPosition = (el: HTMLElement, openMenus: RuntimeMenuDescriptor[]) => {\n const [{ left, top: menuTop }] = openMenus.slice(-1);\n // const {top, right, bottom, left} = el.getBoundingClientRect();\n // this will not work for MenuList within window, we need the\n // const {offsetLeft: left, offsetTop: menuTop} = el.closest('.vuuMenuList');\n const { offsetWidth: width, offsetTop: top } = el;\n return { left: left + width, top: top + menuTop };\n};\n\nexport type RuntimeMenuDescriptor = {\n id: string;\n left: number;\n top: number;\n};\n\nexport const getItemId = (id: string) => {\n const pos = id.lastIndexOf(\"-\");\n return pos === -1 ? id : id.slice(pos + 1);\n};\n\nexport const getMenuId = (id: string) => {\n const itemId = getItemId(id);\n const pos = itemId.lastIndexOf(\".\");\n return pos > -1 ? itemId.slice(0, pos) : \"root\";\n};\n\nconst getMenuDepth = (id: string) => {\n let count = 0,\n pos = id.indexOf(\".\", 0);\n while (pos !== -1) {\n count += 1;\n pos = id.indexOf(\".\", pos + 1);\n }\n return count;\n};\n\nconst identifyItem = (el: HTMLElement) => ({\n menuId: getMenuId(el.id),\n itemId: getItemId(el.id),\n isGroup: el.ariaHasPopup === \"true\",\n isOpen: el.ariaExpanded === \"true\",\n level: getMenuDepth(el.id),\n});\n\nexport interface CascadeHookProps {\n id: string;\n onActivate: (menuId: string) => void;\n onMouseEnterItem: (evt: MouseEvent, itemId: string) => void;\n position: { x: number; y: number };\n}\n\nexport interface CascadeHooksResult {\n closeMenu: () => void;\n handleRender: () => void;\n listItemProps: Partial<MenuItemProps>;\n openMenu: (menuId?: string, itemId?: string) => void;\n openMenus: RuntimeMenuDescriptor[];\n}\n\ntype MenuStatus = \"no-popup\" | \"popup-open\" | \"pending-close\" | \"popup-pending\";\ntype MenuState = { [key: string]: MenuStatus };\n\nexport const useCascade = ({\n id,\n onActivate,\n onMouseEnterItem,\n position: { x: posX, y: posY },\n}: CascadeHookProps): CascadeHooksResult => {\n const [, forceRefresh] = useState({});\n const openMenus = useRef<RuntimeMenuDescriptor[]>([\n { id: \"root\", left: posX, top: posY },\n ]);\n\n const setOpenMenus = useCallback((menus: RuntimeMenuDescriptor[]) => {\n openMenus.current = menus;\n forceRefresh({});\n }, []);\n\n const menuOpenPendingTimeout = useRef<number | undefined>();\n const menuClosePendingTimeout = useRef<number | undefined>();\n const menuState = useRef<MenuState>({ root: \"no-popup\" });\n const prevLevel = useRef(0);\n\n // const prevAim = useRef({mousePos: null, distance: true});\n\n const openMenu = useCallback(\n (menuId = \"root\", itemId = null, listItemEl = null) => {\n if (menuId === \"root\" && itemId === null) {\n setOpenMenus([{ id: \"root\", left: posX, top: posY }]);\n } else {\n menuState.current[menuId] = \"popup-open\";\n const doc = listItemEl ? listItemEl.ownerDocument : document;\n const el = doc.getElementById(`${id}-${menuId}-${itemId}`);\n const { left, top } = getPosition(el, openMenus.current);\n setOpenMenus(openMenus.current.concat({ id: itemId, left, top }));\n }\n },\n [id, posX, posY, setOpenMenus]\n );\n\n const closeMenu = useCallback(\n (menuId?: string) => {\n if (menuId === \"root\") {\n setOpenMenus([]);\n } else {\n setOpenMenus(openMenus.current.slice(0, -1));\n }\n },\n [setOpenMenus]\n );\n\n const closeMenus = useCallback(\n (menuId, itemId) => {\n const menus = openMenus.current.slice();\n let { id: lastMenuId } = menus[menus.length - 1];\n while (menus.length > 1 && !itemId.startsWith(lastMenuId)) {\n const parentMenuId = getMenuId(lastMenuId);\n menus.pop();\n menuState.current[lastMenuId] = \"no-popup\";\n menuState.current[parentMenuId] = \"no-popup\";\n ({ id: lastMenuId } = menus[menus.length - 1]);\n }\n if (menus.length < openMenus.current.length) {\n setOpenMenus(menus);\n }\n },\n [setOpenMenus]\n );\n\n const scheduleOpen = useCallback(\n (menuId, itemId, listItemEl) => {\n if (menuOpenPendingTimeout.current) {\n clearTimeout(menuOpenPendingTimeout.current);\n }\n menuOpenPendingTimeout.current = window.setTimeout(() => {\n console.log(`scheduleOpen timed out opening ${itemId}`);\n closeMenus(menuId, itemId);\n menuState.current[menuId] = \"popup-open\";\n menuState.current[itemId] = \"no-popup\";\n openMenu(menuId, itemId, listItemEl);\n }, 400);\n },\n [closeMenus, openMenu]\n );\n\n const scheduleClose = useCallback(\n (openMenuId, menuId, itemId) => {\n console.log(\n `scheduleClose openMenuId ${openMenuId} menuId ${menuId} itemId ${itemId}`\n );\n menuState.current[openMenuId] = \"pending-close\";\n menuClosePendingTimeout.current = window.setTimeout(() => {\n closeMenus(menuId, itemId);\n }, 400);\n },\n [closeMenus]\n );\n\n const handleRender = useCallback(() => {\n const { current: menus } = openMenus;\n const [menu] = menus.slice(-1);\n const el = document.getElementById(`${id}-${menu.id}`);\n if (el) {\n const { right, bottom } = el.getBoundingClientRect();\n const { clientHeight, clientWidth } = document.body;\n if (right > clientWidth) {\n const newMenus =\n menus.length > 1\n ? flipSides(id, menus)\n : nudgeLeft(menus, right - clientWidth);\n setOpenMenus(newMenus);\n } else if (bottom > clientHeight) {\n const newMenus = nudgeUp(menus, bottom - clientHeight);\n setOpenMenus(newMenus);\n }\n }\n }, [id, setOpenMenus]);\n\n const listItemProps: Partial<MenuItemProps> = useMemo(\n () => ({\n onMouseEnter: (evt: MouseEvent) => {\n const listItemEl = closestListItem(evt.target as HTMLElement);\n const { menuId, itemId, isGroup, isOpen, level } =\n identifyItem(listItemEl);\n const sameLevel = prevLevel.current === level;\n const {\n current: { [menuId]: state },\n } = menuState;\n prevLevel.current = level;\n\n // console.log(\n // `%conMouseEnter #${menuId}[${itemId}] @${level}\n // isGroup ${isGroup} isOpen ${isOpen}\n // openMenus [${openMenus.current.join(',')}]\n // state='${JSON.stringify(menuState.current)}`,\n // 'color: green; font-weight: bold;'\n // );\n\n if (state === \"no-popup\" && isGroup) {\n // Shouldn;t we always set this ?\n menuState.current[menuId] = \"popup-pending\";\n scheduleOpen(menuId, itemId, listItemEl);\n } else if (state === \"popup-pending\" && !isGroup) {\n menuState.current[menuId] = \"no-popup\";\n clearTimeout(menuOpenPendingTimeout.current);\n menuOpenPendingTimeout.current = undefined;\n } else if (state === \"popup-pending\" && isGroup) {\n clearTimeout(menuOpenPendingTimeout.current);\n scheduleOpen(menuId, itemId, listItemEl);\n } else if (state === \"popup-open\") {\n const [{ id: parentMenuId }, { id: openMenuId }] =\n openMenus.current.slice(-2);\n if (\n parentMenuId === menuId &&\n menuState.current[openMenuId] !== \"pending-close\" &&\n sameLevel\n ) {\n scheduleClose(openMenuId, menuId, itemId);\n if (isGroup && !isOpen) {\n scheduleOpen(menuId, itemId, listItemEl);\n }\n } else if (\n parentMenuId === menuId &&\n isGroup &&\n itemId !== openMenuId &&\n menuState.current[openMenuId] === \"pending-close\"\n ) {\n // if there is already an item queued for opening cancel it\n scheduleOpen(menuId, itemId, listItemEl);\n } else if (isGroup) {\n closeMenus(menuId, itemId);\n scheduleOpen(menuId, itemId, listItemEl);\n } else if (\n !(menuState.current[openMenuId] === \"pending-close\" && sameLevel)\n ) {\n closeMenus(menuId, itemId);\n }\n }\n\n if (state === \"pending-close\") {\n if (menuOpenPendingTimeout.current) {\n clearTimeout(menuOpenPendingTimeout.current);\n menuOpenPendingTimeout.current = undefined;\n }\n clearTimeout(menuClosePendingTimeout.current);\n menuClosePendingTimeout.current = undefined;\n menuState.current[menuId] = \"popup-open\";\n }\n\n onMouseEnterItem(evt, itemId);\n },\n\n onClick: (evt: SyntheticEvent) => {\n const targetElement = evt.target as HTMLElement;\n const listItemEl = closestListItem(targetElement);\n const idx = listItemIndex(listItemEl);\n console.log(\n `list item click [${idx}] hasPopup ${listItemEl.ariaHasPopup}`\n );\n if (listItemEl.ariaHasPopup === \"true\") {\n if (listItemEl.ariaExpanded !== \"true\") {\n openMenu(idx);\n } else {\n // do nothing\n }\n } else {\n onActivate(getItemId(listItemEl.id));\n }\n },\n }),\n [\n closeMenus,\n onActivate,\n\n onMouseEnterItem,\n openMenu,\n scheduleClose,\n scheduleOpen,\n ]\n );\n\n return {\n closeMenu,\n handleRender,\n listItemProps,\n openMenu,\n openMenus: openMenus.current,\n };\n};\n", "// const listItemElement = (listEl: HTMLElement, listItemIdx: number) =>\n// listEl.querySelector(`:scope > [data-idx=\"${listItemIdx}\"]`);\n\nexport function listItemIndex(listItemEl: HTMLElement) {\n if (listItemEl) {\n const idx = listItemEl.dataset.idx;\n if (idx) {\n return parseInt(idx, 10);\n // eslint-disable-next-line no-cond-assign\n } else if (listItemEl.ariaPosInSet) {\n return parseInt(listItemEl.ariaPosInSet, 10) - 1;\n }\n }\n}\n\nconst listItemId = (el: HTMLElement | null | undefined) => el?.id;\n\nexport const closestListItem = (el: HTMLElement | null | undefined) =>\n el?.closest(\"[data-idx],[aria-posinset]\") as HTMLElement;\n\nexport const closestListItemId = (el: HTMLElement) =>\n listItemId(closestListItem(el));\n\nexport const closestListItemIndex = (el: HTMLElement) =>\n listItemIndex(closestListItem(el));\n", "import { useEffect } from \"react\";\n\nexport interface ClickAwayHookProps {\n containerClassName: string;\n isOpen: boolean;\n onClose?: (target: string) => void;\n}\n\nexport const useClickAway = ({\n containerClassName,\n isOpen,\n onClose,\n}: ClickAwayHookProps) => {\n useEffect(() => {\n let clickHandler: (evt: MouseEvent) => void;\n if (isOpen) {\n clickHandler = (evt) => {\n const target = evt.target as HTMLElement;\n const container = target.closest(`.${containerClassName}`);\n if (container === null) {\n onClose?.(\"root\");\n }\n };\n\n document.body.addEventListener(\"click\", clickHandler, true);\n }\n\n return () => {\n if (clickHandler) {\n document.body.removeEventListener(\"click\", clickHandler, true);\n }\n };\n }, [containerClassName, isOpen, onClose]);\n};\n", "import { createContext, ReactNode, useCallback, useMemo } from \"react\";\n\nexport type MenuActionHandler = (\n type: string,\n options: unknown\n) => boolean | undefined;\nexport type MenuBuilder<L = string, O = unknown> = (\n location: L,\n options: O\n) => ContextMenuItemDescriptor[];\n\nexport interface ContextMenuContext {\n menuBuilders: MenuBuilder[];\n menuActionHandler: MenuActionHandler;\n}\n\nexport const ContextMenuContext = createContext<ContextMenuContext | null>(\n null\n);\n\nexport interface ContextMenuItemBase {\n icon?: string;\n label: string;\n location?: string;\n}\n\nexport interface ContextMenuLeafItemDescriptor extends ContextMenuItemBase {\n action: string;\n options?: unknown;\n}\n\nexport interface ContextMenuGroupItemDescriptor extends ContextMenuItemBase {\n children: ContextMenuItemDescriptor[];\n}\n\nexport type ContextMenuItemDescriptor =\n | ContextMenuLeafItemDescriptor\n | ContextMenuGroupItemDescriptor;\n\nexport const isGroupMenuItemDescriptor = (\n menuItem?: ContextMenuItemDescriptor\n): menuItem is ContextMenuGroupItemDescriptor =>\n menuItem !== undefined && \"children\" in menuItem;\n\nexport interface ContextMenuProviderProps {\n children: ReactNode;\n label?: string;\n menuActionHandler?: MenuActionHandler;\n menuBuilder: MenuBuilder;\n}\n\ninterface ProviderProps extends ContextMenuProviderProps {\n context: ContextMenuContext | null;\n}\n\nconst Provider = ({\n children,\n context,\n menuActionHandler,\n menuBuilder,\n}: ProviderProps) => {\n const menuBuilders = useMemo(() => {\n if (context?.menuBuilders && menuBuilder) {\n return context.menuBuilders.concat(menuBuilder);\n } else if (menuBuilder) {\n return [menuBuilder];\n } else {\n return context?.menuBuilders || [];\n }\n }, [context, menuBuilder]);\n\n const handleMenuAction = useCallback(\n (type, options) => {\n if (menuActionHandler?.(type, options)) {\n return true;\n }\n\n if (context?.menuActionHandler?.(type, options)) {\n return true;\n }\n },\n [context, menuActionHandler]\n );\n\n return (\n <ContextMenuContext.Provider\n value={{\n menuActionHandler: handleMenuAction,\n menuBuilders,\n }}\n >\n {children}\n </ContextMenuContext.Provider>\n );\n};\n\n// Need an option for local menu to override higher-level menu, rather than extend\nexport const ContextMenuProvider = ({\n children,\n label,\n menuActionHandler,\n menuBuilder,\n}: ContextMenuProviderProps) => {\n return (\n <ContextMenuContext.Consumer>\n {(parentContext) => (\n <Provider\n context={parentContext}\n label={label}\n menuActionHandler={menuActionHandler}\n menuBuilder={menuBuilder}\n >\n {children}\n </Provider>\n )}\n </ContextMenuContext.Consumer>\n );\n};\n", "// The menuBuilder will always be supplied by the code that will display the local\n// context menu. It will be passed all configured menu descriptors. It is free to\n\nimport { MouseEvent, useCallback, useContext } from \"react\";\nimport { PopupService } from \"../popup\";\nimport {\n ContextMenuContext,\n ContextMenuItemDescriptor,\n isGroupMenuItemDescriptor,\n MenuActionHandler,\n MenuBuilder,\n} from \"./context-menu-provider\";\nimport { ContextMenu } from \"./ContextMenu\";\nimport { MenuItem, MenuItemGroup } from \"./MenuList\";\n\n// The argument allows a top-level menuBuilder to operate outside the Contect\nexport const useContextMenu = (menuBuilder?: MenuBuilder) => {\n const ctx = useContext(ContextMenuContext);\n\n const buildMenuOptions = useCallback(\n (menuBuilders: MenuBuilder[], location, options) => {\n let results: ContextMenuItemDescriptor[] = [];\n for (const menuBuilder of menuBuilders) {\n // Maybe we should leave the concatenation to the menuBuilder, then it can control menuItem order\n results = results.concat(menuBuilder(location, options));\n }\n return results;\n },\n []\n );\n\n const handleShowContextMenu = useCallback(\n (e: MouseEvent<HTMLElement>, location: string, options: unknown) => {\n e.stopPropagation();\n e.preventDefault();\n const menuBuilders =\n ctx?.menuBuilders ?? (menuBuilder ? [menuBuilder] : undefined);\n if (Array.isArray(menuBuilders) && menuBuilders.length > 0) {\n const menuItemDescriptors = buildMenuOptions(\n menuBuilders,\n location,\n options\n );\n console.log({\n menuItemDescriptors,\n });\n if (menuItemDescriptors.length && ctx?.menuActionHandler) {\n console.log(`showContextMenu ${location}`, {\n options,\n });\n showContextMenu(e, menuItemDescriptors, ctx.menuActionHandler);\n }\n } else {\n console.warn(\n \"useContextMenu, no menuBuilders configured. These should be supplied via the ContextMenuProvider(s)\"\n );\n }\n },\n [buildMenuOptions, ctx?.menuActionHandler, ctx?.menuBuilders, menuBuilder]\n );\n\n return handleShowContextMenu;\n};\n\nconst showContextMenu = (\n e: MouseEvent<HTMLElement>,\n menuDescriptors: ContextMenuItemDescriptor[],\n handleContextMenuAction: MenuActionHandler\n) => {\n const { clientX: left, clientY: top } = e;\n const menuItems = (menuDescriptors: ContextMenuItemDescriptor[]) => {\n const fromDescriptor = (menuItem: ContextMenuItemDescriptor, i: number) =>\n isGroupMenuItemDescriptor(menuItem) ? (\n <MenuItemGroup key={i} label={menuItem.label}>\n {menuItem.children.map(fromDescriptor)}\n </MenuItemGroup>\n ) : (\n <MenuItem\n key={i}\n action={menuItem.action}\n data-icon={menuItem.icon}\n options={menuItem.options}\n >\n {menuItem.label}\n </MenuItem>\n );\n\n return menuDescriptors.map(fromDescriptor);\n };\n\n const handleClose = (menuId?: string, options?: unknown) => {\n if (menuId) {\n handleContextMenuAction(menuId, options);\n PopupService.hidePopup();\n }\n };\n\n const component = (\n <ContextMenu onClose={handleClose} position={{ x: left, y: top }}>\n {menuItems(menuDescriptors)}\n </ContextMenu>\n );\n PopupService.showPopup({ left: 0, top: 0, component });\n};\n", "import cx from \"classnames\";\nimport React, {\n createElement,\n CSSProperties,\n HTMLAttributes,\n ReactElement,\n useEffect,\n useRef,\n} from \"react\";\nimport ReactDOM from \"react-dom\";\nimport { renderPortal } from \"../portal\";\n\nimport \"./popup-service.css\";\n\nlet _dialogOpen = false;\nconst _popups: string[] = [];\n\nfunction specialKeyHandler(e: KeyboardEvent) {\n if (e.key === \"Esc\") {\n if (_popups.length) {\n closeAllPopups();\n } else if (_dialogOpen) {\n const dialogRoot = document.body.querySelector(\".vuuDialog\");\n if (dialogRoot) {\n ReactDOM.unmountComponentAtNode(dialogRoot);\n }\n }\n }\n}\n\nfunction outsideClickHandler(e: MouseEvent) {\n if (_popups.length) {\n // onsole.log(`Popup.outsideClickHandler`);\n const popupContainers = document.body.querySelectorAll(\".vuuPopup\");\n for (let i = 0; i < popupContainers.length; i++) {\n if (popupContainers[i].contains(e.target as HTMLElement)) {\n return;\n }\n }\n closeAllPopups();\n }\n}\n\nfunction closeAllPopups() {\n if (_popups.length) {\n // onsole.log(`closeAllPopups`);\n const popupContainers = document.body.querySelectorAll(\".vuuPopup\");\n for (let i = 0; i < popupContainers.length; i++) {\n ReactDOM.unmountComponentAtNode(popupContainers[i]);\n }\n popupClosed(\"*\");\n }\n}\n\nfunction dialogOpened() {\n if (_dialogOpen === false) {\n _dialogOpen = true;\n window.addEventListener(\"keydown\", specialKeyHandler, true);\n }\n}\n\nfunction dialogClosed() {\n if (_dialogOpen) {\n _dialogOpen = false;\n window.removeEventListener(\"keydown\", specialKeyHandler, true);\n }\n}\n\nfunction popupOpened(name: string) {\n if (_popups.indexOf(name) === -1) {\n _popups.push(name);\n //onsole.log('PopupService, popup opened ' + name + ' popups : ' + _popups);\n if (_dialogOpen === false) {\n window.addEventListener(\"keydown\", specialKeyHandler, true);\n window.addEventListener(\"click\", outsideClickHandler, true);\n }\n }\n}\n\nfunction popupClosed(name: string /*, group=null*/) {\n if (_popups.length) {\n if (name === \"*\") {\n _popups.length = 0;\n } else {\n const pos = _popups.indexOf(name);\n if (pos !== -1) {\n _popups.splice(pos, 1);\n }\n }\n //onsole.log('PopupService, popup closed ' + name + ' popups : ' + _popups);\n if (_popups.length === 0 && _dialogOpen === false) {\n window.removeEventListener(\"keydown\", specialKeyHandler, true);\n window.removeEventListener(\"click\", outsideClickHandler, true);\n }\n }\n}\n\nconst PopupComponent = ({\n children,\n position,\n style,\n}: HTMLAttributes<HTMLDivElement> & {\n position?: \"above\" | \"below\" | \"\";\n style?: CSSProperties;\n}) => {\n const className = cx(\"hwPopup\", \"hwPopupContainer\", position);\n return createElement(\"div\", { className, style }, children);\n};\n\nlet incrementingKey = 1;\n\nexport class PopupService {\n static showPopup({\n name = \"anon\",\n group = \"all\",\n position = \"\",\n left = 0,\n right = \"auto\",\n top = 0,\n width = \"auto\",\n component,\n }: {\n depth?: number;\n name?: string;\n group?: string;\n position?: \"above\" | \"below\" | \"\";\n left?: number;\n right?: \"auto\" | number;\n top?: number;\n component: ReactElement;\n width?: number | \"auto\";\n }) {\n if (!component) {\n throw Error(`PopupService showPopup, no component supplied`);\n }\n popupOpened(name);\n let el = document.body.querySelector(\".vuuPopup.\" + group) as HTMLElement;\n if (el === null) {\n el = document.createElement(\"div\") as HTMLElement;\n el.className = \"vuuPopup \" + group;\n document.body.appendChild(el);\n }\n\n const style = { width };\n\n renderPortal(\n createElement(\n PopupComponent,\n { key: incrementingKey++, position, style },\n component\n ),\n el,\n left,\n top,\n () => {\n PopupService.keepWithinThePage(el, right);\n }\n );\n }\n\n static hidePopup(name = \"anon\", group = \"all\") {\n //onsole.log('PopupService.hidePopup name=' + name + ', group=' + group)\n\n if (_popups.indexOf(name) !== -1) {\n popupClosed(name);\n const popupRoot = document.body.querySelector(`.vuuPopup.${group}`);\n if (popupRoot) {\n ReactDOM.unmountComponentAtNode(popupRoot);\n }\n }\n }\n\n static keepWithinThePage(el: HTMLElement, right: number | \"auto\" = \"auto\") {\n const target = el.querySelector(\".vuuPopupContainer > *\") as HTMLElement;\n if (target) {\n const {\n top,\n left,\n width,\n height,\n right: currentRight,\n } = target.getBoundingClientRect();\n\n const w = window.innerWidth;\n const h = window.innerHeight;\n\n const overflowH = h - (top + height);\n if (overflowH < 0) {\n target.style.top = Math.round(top) + overflowH + \"px\";\n }\n\n const overflowW = w - (left + width);\n if (overflowW < 0) {\n target.style.left = Math.round(left) + overflowW + \"px\";\n }\n\n if (typeof right === \"number\" && right !== currentRight) {\n const adjustment = right - currentRight;\n target.style.left = left + adjustment + \"px\";\n }\n }\n }\n}\n\nexport class DialogService {\n static showDialog(dialog: ReactElement) {\n const containerEl = \".vuuDialog\";\n const onClose = dialog.props.onClose;\n\n dialogOpened();\n\n ReactDOM.render(\n React.cloneElement(dialog, {\n container: containerEl,\n onClose: () => {\n DialogService.closeDialog();\n if (onClose) {\n onClose();\n }\n },\n }),\n document.body.querySelector(containerEl)\n );\n }\n\n static closeDialog() {\n dialogClosed();\n const dialogRoot = document.body.querySelector(\".vuuDialog\");\n if (dialogRoot) {\n ReactDOM.unmountComponentAtNode(dialogRoot);\n }\n }\n}\n\nexport interface PopupProps {\n children: ReactElement;\n close?: boolean;\n depth: number;\n group?: string;\n name: string;\n position?: \"above\" | \"below\" | \"\";\n width: number;\n}\n\nexport const Popup = (props: PopupProps) => {\n const pendingTask = useRef<number | undefined>();\n const ref = useRef<HTMLElement>(null);\n\n const show = (props: PopupProps, boundingClientRect: DOMRect) => {\n const { name, group, depth, width } = props;\n let left: number | undefined;\n let top: number | undefined;\n\n if (pendingTask.current) {\n window.clearTimeout(pendingTask.current);\n pendingTask.current = undefined;\n }\n\n if (props.close === true) {\n PopupService.hidePopup(name, group);\n } else {\n const { position, children: component } = props;\n const {\n left: targetLeft,\n top: targetTop,\n width: clientWidth,\n bottom: targetBottom,\n } = boundingClientRect;\n\n if (position === \"below\") {\n left = targetLeft;\n top = targetBottom;\n } else if (position === \"above\") {\n left = targetLeft;\n top = targetTop;\n }\n\n pendingTask.current = window.setTimeout(() => {\n PopupService.showPopup({\n name,\n group,\n depth,\n position,\n left,\n top,\n width: width || clientWidth,\n component,\n });\n }, 10);\n }\n };\n\n useEffect(() => {\n if (ref.current) {\n const el = ref.current.parentElement;\n const boundingClientRect = el?.getBoundingClientRect();\n if (boundingClientRect) {\n show(props, boundingClientRect);\n }\n }\n\n return () => {\n PopupService.hidePopup(props.name, props.group);\n };\n }, [props]);\n\n return React.createElement(\"div\", { className: \"popup-proxy\", ref });\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["src_exports", "__export", "ContextMenu", "ContextMenuContext", "ContextMenuProvider", "Dialog", "DialogService", "MenuItem", "MenuItemGroup", "Popup", "PopupService", "Portal", "Separator", "createContainer", "installTheme", "isGroupMenuItemDescriptor", "renderPortal", "useContextMenu", "__toCommonJS", "import_salt_lab", "import_core", "import_classnames", "import_react", "import_react", "ReactDOM", "ReactDOM", "import_core", "import_jsx_runtime", "containerId", "getPortalContainer", "x", "y", "win", "el", "createDOMContainer", "renderPortal", "component", "container", "onRender", "createContainer", "Portal", "children", "x", "y", "onRender", "renderContainer", "createContainer", "renderPortal", "_a", "installTheme", "themeId", "installedThemes", "import_jsx_runtime", "classBase", "Dialog", "children", "className", "isOpen", "onClose", "title", "props", "root", "posX", "posY", "close", "handleRender", "Portal", "cx", "import_core", "import_react", "import_react", "import_classnames", "import_core", "import_react", "isRoot", "el", "hasPopup", "idx", "_a", "union", "set1", "sets", "result", "set", "element", "Enter", "Delete", "actionKeys", "Enter", "focusKeys", "arrowLeftRightKeys", "verticalNavigationKeys", "horizontalNavigationKeys", "functionKeys", "specialKeys", "union", "isNavigationKey", "key", "orientation", "verticalNavigationKeys", "horizontalNavigationKeys", "useKeyboardNavigation", "autoHighlightFirstItem", "count", "highlightedIndexProp", "onActivate", "onHighlight", "onCloseMenu", "onOpenMenu", "highlightedIndexRef", "forceRender", "controlledHighlighting", "setHighlightedIdx", "idx", "setHighlightedIndex", "keyBoardNavigation", "ignoreFocus", "setIgnoreFocus", "value", "highlightedIndex", "navigateChildldItems", "e", "nextIdx", "nextItemIdx", "handleKeyDown", "isNavigationKey", "hasPopup", "isRoot", "listProps", "key", "import_react", "isMenuItemGroup", "child", "MenuItemGroup", "useItemsWithIds", "childrenProp", "normalizeChildren", "collectChildren", "children", "path", "menus", "actions", "list", "idx", "hasSeparator", "React", "Separator", "group", "childPath", "action", "options", "childWithId", "grandChildren", "assignId", "import_jsx_runtime", "classBase", "Separator", "MenuItemGroup", "MenuItem", "children", "idx", "props", "hasIcon", "child", "MenuList", "activatedByKeyboard", "childMenuShowing", "className", "highlightedIdxProp", "idProp", "isRoot", "listItemProps", "menuId", "onHighlightMenuItem", "onActivate", "onCloseMenu", "onOpenMenu", "id", "useId", "root", "mapIdxToId", "handleOpenMenu", "_a", "el", "handleActivate", "focusVisible", "highlightedIndex", "listProps", "useKeyboardNavigation", "React", "appliedFocusVisible", "cx", "renderContent", "propsCommonToAllListItems", "maybeIcon", "childElement", "withIcon", "iconName", "addClonedChild", "list", "itemId", "hasSeparator", "label", "hasSubMenu", "isMenuItemGroup", "subMenuShowing", "ariaControls", "getMenuItemProps", "listItems", "baseId", "key", "highlightedIdx", "MenuList_default", "import_react", "listItemIndex", "listItemEl", "idx", "closestListItem", "el", "nudge", "menus", "distance", "pos", "m", "i", "nudgeLeft", "nudgeUp", "flipSides", "id", "parentMenu", "menu", "el", "width", "getPosition", "openMenus", "left", "menuTop", "top", "getItemId", "getMenuId", "itemId", "getMenuDepth", "count", "identifyItem", "useCascade", "onActivate", "onMouseEnterItem", "posX", "posY", "forceRefresh", "setOpenMenus", "menuOpenPendingTimeout", "menuClosePendingTimeout", "menuState", "prevLevel", "openMenu", "menuId", "listItemEl", "closeMenu", "closeMenus", "lastMenuId", "parentMenuId", "scheduleOpen", "scheduleClose", "openMenuId", "handleRender", "right", "bottom", "clientHeight", "clientWidth", "newMenus", "listItemProps", "evt", "closestListItem", "isGroup", "isOpen", "level", "sameLevel", "state", "targetElement", "idx", "listItemIndex", "import_react", "useClickAway", "containerClassName", "isOpen", "onClose", "clickHandler", "evt", "import_jsx_runtime", "import_react", "noop", "ContextMenu", "activatedByKeyboard", "childrenProp", "className", "idProp", "onClose", "position", "style", "menuListProps", "id", "useId", "closeMenuRef", "menus", "actions", "useItemsWithIds", "navigatingWithKeyboard", "handleMouseEnterItem", "handleActivate", "menuId", "action", "options", "closeMenu", "listItemProps", "openMenu", "openMenus", "handleRender", "useCascade", "handleClose", "useClickAway", "handleOpenMenu", "itemId", "getItemId", "getMenuId", "handleCloseMenu", "handleHighlightMenuItem", "lastMenu", "getChildMenuIndex", "i", "pos", "left", "top", "childMenuIndex", "Portal", "MenuList_default", "import_react", "import_jsx_runtime", "ContextMenuContext", "isGroupMenuItemDescriptor", "menuItem", "Provider", "children", "context", "menuActionHandler", "menuBuilder", "menuBuilders", "handleMenuAction", "type", "options", "_a", "ContextMenuProvider", "label", "parentContext", "import_react", "import_classnames", "import_react", "import_react_dom", "_dialogOpen", "_popups", "specialKeyHandler", "e", "closeAllPopups", "dialogRoot", "ReactDOM", "outsideClickHandler", "popupContainers", "i", "popupClosed", "dialogOpened", "dialogClosed", "popupOpened", "name", "pos", "PopupComponent", "children", "position", "style", "className", "cx", "incrementingKey", "PopupService", "group", "left", "right", "top", "width", "component", "el", "renderPortal", "popupRoot", "target", "height", "currentRight", "w", "overflowH", "overflowW", "adjustment", "DialogService", "dialog", "containerEl", "onClose", "React", "Popup", "props", "pendingTask", "ref", "show", "boundingClientRect", "depth", "targetLeft", "targetTop", "clientWidth", "targetBottom", "import_jsx_runtime", "useContextMenu", "menuBuilder", "ctx", "ContextMenuContext", "buildMenuOptions", "menuBuilders", "location", "options", "results", "e", "_a", "menuItemDescriptors", "showContextMenu", "menuDescriptors", "handleContextMenuAction", "left", "top", "component", "ContextMenu", "menuId", "PopupService", "fromDescriptor", "menuItem", "i", "isGroupMenuItemDescriptor", "MenuItemGroup", "MenuItem"]
7
7
  }
package/esm/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import{Scrim as nt,Toolbar as ot,ToolbarButton as rt}from"@heswell/salt-lab";import{Text as st}from"@salt-ds/core";import it from"classnames";import{useCallback as fe,useRef as ut,useState as ge}from"react";import{useLayoutEffect as de,useMemo as tt}from"react";import*as me from"react-dom";import*as ae from"react-dom";import{SaltProvider as Ye}from"@salt-ds/core";import{jsx as et}from"react/jsx-runtime";var Ze=1,_e=(e=0,t=0,n=window)=>{let o=n.document.createElement("div");return o.className="vuuPopup "+Ze++,o.style.cssText=`left:${e}px; top:${t}px;`,n.document.body.appendChild(o),o},je=(e,t)=>_e(e,t),F=(e,t,n,o,r)=>{t.style.cssText=`left:${n}px; top:${o}px;position: absolute;`,ae.render(et(Ye,{applyClassesTo:"child",children:e}),t,r)},pe=je;var G=function({children:t,x:n=0,y:o=0,onRender:r}){let c=tt(()=>pe(),[]);return de(()=>{F(t,c,n,o,r)},[t,r,c,n,o]),de(()=>()=>{var i;c&&(me.unmountComponentAtNode(c),c.classList.contains("vuuPopup")&&((i=c.parentElement)==null||i.removeChild(c)))},[c]),null};var un=e=>{let t=getComputedStyle(document.body).getPropertyValue("--installed-themes");document.body.style.setProperty("--installed-themes",`${t} ${e}`)};import{jsx as W,jsxs as Me}from"react/jsx-runtime";var Z="vuuDialog",In=({children:e,className:t,isOpen:n=!1,onClose:o,title:r,...c})=>{let i=ut(null),[u]=ge(0),[a]=ge(0),d=fe(()=>{o==null||o()},[o]),l=fe(()=>{},[]);return n?W(G,{onRender:l,x:u,y:a,children:W(nt,{className:`${Z}-scrim`,open:n,children:Me("div",{...c,className:it(Z,t),ref:i,children:[Me(ot,{className:`${Z}-header`,children:[W(st,{children:r}),W(rt,{onClick:d,"data-align-end":!0,"data-icon":"close"},"close")]}),e]})})}):null};import{useIdMemo as Kt}from"@salt-ds/core";import{useCallback as ne,useRef as Se}from"react";import vt,{useLayoutEffect as yt,useMemo as It,useRef as Ct}from"react";import Le from"classnames";import{useIdMemo as wt}from"@salt-ds/core";import{useCallback as q,useMemo as gt,useRef as _,useState as Mt}from"react";var he=e=>e.closest("[data-root='true']")!==null,xe=(e,t)=>{var n;return e.ariaHasPopup==="true"&&((n=e.dataset)==null?void 0:n.idx)===`${t}`||e.querySelector(`:scope > [data-idx='${t}'][aria-haspopup='true']`)!==null};function ct(e,...t){let n=new Set(e);for(let o of t)for(let r of o)n.add(r);return n}var lt="Enter";var at="Delete",pt=new Set([lt,at]),dt=new Set(["Tab"]),mt=new Set(["ArrowRight","ArrowLeft"]),be=new Set(["Home","End","ArrowDown","ArrowUp"]),ve=new Set(["Home","End","ArrowRight","ArrowLeft"]),ft=new Set(["F1","F2","F3","F4","F5","F6","F7","F8","F9","F10","F11","F12"]),Rn=ct(pt,ve,be,mt,ft,dt);var ye=({key:e},t="vertical")=>(t==="vertical"?be:ve).has(e);var Ie=({autoHighlightFirstItem:e=!1,count:t,highlightedIndex:n,onActivate:o,onHighlight:r,onCloseMenu:c,onOpenMenu:i})=>{let u=_((n!=null?n:e)?0:-1),[,a]=Mt(null),d=n!==void 0,l=q(s=>{u.current=s,r==null||r(s),a({})},[r]),h=q(s=>{s!==u.current&&(d||l(s))},[d,l]),f=_(!0),C=_(!1),v=s=>C.current=s,g=d?n:u.current,E=q(s=>{let m=ht(t,s.key,u.current);m!==u.current&&h(m)},[t,h]),R=q(s=>{ye(s)?(s.preventDefault(),s.stopPropagation(),f.current=!0,E(s)):(s.key==="ArrowRight"||s.key==="Enter")&&xe(s.target,g)?i(g):s.key==="ArrowLeft"&&!he(s.target)?c(g):s.key==="Enter"&&o&&o(g)},[g,E,o,c,i]),L=gt(()=>({onFocus:()=>{g===-1&&l(0)},onKeyDown:R,onMouseDownCapture:()=>{f.current=!1,v(!0)},onMouseMove:()=>{f.current&&(f.current=!1)},onMouseLeave:()=>{f.current=!0,v(!1),h(-1)}}),[g,h,E,o,c,i,l]);return{focusVisible:f.current?g:-1,controlledHighlighting:d,highlightedIndex:g,setHighlightedIndex:h,listProps:L,setIgnoreFocus:v}};function ht(e,t,n){return t==="ArrowUp"?n>0?n-1:n:n===null?0:n===e-1?n:n+1}import Ce,{useCallback as xt,useMemo as bt}from"react";var j=e=>e.type===V||!!e.props["data-group"],we=e=>{let t=xt(()=>{let r=(i,u="root",a={},d={})=>{let l=a[u]=[],h=0,f=!1;return Ce.Children.forEach(i,C=>{if(C.type===Ee)f=!0;else{let v=j(C),g=u==="root"?`${h}`:`${u}.${h}`,{props:{action:E,options:R}}=C,{childWithId:L,grandChildren:s}=c(C,g,v,f);l.push(L),s?r(s,g,a,d):d[g]={action:E,options:R},h+=1,f=!1}}),[a,d]},c=(i,u,a,d=!1)=>{let{props:{children:l}}=i;return{childWithId:Ce.cloneElement(i,{hasSeparator:d,id:`${u}`,key:u,children:a?void 0:l}),grandChildren:a?l:void 0}};return r(e)},[e]),[n,o]=bt(()=>t(),[t]);return[n,o]};import{jsx as K}from"react/jsx-runtime";var Pe="vuuMenuList",Ee=()=>K("li",{className:"vuuMenuItem-divider"}),V=()=>null,ee=({children:e,idx:t,...n})=>K("div",{...n,children:e}),Et=e=>e.props["data-icon"],Re=({activatedByKeyboard:e,childMenuShowing:t=-1,children:n,className:o,highlightedIdx:r,id:c,isRoot:i,listItemProps:u,menuId:a,onHighlightMenuItem:d,onActivate:l,onCloseMenu:h,onOpenMenu:f,...C})=>{let v=wt(c),g=Ct(null),E=It(()=>new Map,[]),R=y=>{var b;let M=(b=g.current)==null?void 0:b.querySelector(`:scope > [data-idx='${y}']`);M!=null&&M.id&&(f==null||f(M.id))},L=y=>{var b;let M=(b=g.current)==null?void 0:b.querySelector(`:scope > [data-idx='${y}']`);M!=null&&M.id&&(l==null||l(M.id))},{focusVisible:s,highlightedIndex:m,listProps:p}=Ie({count:vt.Children.count(n),highlightedIndex:r,onActivate:L,onHighlight:d,onOpenMenu:R,onCloseMenu:h}),x=t==-1?s:-1;return yt(()=>{var y;t===-1&&e&&((y=g.current)==null||y.focus())},[e,t]),K("div",{...C,...p,"aria-activedescendant":(()=>m===void 0||m===-1?void 0:E.get(m))(),className:Le(Pe,o,{[`${Pe}-childMenuShowing`]:t!==-1}),"data-root":i||void 0,id:`${v}-${a}`,ref:g,role:"menu",tabIndex:0,children:k()});function k(){let y={...u,role:"menuitem"},M=(I,D,$)=>D?[K("span",{className:"vuuIconContainer","data-icon":$},"icon")].concat(I):I;function b(I,D,$,ie){var le;let{children:Ve,className:Ue,"data-icon":ue,id:X,hasSeparator:ze,label:Je,...Qe}=D.props,Y=j(D),ce=Y&&t===$,Xe=ce?`${v}-${X}`:void 0;I.push(K(ee,{...Qe,...y,...Pt(`${v}-${a}`,X,$,(le=D.key)!=null?le:X,m,x,Ue,ze),"aria-controls":Xe,"aria-haspopup":Y||void 0,"aria-expanded":ce||void 0,children:M(Y?Je:Ve,ie,ue)}))}let P=[];if(n.length>0){let I=n.some(Et);n.forEach((D,$)=>{b(P,D,$,I)})}return P}},Pt=(e,t,n,o,r,c,i,u)=>({id:`${e}-${t}`,key:o!=null?o:n,"data-idx":n,"data-highlighted":n===r||void 0,className:Le("vuuMenuItem",i,{"vuuMenuItem-separator":u,focusVisible:c===n})});Re.displayName="MenuList";var He=Re;import{useCallback as A,useMemo as Lt,useRef as N,useState as Rt}from"react";function ke(e){if(e){let t=e.dataset.idx;if(t)return parseInt(t,10);if(e.ariaPosInSet)return parseInt(e.ariaPosInSet,10)-1}}var te=e=>e==null?void 0:e.closest("[data-idx],[aria-posinset]");var Te=(e,t,n)=>e.map((o,r)=>r===e.length-1?{...o,[n]:o[n]-t}:o),Ht=(e,t)=>Te(e,t,"left"),kt=(e,t)=>Te(e,t,"top"),Tt=(e,t)=>{let[n,o]=t.slice(-2),r=document.getElementById(`${e}-${o.id}`);if(r===null)throw Error(`useCascade.flipSides element with id ${o.id} not found`);let{width:c}=r.getBoundingClientRect();return t.map(i=>i===o?{...i,left:n.left-(c-2)}:i)},Dt=(e,t)=>{let[{left:n,top:o}]=t.slice(-1),{offsetWidth:r,offsetTop:c}=e;return{left:n+r,top:c+o}},O=e=>{let t=e.lastIndexOf("-");return t===-1?e:e.slice(t+1)},U=e=>{let t=O(e),n=t.lastIndexOf(".");return n>-1?t.slice(0,n):"root"},At=e=>{let t=0,n=e.indexOf(".",0);for(;n!==-1;)t+=1,n=e.indexOf(".",n+1);return t},St=e=>({menuId:U(e.id),itemId:O(e.id),isGroup:e.ariaHasPopup==="true",isOpen:e.ariaExpanded==="true",level:At(e.id)}),De=({id:e,onActivate:t,onMouseEnterItem:n,position:{x:o,y:r}})=>{let[,c]=Rt({}),i=N([{id:"root",left:o,top:r}]),u=A(s=>{i.current=s,c({})},[]),a=N(),d=N(),l=N({root:"no-popup"}),h=N(0),f=A((s="root",m=null,p=null)=>{if(s==="root"&&m===null)u([{id:"root",left:o,top:r}]);else{l.current[s]="popup-open";let w=(p?p.ownerDocument:document).getElementById(`${e}-${s}-${m}`),{left:k,top:y}=Dt(w,i.current);u(i.current.concat({id:m,left:k,top:y}))}},[e,o,r,u]),C=A(s=>{u(s==="root"?[]:i.current.slice(0,-1))},[u]),v=A((s,m)=>{let p=i.current.slice(),{id:x}=p[p.length-1];for(;p.length>1&&!m.startsWith(x);){let w=U(x);p.pop(),l.current[x]="no-popup",l.current[w]="no-popup",{id:x}=p[p.length-1]}p.length<i.current.length&&u(p)},[u]),g=A((s,m,p)=>{a.current&&clearTimeout(a.current),a.current=window.setTimeout(()=>{console.log(`scheduleOpen timed out opening ${m}`),v(s,m),l.current[s]="popup-open",l.current[m]="no-popup",f(s,m,p)},400)},[v,f]),E=A((s,m,p)=>{console.log(`scheduleClose openMenuId ${s} menuId ${m} itemId ${p}`),l.current[s]="pending-close",d.current=window.setTimeout(()=>{v(m,p)},400)},[v]),R=A(()=>{let{current:s}=i,[m]=s.slice(-1),p=document.getElementById(`${e}-${m.id}`);if(p){let{right:x,bottom:w}=p.getBoundingClientRect(),{clientHeight:k,clientWidth:y}=document.body;if(x>y){let M=s.length>1?Tt(e,s):Ht(s,x-y);u(M)}else if(w>k){let M=kt(s,w-k);u(M)}}},[e,u]),L=Lt(()=>({onMouseEnter:s=>{let m=te(s.target),{menuId:p,itemId:x,isGroup:w,isOpen:k,level:y}=St(m),M=h.current===y,{current:{[p]:b}}=l;if(h.current=y,b==="no-popup"&&w)l.current[p]="popup-pending",g(p,x,m);else if(b==="popup-pending"&&!w)l.current[p]="no-popup",clearTimeout(a.current),a.current=void 0;else if(b==="popup-pending"&&w)clearTimeout(a.current),g(p,x,m);else if(b==="popup-open"){let[{id:P},{id:I}]=i.current.slice(-2);P===p&&l.current[I]!=="pending-close"&&M?(E(I,p,x),w&&!k&&g(p,x,m)):P===p&&w&&x!==I&&l.current[I]==="pending-close"?g(p,x,m):w?(v(p,x),g(p,x,m)):l.current[I]==="pending-close"&&M||v(p,x)}b==="pending-close"&&(a.current&&(clearTimeout(a.current),a.current=void 0),clearTimeout(d.current),d.current=void 0,l.current[p]="popup-open"),n(s,x)},onClick:s=>{let m=s.target,p=te(m),x=ke(p);console.log(`list item click [${x}] hasPopup ${p.ariaHasPopup}`),p.ariaHasPopup==="true"?p.ariaExpanded!=="true"&&f(x):t(O(p.id))}}),[v,t,n,f,E,g]);return{closeMenu:C,handleRender:R,listItemProps:L,openMenu:f,openMenus:i.current}};import{useEffect as $t}from"react";var Ae=({containerClassName:e,isOpen:t,onClose:n})=>{$t(()=>{let o;return t&&(o=r=>{r.target.closest(`.${e}`)===null&&(n==null||n("root"))},document.body.addEventListener("click",o,!0)),()=>{o&&document.body.removeEventListener("click",o,!0)}},[e,t,n])};import{Fragment as Bt,jsx as $e}from"react/jsx-runtime";import{createElement as Ot}from"react";var Nt=()=>{},oe=({activatedByKeyboard:e,children:t,className:n,id:o,onClose:r=()=>{},position:c={x:0,y:0},style:i,...u})=>{let a=Kt(o),d=Se(Nt),[l,h]=we(t),f=Se(e),C=ne(()=>{f.current=!1},[]),v=ne(M=>{let{action:b,options:P}=h[M];d.current("root"),r(b,P)},[h,r]),{closeMenu:g,listItemProps:E,openMenu:R,openMenus:L,handleRender:s}=De({id:a,onActivate:v,onMouseEnterItem:C,position:c});d.current=g,console.log({openMenus:L});let m=ne(()=>{g(),r()},[g,r]);Ae({containerClassName:"vuuMenuList",onClose:m,isOpen:L.length>0});let p=M=>{let b=O(M),P=U(b);f.current=!0,R(P,b)},x=()=>{f.current=!0,g()},w=()=>{},k=L.length-1,y=M=>{if(M>=k)return-1;{let{id:b}=L[M+1],P=b.lastIndexOf(".");return parseInt(P===-1?b:b.slice(-P),10)}};return $e(Bt,{children:L.map(({id:M,left:b,top:P},I)=>{let D=y(I);return $e(G,{x:b,y:P,onRender:s,children:Ot(He,{...u,activatedByKeyboard:f.current,childMenuShowing:D,className:n,id:a,menuId:M,isRoot:I===0,key:I,listItemProps:E,onActivate:v,onHighlightMenuItem:w,onCloseMenu:x,onOpenMenu:p,style:i},l[M])},I)})})};oe.displayName="ContextMenu";import{createContext as Ft,useCallback as Gt,useMemo as Wt}from"react";import{jsx as re}from"react/jsx-runtime";var z=Ft(null),Ke=e=>e!==void 0&&"children"in e,qt=({children:e,context:t,menuActionHandler:n,menuBuilder:o})=>{let r=Wt(()=>t!=null&&t.menuBuilders&&o?t.menuBuilders.concat(o):o?[o]:(t==null?void 0:t.menuBuilders)||[],[t,o]),c=Gt((i,u)=>{var a;if(n!=null&&n(i,u)||(a=t==null?void 0:t.menuActionHandler)!=null&&a.call(t,i,u))return!0},[t,n]);return re(z.Provider,{value:{menuActionHandler:c,menuBuilders:r},children:e})},yo=({children:e,label:t,menuActionHandler:n,menuBuilder:o})=>re(z.Consumer,{children:r=>re(qt,{context:r,label:t,menuActionHandler:n,menuBuilder:o,children:e})});import{useCallback as qe,useContext as Zt}from"react";import Vt from"classnames";import Oe,{createElement as Be,useEffect as Ut,useRef as Ne}from"react";import B from"react-dom";var S=!1,H=[];function Q(e){if(e.key==="Esc"){if(H.length)Ge();else if(S){let t=document.body.querySelector(".vuuDialog");t&&B.unmountComponentAtNode(t)}}}function Fe(e){if(H.length){let t=document.body.querySelectorAll(".vuuPopup");for(let n=0;n<t.length;n++)if(t[n].contains(e.target))return;Ge()}}function Ge(){if(H.length){let e=document.body.querySelectorAll(".vuuPopup");for(let t=0;t<e.length;t++)B.unmountComponentAtNode(e[t]);We("*")}}function zt(){S===!1&&(S=!0,window.addEventListener("keydown",Q,!0))}function Jt(){S&&(S=!1,window.removeEventListener("keydown",Q,!0))}function Qt(e){H.indexOf(e)===-1&&(H.push(e),S===!1&&(window.addEventListener("keydown",Q,!0),window.addEventListener("click",Fe,!0)))}function We(e){if(H.length){if(e==="*")H.length=0;else{let t=H.indexOf(e);t!==-1&&H.splice(t,1)}H.length===0&&S===!1&&(window.removeEventListener("keydown",Q,!0),window.removeEventListener("click",Fe,!0))}}var Xt=({children:e,position:t,style:n})=>{let o=Vt("hwPopup","hwPopupContainer",t);return Be("div",{className:o,style:n},e)},Yt=1,T=class{static showPopup({name:t="anon",group:n="all",position:o="",left:r=0,right:c="auto",top:i=0,width:u="auto",component:a}){if(!a)throw Error("PopupService showPopup, no component supplied");Qt(t);let d=document.body.querySelector(".vuuPopup."+n);d===null&&(d=document.createElement("div"),d.className="vuuPopup "+n,document.body.appendChild(d));let l={width:u};F(Be(Xt,{key:Yt++,position:o,style:l},a),d,r,i,()=>{T.keepWithinThePage(d,c)})}static hidePopup(t="anon",n="all"){if(H.indexOf(t)!==-1){We(t);let o=document.body.querySelector(`.vuuPopup.${n}`);o&&B.unmountComponentAtNode(o)}}static keepWithinThePage(t,n="auto"){let o=t.querySelector(".vuuPopupContainer > *");if(o){let{top:r,left:c,width:i,height:u,right:a}=o.getBoundingClientRect(),d=window.innerWidth,h=window.innerHeight-(r+u);h<0&&(o.style.top=Math.round(r)+h+"px");let f=d-(c+i);if(f<0&&(o.style.left=Math.round(c)+f+"px"),typeof n=="number"&&n!==a){let C=n-a;o.style.left=c+C+"px"}}}},J=class{static showDialog(t){let n=".vuuDialog",o=t.props.onClose;zt(),B.render(Oe.cloneElement(t,{container:n,onClose:()=>{J.closeDialog(),o&&o()}}),document.body.querySelector(n))}static closeDialog(){Jt();let t=document.body.querySelector(".vuuDialog");t&&B.unmountComponentAtNode(t)}},So=e=>{let t=Ne(),n=Ne(null),o=(r,c)=>{let{name:i,group:u,depth:a,width:d}=r,l,h;if(t.current&&(window.clearTimeout(t.current),t.current=void 0),r.close===!0)T.hidePopup(i,u);else{let{position:f,children:C}=r,{left:v,top:g,width:E,bottom:R}=c;f==="below"?(l=v,h=R):f==="above"&&(l=v,h=g),t.current=window.setTimeout(()=>{T.showPopup({name:i,group:u,depth:a,position:f,left:l,top:h,width:d||E,component:C})},10)}};return Ut(()=>{if(n.current){let r=n.current.parentElement,c=r==null?void 0:r.getBoundingClientRect();c&&o(e,c)}return()=>{T.hidePopup(e.name,e.group)}},[e]),Oe.createElement("div",{className:"popup-proxy",ref:n})};import{jsx as se}from"react/jsx-runtime";var Jo=()=>{let e=Zt(z),t=qe((o,r,c)=>{let i=[];for(let u of o)i=i.concat(u(r,c));return i},[]);return qe((o,r,c)=>{var a;o.stopPropagation(),o.preventDefault();let i=(a=e==null?void 0:e.menuBuilders)!=null?a:[],u=t(i,r,c);console.log({menuItemDescriptors:u}),u.length&&(e!=null&&e.menuActionHandler)&&(console.log(`showContextMenu ${r}`,{options:c}),_t(o,u,e.menuActionHandler))},[t,e])},_t=(e,t,n)=>{let{clientX:o,clientY:r}=e,u=se(oe,{onClose:(a,d)=>{a&&(n(a,d),T.hidePopup())},position:{x:o,y:r},children:(a=>{let d=(l,h)=>Ke(l)?se(V,{label:l.label,children:l.children.map(d)},h):se(ee,{action:l.action,"data-icon":l.icon,options:l.options,children:l.label},h);return a.map(d)})(t)});T.showPopup({left:0,top:0,component:u})};export{oe as ContextMenu,z as ContextMenuContext,yo as ContextMenuProvider,In as Dialog,J as DialogService,ee as MenuItem,V as MenuItemGroup,So as Popup,T as PopupService,G as Portal,Ee as Separator,pe as createContainer,un as installTheme,Ke as isGroupMenuItemDescriptor,F as renderPortal,Jo as useContextMenu};
1
+ import{Scrim as nt,Toolbar as ot,ToolbarButton as rt}from"@heswell/salt-lab";import{Text as st}from"@salt-ds/core";import it from"classnames";import{useCallback as fe,useRef as ut,useState as ge}from"react";import{useLayoutEffect as de,useMemo as tt}from"react";import*as me from"react-dom";import*as ae from"react-dom";import{SaltProvider as Ye}from"@salt-ds/core";import{jsx as et}from"react/jsx-runtime";var Ze=1,_e=(t=0,e=0,n=window)=>{let o=n.document.createElement("div");return o.className="vuuPopup "+Ze++,o.style.cssText=`left:${t}px; top:${e}px;`,n.document.body.appendChild(o),o},je=(t,e)=>_e(t,e),F=(t,e,n,o,r)=>{e.style.cssText=`left:${n}px; top:${o}px;position: absolute;`,ae.render(et(Ye,{applyClassesTo:"child",children:t}),e,r)},pe=je;var G=function({children:e,x:n=0,y:o=0,onRender:r}){let c=tt(()=>pe(),[]);return de(()=>{F(e,c,n,o,r)},[e,r,c,n,o]),de(()=>()=>{var u;c&&(me.unmountComponentAtNode(c),c.classList.contains("vuuPopup")&&((u=c.parentElement)==null||u.removeChild(c)))},[c]),null};var un=t=>{let e=getComputedStyle(document.body).getPropertyValue("--installed-themes");document.body.style.setProperty("--installed-themes",`${e} ${t}`)};import{jsx as W,jsxs as Me}from"react/jsx-runtime";var Z="vuuDialog",Cn=({children:t,className:e,isOpen:n=!1,onClose:o,title:r,...c})=>{let u=ut(null),[i]=ge(0),[l]=ge(0),d=fe(()=>{o==null||o()},[o]),a=fe(()=>{},[]);return n?W(G,{onRender:a,x:i,y:l,children:W(nt,{className:`${Z}-scrim`,open:n,children:Me("div",{...c,className:it(Z,e),ref:u,children:[Me(ot,{className:`${Z}-header`,children:[W(st,{children:r}),W(rt,{onClick:d,"data-align-end":!0,"data-icon":"close"},"close")]}),t]})})}):null};import{useIdMemo as Kt}from"@salt-ds/core";import{useCallback as ne,useRef as Se}from"react";import vt,{useLayoutEffect as yt,useMemo as Ct,useRef as It}from"react";import Le from"classnames";import{useIdMemo as wt}from"@salt-ds/core";import{useCallback as q,useMemo as gt,useRef as _,useState as Mt}from"react";var he=t=>t.closest("[data-root='true']")!==null,xe=(t,e)=>{var n;return t.ariaHasPopup==="true"&&((n=t.dataset)==null?void 0:n.idx)===`${e}`||t.querySelector(`:scope > [data-idx='${e}'][aria-haspopup='true']`)!==null};function ct(t,...e){let n=new Set(t);for(let o of e)for(let r of o)n.add(r);return n}var lt="Enter";var at="Delete",pt=new Set([lt,at]),dt=new Set(["Tab"]),mt=new Set(["ArrowRight","ArrowLeft"]),be=new Set(["Home","End","ArrowDown","ArrowUp"]),ve=new Set(["Home","End","ArrowRight","ArrowLeft"]),ft=new Set(["F1","F2","F3","F4","F5","F6","F7","F8","F9","F10","F11","F12"]),Rn=ct(pt,ve,be,mt,ft,dt);var ye=({key:t},e="vertical")=>(e==="vertical"?be:ve).has(t);var Ce=({autoHighlightFirstItem:t=!1,count:e,highlightedIndex:n,onActivate:o,onHighlight:r,onCloseMenu:c,onOpenMenu:u})=>{let i=_((n!=null?n:t)?0:-1),[,l]=Mt(null),d=n!==void 0,a=q(s=>{i.current=s,r==null||r(s),l({})},[r]),h=q(s=>{s!==i.current&&(d||a(s))},[d,a]),f=_(!0),I=_(!1),v=s=>I.current=s,g=d?n:i.current,P=q(s=>{let m=ht(e,s.key,i.current);m!==i.current&&h(m)},[e,h]),R=q(s=>{ye(s)?(s.preventDefault(),s.stopPropagation(),f.current=!0,P(s)):(s.key==="ArrowRight"||s.key==="Enter")&&xe(s.target,g)?u(g):s.key==="ArrowLeft"&&!he(s.target)?c(g):s.key==="Enter"&&o&&o(g)},[g,P,o,c,u]),L=gt(()=>({onFocus:()=>{g===-1&&a(0)},onKeyDown:R,onMouseDownCapture:()=>{f.current=!1,v(!0)},onMouseMove:()=>{f.current&&(f.current=!1)},onMouseLeave:()=>{f.current=!0,v(!1),h(-1)}}),[g,h,P,o,c,u,a]);return{focusVisible:f.current?g:-1,controlledHighlighting:d,highlightedIndex:g,setHighlightedIndex:h,listProps:L,setIgnoreFocus:v}};function ht(t,e,n){return e==="ArrowUp"?n>0?n-1:n:n===null?0:n===t-1?n:n+1}import Ie,{useCallback as xt,useMemo as bt}from"react";var j=t=>t.type===V||!!t.props["data-group"],we=t=>{let e=xt(()=>{let r=(u,i="root",l={},d={})=>{let a=l[i]=[],h=0,f=!1;return Ie.Children.forEach(u,I=>{if(I.type===Pe)f=!0;else{let v=j(I),g=i==="root"?`${h}`:`${i}.${h}`,{props:{action:P,options:R}}=I,{childWithId:L,grandChildren:s}=c(I,g,v,f);a.push(L),s?r(s,g,l,d):d[g]={action:P,options:R},h+=1,f=!1}}),[l,d]},c=(u,i,l,d=!1)=>{let{props:{children:a}}=u;return{childWithId:Ie.cloneElement(u,{hasSeparator:d,id:`${i}`,key:i,children:l?void 0:a}),grandChildren:l?a:void 0}};return r(t)},[t]),[n,o]=bt(()=>e(),[e]);return[n,o]};import{jsx as K}from"react/jsx-runtime";var Ee="vuuMenuList",Pe=()=>K("li",{className:"vuuMenuItem-divider"}),V=()=>null,ee=({children:t,idx:e,...n})=>K("div",{...n,children:t}),Pt=t=>t.props["data-icon"],Re=({activatedByKeyboard:t,childMenuShowing:e=-1,children:n,className:o,highlightedIdx:r,id:c,isRoot:u,listItemProps:i,menuId:l,onHighlightMenuItem:d,onActivate:a,onCloseMenu:h,onOpenMenu:f,...I})=>{let v=wt(c),g=It(null),P=Ct(()=>new Map,[]),R=y=>{var b;let M=(b=g.current)==null?void 0:b.querySelector(`:scope > [data-idx='${y}']`);M!=null&&M.id&&(f==null||f(M.id))},L=y=>{var b;let M=(b=g.current)==null?void 0:b.querySelector(`:scope > [data-idx='${y}']`);M!=null&&M.id&&(a==null||a(M.id))},{focusVisible:s,highlightedIndex:m,listProps:p}=Ce({count:vt.Children.count(n),highlightedIndex:r,onActivate:L,onHighlight:d,onOpenMenu:R,onCloseMenu:h}),x=e==-1?s:-1;return yt(()=>{var y;e===-1&&t&&((y=g.current)==null||y.focus())},[t,e]),K("div",{...I,...p,"aria-activedescendant":(()=>m===void 0||m===-1?void 0:P.get(m))(),className:Le(Ee,o,{[`${Ee}-childMenuShowing`]:e!==-1}),"data-root":u||void 0,id:`${v}-${l}`,ref:g,role:"menu",tabIndex:0,children:T()});function T(){let y={...i,role:"menuitem"},M=(C,D,$)=>D?[K("span",{className:"vuuIconContainer","data-icon":$},"icon")].concat(C):C;function b(C,D,$,ie){var le;let{children:Ve,className:Ue,"data-icon":ue,id:X,hasSeparator:ze,label:Je,...Qe}=D.props,Y=j(D),ce=Y&&e===$,Xe=ce?`${v}-${X}`:void 0;C.push(K(ee,{...Qe,...y,...Et(`${v}-${l}`,X,$,(le=D.key)!=null?le:X,m,x,Ue,ze),"aria-controls":Xe,"aria-haspopup":Y||void 0,"aria-expanded":ce||void 0,children:M(Y?Je:Ve,ie,ue)}))}let E=[];if(n.length>0){let C=n.some(Pt);n.forEach((D,$)=>{b(E,D,$,C)})}return E}},Et=(t,e,n,o,r,c,u,i)=>({id:`${t}-${e}`,key:o!=null?o:n,"data-idx":n,"data-highlighted":n===r||void 0,className:Le("vuuMenuItem",u,{"vuuMenuItem-separator":i,focusVisible:c===n})});Re.displayName="MenuList";var He=Re;import{useCallback as A,useMemo as Lt,useRef as N,useState as Rt}from"react";function Te(t){if(t){let e=t.dataset.idx;if(e)return parseInt(e,10);if(t.ariaPosInSet)return parseInt(t.ariaPosInSet,10)-1}}var te=t=>t==null?void 0:t.closest("[data-idx],[aria-posinset]");var ke=(t,e,n)=>t.map((o,r)=>r===t.length-1?{...o,[n]:o[n]-e}:o),Ht=(t,e)=>ke(t,e,"left"),Tt=(t,e)=>ke(t,e,"top"),kt=(t,e)=>{let[n,o]=e.slice(-2),r=document.getElementById(`${t}-${o.id}`);if(r===null)throw Error(`useCascade.flipSides element with id ${o.id} not found`);let{width:c}=r.getBoundingClientRect();return e.map(u=>u===o?{...u,left:n.left-(c-2)}:u)},Dt=(t,e)=>{let[{left:n,top:o}]=e.slice(-1),{offsetWidth:r,offsetTop:c}=t;return{left:n+r,top:c+o}},B=t=>{let e=t.lastIndexOf("-");return e===-1?t:t.slice(e+1)},U=t=>{let e=B(t),n=e.lastIndexOf(".");return n>-1?e.slice(0,n):"root"},At=t=>{let e=0,n=t.indexOf(".",0);for(;n!==-1;)e+=1,n=t.indexOf(".",n+1);return e},St=t=>({menuId:U(t.id),itemId:B(t.id),isGroup:t.ariaHasPopup==="true",isOpen:t.ariaExpanded==="true",level:At(t.id)}),De=({id:t,onActivate:e,onMouseEnterItem:n,position:{x:o,y:r}})=>{let[,c]=Rt({}),u=N([{id:"root",left:o,top:r}]),i=A(s=>{u.current=s,c({})},[]),l=N(),d=N(),a=N({root:"no-popup"}),h=N(0),f=A((s="root",m=null,p=null)=>{if(s==="root"&&m===null)i([{id:"root",left:o,top:r}]);else{a.current[s]="popup-open";let w=(p?p.ownerDocument:document).getElementById(`${t}-${s}-${m}`),{left:T,top:y}=Dt(w,u.current);i(u.current.concat({id:m,left:T,top:y}))}},[t,o,r,i]),I=A(s=>{i(s==="root"?[]:u.current.slice(0,-1))},[i]),v=A((s,m)=>{let p=u.current.slice(),{id:x}=p[p.length-1];for(;p.length>1&&!m.startsWith(x);){let w=U(x);p.pop(),a.current[x]="no-popup",a.current[w]="no-popup",{id:x}=p[p.length-1]}p.length<u.current.length&&i(p)},[i]),g=A((s,m,p)=>{l.current&&clearTimeout(l.current),l.current=window.setTimeout(()=>{console.log(`scheduleOpen timed out opening ${m}`),v(s,m),a.current[s]="popup-open",a.current[m]="no-popup",f(s,m,p)},400)},[v,f]),P=A((s,m,p)=>{console.log(`scheduleClose openMenuId ${s} menuId ${m} itemId ${p}`),a.current[s]="pending-close",d.current=window.setTimeout(()=>{v(m,p)},400)},[v]),R=A(()=>{let{current:s}=u,[m]=s.slice(-1),p=document.getElementById(`${t}-${m.id}`);if(p){let{right:x,bottom:w}=p.getBoundingClientRect(),{clientHeight:T,clientWidth:y}=document.body;if(x>y){let M=s.length>1?kt(t,s):Ht(s,x-y);i(M)}else if(w>T){let M=Tt(s,w-T);i(M)}}},[t,i]),L=Lt(()=>({onMouseEnter:s=>{let m=te(s.target),{menuId:p,itemId:x,isGroup:w,isOpen:T,level:y}=St(m),M=h.current===y,{current:{[p]:b}}=a;if(h.current=y,b==="no-popup"&&w)a.current[p]="popup-pending",g(p,x,m);else if(b==="popup-pending"&&!w)a.current[p]="no-popup",clearTimeout(l.current),l.current=void 0;else if(b==="popup-pending"&&w)clearTimeout(l.current),g(p,x,m);else if(b==="popup-open"){let[{id:E},{id:C}]=u.current.slice(-2);E===p&&a.current[C]!=="pending-close"&&M?(P(C,p,x),w&&!T&&g(p,x,m)):E===p&&w&&x!==C&&a.current[C]==="pending-close"?g(p,x,m):w?(v(p,x),g(p,x,m)):a.current[C]==="pending-close"&&M||v(p,x)}b==="pending-close"&&(l.current&&(clearTimeout(l.current),l.current=void 0),clearTimeout(d.current),d.current=void 0,a.current[p]="popup-open"),n(s,x)},onClick:s=>{let m=s.target,p=te(m),x=Te(p);console.log(`list item click [${x}] hasPopup ${p.ariaHasPopup}`),p.ariaHasPopup==="true"?p.ariaExpanded!=="true"&&f(x):e(B(p.id))}}),[v,e,n,f,P,g]);return{closeMenu:I,handleRender:R,listItemProps:L,openMenu:f,openMenus:u.current}};import{useEffect as $t}from"react";var Ae=({containerClassName:t,isOpen:e,onClose:n})=>{$t(()=>{let o;return e&&(o=r=>{r.target.closest(`.${t}`)===null&&(n==null||n("root"))},document.body.addEventListener("click",o,!0)),()=>{o&&document.body.removeEventListener("click",o,!0)}},[t,e,n])};import{Fragment as Ot,jsx as $e}from"react/jsx-runtime";import{createElement as Bt}from"react";var Nt=()=>{},oe=({activatedByKeyboard:t,children:e,className:n,id:o,onClose:r=()=>{},position:c={x:0,y:0},style:u,...i})=>{let l=Kt(o),d=Se(Nt),[a,h]=we(e),f=Se(t),I=ne(()=>{f.current=!1},[]),v=ne(M=>{let{action:b,options:E}=h[M];d.current("root"),r(b,E)},[h,r]),{closeMenu:g,listItemProps:P,openMenu:R,openMenus:L,handleRender:s}=De({id:l,onActivate:v,onMouseEnterItem:I,position:c});d.current=g,console.log({openMenus:L});let m=ne(()=>{g(),r()},[g,r]);Ae({containerClassName:"vuuMenuList",onClose:m,isOpen:L.length>0});let p=M=>{let b=B(M),E=U(b);f.current=!0,R(E,b)},x=()=>{f.current=!0,g()},w=()=>{},T=L.length-1,y=M=>{if(M>=T)return-1;{let{id:b}=L[M+1],E=b.lastIndexOf(".");return parseInt(E===-1?b:b.slice(-E),10)}};return $e(Ot,{children:L.map(({id:M,left:b,top:E},C)=>{let D=y(C);return $e(G,{x:b,y:E,onRender:s,children:Bt(He,{...i,activatedByKeyboard:f.current,childMenuShowing:D,className:n,id:l,menuId:M,isRoot:C===0,key:C,listItemProps:P,onActivate:v,onHighlightMenuItem:w,onCloseMenu:x,onOpenMenu:p,style:u},a[M])},C)})})};oe.displayName="ContextMenu";import{createContext as Ft,useCallback as Gt,useMemo as Wt}from"react";import{jsx as re}from"react/jsx-runtime";var z=Ft(null),Ke=t=>t!==void 0&&"children"in t,qt=({children:t,context:e,menuActionHandler:n,menuBuilder:o})=>{let r=Wt(()=>e!=null&&e.menuBuilders&&o?e.menuBuilders.concat(o):o?[o]:(e==null?void 0:e.menuBuilders)||[],[e,o]),c=Gt((u,i)=>{var l;if(n!=null&&n(u,i)||(l=e==null?void 0:e.menuActionHandler)!=null&&l.call(e,u,i))return!0},[e,n]);return re(z.Provider,{value:{menuActionHandler:c,menuBuilders:r},children:t})},yo=({children:t,label:e,menuActionHandler:n,menuBuilder:o})=>re(z.Consumer,{children:r=>re(qt,{context:r,label:e,menuActionHandler:n,menuBuilder:o,children:t})});import{useCallback as qe,useContext as Zt}from"react";import Vt from"classnames";import Be,{createElement as Oe,useEffect as Ut,useRef as Ne}from"react";import O from"react-dom";var S=!1,H=[];function Q(t){if(t.key==="Esc"){if(H.length)Ge();else if(S){let e=document.body.querySelector(".vuuDialog");e&&O.unmountComponentAtNode(e)}}}function Fe(t){if(H.length){let e=document.body.querySelectorAll(".vuuPopup");for(let n=0;n<e.length;n++)if(e[n].contains(t.target))return;Ge()}}function Ge(){if(H.length){let t=document.body.querySelectorAll(".vuuPopup");for(let e=0;e<t.length;e++)O.unmountComponentAtNode(t[e]);We("*")}}function zt(){S===!1&&(S=!0,window.addEventListener("keydown",Q,!0))}function Jt(){S&&(S=!1,window.removeEventListener("keydown",Q,!0))}function Qt(t){H.indexOf(t)===-1&&(H.push(t),S===!1&&(window.addEventListener("keydown",Q,!0),window.addEventListener("click",Fe,!0)))}function We(t){if(H.length){if(t==="*")H.length=0;else{let e=H.indexOf(t);e!==-1&&H.splice(e,1)}H.length===0&&S===!1&&(window.removeEventListener("keydown",Q,!0),window.removeEventListener("click",Fe,!0))}}var Xt=({children:t,position:e,style:n})=>{let o=Vt("hwPopup","hwPopupContainer",e);return Oe("div",{className:o,style:n},t)},Yt=1,k=class{static showPopup({name:e="anon",group:n="all",position:o="",left:r=0,right:c="auto",top:u=0,width:i="auto",component:l}){if(!l)throw Error("PopupService showPopup, no component supplied");Qt(e);let d=document.body.querySelector(".vuuPopup."+n);d===null&&(d=document.createElement("div"),d.className="vuuPopup "+n,document.body.appendChild(d));let a={width:i};F(Oe(Xt,{key:Yt++,position:o,style:a},l),d,r,u,()=>{k.keepWithinThePage(d,c)})}static hidePopup(e="anon",n="all"){if(H.indexOf(e)!==-1){We(e);let o=document.body.querySelector(`.vuuPopup.${n}`);o&&O.unmountComponentAtNode(o)}}static keepWithinThePage(e,n="auto"){let o=e.querySelector(".vuuPopupContainer > *");if(o){let{top:r,left:c,width:u,height:i,right:l}=o.getBoundingClientRect(),d=window.innerWidth,h=window.innerHeight-(r+i);h<0&&(o.style.top=Math.round(r)+h+"px");let f=d-(c+u);if(f<0&&(o.style.left=Math.round(c)+f+"px"),typeof n=="number"&&n!==l){let I=n-l;o.style.left=c+I+"px"}}}},J=class{static showDialog(e){let n=".vuuDialog",o=e.props.onClose;zt(),O.render(Be.cloneElement(e,{container:n,onClose:()=>{J.closeDialog(),o&&o()}}),document.body.querySelector(n))}static closeDialog(){Jt();let e=document.body.querySelector(".vuuDialog");e&&O.unmountComponentAtNode(e)}},So=t=>{let e=Ne(),n=Ne(null),o=(r,c)=>{let{name:u,group:i,depth:l,width:d}=r,a,h;if(e.current&&(window.clearTimeout(e.current),e.current=void 0),r.close===!0)k.hidePopup(u,i);else{let{position:f,children:I}=r,{left:v,top:g,width:P,bottom:R}=c;f==="below"?(a=v,h=R):f==="above"&&(a=v,h=g),e.current=window.setTimeout(()=>{k.showPopup({name:u,group:i,depth:l,position:f,left:a,top:h,width:d||P,component:I})},10)}};return Ut(()=>{if(n.current){let r=n.current.parentElement,c=r==null?void 0:r.getBoundingClientRect();c&&o(t,c)}return()=>{k.hidePopup(t.name,t.group)}},[t]),Be.createElement("div",{className:"popup-proxy",ref:n})};import{jsx as se}from"react/jsx-runtime";var Jo=t=>{let e=Zt(z),n=qe((r,c,u)=>{let i=[];for(let l of r)i=i.concat(l(c,u));return i},[]);return qe((r,c,u)=>{var l;r.stopPropagation(),r.preventDefault();let i=(l=e==null?void 0:e.menuBuilders)!=null?l:t?[t]:void 0;if(Array.isArray(i)&&i.length>0){let d=n(i,c,u);console.log({menuItemDescriptors:d}),d.length&&(e!=null&&e.menuActionHandler)&&(console.log(`showContextMenu ${c}`,{options:u}),_t(r,d,e.menuActionHandler))}else console.warn("useContextMenu, no menuBuilders configured. These should be supplied via the ContextMenuProvider(s)")},[n,e==null?void 0:e.menuActionHandler,e==null?void 0:e.menuBuilders,t])},_t=(t,e,n)=>{let{clientX:o,clientY:r}=t,i=se(oe,{onClose:(l,d)=>{l&&(n(l,d),k.hidePopup())},position:{x:o,y:r},children:(l=>{let d=(a,h)=>Ke(a)?se(V,{label:a.label,children:a.children.map(d)},h):se(ee,{action:a.action,"data-icon":a.icon,options:a.options,children:a.label},h);return l.map(d)})(e)});k.showPopup({left:0,top:0,component:i})};export{oe as ContextMenu,z as ContextMenuContext,yo as ContextMenuProvider,Cn as Dialog,J as DialogService,ee as MenuItem,V as MenuItemGroup,So as Popup,k as PopupService,G as Portal,Pe as Separator,pe as createContainer,un as installTheme,Ke as isGroupMenuItemDescriptor,F as renderPortal,Jo as useContextMenu};
2
2
  //# sourceMappingURL=index.js.map
package/esm/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../packages/vuu-popups/src/dialog/Dialog.tsx", "../../../packages/vuu-popups/src/portal/Portal.tsx", "../../../packages/vuu-popups/src/portal/render-portal.tsx", "../../../packages/vuu-popups/src/portal/portal-utils.ts", "../../../packages/vuu-popups/src/menu/ContextMenu.tsx", "../../../packages/vuu-popups/src/menu/MenuList.tsx", "../../../packages/vuu-popups/src/menu/use-keyboard-navigation.ts", "../../../packages/vuu-popups/src/menu/utils.ts", "../../../packages/vuu-popups/src/menu/key-code.ts", "../../../packages/vuu-popups/src/menu/use-items-with-ids.ts", "../../../packages/vuu-popups/src/menu/use-cascade.ts", "../../../packages/vuu-popups/src/menu/list-dom-utils.ts", "../../../packages/vuu-popups/src/menu/use-click-away.ts", "../../../packages/vuu-popups/src/menu/context-menu-provider.tsx", "../../../packages/vuu-popups/src/menu/useContextMenu.tsx", "../../../packages/vuu-popups/src/popup/popup-service.ts"],
4
- "sourcesContent": ["import { Scrim, Toolbar, ToolbarButton } from \"@heswell/salt-lab\";\nimport { Text } from \"@salt-ds/core\";\nimport cx from \"classnames\";\nimport { HTMLAttributes, useCallback, useRef, useState } from \"react\";\nimport { Portal } from \"../portal\";\n\nimport \"./Dialog.css\";\n\nconst classBase = \"vuuDialog\";\n\nexport interface DialogProps extends HTMLAttributes<HTMLDivElement> {\n isOpen?: boolean;\n onClose?: () => void;\n}\n\nexport const Dialog = ({\n children,\n className,\n isOpen = false,\n onClose,\n title,\n ...props\n}: DialogProps) => {\n const root = useRef<HTMLDivElement>(null);\n const [posX] = useState(0);\n const [posY] = useState(0);\n\n const close = useCallback(() => {\n onClose?.();\n }, [onClose]);\n\n const handleRender = useCallback(() => {\n // if (center && isOpen && root.current) {\n // const { width, height } = root.current.getBoundingClientRect();\n // const { innerWidth, innerHeight } = window;\n // const x = innerWidth / 2 - width / 2;\n // const y = innerHeight / 2 - height / 2;\n // setPosX(x);\n // setPosY(y);\n // }\n }, []);\n\n if (!isOpen) {\n return null;\n }\n\n return (\n <Portal onRender={handleRender} x={posX} y={posY}>\n <Scrim className={`${classBase}-scrim`} open={isOpen}>\n <div {...props} className={cx(classBase, className)} ref={root}>\n <Toolbar className={`${classBase}-header`}>\n <Text>{title}</Text>\n <ToolbarButton\n key=\"close\"\n onClick={close}\n data-align-end\n data-icon=\"close\"\n />\n </Toolbar>\n {children}\n </div>\n </Scrim>\n </Portal>\n );\n};\n", "import { ReactElement, useLayoutEffect, useMemo } from \"react\";\nimport * as ReactDOM from \"react-dom\";\nimport { createContainer, renderPortal } from \"./render-portal\";\n\nexport interface PortalProps {\n children: ReactElement;\n onRender?: () => void;\n x?: number;\n y?: number;\n}\n\nexport const Portal = function Portal({\n children,\n x = 0,\n y = 0,\n onRender,\n}: PortalProps) {\n // Do we need to accept container here as a prop ?\n const renderContainer = useMemo(() => {\n return createContainer();\n }, []);\n\n useLayoutEffect(() => {\n renderPortal(children, renderContainer, x, y, onRender);\n }, [children, onRender, renderContainer, x, y]);\n\n useLayoutEffect(() => {\n return () => {\n if (renderContainer) {\n ReactDOM.unmountComponentAtNode(renderContainer);\n if (renderContainer.classList.contains(\"vuuPopup\")) {\n renderContainer.parentElement?.removeChild(renderContainer);\n }\n }\n };\n }, [renderContainer]);\n\n // useLayoutEffect(() => {\n // renderContainer.current = renderPortal(children, x, y, container)\n // return () => {\n // if (renderContainer.current){\n // console.log('EXPLICIT UNMOUNT')\n // ReactDOM.unmountComponentAtNode(renderContainer.current);\n // if (renderContainer.current.classList.contains('hwReactPopup')){\n // renderContainer.current.parentElement.removeChild(renderContainer.current);\n // renderContainer.current = null;\n // }\n // }\n // }\n // },[])\n return null;\n};\n", "import * as ReactDOM from \"react-dom\";\nimport { SaltProvider } from \"@salt-ds/core\";\nimport { ReactElement } from \"react\";\n\nlet containerId = 1;\n\nconst getPortalContainer = (x = 0, y = 0, win = window) => {\n const el = win.document.createElement(\"div\");\n el.className = \"vuuPopup \" + containerId++;\n el.style.cssText = `left:${x}px; top:${y}px;`;\n win.document.body.appendChild(el);\n return el;\n};\n\nconst createDOMContainer = (x?: number, y?: number) => getPortalContainer(x, y);\n\nexport const renderPortal = (\n component: ReactElement,\n container: HTMLElement,\n x: number,\n y: number,\n onRender?: () => void\n) => {\n // check this first to see if position has changed\n container.style.cssText = `left:${x}px; top:${y}px;position: absolute;`;\n\n ReactDOM.render(\n <SaltProvider applyClassesTo=\"child\">{component}</SaltProvider>,\n container,\n onRender\n );\n};\n\nexport const createContainer = createDOMContainer;\n", "export const installTheme = (themeId: string) => {\n const installedThemes = getComputedStyle(document.body).getPropertyValue(\n \"--installed-themes\"\n );\n document.body.style.setProperty(\n \"--installed-themes\",\n `${installedThemes} ${themeId}`\n );\n};\n", "import { useIdMemo as useId } from \"@salt-ds/core\";\nimport { useCallback, useRef } from \"react\";\nimport { Portal } from \"../portal\";\nimport MenuList, { MenuListProps } from \"./MenuList\";\nimport { getItemId, getMenuId, useCascade } from \"./use-cascade\";\nimport { useClickAway } from \"./use-click-away\";\nimport { useItemsWithIds } from \"./use-items-with-ids\";\n\nexport interface ContextMenuProps extends Omit<MenuListProps, \"onCloseMenu\"> {\n onClose?: (menuId?: string, options?: unknown) => void;\n position?: { x: number; y: number };\n withPortal?: boolean;\n}\n\nconst noop = () => undefined;\n\nexport const ContextMenu = ({\n activatedByKeyboard,\n children: childrenProp,\n className,\n id: idProp,\n onClose = () => undefined,\n position = { x: 0, y: 0 },\n style,\n ...menuListProps\n}: ContextMenuProps) => {\n const id = useId(idProp);\n const closeMenuRef = useRef<(location?: string) => void>(noop);\n const [menus, actions] = useItemsWithIds(childrenProp);\n const navigatingWithKeyboard = useRef(activatedByKeyboard);\n const handleMouseEnterItem = useCallback(() => {\n navigatingWithKeyboard.current = false;\n }, []);\n\n const handleActivate = useCallback(\n (menuId: string) => {\n const { action, options } = actions[menuId];\n closeMenuRef.current(\"root\");\n onClose(action, options);\n },\n [actions, onClose]\n );\n\n const { closeMenu, listItemProps, openMenu, openMenus, handleRender } =\n useCascade({\n id,\n onActivate: handleActivate,\n onMouseEnterItem: handleMouseEnterItem,\n position,\n });\n closeMenuRef.current = closeMenu;\n\n console.log({ openMenus });\n\n const handleClose = useCallback(() => {\n closeMenu();\n onClose();\n }, [closeMenu, onClose]);\n\n useClickAway({\n containerClassName: \"vuuMenuList\",\n onClose: handleClose,\n isOpen: openMenus.length > 0,\n });\n\n const handleOpenMenu = (id: string) => {\n const itemId = getItemId(id);\n const menuId = getMenuId(itemId);\n navigatingWithKeyboard.current = true;\n openMenu(menuId, itemId);\n };\n const handleCloseMenu = () => {\n navigatingWithKeyboard.current = true;\n closeMenu();\n };\n\n const handleHighlightMenuItem = () => {\n // console.log(`highlight ${idx}`);\n };\n\n const lastMenu = openMenus.length - 1;\n\n const getChildMenuIndex = (i: number) => {\n if (i >= lastMenu) {\n return -1;\n } else {\n const { id: menuId } = openMenus[i + 1];\n const pos = menuId.lastIndexOf(\".\");\n const idx =\n pos === -1 ? parseInt(menuId, 10) : parseInt(menuId.slice(-pos), 10);\n return idx;\n }\n };\n\n return (\n <>\n {openMenus.map(({ id: menuId, left, top }, i) => {\n const childMenuIndex = getChildMenuIndex(i);\n\n return (\n <Portal key={i} x={left} y={top} onRender={handleRender}>\n <MenuList\n {...menuListProps}\n activatedByKeyboard={navigatingWithKeyboard.current}\n childMenuShowing={childMenuIndex}\n className={className}\n id={id}\n menuId={menuId}\n isRoot={i === 0}\n key={i}\n listItemProps={listItemProps}\n onActivate={handleActivate}\n onHighlightMenuItem={handleHighlightMenuItem}\n onCloseMenu={handleCloseMenu}\n onOpenMenu={handleOpenMenu}\n style={style}\n >\n {menus[menuId]}\n </MenuList>\n </Portal>\n );\n })}\n </>\n );\n};\n\nContextMenu.displayName = \"ContextMenu\";\n", "import React, {\n FC,\n HTMLAttributes,\n ReactElement,\n useLayoutEffect,\n useMemo,\n useRef,\n} from \"react\";\nimport cx from \"classnames\";\nimport { useIdMemo as useId } from \"@salt-ds/core\";\nimport { useKeyboardNavigation } from \"./use-keyboard-navigation\";\nimport { isMenuItemGroup } from \"./use-items-with-ids\";\n\nimport \"./MenuList.css\";\n\nconst classBase = \"vuuMenuList\";\n\nexport const Separator = () => <li className=\"vuuMenuItem-divider\" />;\n\nexport interface MenuItemGroupProps {\n children: ReactElement<MenuItemProps>[];\n label: string;\n}\n\nexport interface MenuItemProps extends HTMLAttributes<HTMLDivElement> {\n action?: string;\n idx?: number;\n options?: unknown;\n}\n\n// Purely used as markers, props will be extracted\nexport const MenuItemGroup: FC<MenuItemGroupProps> = () => null;\n// eslint-disable-next-line no-unused-vars\nexport const MenuItem = ({ children, idx, ...props }: MenuItemProps) => {\n return <div {...props}>{children}</div>;\n};\n\nconst hasIcon = (child: ReactElement) => child.props[\"data-icon\"];\n\nexport interface MenuListProps extends HTMLAttributes<HTMLDivElement> {\n activatedByKeyboard?: boolean;\n children: ReactElement[];\n childMenuShowing?: number;\n highlightedIdx?: number;\n isRoot?: boolean;\n listItemProps?: Partial<MenuItemProps>;\n menuId?: string;\n onActivate?: (menuId: string) => void;\n onCloseMenu: (idx: number) => void;\n onOpenMenu?: (menuId: string) => void;\n onHighlightMenuItem?: (idx: number) => void;\n}\n\nconst MenuList = ({\n activatedByKeyboard,\n childMenuShowing = -1,\n children,\n className,\n highlightedIdx: highlightedIdxProp,\n id: idProp,\n isRoot,\n listItemProps,\n menuId,\n onHighlightMenuItem,\n onActivate,\n onCloseMenu,\n onOpenMenu,\n ...props\n}: MenuListProps) => {\n const id = useId(idProp);\n const root = useRef<HTMLDivElement>(null);\n\n // The id generation be,ongs in useIttemsWithIds\n const mapIdxToId = useMemo(() => new Map(), []);\n\n const handleOpenMenu = (idx: number) => {\n const el = root.current?.querySelector(`:scope > [data-idx='${idx}']`);\n el?.id && onOpenMenu?.(el.id);\n };\n\n const handleActivate = (idx: number) => {\n const el = root.current?.querySelector(`:scope > [data-idx='${idx}']`);\n el?.id && onActivate?.(el.id);\n };\n\n const { focusVisible, highlightedIndex, listProps } = useKeyboardNavigation({\n count: React.Children.count(children),\n highlightedIndex: highlightedIdxProp,\n onActivate: handleActivate,\n onHighlight: onHighlightMenuItem,\n onOpenMenu: handleOpenMenu,\n onCloseMenu,\n });\n\n const appliedFocusVisible = childMenuShowing == -1 ? focusVisible : -1;\n\n useLayoutEffect(() => {\n if (childMenuShowing === -1 && activatedByKeyboard) {\n root.current?.focus();\n }\n }, [activatedByKeyboard, childMenuShowing]);\n\n const getActiveDescendant = () =>\n highlightedIndex === undefined || highlightedIndex === -1\n ? undefined\n : mapIdxToId.get(highlightedIndex);\n\n return (\n <div\n {...props}\n {...listProps}\n aria-activedescendant={getActiveDescendant()}\n className={cx(classBase, className, {\n [`${classBase}-childMenuShowing`]: childMenuShowing !== -1,\n })}\n data-root={isRoot || undefined}\n id={`${id}-${menuId}`}\n ref={root}\n role=\"menu\"\n tabIndex={0}\n >\n {renderContent()}\n </div>\n );\n\n function renderContent() {\n const propsCommonToAllListItems = {\n ...listItemProps,\n role: \"menuitem\",\n };\n\n const maybeIcon = (\n childElement: ReactElement,\n withIcon: boolean,\n iconName?: string\n ) =>\n withIcon\n ? [\n <span\n className=\"vuuIconContainer\"\n data-icon={iconName}\n key=\"icon\"\n />,\n ].concat(childElement)\n : childElement;\n\n function addClonedChild(\n list: ReactElement[],\n child: ReactElement,\n idx: number,\n withIcon: boolean\n ) {\n const {\n children,\n className,\n \"data-icon\": iconName,\n id: itemId,\n hasSeparator,\n label,\n ...props\n } = child.props;\n const hasSubMenu = isMenuItemGroup(child);\n const subMenuShowing = hasSubMenu && childMenuShowing === idx;\n const ariaControls = subMenuShowing ? `${id}-${itemId}` : undefined;\n\n list.push(\n <MenuItem\n {...props}\n {...propsCommonToAllListItems}\n {...getMenuItemProps(\n `${id}-${menuId}`,\n itemId,\n idx,\n child.key ?? itemId,\n highlightedIndex,\n appliedFocusVisible,\n className,\n hasSeparator\n )}\n aria-controls={ariaControls}\n aria-haspopup={hasSubMenu || undefined}\n aria-expanded={subMenuShowing || undefined}\n >\n {hasSubMenu\n ? maybeIcon(label, withIcon, iconName)\n : maybeIcon(children, withIcon, iconName)}\n </MenuItem>\n );\n // mapIdxToId.set(idx, itemId);\n }\n\n const listItems: ReactElement[] = [];\n\n if (children.length > 0) {\n const withIcon = children.some(hasIcon);\n\n children.forEach((child, idx) => {\n addClonedChild(listItems, child, idx, withIcon);\n });\n }\n\n return listItems;\n }\n};\n\nconst getMenuItemProps = (\n baseId: string,\n itemId: string,\n idx: number,\n key: string,\n highlightedIdx: number,\n focusVisible: number,\n className: string,\n hasSeparator: boolean\n) => ({\n id: `${baseId}-${itemId}`,\n key: key ?? idx,\n \"data-idx\": idx,\n \"data-highlighted\": idx === highlightedIdx || undefined,\n className: cx(\"vuuMenuItem\", className, {\n \"vuuMenuItem-separator\": hasSeparator,\n focusVisible: focusVisible === idx,\n }),\n});\n\nMenuList.displayName = \"MenuList\";\nexport default MenuList;\n", "import {\n FocusEvent,\n KeyboardEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { hasPopup, isRoot } from \"./utils\";\nimport { isNavigationKey } from \"./key-code\";\n\nexport interface KeyboardNavigationProps {\n autoHighlightFirstItem?: boolean;\n count: number;\n highlightedIndex?: number;\n onActivate: (idx: number) => void;\n onHighlight?: (idx: number) => void;\n onCloseMenu: (idx: number) => void;\n onOpenMenu: (idx: number) => void;\n}\n\nexport interface KeyboardHookListProps {\n // onBlur: (evt: FocusEvent) => void;\n onFocus: (evt: FocusEvent) => void;\n onKeyDown: (evt: KeyboardEvent) => void;\n onMouseDownCapture: () => void;\n onMouseMove: () => void;\n onMouseLeave: () => void;\n}\n\nexport interface NavigationHookResult {\n focusVisible: number;\n controlledHighlighting: boolean;\n highlightedIndex: number;\n setHighlightedIndex: (idx: number) => void;\n // keyboardNavigation: RefObject<boolean>;\n listProps: KeyboardHookListProps;\n setIgnoreFocus: (ignoreFocus: boolean) => void;\n}\n\n// we need a way to set highlightedIdx when selection changes\nexport const useKeyboardNavigation = ({\n autoHighlightFirstItem = false,\n count,\n highlightedIndex: highlightedIndexProp,\n onActivate,\n onHighlight,\n // onKeyDown,\n onCloseMenu,\n onOpenMenu,\n}: KeyboardNavigationProps): NavigationHookResult => {\n // const prevCount = useRef(count);\n const highlightedIndexRef = useRef(\n highlightedIndexProp ?? autoHighlightFirstItem ? 0 : -1\n );\n const [, forceRender] = useState<unknown>(null);\n const controlledHighlighting = highlightedIndexProp !== undefined;\n\n // count will not work for this, as it will change when we expand collapse groups\n // if (count !== prevCount.current) {\n // prevCount.current = count;\n // if (highlightedIndexRef.current !== -1){\n // highlightedIndexRef.current = autoHighlightFirstItem ? 0 : -1;\n // }\n // }\n\n const setHighlightedIdx = useCallback(\n (idx) => {\n highlightedIndexRef.current = idx;\n onHighlight?.(idx);\n forceRender({});\n },\n [onHighlight]\n );\n\n const setHighlightedIndex = useCallback(\n (idx) => {\n if (idx !== highlightedIndexRef.current) {\n if (!controlledHighlighting) {\n setHighlightedIdx(idx);\n }\n }\n },\n [controlledHighlighting, setHighlightedIdx]\n );\n\n // does this belong here or should it be a method passed in?\n const keyBoardNavigation = useRef(true);\n const ignoreFocus = useRef(false);\n const setIgnoreFocus = (value: boolean) => (ignoreFocus.current = value);\n\n const highlightedIndex = controlledHighlighting\n ? highlightedIndexProp\n : highlightedIndexRef.current;\n\n const navigateChildldItems = useCallback(\n (e: KeyboardEvent) => {\n const nextIdx = nextItemIdx(count, e.key, highlightedIndexRef.current);\n if (nextIdx !== highlightedIndexRef.current) {\n setHighlightedIndex(nextIdx);\n }\n },\n [count, setHighlightedIndex]\n );\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (isNavigationKey(e)) {\n e.preventDefault();\n e.stopPropagation();\n keyBoardNavigation.current = true;\n navigateChildldItems(e);\n } else if (\n (e.key === \"ArrowRight\" || e.key === \"Enter\") &&\n hasPopup(e.target as HTMLElement, highlightedIndex)\n ) {\n onOpenMenu(highlightedIndex);\n } else if (e.key === \"ArrowLeft\" && !isRoot(e.target as HTMLElement)) {\n onCloseMenu(highlightedIndex);\n } else if (e.key === \"Enter\") {\n onActivate && onActivate(highlightedIndex);\n }\n },\n [\n highlightedIndex,\n navigateChildldItems,\n onActivate,\n onCloseMenu,\n onOpenMenu,\n ]\n );\n\n const listProps: KeyboardHookListProps = useMemo(\n () => ({\n onFocus: () => {\n if (highlightedIndex === -1) {\n setHighlightedIdx(0);\n }\n },\n onKeyDown: handleKeyDown,\n onMouseDownCapture: () => {\n keyBoardNavigation.current = false;\n setIgnoreFocus(true);\n },\n\n // onMouseEnter would seem less expensive but it misses some cases\n onMouseMove: () => {\n if (keyBoardNavigation.current) {\n keyBoardNavigation.current = false;\n }\n },\n onMouseLeave: () => {\n // label === 'ParsedInput' && console.log(`%c[useKeyboardNavigationHook]<${label}> onMouseLeave`,'color:brown')\n keyBoardNavigation.current = true;\n setIgnoreFocus(false);\n setHighlightedIndex(-1);\n },\n }),\n [\n highlightedIndex,\n setHighlightedIndex,\n navigateChildldItems,\n onActivate,\n onCloseMenu,\n onOpenMenu,\n setHighlightedIdx,\n ]\n );\n\n // label === 'ParsedInput' && console.log(`%cuseNavigationHook<${label}>\n // highlightedIdxProp= ${highlightedIdxProp},\n // highlightedIndexRef= ${highlightedIndexRef.current},\n // %chighlightedIdx= ${highlightedIdx}`, 'color: brown','color: brown;font-weight: bold;')\n\n return {\n focusVisible: keyBoardNavigation.current ? highlightedIndex : -1,\n controlledHighlighting,\n highlightedIndex,\n setHighlightedIndex: setHighlightedIndex,\n // keyBoardNavigation,\n listProps,\n setIgnoreFocus,\n };\n};\n\n// need to be able to accommodate disabled items\nfunction nextItemIdx(count: number, key: string, idx: number) {\n if (key === \"ArrowUp\") {\n if (idx > 0) {\n return idx - 1;\n } else {\n return idx;\n }\n } else {\n if (idx === null) {\n return 0;\n } else if (idx === count - 1) {\n return idx;\n } else {\n return idx + 1;\n }\n }\n}\n", "export const isRoot = (el: HTMLElement) =>\n el.closest(`[data-root='true']`) !== null;\n\nexport const hasPopup = (el: HTMLElement, idx: number) =>\n (el.ariaHasPopup === \"true\" && el.dataset?.idx === `${idx}`) ||\n el.querySelector(`:scope > [data-idx='${idx}'][aria-haspopup='true']`) !==\n null;\n", "function union(set1: Set<string>, ...sets: Set<string>[]) {\n const result = new Set(set1);\n for (const set of sets) {\n for (const element of set) {\n result.add(element);\n }\n }\n return result;\n}\n\nexport const ArrowUp = \"ArrowUp\";\nexport const ArrowDown = \"ArrowDown\";\nexport const ArrowLeft = \"ArrowLeft\";\nexport const Backspace = \"Backspace\";\nexport const ArrowRight = \"ArrowRight\";\nexport const Enter = \"Enter\";\nexport const Escape = \"Escape\";\nexport const Delete = \"Delete\";\n\nconst actionKeys = new Set([Enter, Delete]);\nconst focusKeys = new Set([\"Tab\"]);\n// const navigationKeys = new Set([\"Home\", \"End\", \"ArrowRight\", \"ArrowLeft\",\"ArrowDown\", \"ArrowUp\"]);\nconst arrowLeftRightKeys = new Set([\"ArrowRight\", \"ArrowLeft\"]);\nconst verticalNavigationKeys = new Set([\"Home\", \"End\", \"ArrowDown\", \"ArrowUp\"]);\nconst horizontalNavigationKeys = new Set([\n \"Home\",\n \"End\",\n \"ArrowRight\",\n \"ArrowLeft\",\n]);\nconst functionKeys = new Set([\n \"F1\",\n \"F2\",\n \"F3\",\n \"F4\",\n \"F5\",\n \"F6\",\n \"F7\",\n \"F8\",\n \"F9\",\n \"F10\",\n \"F11\",\n \"F12\",\n]);\nconst specialKeys = union(\n actionKeys,\n horizontalNavigationKeys,\n verticalNavigationKeys,\n arrowLeftRightKeys,\n functionKeys,\n focusKeys\n);\nexport const isCharacterKey = (evt: KeyboardEvent) => {\n if (specialKeys.has(evt.key)) {\n return false;\n }\n if (typeof evt.which === \"number\" && evt.which > 0) {\n return !evt.ctrlKey && !evt.metaKey && !evt.altKey && evt.which !== 8;\n }\n};\n\nexport const isNavigationKey = (\n { key }: { key: string },\n orientation = \"vertical\"\n) => {\n const navigationKeys =\n orientation === \"vertical\"\n ? verticalNavigationKeys\n : horizontalNavigationKeys;\n return navigationKeys.has(key);\n};\n", "import React, { ReactElement, useCallback, useMemo } from \"react\";\nimport { MenuItemGroup, Separator } from \"./MenuList\";\n\nexport const isMenuItemGroup = (child: ReactElement) =>\n child.type === MenuItemGroup || !!child.props[\"data-group\"];\n\ntype Menus = { [key: string]: ReactElement[] };\ntype Actions = { [key: string]: { action: string; options?: unknown } };\n\nexport const useItemsWithIds = (\n childrenProp: ReactElement[]\n): [Menus, Actions] => {\n const normalizeChildren = useCallback(() => {\n const collectChildren = (\n children: ReactElement[],\n path = \"root\",\n menus: Menus = {},\n actions: Actions = {}\n ) => {\n const list: ReactElement[] = (menus[path] = []);\n let idx = 0;\n let hasSeparator = false;\n\n React.Children.forEach(children, (child) => {\n if (child.type === Separator) {\n hasSeparator = true;\n } else {\n const group = isMenuItemGroup(child);\n const childPath = path === \"root\" ? `${idx}` : `${path}.${idx}`;\n const {\n props: { action, options },\n } = child;\n const { childWithId, grandChildren } = assignId(\n child,\n childPath,\n group,\n hasSeparator\n );\n list.push(childWithId);\n if (grandChildren) {\n collectChildren(grandChildren, childPath, menus, actions);\n } else {\n actions[childPath] = { action, options };\n }\n idx += 1;\n hasSeparator = false;\n }\n });\n return [menus, actions];\n };\n\n const assignId = (\n child: ReactElement,\n path: string,\n group: boolean,\n hasSeparator = false\n ) => {\n const {\n props: { children },\n } = child;\n return {\n childWithId: React.cloneElement(child, {\n hasSeparator,\n id: `${path}`,\n key: path,\n children: group ? undefined : children,\n }),\n grandChildren: group ? children : undefined,\n };\n };\n\n return collectChildren(childrenProp);\n }, [childrenProp]);\n\n const [menus, actions] = useMemo(\n () => normalizeChildren(),\n [normalizeChildren]\n );\n\n return [menus, actions] as [Menus, Actions];\n};\n", "import {\n MouseEvent,\n SyntheticEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { closestListItem, listItemIndex } from \"./list-dom-utils\";\nimport { MenuItemProps } from \"./MenuList\";\n// import {mousePosition} from './aim/utils';\n// import {aiming} from './aim/aim';\n\nconst nudge = (\n menus: RuntimeMenuDescriptor[],\n distance: number,\n pos: \"left\" | \"top\"\n) => {\n return menus.map((m, i) =>\n i === menus.length - 1\n ? {\n ...m,\n [pos]: m[pos] - distance,\n }\n : m\n );\n};\nconst nudgeLeft = (menus: RuntimeMenuDescriptor[], distance: number) =>\n nudge(menus, distance, \"left\");\nconst nudgeUp = (menus: RuntimeMenuDescriptor[], distance: number) =>\n nudge(menus, distance, \"top\");\n\nconst flipSides = (id: string, menus: RuntimeMenuDescriptor[]) => {\n const [parentMenu, menu] = menus.slice(-2);\n const el = document.getElementById(`${id}-${menu.id}`);\n if (el === null) {\n throw Error(`useCascade.flipSides element with id ${menu.id} not found`);\n }\n const { width } = el.getBoundingClientRect();\n return menus.map((m) =>\n m === menu\n ? {\n ...m,\n left: parentMenu.left - (width - 2),\n }\n : m\n );\n};\n\n// const closedNode = (el: HTMLElement) =>\n// el.ariaHasPopup === \"true\" && el.ariaExpanded !== \"true\";\nconst getPosition = (el: HTMLElement, openMenus: RuntimeMenuDescriptor[]) => {\n const [{ left, top: menuTop }] = openMenus.slice(-1);\n // const {top, right, bottom, left} = el.getBoundingClientRect();\n // this will not work for MenuList within window, we need the\n // const {offsetLeft: left, offsetTop: menuTop} = el.closest('.vuuMenuList');\n const { offsetWidth: width, offsetTop: top } = el;\n return { left: left + width, top: top + menuTop };\n};\n\nexport type RuntimeMenuDescriptor = {\n id: string;\n left: number;\n top: number;\n};\n\nexport const getItemId = (id: string) => {\n const pos = id.lastIndexOf(\"-\");\n return pos === -1 ? id : id.slice(pos + 1);\n};\n\nexport const getMenuId = (id: string) => {\n const itemId = getItemId(id);\n const pos = itemId.lastIndexOf(\".\");\n return pos > -1 ? itemId.slice(0, pos) : \"root\";\n};\n\nconst getMenuDepth = (id: string) => {\n let count = 0,\n pos = id.indexOf(\".\", 0);\n while (pos !== -1) {\n count += 1;\n pos = id.indexOf(\".\", pos + 1);\n }\n return count;\n};\n\nconst identifyItem = (el: HTMLElement) => ({\n menuId: getMenuId(el.id),\n itemId: getItemId(el.id),\n isGroup: el.ariaHasPopup === \"true\",\n isOpen: el.ariaExpanded === \"true\",\n level: getMenuDepth(el.id),\n});\n\nexport interface CascadeHookProps {\n id: string;\n onActivate: (menuId: string) => void;\n onMouseEnterItem: (evt: MouseEvent, itemId: string) => void;\n position: { x: number; y: number };\n}\n\nexport interface CascadeHooksResult {\n closeMenu: () => void;\n handleRender: () => void;\n listItemProps: Partial<MenuItemProps>;\n openMenu: (menuId?: string, itemId?: string) => void;\n openMenus: RuntimeMenuDescriptor[];\n}\n\ntype MenuStatus = \"no-popup\" | \"popup-open\" | \"pending-close\" | \"popup-pending\";\ntype MenuState = { [key: string]: MenuStatus };\n\nexport const useCascade = ({\n id,\n onActivate,\n onMouseEnterItem,\n position: { x: posX, y: posY },\n}: CascadeHookProps): CascadeHooksResult => {\n const [, forceRefresh] = useState({});\n const openMenus = useRef<RuntimeMenuDescriptor[]>([\n { id: \"root\", left: posX, top: posY },\n ]);\n\n const setOpenMenus = useCallback((menus: RuntimeMenuDescriptor[]) => {\n openMenus.current = menus;\n forceRefresh({});\n }, []);\n\n const menuOpenPendingTimeout = useRef<number | undefined>();\n const menuClosePendingTimeout = useRef<number | undefined>();\n const menuState = useRef<MenuState>({ root: \"no-popup\" });\n const prevLevel = useRef(0);\n\n // const prevAim = useRef({mousePos: null, distance: true});\n\n const openMenu = useCallback(\n (menuId = \"root\", itemId = null, listItemEl = null) => {\n if (menuId === \"root\" && itemId === null) {\n setOpenMenus([{ id: \"root\", left: posX, top: posY }]);\n } else {\n menuState.current[menuId] = \"popup-open\";\n const doc = listItemEl ? listItemEl.ownerDocument : document;\n const el = doc.getElementById(`${id}-${menuId}-${itemId}`);\n const { left, top } = getPosition(el, openMenus.current);\n setOpenMenus(openMenus.current.concat({ id: itemId, left, top }));\n }\n },\n [id, posX, posY, setOpenMenus]\n );\n\n const closeMenu = useCallback(\n (menuId?: string) => {\n if (menuId === \"root\") {\n setOpenMenus([]);\n } else {\n setOpenMenus(openMenus.current.slice(0, -1));\n }\n },\n [setOpenMenus]\n );\n\n const closeMenus = useCallback(\n (menuId, itemId) => {\n const menus = openMenus.current.slice();\n let { id: lastMenuId } = menus[menus.length - 1];\n while (menus.length > 1 && !itemId.startsWith(lastMenuId)) {\n const parentMenuId = getMenuId(lastMenuId);\n menus.pop();\n menuState.current[lastMenuId] = \"no-popup\";\n menuState.current[parentMenuId] = \"no-popup\";\n ({ id: lastMenuId } = menus[menus.length - 1]);\n }\n if (menus.length < openMenus.current.length) {\n setOpenMenus(menus);\n }\n },\n [setOpenMenus]\n );\n\n const scheduleOpen = useCallback(\n (menuId, itemId, listItemEl) => {\n if (menuOpenPendingTimeout.current) {\n clearTimeout(menuOpenPendingTimeout.current);\n }\n menuOpenPendingTimeout.current = window.setTimeout(() => {\n console.log(`scheduleOpen timed out opening ${itemId}`);\n closeMenus(menuId, itemId);\n menuState.current[menuId] = \"popup-open\";\n menuState.current[itemId] = \"no-popup\";\n openMenu(menuId, itemId, listItemEl);\n }, 400);\n },\n [closeMenus, openMenu]\n );\n\n const scheduleClose = useCallback(\n (openMenuId, menuId, itemId) => {\n console.log(\n `scheduleClose openMenuId ${openMenuId} menuId ${menuId} itemId ${itemId}`\n );\n menuState.current[openMenuId] = \"pending-close\";\n menuClosePendingTimeout.current = window.setTimeout(() => {\n closeMenus(menuId, itemId);\n }, 400);\n },\n [closeMenus]\n );\n\n const handleRender = useCallback(() => {\n const { current: menus } = openMenus;\n const [menu] = menus.slice(-1);\n const el = document.getElementById(`${id}-${menu.id}`);\n if (el) {\n const { right, bottom } = el.getBoundingClientRect();\n const { clientHeight, clientWidth } = document.body;\n if (right > clientWidth) {\n const newMenus =\n menus.length > 1\n ? flipSides(id, menus)\n : nudgeLeft(menus, right - clientWidth);\n setOpenMenus(newMenus);\n } else if (bottom > clientHeight) {\n const newMenus = nudgeUp(menus, bottom - clientHeight);\n setOpenMenus(newMenus);\n }\n }\n }, [id, setOpenMenus]);\n\n const listItemProps: Partial<MenuItemProps> = useMemo(\n () => ({\n onMouseEnter: (evt: MouseEvent) => {\n const listItemEl = closestListItem(evt.target as HTMLElement);\n const { menuId, itemId, isGroup, isOpen, level } =\n identifyItem(listItemEl);\n const sameLevel = prevLevel.current === level;\n const {\n current: { [menuId]: state },\n } = menuState;\n prevLevel.current = level;\n\n // console.log(\n // `%conMouseEnter #${menuId}[${itemId}] @${level}\n // isGroup ${isGroup} isOpen ${isOpen}\n // openMenus [${openMenus.current.join(',')}]\n // state='${JSON.stringify(menuState.current)}`,\n // 'color: green; font-weight: bold;'\n // );\n\n if (state === \"no-popup\" && isGroup) {\n // Shouldn;t we always set this ?\n menuState.current[menuId] = \"popup-pending\";\n scheduleOpen(menuId, itemId, listItemEl);\n } else if (state === \"popup-pending\" && !isGroup) {\n menuState.current[menuId] = \"no-popup\";\n clearTimeout(menuOpenPendingTimeout.current);\n menuOpenPendingTimeout.current = undefined;\n } else if (state === \"popup-pending\" && isGroup) {\n clearTimeout(menuOpenPendingTimeout.current);\n scheduleOpen(menuId, itemId, listItemEl);\n } else if (state === \"popup-open\") {\n const [{ id: parentMenuId }, { id: openMenuId }] =\n openMenus.current.slice(-2);\n if (\n parentMenuId === menuId &&\n menuState.current[openMenuId] !== \"pending-close\" &&\n sameLevel\n ) {\n scheduleClose(openMenuId, menuId, itemId);\n if (isGroup && !isOpen) {\n scheduleOpen(menuId, itemId, listItemEl);\n }\n } else if (\n parentMenuId === menuId &&\n isGroup &&\n itemId !== openMenuId &&\n menuState.current[openMenuId] === \"pending-close\"\n ) {\n // if there is already an item queued for opening cancel it\n scheduleOpen(menuId, itemId, listItemEl);\n } else if (isGroup) {\n closeMenus(menuId, itemId);\n scheduleOpen(menuId, itemId, listItemEl);\n } else if (\n !(menuState.current[openMenuId] === \"pending-close\" && sameLevel)\n ) {\n closeMenus(menuId, itemId);\n }\n }\n\n if (state === \"pending-close\") {\n if (menuOpenPendingTimeout.current) {\n clearTimeout(menuOpenPendingTimeout.current);\n menuOpenPendingTimeout.current = undefined;\n }\n clearTimeout(menuClosePendingTimeout.current);\n menuClosePendingTimeout.current = undefined;\n menuState.current[menuId] = \"popup-open\";\n }\n\n onMouseEnterItem(evt, itemId);\n },\n\n onClick: (evt: SyntheticEvent) => {\n const targetElement = evt.target as HTMLElement;\n const listItemEl = closestListItem(targetElement);\n const idx = listItemIndex(listItemEl);\n console.log(\n `list item click [${idx}] hasPopup ${listItemEl.ariaHasPopup}`\n );\n if (listItemEl.ariaHasPopup === \"true\") {\n if (listItemEl.ariaExpanded !== \"true\") {\n openMenu(idx);\n } else {\n // do nothing\n }\n } else {\n onActivate(getItemId(listItemEl.id));\n }\n },\n }),\n [\n closeMenus,\n onActivate,\n\n onMouseEnterItem,\n openMenu,\n scheduleClose,\n scheduleOpen,\n ]\n );\n\n return {\n closeMenu,\n handleRender,\n listItemProps,\n openMenu,\n openMenus: openMenus.current,\n };\n};\n", "// const listItemElement = (listEl: HTMLElement, listItemIdx: number) =>\n// listEl.querySelector(`:scope > [data-idx=\"${listItemIdx}\"]`);\n\nexport function listItemIndex(listItemEl: HTMLElement) {\n if (listItemEl) {\n const idx = listItemEl.dataset.idx;\n if (idx) {\n return parseInt(idx, 10);\n // eslint-disable-next-line no-cond-assign\n } else if (listItemEl.ariaPosInSet) {\n return parseInt(listItemEl.ariaPosInSet, 10) - 1;\n }\n }\n}\n\nconst listItemId = (el: HTMLElement | null | undefined) => el?.id;\n\nexport const closestListItem = (el: HTMLElement | null | undefined) =>\n el?.closest(\"[data-idx],[aria-posinset]\") as HTMLElement;\n\nexport const closestListItemId = (el: HTMLElement) =>\n listItemId(closestListItem(el));\n\nexport const closestListItemIndex = (el: HTMLElement) =>\n listItemIndex(closestListItem(el));\n", "import { useEffect } from \"react\";\n\nexport interface ClickAwayHookProps {\n containerClassName: string;\n isOpen: boolean;\n onClose?: (target: string) => void;\n}\n\nexport const useClickAway = ({\n containerClassName,\n isOpen,\n onClose,\n}: ClickAwayHookProps) => {\n useEffect(() => {\n let clickHandler: (evt: MouseEvent) => void;\n if (isOpen) {\n clickHandler = (evt) => {\n const target = evt.target as HTMLElement;\n const container = target.closest(`.${containerClassName}`);\n if (container === null) {\n onClose?.(\"root\");\n }\n };\n\n document.body.addEventListener(\"click\", clickHandler, true);\n }\n\n return () => {\n if (clickHandler) {\n document.body.removeEventListener(\"click\", clickHandler, true);\n }\n };\n }, [containerClassName, isOpen, onClose]);\n};\n", "import { createContext, ReactNode, useCallback, useMemo } from \"react\";\n\nexport type MenuActionHandler = (\n type: string,\n options: unknown\n) => boolean | undefined;\nexport type MenuBuilder<L = string, O = unknown> = (\n location: L,\n options: O\n) => ContextMenuItemDescriptor[];\n\nexport interface ContextMenuContext {\n menuBuilders: MenuBuilder[];\n menuActionHandler: MenuActionHandler;\n}\n\nexport const ContextMenuContext = createContext<ContextMenuContext | null>(\n null\n);\n\nexport interface ContextMenuItemBase {\n icon?: string;\n label: string;\n location?: string;\n}\n\nexport interface ContextMenuLeafItemDescriptor extends ContextMenuItemBase {\n action: string;\n options?: unknown;\n}\n\nexport interface ContextMenuGroupItemDescriptor extends ContextMenuItemBase {\n children: ContextMenuItemDescriptor[];\n}\n\nexport type ContextMenuItemDescriptor =\n | ContextMenuLeafItemDescriptor\n | ContextMenuGroupItemDescriptor;\n\nexport const isGroupMenuItemDescriptor = (\n menuItem?: ContextMenuItemDescriptor\n): menuItem is ContextMenuGroupItemDescriptor =>\n menuItem !== undefined && \"children\" in menuItem;\n\nexport interface ContextMenuProviderProps {\n children: ReactNode;\n label?: string;\n menuActionHandler?: MenuActionHandler;\n menuBuilder: MenuBuilder;\n}\n\ninterface ProviderProps extends ContextMenuProviderProps {\n context: ContextMenuContext | null;\n}\n\nconst Provider = ({\n children,\n context,\n menuActionHandler,\n menuBuilder,\n}: ProviderProps) => {\n const menuBuilders = useMemo(() => {\n if (context?.menuBuilders && menuBuilder) {\n return context.menuBuilders.concat(menuBuilder);\n } else if (menuBuilder) {\n return [menuBuilder];\n } else {\n return context?.menuBuilders || [];\n }\n }, [context, menuBuilder]);\n\n const handleMenuAction = useCallback(\n (type, options) => {\n if (menuActionHandler?.(type, options)) {\n return true;\n }\n\n if (context?.menuActionHandler?.(type, options)) {\n return true;\n }\n },\n [context, menuActionHandler]\n );\n\n return (\n <ContextMenuContext.Provider\n value={{\n menuActionHandler: handleMenuAction,\n menuBuilders,\n }}\n >\n {children}\n </ContextMenuContext.Provider>\n );\n};\n\n// Need an option for local menu to override higher-level menu, rather than extend\nexport const ContextMenuProvider = ({\n children,\n label,\n menuActionHandler,\n menuBuilder,\n}: ContextMenuProviderProps) => {\n return (\n <ContextMenuContext.Consumer>\n {(parentContext) => (\n <Provider\n context={parentContext}\n label={label}\n menuActionHandler={menuActionHandler}\n menuBuilder={menuBuilder}\n >\n {children}\n </Provider>\n )}\n </ContextMenuContext.Consumer>\n );\n};\n", "// The menuBuilder will always be supplied by the code that will display the local\n// context menu. It will be passed all configured menu descriptors. It is free to\n\nimport { VuuServerMenuOptions } from \"@vuu-ui/vuu-data\";\nimport { MouseEvent, useCallback, useContext } from \"react\";\nimport { PopupService } from \"../popup\";\nimport {\n ContextMenuContext,\n ContextMenuItemDescriptor,\n isGroupMenuItemDescriptor,\n MenuActionHandler,\n MenuBuilder,\n} from \"./context-menu-provider\";\nimport { ContextMenu } from \"./ContextMenu\";\nimport { MenuItem, MenuItemGroup } from \"./MenuList\";\n\n// augment, replace or ignore the existing menu descriptors.\nexport const useContextMenu = () => {\n const ctx = useContext(ContextMenuContext);\n\n const buildMenuOptions = useCallback(\n (menuBuilders: MenuBuilder[], location, options) => {\n let results: ContextMenuItemDescriptor[] = [];\n for (const menuBuilder of menuBuilders) {\n // Maybe we should leave the concatenation to the menuBuilder, then it can control menuItem order\n results = results.concat(menuBuilder(location, options));\n }\n return results;\n },\n []\n );\n\n const handleShowContextMenu = useCallback(\n (e: MouseEvent<HTMLElement>, location: string, options: unknown) => {\n e.stopPropagation();\n e.preventDefault();\n const menuBuilders = ctx?.menuBuilders ?? [];\n const menuItemDescriptors = buildMenuOptions(\n menuBuilders,\n location,\n options\n );\n console.log({\n menuItemDescriptors,\n });\n if (menuItemDescriptors.length && ctx?.menuActionHandler) {\n console.log(`showContextMenu ${location}`, {\n options,\n });\n showContextMenu(e, menuItemDescriptors, ctx.menuActionHandler);\n }\n },\n [buildMenuOptions, ctx]\n );\n\n return handleShowContextMenu;\n};\n\nconst showContextMenu = (\n e: MouseEvent<HTMLElement>,\n menuDescriptors: ContextMenuItemDescriptor[],\n handleContextMenuAction: MenuActionHandler\n) => {\n const { clientX: left, clientY: top } = e;\n const menuItems = (menuDescriptors: ContextMenuItemDescriptor[]) => {\n const fromDescriptor = (menuItem: ContextMenuItemDescriptor, i: number) =>\n isGroupMenuItemDescriptor(menuItem) ? (\n <MenuItemGroup key={i} label={menuItem.label}>\n {menuItem.children.map(fromDescriptor)}\n </MenuItemGroup>\n ) : (\n <MenuItem\n key={i}\n action={menuItem.action}\n data-icon={menuItem.icon}\n options={menuItem.options}\n >\n {menuItem.label}\n </MenuItem>\n );\n\n return menuDescriptors.map(fromDescriptor);\n };\n\n const handleClose = (menuId?: string, options?: unknown) => {\n if (menuId) {\n handleContextMenuAction(menuId, options);\n PopupService.hidePopup();\n }\n };\n\n const component = (\n <ContextMenu onClose={handleClose} position={{ x: left, y: top }}>\n {menuItems(menuDescriptors)}\n </ContextMenu>\n );\n PopupService.showPopup({ left: 0, top: 0, component });\n};\n", "import cx from \"classnames\";\nimport React, {\n createElement,\n CSSProperties,\n HTMLAttributes,\n ReactElement,\n useEffect,\n useRef,\n} from \"react\";\nimport ReactDOM from \"react-dom\";\nimport { renderPortal } from \"../portal\";\n\nimport \"./popup-service.css\";\n\nlet _dialogOpen = false;\nconst _popups: string[] = [];\n\nfunction specialKeyHandler(e: KeyboardEvent) {\n if (e.key === \"Esc\") {\n if (_popups.length) {\n closeAllPopups();\n } else if (_dialogOpen) {\n const dialogRoot = document.body.querySelector(\".vuuDialog\");\n if (dialogRoot) {\n ReactDOM.unmountComponentAtNode(dialogRoot);\n }\n }\n }\n}\n\nfunction outsideClickHandler(e: MouseEvent) {\n if (_popups.length) {\n // onsole.log(`Popup.outsideClickHandler`);\n const popupContainers = document.body.querySelectorAll(\".vuuPopup\");\n for (let i = 0; i < popupContainers.length; i++) {\n if (popupContainers[i].contains(e.target as HTMLElement)) {\n return;\n }\n }\n closeAllPopups();\n }\n}\n\nfunction closeAllPopups() {\n if (_popups.length) {\n // onsole.log(`closeAllPopups`);\n const popupContainers = document.body.querySelectorAll(\".vuuPopup\");\n for (let i = 0; i < popupContainers.length; i++) {\n ReactDOM.unmountComponentAtNode(popupContainers[i]);\n }\n popupClosed(\"*\");\n }\n}\n\nfunction dialogOpened() {\n if (_dialogOpen === false) {\n _dialogOpen = true;\n window.addEventListener(\"keydown\", specialKeyHandler, true);\n }\n}\n\nfunction dialogClosed() {\n if (_dialogOpen) {\n _dialogOpen = false;\n window.removeEventListener(\"keydown\", specialKeyHandler, true);\n }\n}\n\nfunction popupOpened(name: string) {\n if (_popups.indexOf(name) === -1) {\n _popups.push(name);\n //onsole.log('PopupService, popup opened ' + name + ' popups : ' + _popups);\n if (_dialogOpen === false) {\n window.addEventListener(\"keydown\", specialKeyHandler, true);\n window.addEventListener(\"click\", outsideClickHandler, true);\n }\n }\n}\n\nfunction popupClosed(name: string /*, group=null*/) {\n if (_popups.length) {\n if (name === \"*\") {\n _popups.length = 0;\n } else {\n const pos = _popups.indexOf(name);\n if (pos !== -1) {\n _popups.splice(pos, 1);\n }\n }\n //onsole.log('PopupService, popup closed ' + name + ' popups : ' + _popups);\n if (_popups.length === 0 && _dialogOpen === false) {\n window.removeEventListener(\"keydown\", specialKeyHandler, true);\n window.removeEventListener(\"click\", outsideClickHandler, true);\n }\n }\n}\n\nconst PopupComponent = ({\n children,\n position,\n style,\n}: HTMLAttributes<HTMLDivElement> & {\n position?: \"above\" | \"below\" | \"\";\n style?: CSSProperties;\n}) => {\n const className = cx(\"hwPopup\", \"hwPopupContainer\", position);\n return createElement(\"div\", { className, style }, children);\n};\n\nlet incrementingKey = 1;\n\nexport class PopupService {\n static showPopup({\n name = \"anon\",\n group = \"all\",\n position = \"\",\n left = 0,\n right = \"auto\",\n top = 0,\n width = \"auto\",\n component,\n }: {\n depth?: number;\n name?: string;\n group?: string;\n position?: \"above\" | \"below\" | \"\";\n left?: number;\n right?: \"auto\" | number;\n top?: number;\n component: ReactElement;\n width?: number | \"auto\";\n }) {\n if (!component) {\n throw Error(`PopupService showPopup, no component supplied`);\n }\n popupOpened(name);\n let el = document.body.querySelector(\".vuuPopup.\" + group) as HTMLElement;\n if (el === null) {\n el = document.createElement(\"div\") as HTMLElement;\n el.className = \"vuuPopup \" + group;\n document.body.appendChild(el);\n }\n\n const style = { width };\n\n renderPortal(\n createElement(\n PopupComponent,\n { key: incrementingKey++, position, style },\n component\n ),\n el,\n left,\n top,\n () => {\n PopupService.keepWithinThePage(el, right);\n }\n );\n }\n\n static hidePopup(name = \"anon\", group = \"all\") {\n //onsole.log('PopupService.hidePopup name=' + name + ', group=' + group)\n\n if (_popups.indexOf(name) !== -1) {\n popupClosed(name);\n const popupRoot = document.body.querySelector(`.vuuPopup.${group}`);\n if (popupRoot) {\n ReactDOM.unmountComponentAtNode(popupRoot);\n }\n }\n }\n\n static keepWithinThePage(el: HTMLElement, right: number | \"auto\" = \"auto\") {\n const target = el.querySelector(\".vuuPopupContainer > *\") as HTMLElement;\n if (target) {\n const {\n top,\n left,\n width,\n height,\n right: currentRight,\n } = target.getBoundingClientRect();\n\n const w = window.innerWidth;\n const h = window.innerHeight;\n\n const overflowH = h - (top + height);\n if (overflowH < 0) {\n target.style.top = Math.round(top) + overflowH + \"px\";\n }\n\n const overflowW = w - (left + width);\n if (overflowW < 0) {\n target.style.left = Math.round(left) + overflowW + \"px\";\n }\n\n if (typeof right === \"number\" && right !== currentRight) {\n const adjustment = right - currentRight;\n target.style.left = left + adjustment + \"px\";\n }\n }\n }\n}\n\nexport class DialogService {\n static showDialog(dialog: ReactElement) {\n const containerEl = \".vuuDialog\";\n const onClose = dialog.props.onClose;\n\n dialogOpened();\n\n ReactDOM.render(\n React.cloneElement(dialog, {\n container: containerEl,\n onClose: () => {\n DialogService.closeDialog();\n if (onClose) {\n onClose();\n }\n },\n }),\n document.body.querySelector(containerEl)\n );\n }\n\n static closeDialog() {\n dialogClosed();\n const dialogRoot = document.body.querySelector(\".vuuDialog\");\n if (dialogRoot) {\n ReactDOM.unmountComponentAtNode(dialogRoot);\n }\n }\n}\n\nexport interface PopupProps {\n children: ReactElement;\n close?: boolean;\n depth: number;\n group?: string;\n name: string;\n position?: \"above\" | \"below\" | \"\";\n width: number;\n}\n\nexport const Popup = (props: PopupProps) => {\n const pendingTask = useRef<number | undefined>();\n const ref = useRef<HTMLElement>(null);\n\n const show = (props: PopupProps, boundingClientRect: DOMRect) => {\n const { name, group, depth, width } = props;\n let left: number | undefined;\n let top: number | undefined;\n\n if (pendingTask.current) {\n window.clearTimeout(pendingTask.current);\n pendingTask.current = undefined;\n }\n\n if (props.close === true) {\n PopupService.hidePopup(name, group);\n } else {\n const { position, children: component } = props;\n const {\n left: targetLeft,\n top: targetTop,\n width: clientWidth,\n bottom: targetBottom,\n } = boundingClientRect;\n\n if (position === \"below\") {\n left = targetLeft;\n top = targetBottom;\n } else if (position === \"above\") {\n left = targetLeft;\n top = targetTop;\n }\n\n pendingTask.current = window.setTimeout(() => {\n PopupService.showPopup({\n name,\n group,\n depth,\n position,\n left,\n top,\n width: width || clientWidth,\n component,\n });\n }, 10);\n }\n };\n\n useEffect(() => {\n if (ref.current) {\n const el = ref.current.parentElement;\n const boundingClientRect = el?.getBoundingClientRect();\n if (boundingClientRect) {\n show(props, boundingClientRect);\n }\n }\n\n return () => {\n PopupService.hidePopup(props.name, props.group);\n };\n }, [props]);\n\n return React.createElement(\"div\", { className: \"popup-proxy\", ref });\n};\n"],
5
- "mappings": "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",
6
- "names": ["Scrim", "Toolbar", "ToolbarButton", "Text", "cx", "useCallback", "useRef", "useState", "useLayoutEffect", "useMemo", "ReactDOM", "ReactDOM", "SaltProvider", "jsx", "containerId", "getPortalContainer", "x", "y", "win", "el", "createDOMContainer", "renderPortal", "component", "container", "onRender", "createContainer", "Portal", "children", "x", "y", "onRender", "renderContainer", "useMemo", "createContainer", "useLayoutEffect", "renderPortal", "_a", "installTheme", "themeId", "installedThemes", "jsx", "jsxs", "classBase", "Dialog", "children", "className", "isOpen", "onClose", "title", "props", "root", "useRef", "posX", "useState", "posY", "close", "useCallback", "handleRender", "Portal", "Scrim", "cx", "Toolbar", "Text", "ToolbarButton", "useId", "useCallback", "useRef", "React", "useLayoutEffect", "useMemo", "useRef", "cx", "useId", "useCallback", "useMemo", "useRef", "useState", "isRoot", "el", "hasPopup", "idx", "_a", "union", "set1", "sets", "result", "set", "element", "Enter", "Delete", "actionKeys", "Enter", "focusKeys", "arrowLeftRightKeys", "verticalNavigationKeys", "horizontalNavigationKeys", "functionKeys", "specialKeys", "union", "isNavigationKey", "key", "orientation", "verticalNavigationKeys", "horizontalNavigationKeys", "useKeyboardNavigation", "autoHighlightFirstItem", "count", "highlightedIndexProp", "onActivate", "onHighlight", "onCloseMenu", "onOpenMenu", "highlightedIndexRef", "useRef", "forceRender", "useState", "controlledHighlighting", "setHighlightedIdx", "useCallback", "idx", "setHighlightedIndex", "keyBoardNavigation", "ignoreFocus", "setIgnoreFocus", "value", "highlightedIndex", "navigateChildldItems", "e", "nextIdx", "nextItemIdx", "handleKeyDown", "isNavigationKey", "hasPopup", "isRoot", "listProps", "useMemo", "key", "React", "useCallback", "useMemo", "isMenuItemGroup", "child", "MenuItemGroup", "useItemsWithIds", "childrenProp", "normalizeChildren", "useCallback", "collectChildren", "children", "path", "menus", "actions", "list", "idx", "hasSeparator", "React", "Separator", "group", "childPath", "action", "options", "childWithId", "grandChildren", "assignId", "useMemo", "jsx", "classBase", "Separator", "MenuItemGroup", "MenuItem", "children", "idx", "props", "hasIcon", "child", "MenuList", "activatedByKeyboard", "childMenuShowing", "className", "highlightedIdxProp", "idProp", "isRoot", "listItemProps", "menuId", "onHighlightMenuItem", "onActivate", "onCloseMenu", "onOpenMenu", "id", "useId", "root", "useRef", "mapIdxToId", "useMemo", "handleOpenMenu", "_a", "el", "handleActivate", "focusVisible", "highlightedIndex", "listProps", "useKeyboardNavigation", "React", "appliedFocusVisible", "useLayoutEffect", "cx", "renderContent", "propsCommonToAllListItems", "maybeIcon", "childElement", "withIcon", "iconName", "addClonedChild", "list", "itemId", "hasSeparator", "label", "hasSubMenu", "isMenuItemGroup", "subMenuShowing", "ariaControls", "getMenuItemProps", "listItems", "baseId", "key", "highlightedIdx", "MenuList_default", "useCallback", "useMemo", "useRef", "useState", "listItemIndex", "listItemEl", "idx", "closestListItem", "el", "nudge", "menus", "distance", "pos", "m", "i", "nudgeLeft", "nudgeUp", "flipSides", "id", "parentMenu", "menu", "el", "width", "getPosition", "openMenus", "left", "menuTop", "top", "getItemId", "getMenuId", "itemId", "getMenuDepth", "count", "identifyItem", "useCascade", "onActivate", "onMouseEnterItem", "posX", "posY", "forceRefresh", "useState", "useRef", "setOpenMenus", "useCallback", "menuOpenPendingTimeout", "menuClosePendingTimeout", "menuState", "prevLevel", "openMenu", "menuId", "listItemEl", "closeMenu", "closeMenus", "lastMenuId", "parentMenuId", "scheduleOpen", "scheduleClose", "openMenuId", "handleRender", "right", "bottom", "clientHeight", "clientWidth", "newMenus", "listItemProps", "useMemo", "evt", "closestListItem", "isGroup", "isOpen", "level", "sameLevel", "state", "targetElement", "idx", "listItemIndex", "useEffect", "useClickAway", "containerClassName", "isOpen", "onClose", "clickHandler", "evt", "Fragment", "jsx", "createElement", "noop", "ContextMenu", "activatedByKeyboard", "childrenProp", "className", "idProp", "onClose", "position", "style", "menuListProps", "id", "useId", "closeMenuRef", "useRef", "menus", "actions", "useItemsWithIds", "navigatingWithKeyboard", "handleMouseEnterItem", "useCallback", "handleActivate", "menuId", "action", "options", "closeMenu", "listItemProps", "openMenu", "openMenus", "handleRender", "useCascade", "handleClose", "useClickAway", "handleOpenMenu", "itemId", "getItemId", "getMenuId", "handleCloseMenu", "handleHighlightMenuItem", "lastMenu", "getChildMenuIndex", "i", "pos", "left", "top", "childMenuIndex", "Portal", "MenuList_default", "createContext", "useCallback", "useMemo", "jsx", "ContextMenuContext", "isGroupMenuItemDescriptor", "menuItem", "Provider", "children", "context", "menuActionHandler", "menuBuilder", "menuBuilders", "handleMenuAction", "type", "options", "_a", "ContextMenuProvider", "label", "parentContext", "useCallback", "useContext", "cx", "React", "createElement", "useEffect", "useRef", "ReactDOM", "_dialogOpen", "_popups", "specialKeyHandler", "closeAllPopups", "dialogRoot", "ReactDOM", "outsideClickHandler", "popupContainers", "i", "popupClosed", "dialogOpened", "dialogClosed", "popupOpened", "name", "pos", "PopupComponent", "children", "position", "style", "className", "cx", "createElement", "incrementingKey", "PopupService", "group", "left", "right", "top", "width", "component", "el", "renderPortal", "popupRoot", "target", "height", "currentRight", "w", "overflowH", "overflowW", "adjustment", "DialogService", "dialog", "containerEl", "onClose", "React", "Popup", "props", "pendingTask", "useRef", "ref", "show", "boundingClientRect", "depth", "targetLeft", "targetTop", "clientWidth", "targetBottom", "useEffect", "jsx", "useContextMenu", "ctx", "useContext", "ContextMenuContext", "buildMenuOptions", "useCallback", "menuBuilders", "location", "options", "results", "menuBuilder", "e", "_a", "menuItemDescriptors", "showContextMenu", "menuDescriptors", "handleContextMenuAction", "left", "top", "component", "ContextMenu", "menuId", "PopupService", "fromDescriptor", "menuItem", "i", "isGroupMenuItemDescriptor", "MenuItemGroup", "MenuItem"]
4
+ "sourcesContent": ["import { Scrim, Toolbar, ToolbarButton } from \"@heswell/salt-lab\";\nimport { Text } from \"@salt-ds/core\";\nimport cx from \"classnames\";\nimport { HTMLAttributes, useCallback, useRef, useState } from \"react\";\nimport { Portal } from \"../portal\";\n\nimport \"./Dialog.css\";\n\nconst classBase = \"vuuDialog\";\n\nexport interface DialogProps extends HTMLAttributes<HTMLDivElement> {\n isOpen?: boolean;\n onClose?: () => void;\n}\n\nexport const Dialog = ({\n children,\n className,\n isOpen = false,\n onClose,\n title,\n ...props\n}: DialogProps) => {\n const root = useRef<HTMLDivElement>(null);\n const [posX] = useState(0);\n const [posY] = useState(0);\n\n const close = useCallback(() => {\n onClose?.();\n }, [onClose]);\n\n const handleRender = useCallback(() => {\n // if (center && isOpen && root.current) {\n // const { width, height } = root.current.getBoundingClientRect();\n // const { innerWidth, innerHeight } = window;\n // const x = innerWidth / 2 - width / 2;\n // const y = innerHeight / 2 - height / 2;\n // setPosX(x);\n // setPosY(y);\n // }\n }, []);\n\n if (!isOpen) {\n return null;\n }\n\n return (\n <Portal onRender={handleRender} x={posX} y={posY}>\n <Scrim className={`${classBase}-scrim`} open={isOpen}>\n <div {...props} className={cx(classBase, className)} ref={root}>\n <Toolbar className={`${classBase}-header`}>\n <Text>{title}</Text>\n <ToolbarButton\n key=\"close\"\n onClick={close}\n data-align-end\n data-icon=\"close\"\n />\n </Toolbar>\n {children}\n </div>\n </Scrim>\n </Portal>\n );\n};\n", "import { ReactElement, useLayoutEffect, useMemo } from \"react\";\nimport * as ReactDOM from \"react-dom\";\nimport { createContainer, renderPortal } from \"./render-portal\";\n\nexport interface PortalProps {\n children: ReactElement;\n onRender?: () => void;\n x?: number;\n y?: number;\n}\n\nexport const Portal = function Portal({\n children,\n x = 0,\n y = 0,\n onRender,\n}: PortalProps) {\n // Do we need to accept container here as a prop ?\n const renderContainer = useMemo(() => {\n return createContainer();\n }, []);\n\n useLayoutEffect(() => {\n renderPortal(children, renderContainer, x, y, onRender);\n }, [children, onRender, renderContainer, x, y]);\n\n useLayoutEffect(() => {\n return () => {\n if (renderContainer) {\n ReactDOM.unmountComponentAtNode(renderContainer);\n if (renderContainer.classList.contains(\"vuuPopup\")) {\n renderContainer.parentElement?.removeChild(renderContainer);\n }\n }\n };\n }, [renderContainer]);\n\n // useLayoutEffect(() => {\n // renderContainer.current = renderPortal(children, x, y, container)\n // return () => {\n // if (renderContainer.current){\n // console.log('EXPLICIT UNMOUNT')\n // ReactDOM.unmountComponentAtNode(renderContainer.current);\n // if (renderContainer.current.classList.contains('hwReactPopup')){\n // renderContainer.current.parentElement.removeChild(renderContainer.current);\n // renderContainer.current = null;\n // }\n // }\n // }\n // },[])\n return null;\n};\n", "import * as ReactDOM from \"react-dom\";\nimport { SaltProvider } from \"@salt-ds/core\";\nimport { ReactElement } from \"react\";\n\nlet containerId = 1;\n\nconst getPortalContainer = (x = 0, y = 0, win = window) => {\n const el = win.document.createElement(\"div\");\n el.className = \"vuuPopup \" + containerId++;\n el.style.cssText = `left:${x}px; top:${y}px;`;\n win.document.body.appendChild(el);\n return el;\n};\n\nconst createDOMContainer = (x?: number, y?: number) => getPortalContainer(x, y);\n\nexport const renderPortal = (\n component: ReactElement,\n container: HTMLElement,\n x: number,\n y: number,\n onRender?: () => void\n) => {\n // check this first to see if position has changed\n container.style.cssText = `left:${x}px; top:${y}px;position: absolute;`;\n\n ReactDOM.render(\n <SaltProvider applyClassesTo=\"child\">{component}</SaltProvider>,\n container,\n onRender\n );\n};\n\nexport const createContainer = createDOMContainer;\n", "export const installTheme = (themeId: string) => {\n const installedThemes = getComputedStyle(document.body).getPropertyValue(\n \"--installed-themes\"\n );\n document.body.style.setProperty(\n \"--installed-themes\",\n `${installedThemes} ${themeId}`\n );\n};\n", "import { useIdMemo as useId } from \"@salt-ds/core\";\nimport { useCallback, useRef } from \"react\";\nimport { Portal } from \"../portal\";\nimport MenuList, { MenuListProps } from \"./MenuList\";\nimport { getItemId, getMenuId, useCascade } from \"./use-cascade\";\nimport { useClickAway } from \"./use-click-away\";\nimport { useItemsWithIds } from \"./use-items-with-ids\";\n\nexport interface ContextMenuProps extends Omit<MenuListProps, \"onCloseMenu\"> {\n onClose?: (menuId?: string, options?: unknown) => void;\n position?: { x: number; y: number };\n withPortal?: boolean;\n}\n\nconst noop = () => undefined;\n\nexport const ContextMenu = ({\n activatedByKeyboard,\n children: childrenProp,\n className,\n id: idProp,\n onClose = () => undefined,\n position = { x: 0, y: 0 },\n style,\n ...menuListProps\n}: ContextMenuProps) => {\n const id = useId(idProp);\n const closeMenuRef = useRef<(location?: string) => void>(noop);\n const [menus, actions] = useItemsWithIds(childrenProp);\n const navigatingWithKeyboard = useRef(activatedByKeyboard);\n const handleMouseEnterItem = useCallback(() => {\n navigatingWithKeyboard.current = false;\n }, []);\n\n const handleActivate = useCallback(\n (menuId: string) => {\n const { action, options } = actions[menuId];\n closeMenuRef.current(\"root\");\n onClose(action, options);\n },\n [actions, onClose]\n );\n\n const { closeMenu, listItemProps, openMenu, openMenus, handleRender } =\n useCascade({\n id,\n onActivate: handleActivate,\n onMouseEnterItem: handleMouseEnterItem,\n position,\n });\n closeMenuRef.current = closeMenu;\n\n console.log({ openMenus });\n\n const handleClose = useCallback(() => {\n closeMenu();\n onClose();\n }, [closeMenu, onClose]);\n\n useClickAway({\n containerClassName: \"vuuMenuList\",\n onClose: handleClose,\n isOpen: openMenus.length > 0,\n });\n\n const handleOpenMenu = (id: string) => {\n const itemId = getItemId(id);\n const menuId = getMenuId(itemId);\n navigatingWithKeyboard.current = true;\n openMenu(menuId, itemId);\n };\n const handleCloseMenu = () => {\n navigatingWithKeyboard.current = true;\n closeMenu();\n };\n\n const handleHighlightMenuItem = () => {\n // console.log(`highlight ${idx}`);\n };\n\n const lastMenu = openMenus.length - 1;\n\n const getChildMenuIndex = (i: number) => {\n if (i >= lastMenu) {\n return -1;\n } else {\n const { id: menuId } = openMenus[i + 1];\n const pos = menuId.lastIndexOf(\".\");\n const idx =\n pos === -1 ? parseInt(menuId, 10) : parseInt(menuId.slice(-pos), 10);\n return idx;\n }\n };\n\n return (\n <>\n {openMenus.map(({ id: menuId, left, top }, i) => {\n const childMenuIndex = getChildMenuIndex(i);\n\n return (\n <Portal key={i} x={left} y={top} onRender={handleRender}>\n <MenuList\n {...menuListProps}\n activatedByKeyboard={navigatingWithKeyboard.current}\n childMenuShowing={childMenuIndex}\n className={className}\n id={id}\n menuId={menuId}\n isRoot={i === 0}\n key={i}\n listItemProps={listItemProps}\n onActivate={handleActivate}\n onHighlightMenuItem={handleHighlightMenuItem}\n onCloseMenu={handleCloseMenu}\n onOpenMenu={handleOpenMenu}\n style={style}\n >\n {menus[menuId]}\n </MenuList>\n </Portal>\n );\n })}\n </>\n );\n};\n\nContextMenu.displayName = \"ContextMenu\";\n", "import React, {\n FC,\n HTMLAttributes,\n ReactElement,\n useLayoutEffect,\n useMemo,\n useRef,\n} from \"react\";\nimport cx from \"classnames\";\nimport { useIdMemo as useId } from \"@salt-ds/core\";\nimport { useKeyboardNavigation } from \"./use-keyboard-navigation\";\nimport { isMenuItemGroup } from \"./use-items-with-ids\";\n\nimport \"./MenuList.css\";\n\nconst classBase = \"vuuMenuList\";\n\nexport const Separator = () => <li className=\"vuuMenuItem-divider\" />;\n\nexport interface MenuItemGroupProps {\n children: ReactElement<MenuItemProps>[];\n label: string;\n}\n\nexport interface MenuItemProps extends HTMLAttributes<HTMLDivElement> {\n action?: string;\n idx?: number;\n options?: unknown;\n}\n\n// Purely used as markers, props will be extracted\nexport const MenuItemGroup: FC<MenuItemGroupProps> = () => null;\n// eslint-disable-next-line no-unused-vars\nexport const MenuItem = ({ children, idx, ...props }: MenuItemProps) => {\n return <div {...props}>{children}</div>;\n};\n\nconst hasIcon = (child: ReactElement) => child.props[\"data-icon\"];\n\nexport interface MenuListProps extends HTMLAttributes<HTMLDivElement> {\n activatedByKeyboard?: boolean;\n children: ReactElement[];\n childMenuShowing?: number;\n highlightedIdx?: number;\n isRoot?: boolean;\n listItemProps?: Partial<MenuItemProps>;\n menuId?: string;\n onActivate?: (menuId: string) => void;\n onCloseMenu: (idx: number) => void;\n onOpenMenu?: (menuId: string) => void;\n onHighlightMenuItem?: (idx: number) => void;\n}\n\nconst MenuList = ({\n activatedByKeyboard,\n childMenuShowing = -1,\n children,\n className,\n highlightedIdx: highlightedIdxProp,\n id: idProp,\n isRoot,\n listItemProps,\n menuId,\n onHighlightMenuItem,\n onActivate,\n onCloseMenu,\n onOpenMenu,\n ...props\n}: MenuListProps) => {\n const id = useId(idProp);\n const root = useRef<HTMLDivElement>(null);\n\n // The id generation be,ongs in useIttemsWithIds\n const mapIdxToId = useMemo(() => new Map(), []);\n\n const handleOpenMenu = (idx: number) => {\n const el = root.current?.querySelector(`:scope > [data-idx='${idx}']`);\n el?.id && onOpenMenu?.(el.id);\n };\n\n const handleActivate = (idx: number) => {\n const el = root.current?.querySelector(`:scope > [data-idx='${idx}']`);\n el?.id && onActivate?.(el.id);\n };\n\n const { focusVisible, highlightedIndex, listProps } = useKeyboardNavigation({\n count: React.Children.count(children),\n highlightedIndex: highlightedIdxProp,\n onActivate: handleActivate,\n onHighlight: onHighlightMenuItem,\n onOpenMenu: handleOpenMenu,\n onCloseMenu,\n });\n\n const appliedFocusVisible = childMenuShowing == -1 ? focusVisible : -1;\n\n useLayoutEffect(() => {\n if (childMenuShowing === -1 && activatedByKeyboard) {\n root.current?.focus();\n }\n }, [activatedByKeyboard, childMenuShowing]);\n\n const getActiveDescendant = () =>\n highlightedIndex === undefined || highlightedIndex === -1\n ? undefined\n : mapIdxToId.get(highlightedIndex);\n\n return (\n <div\n {...props}\n {...listProps}\n aria-activedescendant={getActiveDescendant()}\n className={cx(classBase, className, {\n [`${classBase}-childMenuShowing`]: childMenuShowing !== -1,\n })}\n data-root={isRoot || undefined}\n id={`${id}-${menuId}`}\n ref={root}\n role=\"menu\"\n tabIndex={0}\n >\n {renderContent()}\n </div>\n );\n\n function renderContent() {\n const propsCommonToAllListItems = {\n ...listItemProps,\n role: \"menuitem\",\n };\n\n const maybeIcon = (\n childElement: ReactElement,\n withIcon: boolean,\n iconName?: string\n ) =>\n withIcon\n ? [\n <span\n className=\"vuuIconContainer\"\n data-icon={iconName}\n key=\"icon\"\n />,\n ].concat(childElement)\n : childElement;\n\n function addClonedChild(\n list: ReactElement[],\n child: ReactElement,\n idx: number,\n withIcon: boolean\n ) {\n const {\n children,\n className,\n \"data-icon\": iconName,\n id: itemId,\n hasSeparator,\n label,\n ...props\n } = child.props;\n const hasSubMenu = isMenuItemGroup(child);\n const subMenuShowing = hasSubMenu && childMenuShowing === idx;\n const ariaControls = subMenuShowing ? `${id}-${itemId}` : undefined;\n\n list.push(\n <MenuItem\n {...props}\n {...propsCommonToAllListItems}\n {...getMenuItemProps(\n `${id}-${menuId}`,\n itemId,\n idx,\n child.key ?? itemId,\n highlightedIndex,\n appliedFocusVisible,\n className,\n hasSeparator\n )}\n aria-controls={ariaControls}\n aria-haspopup={hasSubMenu || undefined}\n aria-expanded={subMenuShowing || undefined}\n >\n {hasSubMenu\n ? maybeIcon(label, withIcon, iconName)\n : maybeIcon(children, withIcon, iconName)}\n </MenuItem>\n );\n // mapIdxToId.set(idx, itemId);\n }\n\n const listItems: ReactElement[] = [];\n\n if (children.length > 0) {\n const withIcon = children.some(hasIcon);\n\n children.forEach((child, idx) => {\n addClonedChild(listItems, child, idx, withIcon);\n });\n }\n\n return listItems;\n }\n};\n\nconst getMenuItemProps = (\n baseId: string,\n itemId: string,\n idx: number,\n key: string,\n highlightedIdx: number,\n focusVisible: number,\n className: string,\n hasSeparator: boolean\n) => ({\n id: `${baseId}-${itemId}`,\n key: key ?? idx,\n \"data-idx\": idx,\n \"data-highlighted\": idx === highlightedIdx || undefined,\n className: cx(\"vuuMenuItem\", className, {\n \"vuuMenuItem-separator\": hasSeparator,\n focusVisible: focusVisible === idx,\n }),\n});\n\nMenuList.displayName = \"MenuList\";\nexport default MenuList;\n", "import {\n FocusEvent,\n KeyboardEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { hasPopup, isRoot } from \"./utils\";\nimport { isNavigationKey } from \"./key-code\";\n\nexport interface KeyboardNavigationProps {\n autoHighlightFirstItem?: boolean;\n count: number;\n highlightedIndex?: number;\n onActivate: (idx: number) => void;\n onHighlight?: (idx: number) => void;\n onCloseMenu: (idx: number) => void;\n onOpenMenu: (idx: number) => void;\n}\n\nexport interface KeyboardHookListProps {\n // onBlur: (evt: FocusEvent) => void;\n onFocus: (evt: FocusEvent) => void;\n onKeyDown: (evt: KeyboardEvent) => void;\n onMouseDownCapture: () => void;\n onMouseMove: () => void;\n onMouseLeave: () => void;\n}\n\nexport interface NavigationHookResult {\n focusVisible: number;\n controlledHighlighting: boolean;\n highlightedIndex: number;\n setHighlightedIndex: (idx: number) => void;\n // keyboardNavigation: RefObject<boolean>;\n listProps: KeyboardHookListProps;\n setIgnoreFocus: (ignoreFocus: boolean) => void;\n}\n\n// we need a way to set highlightedIdx when selection changes\nexport const useKeyboardNavigation = ({\n autoHighlightFirstItem = false,\n count,\n highlightedIndex: highlightedIndexProp,\n onActivate,\n onHighlight,\n // onKeyDown,\n onCloseMenu,\n onOpenMenu,\n}: KeyboardNavigationProps): NavigationHookResult => {\n // const prevCount = useRef(count);\n const highlightedIndexRef = useRef(\n highlightedIndexProp ?? autoHighlightFirstItem ? 0 : -1\n );\n const [, forceRender] = useState<unknown>(null);\n const controlledHighlighting = highlightedIndexProp !== undefined;\n\n // count will not work for this, as it will change when we expand collapse groups\n // if (count !== prevCount.current) {\n // prevCount.current = count;\n // if (highlightedIndexRef.current !== -1){\n // highlightedIndexRef.current = autoHighlightFirstItem ? 0 : -1;\n // }\n // }\n\n const setHighlightedIdx = useCallback(\n (idx) => {\n highlightedIndexRef.current = idx;\n onHighlight?.(idx);\n forceRender({});\n },\n [onHighlight]\n );\n\n const setHighlightedIndex = useCallback(\n (idx) => {\n if (idx !== highlightedIndexRef.current) {\n if (!controlledHighlighting) {\n setHighlightedIdx(idx);\n }\n }\n },\n [controlledHighlighting, setHighlightedIdx]\n );\n\n // does this belong here or should it be a method passed in?\n const keyBoardNavigation = useRef(true);\n const ignoreFocus = useRef(false);\n const setIgnoreFocus = (value: boolean) => (ignoreFocus.current = value);\n\n const highlightedIndex = controlledHighlighting\n ? highlightedIndexProp\n : highlightedIndexRef.current;\n\n const navigateChildldItems = useCallback(\n (e: KeyboardEvent) => {\n const nextIdx = nextItemIdx(count, e.key, highlightedIndexRef.current);\n if (nextIdx !== highlightedIndexRef.current) {\n setHighlightedIndex(nextIdx);\n }\n },\n [count, setHighlightedIndex]\n );\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (isNavigationKey(e)) {\n e.preventDefault();\n e.stopPropagation();\n keyBoardNavigation.current = true;\n navigateChildldItems(e);\n } else if (\n (e.key === \"ArrowRight\" || e.key === \"Enter\") &&\n hasPopup(e.target as HTMLElement, highlightedIndex)\n ) {\n onOpenMenu(highlightedIndex);\n } else if (e.key === \"ArrowLeft\" && !isRoot(e.target as HTMLElement)) {\n onCloseMenu(highlightedIndex);\n } else if (e.key === \"Enter\") {\n onActivate && onActivate(highlightedIndex);\n }\n },\n [\n highlightedIndex,\n navigateChildldItems,\n onActivate,\n onCloseMenu,\n onOpenMenu,\n ]\n );\n\n const listProps: KeyboardHookListProps = useMemo(\n () => ({\n onFocus: () => {\n if (highlightedIndex === -1) {\n setHighlightedIdx(0);\n }\n },\n onKeyDown: handleKeyDown,\n onMouseDownCapture: () => {\n keyBoardNavigation.current = false;\n setIgnoreFocus(true);\n },\n\n // onMouseEnter would seem less expensive but it misses some cases\n onMouseMove: () => {\n if (keyBoardNavigation.current) {\n keyBoardNavigation.current = false;\n }\n },\n onMouseLeave: () => {\n // label === 'ParsedInput' && console.log(`%c[useKeyboardNavigationHook]<${label}> onMouseLeave`,'color:brown')\n keyBoardNavigation.current = true;\n setIgnoreFocus(false);\n setHighlightedIndex(-1);\n },\n }),\n [\n highlightedIndex,\n setHighlightedIndex,\n navigateChildldItems,\n onActivate,\n onCloseMenu,\n onOpenMenu,\n setHighlightedIdx,\n ]\n );\n\n // label === 'ParsedInput' && console.log(`%cuseNavigationHook<${label}>\n // highlightedIdxProp= ${highlightedIdxProp},\n // highlightedIndexRef= ${highlightedIndexRef.current},\n // %chighlightedIdx= ${highlightedIdx}`, 'color: brown','color: brown;font-weight: bold;')\n\n return {\n focusVisible: keyBoardNavigation.current ? highlightedIndex : -1,\n controlledHighlighting,\n highlightedIndex,\n setHighlightedIndex: setHighlightedIndex,\n // keyBoardNavigation,\n listProps,\n setIgnoreFocus,\n };\n};\n\n// need to be able to accommodate disabled items\nfunction nextItemIdx(count: number, key: string, idx: number) {\n if (key === \"ArrowUp\") {\n if (idx > 0) {\n return idx - 1;\n } else {\n return idx;\n }\n } else {\n if (idx === null) {\n return 0;\n } else if (idx === count - 1) {\n return idx;\n } else {\n return idx + 1;\n }\n }\n}\n", "export const isRoot = (el: HTMLElement) =>\n el.closest(`[data-root='true']`) !== null;\n\nexport const hasPopup = (el: HTMLElement, idx: number) =>\n (el.ariaHasPopup === \"true\" && el.dataset?.idx === `${idx}`) ||\n el.querySelector(`:scope > [data-idx='${idx}'][aria-haspopup='true']`) !==\n null;\n", "function union(set1: Set<string>, ...sets: Set<string>[]) {\n const result = new Set(set1);\n for (const set of sets) {\n for (const element of set) {\n result.add(element);\n }\n }\n return result;\n}\n\nexport const ArrowUp = \"ArrowUp\";\nexport const ArrowDown = \"ArrowDown\";\nexport const ArrowLeft = \"ArrowLeft\";\nexport const Backspace = \"Backspace\";\nexport const ArrowRight = \"ArrowRight\";\nexport const Enter = \"Enter\";\nexport const Escape = \"Escape\";\nexport const Delete = \"Delete\";\n\nconst actionKeys = new Set([Enter, Delete]);\nconst focusKeys = new Set([\"Tab\"]);\n// const navigationKeys = new Set([\"Home\", \"End\", \"ArrowRight\", \"ArrowLeft\",\"ArrowDown\", \"ArrowUp\"]);\nconst arrowLeftRightKeys = new Set([\"ArrowRight\", \"ArrowLeft\"]);\nconst verticalNavigationKeys = new Set([\"Home\", \"End\", \"ArrowDown\", \"ArrowUp\"]);\nconst horizontalNavigationKeys = new Set([\n \"Home\",\n \"End\",\n \"ArrowRight\",\n \"ArrowLeft\",\n]);\nconst functionKeys = new Set([\n \"F1\",\n \"F2\",\n \"F3\",\n \"F4\",\n \"F5\",\n \"F6\",\n \"F7\",\n \"F8\",\n \"F9\",\n \"F10\",\n \"F11\",\n \"F12\",\n]);\nconst specialKeys = union(\n actionKeys,\n horizontalNavigationKeys,\n verticalNavigationKeys,\n arrowLeftRightKeys,\n functionKeys,\n focusKeys\n);\nexport const isCharacterKey = (evt: KeyboardEvent) => {\n if (specialKeys.has(evt.key)) {\n return false;\n }\n if (typeof evt.which === \"number\" && evt.which > 0) {\n return !evt.ctrlKey && !evt.metaKey && !evt.altKey && evt.which !== 8;\n }\n};\n\nexport const isNavigationKey = (\n { key }: { key: string },\n orientation = \"vertical\"\n) => {\n const navigationKeys =\n orientation === \"vertical\"\n ? verticalNavigationKeys\n : horizontalNavigationKeys;\n return navigationKeys.has(key);\n};\n", "import React, { ReactElement, useCallback, useMemo } from \"react\";\nimport { MenuItemGroup, Separator } from \"./MenuList\";\n\nexport const isMenuItemGroup = (child: ReactElement) =>\n child.type === MenuItemGroup || !!child.props[\"data-group\"];\n\ntype Menus = { [key: string]: ReactElement[] };\ntype Actions = { [key: string]: { action: string; options?: unknown } };\n\nexport const useItemsWithIds = (\n childrenProp: ReactElement[]\n): [Menus, Actions] => {\n const normalizeChildren = useCallback(() => {\n const collectChildren = (\n children: ReactElement[],\n path = \"root\",\n menus: Menus = {},\n actions: Actions = {}\n ) => {\n const list: ReactElement[] = (menus[path] = []);\n let idx = 0;\n let hasSeparator = false;\n\n React.Children.forEach(children, (child) => {\n if (child.type === Separator) {\n hasSeparator = true;\n } else {\n const group = isMenuItemGroup(child);\n const childPath = path === \"root\" ? `${idx}` : `${path}.${idx}`;\n const {\n props: { action, options },\n } = child;\n const { childWithId, grandChildren } = assignId(\n child,\n childPath,\n group,\n hasSeparator\n );\n list.push(childWithId);\n if (grandChildren) {\n collectChildren(grandChildren, childPath, menus, actions);\n } else {\n actions[childPath] = { action, options };\n }\n idx += 1;\n hasSeparator = false;\n }\n });\n return [menus, actions];\n };\n\n const assignId = (\n child: ReactElement,\n path: string,\n group: boolean,\n hasSeparator = false\n ) => {\n const {\n props: { children },\n } = child;\n return {\n childWithId: React.cloneElement(child, {\n hasSeparator,\n id: `${path}`,\n key: path,\n children: group ? undefined : children,\n }),\n grandChildren: group ? children : undefined,\n };\n };\n\n return collectChildren(childrenProp);\n }, [childrenProp]);\n\n const [menus, actions] = useMemo(\n () => normalizeChildren(),\n [normalizeChildren]\n );\n\n return [menus, actions] as [Menus, Actions];\n};\n", "import {\n MouseEvent,\n SyntheticEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { closestListItem, listItemIndex } from \"./list-dom-utils\";\nimport { MenuItemProps } from \"./MenuList\";\n// import {mousePosition} from './aim/utils';\n// import {aiming} from './aim/aim';\n\nconst nudge = (\n menus: RuntimeMenuDescriptor[],\n distance: number,\n pos: \"left\" | \"top\"\n) => {\n return menus.map((m, i) =>\n i === menus.length - 1\n ? {\n ...m,\n [pos]: m[pos] - distance,\n }\n : m\n );\n};\nconst nudgeLeft = (menus: RuntimeMenuDescriptor[], distance: number) =>\n nudge(menus, distance, \"left\");\nconst nudgeUp = (menus: RuntimeMenuDescriptor[], distance: number) =>\n nudge(menus, distance, \"top\");\n\nconst flipSides = (id: string, menus: RuntimeMenuDescriptor[]) => {\n const [parentMenu, menu] = menus.slice(-2);\n const el = document.getElementById(`${id}-${menu.id}`);\n if (el === null) {\n throw Error(`useCascade.flipSides element with id ${menu.id} not found`);\n }\n const { width } = el.getBoundingClientRect();\n return menus.map((m) =>\n m === menu\n ? {\n ...m,\n left: parentMenu.left - (width - 2),\n }\n : m\n );\n};\n\n// const closedNode = (el: HTMLElement) =>\n// el.ariaHasPopup === \"true\" && el.ariaExpanded !== \"true\";\nconst getPosition = (el: HTMLElement, openMenus: RuntimeMenuDescriptor[]) => {\n const [{ left, top: menuTop }] = openMenus.slice(-1);\n // const {top, right, bottom, left} = el.getBoundingClientRect();\n // this will not work for MenuList within window, we need the\n // const {offsetLeft: left, offsetTop: menuTop} = el.closest('.vuuMenuList');\n const { offsetWidth: width, offsetTop: top } = el;\n return { left: left + width, top: top + menuTop };\n};\n\nexport type RuntimeMenuDescriptor = {\n id: string;\n left: number;\n top: number;\n};\n\nexport const getItemId = (id: string) => {\n const pos = id.lastIndexOf(\"-\");\n return pos === -1 ? id : id.slice(pos + 1);\n};\n\nexport const getMenuId = (id: string) => {\n const itemId = getItemId(id);\n const pos = itemId.lastIndexOf(\".\");\n return pos > -1 ? itemId.slice(0, pos) : \"root\";\n};\n\nconst getMenuDepth = (id: string) => {\n let count = 0,\n pos = id.indexOf(\".\", 0);\n while (pos !== -1) {\n count += 1;\n pos = id.indexOf(\".\", pos + 1);\n }\n return count;\n};\n\nconst identifyItem = (el: HTMLElement) => ({\n menuId: getMenuId(el.id),\n itemId: getItemId(el.id),\n isGroup: el.ariaHasPopup === \"true\",\n isOpen: el.ariaExpanded === \"true\",\n level: getMenuDepth(el.id),\n});\n\nexport interface CascadeHookProps {\n id: string;\n onActivate: (menuId: string) => void;\n onMouseEnterItem: (evt: MouseEvent, itemId: string) => void;\n position: { x: number; y: number };\n}\n\nexport interface CascadeHooksResult {\n closeMenu: () => void;\n handleRender: () => void;\n listItemProps: Partial<MenuItemProps>;\n openMenu: (menuId?: string, itemId?: string) => void;\n openMenus: RuntimeMenuDescriptor[];\n}\n\ntype MenuStatus = \"no-popup\" | \"popup-open\" | \"pending-close\" | \"popup-pending\";\ntype MenuState = { [key: string]: MenuStatus };\n\nexport const useCascade = ({\n id,\n onActivate,\n onMouseEnterItem,\n position: { x: posX, y: posY },\n}: CascadeHookProps): CascadeHooksResult => {\n const [, forceRefresh] = useState({});\n const openMenus = useRef<RuntimeMenuDescriptor[]>([\n { id: \"root\", left: posX, top: posY },\n ]);\n\n const setOpenMenus = useCallback((menus: RuntimeMenuDescriptor[]) => {\n openMenus.current = menus;\n forceRefresh({});\n }, []);\n\n const menuOpenPendingTimeout = useRef<number | undefined>();\n const menuClosePendingTimeout = useRef<number | undefined>();\n const menuState = useRef<MenuState>({ root: \"no-popup\" });\n const prevLevel = useRef(0);\n\n // const prevAim = useRef({mousePos: null, distance: true});\n\n const openMenu = useCallback(\n (menuId = \"root\", itemId = null, listItemEl = null) => {\n if (menuId === \"root\" && itemId === null) {\n setOpenMenus([{ id: \"root\", left: posX, top: posY }]);\n } else {\n menuState.current[menuId] = \"popup-open\";\n const doc = listItemEl ? listItemEl.ownerDocument : document;\n const el = doc.getElementById(`${id}-${menuId}-${itemId}`);\n const { left, top } = getPosition(el, openMenus.current);\n setOpenMenus(openMenus.current.concat({ id: itemId, left, top }));\n }\n },\n [id, posX, posY, setOpenMenus]\n );\n\n const closeMenu = useCallback(\n (menuId?: string) => {\n if (menuId === \"root\") {\n setOpenMenus([]);\n } else {\n setOpenMenus(openMenus.current.slice(0, -1));\n }\n },\n [setOpenMenus]\n );\n\n const closeMenus = useCallback(\n (menuId, itemId) => {\n const menus = openMenus.current.slice();\n let { id: lastMenuId } = menus[menus.length - 1];\n while (menus.length > 1 && !itemId.startsWith(lastMenuId)) {\n const parentMenuId = getMenuId(lastMenuId);\n menus.pop();\n menuState.current[lastMenuId] = \"no-popup\";\n menuState.current[parentMenuId] = \"no-popup\";\n ({ id: lastMenuId } = menus[menus.length - 1]);\n }\n if (menus.length < openMenus.current.length) {\n setOpenMenus(menus);\n }\n },\n [setOpenMenus]\n );\n\n const scheduleOpen = useCallback(\n (menuId, itemId, listItemEl) => {\n if (menuOpenPendingTimeout.current) {\n clearTimeout(menuOpenPendingTimeout.current);\n }\n menuOpenPendingTimeout.current = window.setTimeout(() => {\n console.log(`scheduleOpen timed out opening ${itemId}`);\n closeMenus(menuId, itemId);\n menuState.current[menuId] = \"popup-open\";\n menuState.current[itemId] = \"no-popup\";\n openMenu(menuId, itemId, listItemEl);\n }, 400);\n },\n [closeMenus, openMenu]\n );\n\n const scheduleClose = useCallback(\n (openMenuId, menuId, itemId) => {\n console.log(\n `scheduleClose openMenuId ${openMenuId} menuId ${menuId} itemId ${itemId}`\n );\n menuState.current[openMenuId] = \"pending-close\";\n menuClosePendingTimeout.current = window.setTimeout(() => {\n closeMenus(menuId, itemId);\n }, 400);\n },\n [closeMenus]\n );\n\n const handleRender = useCallback(() => {\n const { current: menus } = openMenus;\n const [menu] = menus.slice(-1);\n const el = document.getElementById(`${id}-${menu.id}`);\n if (el) {\n const { right, bottom } = el.getBoundingClientRect();\n const { clientHeight, clientWidth } = document.body;\n if (right > clientWidth) {\n const newMenus =\n menus.length > 1\n ? flipSides(id, menus)\n : nudgeLeft(menus, right - clientWidth);\n setOpenMenus(newMenus);\n } else if (bottom > clientHeight) {\n const newMenus = nudgeUp(menus, bottom - clientHeight);\n setOpenMenus(newMenus);\n }\n }\n }, [id, setOpenMenus]);\n\n const listItemProps: Partial<MenuItemProps> = useMemo(\n () => ({\n onMouseEnter: (evt: MouseEvent) => {\n const listItemEl = closestListItem(evt.target as HTMLElement);\n const { menuId, itemId, isGroup, isOpen, level } =\n identifyItem(listItemEl);\n const sameLevel = prevLevel.current === level;\n const {\n current: { [menuId]: state },\n } = menuState;\n prevLevel.current = level;\n\n // console.log(\n // `%conMouseEnter #${menuId}[${itemId}] @${level}\n // isGroup ${isGroup} isOpen ${isOpen}\n // openMenus [${openMenus.current.join(',')}]\n // state='${JSON.stringify(menuState.current)}`,\n // 'color: green; font-weight: bold;'\n // );\n\n if (state === \"no-popup\" && isGroup) {\n // Shouldn;t we always set this ?\n menuState.current[menuId] = \"popup-pending\";\n scheduleOpen(menuId, itemId, listItemEl);\n } else if (state === \"popup-pending\" && !isGroup) {\n menuState.current[menuId] = \"no-popup\";\n clearTimeout(menuOpenPendingTimeout.current);\n menuOpenPendingTimeout.current = undefined;\n } else if (state === \"popup-pending\" && isGroup) {\n clearTimeout(menuOpenPendingTimeout.current);\n scheduleOpen(menuId, itemId, listItemEl);\n } else if (state === \"popup-open\") {\n const [{ id: parentMenuId }, { id: openMenuId }] =\n openMenus.current.slice(-2);\n if (\n parentMenuId === menuId &&\n menuState.current[openMenuId] !== \"pending-close\" &&\n sameLevel\n ) {\n scheduleClose(openMenuId, menuId, itemId);\n if (isGroup && !isOpen) {\n scheduleOpen(menuId, itemId, listItemEl);\n }\n } else if (\n parentMenuId === menuId &&\n isGroup &&\n itemId !== openMenuId &&\n menuState.current[openMenuId] === \"pending-close\"\n ) {\n // if there is already an item queued for opening cancel it\n scheduleOpen(menuId, itemId, listItemEl);\n } else if (isGroup) {\n closeMenus(menuId, itemId);\n scheduleOpen(menuId, itemId, listItemEl);\n } else if (\n !(menuState.current[openMenuId] === \"pending-close\" && sameLevel)\n ) {\n closeMenus(menuId, itemId);\n }\n }\n\n if (state === \"pending-close\") {\n if (menuOpenPendingTimeout.current) {\n clearTimeout(menuOpenPendingTimeout.current);\n menuOpenPendingTimeout.current = undefined;\n }\n clearTimeout(menuClosePendingTimeout.current);\n menuClosePendingTimeout.current = undefined;\n menuState.current[menuId] = \"popup-open\";\n }\n\n onMouseEnterItem(evt, itemId);\n },\n\n onClick: (evt: SyntheticEvent) => {\n const targetElement = evt.target as HTMLElement;\n const listItemEl = closestListItem(targetElement);\n const idx = listItemIndex(listItemEl);\n console.log(\n `list item click [${idx}] hasPopup ${listItemEl.ariaHasPopup}`\n );\n if (listItemEl.ariaHasPopup === \"true\") {\n if (listItemEl.ariaExpanded !== \"true\") {\n openMenu(idx);\n } else {\n // do nothing\n }\n } else {\n onActivate(getItemId(listItemEl.id));\n }\n },\n }),\n [\n closeMenus,\n onActivate,\n\n onMouseEnterItem,\n openMenu,\n scheduleClose,\n scheduleOpen,\n ]\n );\n\n return {\n closeMenu,\n handleRender,\n listItemProps,\n openMenu,\n openMenus: openMenus.current,\n };\n};\n", "// const listItemElement = (listEl: HTMLElement, listItemIdx: number) =>\n// listEl.querySelector(`:scope > [data-idx=\"${listItemIdx}\"]`);\n\nexport function listItemIndex(listItemEl: HTMLElement) {\n if (listItemEl) {\n const idx = listItemEl.dataset.idx;\n if (idx) {\n return parseInt(idx, 10);\n // eslint-disable-next-line no-cond-assign\n } else if (listItemEl.ariaPosInSet) {\n return parseInt(listItemEl.ariaPosInSet, 10) - 1;\n }\n }\n}\n\nconst listItemId = (el: HTMLElement | null | undefined) => el?.id;\n\nexport const closestListItem = (el: HTMLElement | null | undefined) =>\n el?.closest(\"[data-idx],[aria-posinset]\") as HTMLElement;\n\nexport const closestListItemId = (el: HTMLElement) =>\n listItemId(closestListItem(el));\n\nexport const closestListItemIndex = (el: HTMLElement) =>\n listItemIndex(closestListItem(el));\n", "import { useEffect } from \"react\";\n\nexport interface ClickAwayHookProps {\n containerClassName: string;\n isOpen: boolean;\n onClose?: (target: string) => void;\n}\n\nexport const useClickAway = ({\n containerClassName,\n isOpen,\n onClose,\n}: ClickAwayHookProps) => {\n useEffect(() => {\n let clickHandler: (evt: MouseEvent) => void;\n if (isOpen) {\n clickHandler = (evt) => {\n const target = evt.target as HTMLElement;\n const container = target.closest(`.${containerClassName}`);\n if (container === null) {\n onClose?.(\"root\");\n }\n };\n\n document.body.addEventListener(\"click\", clickHandler, true);\n }\n\n return () => {\n if (clickHandler) {\n document.body.removeEventListener(\"click\", clickHandler, true);\n }\n };\n }, [containerClassName, isOpen, onClose]);\n};\n", "import { createContext, ReactNode, useCallback, useMemo } from \"react\";\n\nexport type MenuActionHandler = (\n type: string,\n options: unknown\n) => boolean | undefined;\nexport type MenuBuilder<L = string, O = unknown> = (\n location: L,\n options: O\n) => ContextMenuItemDescriptor[];\n\nexport interface ContextMenuContext {\n menuBuilders: MenuBuilder[];\n menuActionHandler: MenuActionHandler;\n}\n\nexport const ContextMenuContext = createContext<ContextMenuContext | null>(\n null\n);\n\nexport interface ContextMenuItemBase {\n icon?: string;\n label: string;\n location?: string;\n}\n\nexport interface ContextMenuLeafItemDescriptor extends ContextMenuItemBase {\n action: string;\n options?: unknown;\n}\n\nexport interface ContextMenuGroupItemDescriptor extends ContextMenuItemBase {\n children: ContextMenuItemDescriptor[];\n}\n\nexport type ContextMenuItemDescriptor =\n | ContextMenuLeafItemDescriptor\n | ContextMenuGroupItemDescriptor;\n\nexport const isGroupMenuItemDescriptor = (\n menuItem?: ContextMenuItemDescriptor\n): menuItem is ContextMenuGroupItemDescriptor =>\n menuItem !== undefined && \"children\" in menuItem;\n\nexport interface ContextMenuProviderProps {\n children: ReactNode;\n label?: string;\n menuActionHandler?: MenuActionHandler;\n menuBuilder: MenuBuilder;\n}\n\ninterface ProviderProps extends ContextMenuProviderProps {\n context: ContextMenuContext | null;\n}\n\nconst Provider = ({\n children,\n context,\n menuActionHandler,\n menuBuilder,\n}: ProviderProps) => {\n const menuBuilders = useMemo(() => {\n if (context?.menuBuilders && menuBuilder) {\n return context.menuBuilders.concat(menuBuilder);\n } else if (menuBuilder) {\n return [menuBuilder];\n } else {\n return context?.menuBuilders || [];\n }\n }, [context, menuBuilder]);\n\n const handleMenuAction = useCallback(\n (type, options) => {\n if (menuActionHandler?.(type, options)) {\n return true;\n }\n\n if (context?.menuActionHandler?.(type, options)) {\n return true;\n }\n },\n [context, menuActionHandler]\n );\n\n return (\n <ContextMenuContext.Provider\n value={{\n menuActionHandler: handleMenuAction,\n menuBuilders,\n }}\n >\n {children}\n </ContextMenuContext.Provider>\n );\n};\n\n// Need an option for local menu to override higher-level menu, rather than extend\nexport const ContextMenuProvider = ({\n children,\n label,\n menuActionHandler,\n menuBuilder,\n}: ContextMenuProviderProps) => {\n return (\n <ContextMenuContext.Consumer>\n {(parentContext) => (\n <Provider\n context={parentContext}\n label={label}\n menuActionHandler={menuActionHandler}\n menuBuilder={menuBuilder}\n >\n {children}\n </Provider>\n )}\n </ContextMenuContext.Consumer>\n );\n};\n", "// The menuBuilder will always be supplied by the code that will display the local\n// context menu. It will be passed all configured menu descriptors. It is free to\n\nimport { MouseEvent, useCallback, useContext } from \"react\";\nimport { PopupService } from \"../popup\";\nimport {\n ContextMenuContext,\n ContextMenuItemDescriptor,\n isGroupMenuItemDescriptor,\n MenuActionHandler,\n MenuBuilder,\n} from \"./context-menu-provider\";\nimport { ContextMenu } from \"./ContextMenu\";\nimport { MenuItem, MenuItemGroup } from \"./MenuList\";\n\n// The argument allows a top-level menuBuilder to operate outside the Contect\nexport const useContextMenu = (menuBuilder?: MenuBuilder) => {\n const ctx = useContext(ContextMenuContext);\n\n const buildMenuOptions = useCallback(\n (menuBuilders: MenuBuilder[], location, options) => {\n let results: ContextMenuItemDescriptor[] = [];\n for (const menuBuilder of menuBuilders) {\n // Maybe we should leave the concatenation to the menuBuilder, then it can control menuItem order\n results = results.concat(menuBuilder(location, options));\n }\n return results;\n },\n []\n );\n\n const handleShowContextMenu = useCallback(\n (e: MouseEvent<HTMLElement>, location: string, options: unknown) => {\n e.stopPropagation();\n e.preventDefault();\n const menuBuilders =\n ctx?.menuBuilders ?? (menuBuilder ? [menuBuilder] : undefined);\n if (Array.isArray(menuBuilders) && menuBuilders.length > 0) {\n const menuItemDescriptors = buildMenuOptions(\n menuBuilders,\n location,\n options\n );\n console.log({\n menuItemDescriptors,\n });\n if (menuItemDescriptors.length && ctx?.menuActionHandler) {\n console.log(`showContextMenu ${location}`, {\n options,\n });\n showContextMenu(e, menuItemDescriptors, ctx.menuActionHandler);\n }\n } else {\n console.warn(\n \"useContextMenu, no menuBuilders configured. These should be supplied via the ContextMenuProvider(s)\"\n );\n }\n },\n [buildMenuOptions, ctx?.menuActionHandler, ctx?.menuBuilders, menuBuilder]\n );\n\n return handleShowContextMenu;\n};\n\nconst showContextMenu = (\n e: MouseEvent<HTMLElement>,\n menuDescriptors: ContextMenuItemDescriptor[],\n handleContextMenuAction: MenuActionHandler\n) => {\n const { clientX: left, clientY: top } = e;\n const menuItems = (menuDescriptors: ContextMenuItemDescriptor[]) => {\n const fromDescriptor = (menuItem: ContextMenuItemDescriptor, i: number) =>\n isGroupMenuItemDescriptor(menuItem) ? (\n <MenuItemGroup key={i} label={menuItem.label}>\n {menuItem.children.map(fromDescriptor)}\n </MenuItemGroup>\n ) : (\n <MenuItem\n key={i}\n action={menuItem.action}\n data-icon={menuItem.icon}\n options={menuItem.options}\n >\n {menuItem.label}\n </MenuItem>\n );\n\n return menuDescriptors.map(fromDescriptor);\n };\n\n const handleClose = (menuId?: string, options?: unknown) => {\n if (menuId) {\n handleContextMenuAction(menuId, options);\n PopupService.hidePopup();\n }\n };\n\n const component = (\n <ContextMenu onClose={handleClose} position={{ x: left, y: top }}>\n {menuItems(menuDescriptors)}\n </ContextMenu>\n );\n PopupService.showPopup({ left: 0, top: 0, component });\n};\n", "import cx from \"classnames\";\nimport React, {\n createElement,\n CSSProperties,\n HTMLAttributes,\n ReactElement,\n useEffect,\n useRef,\n} from \"react\";\nimport ReactDOM from \"react-dom\";\nimport { renderPortal } from \"../portal\";\n\nimport \"./popup-service.css\";\n\nlet _dialogOpen = false;\nconst _popups: string[] = [];\n\nfunction specialKeyHandler(e: KeyboardEvent) {\n if (e.key === \"Esc\") {\n if (_popups.length) {\n closeAllPopups();\n } else if (_dialogOpen) {\n const dialogRoot = document.body.querySelector(\".vuuDialog\");\n if (dialogRoot) {\n ReactDOM.unmountComponentAtNode(dialogRoot);\n }\n }\n }\n}\n\nfunction outsideClickHandler(e: MouseEvent) {\n if (_popups.length) {\n // onsole.log(`Popup.outsideClickHandler`);\n const popupContainers = document.body.querySelectorAll(\".vuuPopup\");\n for (let i = 0; i < popupContainers.length; i++) {\n if (popupContainers[i].contains(e.target as HTMLElement)) {\n return;\n }\n }\n closeAllPopups();\n }\n}\n\nfunction closeAllPopups() {\n if (_popups.length) {\n // onsole.log(`closeAllPopups`);\n const popupContainers = document.body.querySelectorAll(\".vuuPopup\");\n for (let i = 0; i < popupContainers.length; i++) {\n ReactDOM.unmountComponentAtNode(popupContainers[i]);\n }\n popupClosed(\"*\");\n }\n}\n\nfunction dialogOpened() {\n if (_dialogOpen === false) {\n _dialogOpen = true;\n window.addEventListener(\"keydown\", specialKeyHandler, true);\n }\n}\n\nfunction dialogClosed() {\n if (_dialogOpen) {\n _dialogOpen = false;\n window.removeEventListener(\"keydown\", specialKeyHandler, true);\n }\n}\n\nfunction popupOpened(name: string) {\n if (_popups.indexOf(name) === -1) {\n _popups.push(name);\n //onsole.log('PopupService, popup opened ' + name + ' popups : ' + _popups);\n if (_dialogOpen === false) {\n window.addEventListener(\"keydown\", specialKeyHandler, true);\n window.addEventListener(\"click\", outsideClickHandler, true);\n }\n }\n}\n\nfunction popupClosed(name: string /*, group=null*/) {\n if (_popups.length) {\n if (name === \"*\") {\n _popups.length = 0;\n } else {\n const pos = _popups.indexOf(name);\n if (pos !== -1) {\n _popups.splice(pos, 1);\n }\n }\n //onsole.log('PopupService, popup closed ' + name + ' popups : ' + _popups);\n if (_popups.length === 0 && _dialogOpen === false) {\n window.removeEventListener(\"keydown\", specialKeyHandler, true);\n window.removeEventListener(\"click\", outsideClickHandler, true);\n }\n }\n}\n\nconst PopupComponent = ({\n children,\n position,\n style,\n}: HTMLAttributes<HTMLDivElement> & {\n position?: \"above\" | \"below\" | \"\";\n style?: CSSProperties;\n}) => {\n const className = cx(\"hwPopup\", \"hwPopupContainer\", position);\n return createElement(\"div\", { className, style }, children);\n};\n\nlet incrementingKey = 1;\n\nexport class PopupService {\n static showPopup({\n name = \"anon\",\n group = \"all\",\n position = \"\",\n left = 0,\n right = \"auto\",\n top = 0,\n width = \"auto\",\n component,\n }: {\n depth?: number;\n name?: string;\n group?: string;\n position?: \"above\" | \"below\" | \"\";\n left?: number;\n right?: \"auto\" | number;\n top?: number;\n component: ReactElement;\n width?: number | \"auto\";\n }) {\n if (!component) {\n throw Error(`PopupService showPopup, no component supplied`);\n }\n popupOpened(name);\n let el = document.body.querySelector(\".vuuPopup.\" + group) as HTMLElement;\n if (el === null) {\n el = document.createElement(\"div\") as HTMLElement;\n el.className = \"vuuPopup \" + group;\n document.body.appendChild(el);\n }\n\n const style = { width };\n\n renderPortal(\n createElement(\n PopupComponent,\n { key: incrementingKey++, position, style },\n component\n ),\n el,\n left,\n top,\n () => {\n PopupService.keepWithinThePage(el, right);\n }\n );\n }\n\n static hidePopup(name = \"anon\", group = \"all\") {\n //onsole.log('PopupService.hidePopup name=' + name + ', group=' + group)\n\n if (_popups.indexOf(name) !== -1) {\n popupClosed(name);\n const popupRoot = document.body.querySelector(`.vuuPopup.${group}`);\n if (popupRoot) {\n ReactDOM.unmountComponentAtNode(popupRoot);\n }\n }\n }\n\n static keepWithinThePage(el: HTMLElement, right: number | \"auto\" = \"auto\") {\n const target = el.querySelector(\".vuuPopupContainer > *\") as HTMLElement;\n if (target) {\n const {\n top,\n left,\n width,\n height,\n right: currentRight,\n } = target.getBoundingClientRect();\n\n const w = window.innerWidth;\n const h = window.innerHeight;\n\n const overflowH = h - (top + height);\n if (overflowH < 0) {\n target.style.top = Math.round(top) + overflowH + \"px\";\n }\n\n const overflowW = w - (left + width);\n if (overflowW < 0) {\n target.style.left = Math.round(left) + overflowW + \"px\";\n }\n\n if (typeof right === \"number\" && right !== currentRight) {\n const adjustment = right - currentRight;\n target.style.left = left + adjustment + \"px\";\n }\n }\n }\n}\n\nexport class DialogService {\n static showDialog(dialog: ReactElement) {\n const containerEl = \".vuuDialog\";\n const onClose = dialog.props.onClose;\n\n dialogOpened();\n\n ReactDOM.render(\n React.cloneElement(dialog, {\n container: containerEl,\n onClose: () => {\n DialogService.closeDialog();\n if (onClose) {\n onClose();\n }\n },\n }),\n document.body.querySelector(containerEl)\n );\n }\n\n static closeDialog() {\n dialogClosed();\n const dialogRoot = document.body.querySelector(\".vuuDialog\");\n if (dialogRoot) {\n ReactDOM.unmountComponentAtNode(dialogRoot);\n }\n }\n}\n\nexport interface PopupProps {\n children: ReactElement;\n close?: boolean;\n depth: number;\n group?: string;\n name: string;\n position?: \"above\" | \"below\" | \"\";\n width: number;\n}\n\nexport const Popup = (props: PopupProps) => {\n const pendingTask = useRef<number | undefined>();\n const ref = useRef<HTMLElement>(null);\n\n const show = (props: PopupProps, boundingClientRect: DOMRect) => {\n const { name, group, depth, width } = props;\n let left: number | undefined;\n let top: number | undefined;\n\n if (pendingTask.current) {\n window.clearTimeout(pendingTask.current);\n pendingTask.current = undefined;\n }\n\n if (props.close === true) {\n PopupService.hidePopup(name, group);\n } else {\n const { position, children: component } = props;\n const {\n left: targetLeft,\n top: targetTop,\n width: clientWidth,\n bottom: targetBottom,\n } = boundingClientRect;\n\n if (position === \"below\") {\n left = targetLeft;\n top = targetBottom;\n } else if (position === \"above\") {\n left = targetLeft;\n top = targetTop;\n }\n\n pendingTask.current = window.setTimeout(() => {\n PopupService.showPopup({\n name,\n group,\n depth,\n position,\n left,\n top,\n width: width || clientWidth,\n component,\n });\n }, 10);\n }\n };\n\n useEffect(() => {\n if (ref.current) {\n const el = ref.current.parentElement;\n const boundingClientRect = el?.getBoundingClientRect();\n if (boundingClientRect) {\n show(props, boundingClientRect);\n }\n }\n\n return () => {\n PopupService.hidePopup(props.name, props.group);\n };\n }, [props]);\n\n return React.createElement(\"div\", { className: \"popup-proxy\", ref });\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["Scrim", "Toolbar", "ToolbarButton", "Text", "cx", "useCallback", "useRef", "useState", "useLayoutEffect", "useMemo", "ReactDOM", "ReactDOM", "SaltProvider", "jsx", "containerId", "getPortalContainer", "x", "y", "win", "el", "createDOMContainer", "renderPortal", "component", "container", "onRender", "createContainer", "Portal", "children", "x", "y", "onRender", "renderContainer", "useMemo", "createContainer", "useLayoutEffect", "renderPortal", "_a", "installTheme", "themeId", "installedThemes", "jsx", "jsxs", "classBase", "Dialog", "children", "className", "isOpen", "onClose", "title", "props", "root", "useRef", "posX", "useState", "posY", "close", "useCallback", "handleRender", "Portal", "Scrim", "cx", "Toolbar", "Text", "ToolbarButton", "useId", "useCallback", "useRef", "React", "useLayoutEffect", "useMemo", "useRef", "cx", "useId", "useCallback", "useMemo", "useRef", "useState", "isRoot", "el", "hasPopup", "idx", "_a", "union", "set1", "sets", "result", "set", "element", "Enter", "Delete", "actionKeys", "Enter", "focusKeys", "arrowLeftRightKeys", "verticalNavigationKeys", "horizontalNavigationKeys", "functionKeys", "specialKeys", "union", "isNavigationKey", "key", "orientation", "verticalNavigationKeys", "horizontalNavigationKeys", "useKeyboardNavigation", "autoHighlightFirstItem", "count", "highlightedIndexProp", "onActivate", "onHighlight", "onCloseMenu", "onOpenMenu", "highlightedIndexRef", "useRef", "forceRender", "useState", "controlledHighlighting", "setHighlightedIdx", "useCallback", "idx", "setHighlightedIndex", "keyBoardNavigation", "ignoreFocus", "setIgnoreFocus", "value", "highlightedIndex", "navigateChildldItems", "e", "nextIdx", "nextItemIdx", "handleKeyDown", "isNavigationKey", "hasPopup", "isRoot", "listProps", "useMemo", "key", "React", "useCallback", "useMemo", "isMenuItemGroup", "child", "MenuItemGroup", "useItemsWithIds", "childrenProp", "normalizeChildren", "useCallback", "collectChildren", "children", "path", "menus", "actions", "list", "idx", "hasSeparator", "React", "Separator", "group", "childPath", "action", "options", "childWithId", "grandChildren", "assignId", "useMemo", "jsx", "classBase", "Separator", "MenuItemGroup", "MenuItem", "children", "idx", "props", "hasIcon", "child", "MenuList", "activatedByKeyboard", "childMenuShowing", "className", "highlightedIdxProp", "idProp", "isRoot", "listItemProps", "menuId", "onHighlightMenuItem", "onActivate", "onCloseMenu", "onOpenMenu", "id", "useId", "root", "useRef", "mapIdxToId", "useMemo", "handleOpenMenu", "_a", "el", "handleActivate", "focusVisible", "highlightedIndex", "listProps", "useKeyboardNavigation", "React", "appliedFocusVisible", "useLayoutEffect", "cx", "renderContent", "propsCommonToAllListItems", "maybeIcon", "childElement", "withIcon", "iconName", "addClonedChild", "list", "itemId", "hasSeparator", "label", "hasSubMenu", "isMenuItemGroup", "subMenuShowing", "ariaControls", "getMenuItemProps", "listItems", "baseId", "key", "highlightedIdx", "MenuList_default", "useCallback", "useMemo", "useRef", "useState", "listItemIndex", "listItemEl", "idx", "closestListItem", "el", "nudge", "menus", "distance", "pos", "m", "i", "nudgeLeft", "nudgeUp", "flipSides", "id", "parentMenu", "menu", "el", "width", "getPosition", "openMenus", "left", "menuTop", "top", "getItemId", "getMenuId", "itemId", "getMenuDepth", "count", "identifyItem", "useCascade", "onActivate", "onMouseEnterItem", "posX", "posY", "forceRefresh", "useState", "useRef", "setOpenMenus", "useCallback", "menuOpenPendingTimeout", "menuClosePendingTimeout", "menuState", "prevLevel", "openMenu", "menuId", "listItemEl", "closeMenu", "closeMenus", "lastMenuId", "parentMenuId", "scheduleOpen", "scheduleClose", "openMenuId", "handleRender", "right", "bottom", "clientHeight", "clientWidth", "newMenus", "listItemProps", "useMemo", "evt", "closestListItem", "isGroup", "isOpen", "level", "sameLevel", "state", "targetElement", "idx", "listItemIndex", "useEffect", "useClickAway", "containerClassName", "isOpen", "onClose", "clickHandler", "evt", "Fragment", "jsx", "createElement", "noop", "ContextMenu", "activatedByKeyboard", "childrenProp", "className", "idProp", "onClose", "position", "style", "menuListProps", "id", "useId", "closeMenuRef", "useRef", "menus", "actions", "useItemsWithIds", "navigatingWithKeyboard", "handleMouseEnterItem", "useCallback", "handleActivate", "menuId", "action", "options", "closeMenu", "listItemProps", "openMenu", "openMenus", "handleRender", "useCascade", "handleClose", "useClickAway", "handleOpenMenu", "itemId", "getItemId", "getMenuId", "handleCloseMenu", "handleHighlightMenuItem", "lastMenu", "getChildMenuIndex", "i", "pos", "left", "top", "childMenuIndex", "Portal", "MenuList_default", "createContext", "useCallback", "useMemo", "jsx", "ContextMenuContext", "isGroupMenuItemDescriptor", "menuItem", "Provider", "children", "context", "menuActionHandler", "menuBuilder", "menuBuilders", "handleMenuAction", "type", "options", "_a", "ContextMenuProvider", "label", "parentContext", "useCallback", "useContext", "cx", "React", "createElement", "useEffect", "useRef", "ReactDOM", "_dialogOpen", "_popups", "specialKeyHandler", "e", "closeAllPopups", "dialogRoot", "ReactDOM", "outsideClickHandler", "popupContainers", "i", "popupClosed", "dialogOpened", "dialogClosed", "popupOpened", "name", "pos", "PopupComponent", "children", "position", "style", "className", "cx", "createElement", "incrementingKey", "PopupService", "group", "left", "right", "top", "width", "component", "el", "renderPortal", "popupRoot", "target", "height", "currentRight", "w", "overflowH", "overflowW", "adjustment", "DialogService", "dialog", "containerEl", "onClose", "React", "Popup", "props", "pendingTask", "useRef", "ref", "show", "boundingClientRect", "depth", "targetLeft", "targetTop", "clientWidth", "targetBottom", "useEffect", "jsx", "useContextMenu", "menuBuilder", "ctx", "useContext", "ContextMenuContext", "buildMenuOptions", "useCallback", "menuBuilders", "location", "options", "results", "e", "_a", "menuItemDescriptors", "showContextMenu", "menuDescriptors", "handleContextMenuAction", "left", "top", "component", "ContextMenu", "menuId", "PopupService", "fromDescriptor", "menuItem", "i", "isGroupMenuItemDescriptor", "MenuItemGroup", "MenuItem"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vuu-ui/vuu-popups",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "VUU popup components - Context Menu, Dialog etc",
5
5
  "author": "heswell",
6
6
  "license": "Apache-2.0",
@@ -8,7 +8,7 @@
8
8
  "@salt-ds/core": "1.2.0",
9
9
  "@salt-ds/icons": "1.1.0",
10
10
  "@heswell/salt-lab": "1.0.0-alpha.2",
11
- "@vuu-ui/vuu-utils": "0.7.0"
11
+ "@vuu-ui/vuu-utils": "0.7.1"
12
12
  },
13
13
  "peerDependencies": {
14
14
  "classnames": "^2.2.6",
@@ -1,2 +1,3 @@
1
1
  import { MouseEvent } from "react";
2
- export declare const useContextMenu: () => (e: MouseEvent<HTMLElement>, location: string, options: unknown) => void;
2
+ import { MenuBuilder } from "./context-menu-provider";
3
+ export declare const useContextMenu: (menuBuilder?: MenuBuilder) => (e: MouseEvent<HTMLElement>, location: string, options: unknown) => void;