@vuu-ui/vuu-table 0.8.23 → 0.8.24-debug

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/esm/index.js CHANGED
@@ -1,2 +1,3863 @@
1
- import{OverflowContainer as Cn}from"@vuu-ui/vuu-ui-controls";import{useLayoutEffectSkipFirst as vn}from"@vuu-ui/vuu-utils";import hn from"clsx";import{useCallback as xn,useRef as wn,useState as Tn}from"react";import tn from"clsx";import{useCallback as nn}from"react";import{jsx as rn,jsxs as ln}from"react/jsx-runtime";var ho="vuuColumnHeaderPill",be=({children:e,className:o,column:t,onRemove:r,removable:n,...l})=>{if(n&&typeof r!="function")throw Error("ColumnHeaderPill onRemove prop must be provided if Pill is removable");let s=nn(i=>{i.preventDefault(),i.stopPropagation(),r==null||r(t)},[t,r]);return ln("div",{...l,className:tn(ho,o),children:[e,n?rn("span",{className:`${ho}-removeButton`,role:"button","data-icon":"cross",onClick:s}):null]})};import{jsx as Ne,jsxs as sn}from"react/jsx-runtime";var xo=({column:e,...o})=>{let{name:t,sorted:r}=e,n=typeof r=="number"?r<0?"arrow-down":"arrow-up":r==="A"?"arrow-up":r==="D"?"arrow-down":void 0;return sn(be,{...o,column:e,children:[Ne("span",{className:"vuuGroupColumnPill-label",children:t}),n!==void 0?Ne("span",{"data-icon":n}):null,typeof r=="number"?Ne("span",{className:"vuuSortPosition",children:Math.abs(r)}):null]})};import{jsx as wo,jsxs as an}from"react/jsx-runtime";var To=({column:e})=>{if(!e.sorted)return null;let o=typeof e.sorted=="number"?e.sorted<0?"arrow-down":"arrow-up":e.sorted==="A"?"arrow-up":"arrow-down";return an(be,{column:e,children:[wo("span",{"data-icon":o}),typeof e.sorted=="number"?wo("span",{className:"vuuSortPosition",children:Math.abs(e.sorted)}):null]})};import{useCallback as Fe,useRef as un}from"react";import{jsx as mn}from"react/jsx-runtime";var Ro=()=>{},cn="vuuColumnResizerNext",we=({onDrag:e,onDragEnd:o=Ro,onDragStart:t=Ro})=>{let r=un({start:0,now:0}),n=Fe(i=>{i.stopPropagation&&i.stopPropagation(),i.preventDefault&&i.preventDefault();let{current:a}=r,u=Math.round(i.clientX),c=u-a.now,p=a.now-a.start;r.current.now=u,c!==0&&e(i,c,p)},[e]),l=Fe(i=>{window.removeEventListener("mouseup",l),window.removeEventListener("mousemove",n);let{current:a}=r,u=a.now-a.start;o(i,u)},[o,n]),s=Fe(i=>{let{current:a}=r;t(i),a.now=a.start=Math.round(i.clientX),window.addEventListener("mouseup",l),window.addEventListener("mousemove",n),i.stopPropagation&&i.stopPropagation(),i.preventDefault&&i.preventDefault()},[t,n,l]);return mn("div",{className:cn,onMouseDown:s})};import{useCallback as Ke,useRef as pn,useState as dn}from"react";var Te=({column:e,onResize:o,rootRef:t})=>{let r=pn({start:0,now:0}),[n,l]=dn(!1),{name:s}=e,i=Ke(()=>{if(o&&t.current){let{current:c}=r,{width:p}=t.current.getBoundingClientRect();c.start=c.now=Math.round(p),l(!0),o==null||o("begin",s)}},[s,o,t]),a=Ke((c,p,f)=>{if(t.current&&o){let{current:g}=r,C=g.start+f;C!==g.now&&C>0&&(o("resize",s,C),g.now=C)}},[s,o,t]),u=Ke(()=>{if(o){let{current:c}=r;o("end",s,c.now),setTimeout(()=>{l(!1)},80)}},[s,o]);return{isResizing:n,onDrag:a,onDragStart:i,onDragEnd:u}};import{getColumnStyle as bn}from"@vuu-ui/vuu-utils";import fn from"clsx";import{useMemo as gn}from"react";var se=(e,o,t)=>gn(()=>{let r=fn(o,{vuuPinFloating:e.pin==="floating",vuuPinLeft:e.pin==="left",vuuPinRight:e.pin==="right",vuuEndPin:t&&e.endPin,[`${o}-editable`]:e.editable,[`${o}-right`]:e.align==="right"}),n=bn(e);return{className:r,style:n}},[e,o,t]);import{jsx as $e,jsxs as Dn}from"react/jsx-runtime";import{createElement as yn}from"react";var Oe="vuuTableGroupHeaderCell",Rn=(e,o)=>e===o?e:o,Ge=({column:e,className:o,onMoveColumn:t,onRemoveColumn:r,onResize:n,...l})=>{let s=wn(null),{isResizing:i,...a}=Te({column:e,onResize:n,rootRef:s}),[u,c]=Tn(e.columns),{className:p,style:f}=se(e,Oe,!0),g=u.length>1?{removable:!0,onRemove:r}:void 0,C=xn((T,m)=>{c(h=>{let x=h.slice(),[P]=x.splice(T,1);if(m===-1){let E=x.concat(P);return t==null||t(E),E}else return x.splice(m,0,P),t==null||t(x),x})},[t]);return vn(()=>{c(T=>Rn(T,e.columns))},[e.columns]),Dn("div",{...l,className:hn(p,o,{[`${Oe}-pending`]:e.groupConfirmed===!1}),ref:s,role:"columnheader",style:f,children:[$e(Cn,{allowDragDrop:!0,className:`${Oe}-inner`,height:24,onMoveItem:C,overflowPosition:"start",children:u.map(T=>yn(xo,{...g,column:T,key:T.name}))}),$e(be,{column:e,removable:!0,onRemove:r}),e.resizeable!==!1?$e(we,{...a}):null]})};import Ln from"clsx";import{useCallback as An,useRef as In}from"react";import{useContextMenu as Mn}from"@vuu-ui/vuu-popups";import Hn from"clsx";import{useCallback as yo,useRef as Pn,useState as En}from"react";import{jsx as kn}from"react/jsx-runtime";var Sn=e=>{if(e){let{bottom:o,left:t}=e.getBoundingClientRect();return{x:t,y:o+6}}},Do=({className:e,column:o,...t})=>{let r=Pn(null),[n,l]=En(!1),[s]=Mn(),i=yo(()=>{l(!1)},[]),a=yo(u=>{l(!0),s(u,"column-menu",{column:o,ContextMenuProps:{onClose:i,position:Sn(r.current)}})},[o,i,s]);return kn("span",{...t,className:Hn("vuuTable-columnMenu",e,{"vuuTable-columnMenu-open":n}),"data-icon":"more-vert",onClick:a,ref:r})};import{jsx as fe,jsxs as zn}from"react/jsx-runtime";var Re="vuuTableHeaderCell",Mo=({className:e,column:o,onClick:t,onResize:r,...n})=>{var x;let{HeaderCellContentRenderer:l,HeaderCellLabelRenderer:s}=o,i=In(null),{isResizing:a,...u}=Te({column:o,onResize:r,rootRef:i}),c=An(P=>{!a&&(t==null||t(P))},[a,t]),{className:p,style:f}=se(o,Re,!0),g=fe(Do,{column:o}),C=s?fe(s,{className:`${Re}-label`,column:o}):fe("div",{className:`${Re}-label`,children:(x=o.label)!=null?x:o.name}),T=l?[fe(l,{column:o},"content")]:[],m=fe(To,{column:o}),h=o.align==="right"?[m,C].concat(T).concat(g):[g,C,m].concat(T);return zn("div",{...n,className:Ln(p,e,{[`${Re}-resizing`]:a}),onClick:c,ref:i,role:"columnheader",style:f,children:[...h,o.resizeable!==!1?fe(we,{...u}):null]})};import{ContextMenuProvider as ui}from"@vuu-ui/vuu-popups";import{MeasuredContainer as ci}from"@vuu-ui/vuu-ui-controls";import{metadataKeys as mi,useId as pi}from"@vuu-ui/vuu-utils";import{useForkRef as di}from"@salt-ds/core";import Pt from"clsx";import{forwardRef as bi,useRef as fi,useState as gi}from"react";import{isGroupColumn as ko,isJsonColumn as Wn,isJsonGroup as Un,metadataKeys as _n,isNotHidden as Xn,RowSelected as Qn}from"@vuu-ui/vuu-utils";import Jn from"clsx";import{memo as Zn,useCallback as Lo}from"react";import{isNumericColumn as Nn}from"@vuu-ui/vuu-utils";import{useCallback as Ho}from"react";import{jsx as Po}from"react/jsx-runtime";var Fn="vuuTableCell",Eo=({column:e,columnMap:o,onClick:t,onDataEdited:r,row:n})=>{let{className:l,style:s}=se(e,Fn),{CellRenderer:i,index:a,name:u,valueFormatter:c}=e,p=o[u],f=Ho(C=>{if(r){let T=C;return Nn(e)&&typeof C=="string"&&(T=e.serverDataType==="double"?parseFloat(C):parseInt(C)),r==null?void 0:r(n,u,T)}else throw Error("TableCell onDataEdited prop not supplied for an editable cell")},[e,u,r,n]),g=Ho(C=>{t==null||t(C,e)},[e,t]);return Po("div",{"aria-colindex":a,className:l,onClick:t?g:void 0,role:"cell",style:s,children:i?Po(i,{column:e,columnMap:o,onCommit:f,row:n}):c(n[p])})};import{getGroupValueAndOffset as Kn,metadataKeys as On}from"@vuu-ui/vuu-utils";import{useCallback as $n}from"react";import Gn from"clsx";import{jsx as Ve,jsxs as Vn}from"react/jsx-runtime";var{IS_LEAF:Bn}=On,Be="vuuTableGroupCell",So=({column:e,columnMap:o,onClick:t,row:r})=>{let{columns:n}=e,[l,s]=Kn(n,r,o),{className:i,style:a}=se(e,Be),u=$n(f=>{t==null||t(f,e)},[e,t]),c=r[Bn],p=Array(s).fill(0).map((f,g)=>Ve("span",{className:`${Be}-spacer`},g));return Vn("div",{className:Gn(i,"vuuTableCell"),role:"cell",style:a,onClick:c?void 0:u,children:[p,c?null:Ve("span",{className:`${Be}-toggle`,"data-icon":"triangle-right"}),Ve("span",{children:l})]})};import{jsx as ye,jsxs as er}from"react/jsx-runtime";var{IDX:Yn,IS_EXPANDED:jn,SELECTED:qn}=_n,ne="vuuTableRow",We=Zn(({className:e,columnMap:o,columns:t,highlighted:r,row:n,offset:l,onClick:s,onDataEdited:i,onToggleGroup:a,virtualColSpan:u=0,zebraStripes:c=!1,...p})=>{let{[Yn]:f,[jn]:g,[qn]:C}=n,T=Lo(M=>{let k=M.shiftKey,N=M.ctrlKey||M.metaKey;s==null||s(n,k,N)},[s,n]),{True:m,First:h,Last:x}=Qn,P=Jn(ne,e,{[`${ne}-even`]:c&&f%2===0,[`${ne}-expanded`]:g,[`${ne}-highlighted`]:r,[`${ne}-selected`]:C&m,[`${ne}-selectedStart`]:C&h,[`${ne}-selectedEnd`]:C&x}),E={transform:`translate3d(0px, ${l}px, 0px)`},H=Lo((M,k)=>{(ko(k)||Un(k,n,o))&&(M.stopPropagation(),a==null||a(n,k))},[o,a,n]);return er("div",{...p,role:"row",className:P,onClick:T,style:E,children:[ye("span",{className:`${ne}-selectionDecorator vuuStickyLeft`}),u>0?ye("div",{className:"vuuTableCell",style:{width:u}}):null,t.filter(Xn).map(M=>{let k=ko(M),N=Wn(M);return ye(k?So:Eo,{column:M,columnMap:o,onClick:k||N?H:void 0,onDataEdited:i,row:n},M.name)}),ye("span",{className:`${ne}-selectionDecorator vuuStickyRight`})]})});We.displayName="Row";import{isGroupColumn as nr,isNotHidden as rr}from"@vuu-ui/vuu-utils";import lr from"clsx";import{memo as ir}from"react";import{useDragDrop as or}from"@vuu-ui/vuu-ui-controls";import{moveColumnTo as Ue,visibleColumnAtIndex as tr}from"@vuu-ui/vuu-utils";import{useCallback as _e,useRef as Ao}from"react";var Io=({columns:e,onMoveColumn:o,onSortColumn:t,tableConfig:r})=>{let n=Ao(null),l=Ao(null),s=_e(f=>{n.current=f,f?l.current=f.closest(".vuuTable-contentContainer"):l.current=null},[]),i=_e(({fromIndex:f,toIndex:g})=>{let C=e[f],T=Ue(e,C,g),m=({name:E})=>H=>H.name===E,h=T.findIndex(m(C)),x=T[h+1],P=x?r.columns.findIndex(m(x)):-1;g>f&&P!==-1?o(Ue(r.columns,C,P-1)):o(Ue(r.columns,C,P))},[e,o,r.columns]),a=_e(f=>{var x;let C=f.target.closest(".vuuTableHeaderCell"),T=parseInt((x=C==null?void 0:C.dataset.index)!=null?x:"-1"),m=tr(e,T),h=f.shiftKey;m&&t(m,h)},[e,t]),{onMouseDown:u,draggable:c,...p}=or({allowDragDrop:!0,containerRef:n,draggableClassName:"vuuTable",itemQuery:".vuuTableHeaderCell",onDrop:i,orientation:"horizontal",scrollingContainerRef:l});return{draggableColumn:c,draggedColumnIndex:p.draggedItemIndex,onClick:a,onMouseDown:u,setContainerRef:s}};import{jsx as he,jsxs as zo}from"react/jsx-runtime";var Xe=ir(({classBase:e="vuuTable",columns:o,headings:t,onMoveColumn:r,onMoveGroupColumn:n,onRemoveGroupColumn:l,onResizeColumn:s,onSortColumn:i,tableConfig:a,tableId:u,virtualColSpan:c=0})=>{let{draggableColumn:p,draggedColumnIndex:f,onClick:g,onMouseDown:C,setContainerRef:T}=Io({columns:o,onMoveColumn:r,onSortColumn:i,tableConfig:a});return zo("div",{className:`${e}-col-headings`,ref:T,children:[t.map((m,h)=>he("div",{className:"vuuTable-heading",children:m.map(({label:x,width:P},E)=>he("div",{className:"vuuTable-headingCell",style:{width:P},children:x},E))},h)),zo("div",{className:`${e}-col-headers`,role:"row",children:[c>0?he("div",{role:"cell",className:"vuuTableCell",style:{width:c}}):null,o.filter(rr).map((m,h)=>nr(m)?he(Ge,{"aria-colindex":m.index,column:m,"data-index":h,onMoveColumn:n,onRemoveColumn:l,onResize:s},m.name):he(Mo,{"aria-colindex":m.index,className:lr({"vuuDraggable-dragAway":h===f}),column:m,"data-index":h,id:`${u}-col-${h}`,onClick:g,onMouseDown:C,onResize:s},m.name)),p]})]})});Xe.displayName="TableHeader";import{useDragDrop as _l}from"@vuu-ui/vuu-ui-controls";import{applySort as Xl,buildColumnMap as Ql,getIndexFromRowElement as Jl,isGroupColumn as Zl,isJsonGroup as Yl,isValidNumber as jl,metadataKeys as ql,updateColumn as ei,useLayoutEffectSkipFirst as oi}from"@vuu-ui/vuu-utils";import{useCallback as z,useEffect as ti,useMemo as Rt,useRef as ni,useState as ri}from"react";import{isNumericColumn as sr}from"@vuu-ui/vuu-utils";var No=e=>(o,t)=>{let r=[];return e===void 0||(o==="header"||o==="column-menu")&&(r.push(...ar(t,e)),r.push(...mr(t,e)),r.push(...ur(t,e)),r.push(...cr(t)),r.push({action:"column-settings",icon:"cog",label:"Column Settings",options:t}),r.push({action:"table-settings",icon:"cog",label:"DataGrid Settings",options:t})),r};function ar(e,{sort:{sortDefs:o}}){let{column:t}=e,r=[];if(t===void 0)return r;let n=o.length>0;return t.sorted==="A"?r.push({label:"Reverse Sort (DSC)",action:"sort-dsc",options:e}):t.sorted==="D"?r.push({label:"Reverse Sort (ASC)",action:"sort-asc",options:e}):typeof t.sorted=="number"?(t.sorted>0?r.push({label:"Reverse Sort (DSC)",action:"sort-add-dsc",options:e}):r.push({label:"Reverse Sort (ASC)",action:"sort-add-asc",options:e}),n&&Math.abs(t.sorted)<o.length&&r.push({label:"Remove from sort",action:"sort-remove",options:e}),r.push({label:"New Sort",children:[{label:"Ascending",action:"sort-asc",options:e},{label:"Descending",action:"sort-dsc",options:e}]})):n?(r.push({label:"Add to sort",children:[{label:"Ascending",action:"sort-add-asc",options:e},{label:"Descending",action:"sort-add-dsc",options:e}]}),r.push({label:"New Sort",children:[{label:"Ascending",action:"sort-asc",options:e},{label:"Descending",action:"sort-dsc",options:e}]})):r.push({label:"Sort",children:[{label:"Ascending",action:"sort-asc",options:e},{label:"Descending",action:"sort-dsc",options:e}]}),r}function ur(e,o){let{column:t}=e;if(t===void 0||o.groupBy.length===0)return[];let{name:r,label:n=r}=t;return[{label:`Aggregate ${n}`,children:[{label:"Count",action:"agg-count",options:e},{label:"Distinct",action:"agg-distinct",options:e}].concat(sr(t)?[{label:"Sum",action:"agg-sum",options:e},{label:"Avg",action:"agg-avg",options:e},{label:"High",action:"agg-high",options:e},{label:"Low",action:"agg-low",options:e}]:[])}]}var Ye=(e,o)=>({label:`Pin ${o}`,action:`column-pin-${o}`,options:e}),Qe=e=>Ye(e,"left"),Je=e=>Ye(e,"floating"),Ze=e=>Ye(e,"right");function cr(e){let{column:o}=e;if(o===void 0)return[];let{pin:t}=o,r=[{label:"Hide column",action:"column-hide",options:e},{label:"Remove column",action:"column-remove",options:e}];return t===void 0?r.push({label:"Pin column",children:[Qe(e),Je(e),Ze(e)]}):t==="left"?r.push({label:"Unpin column",action:"column-unpin",options:e},{label:"Pin column",children:[Je(e),Ze(e)]}):t==="right"?r.push({label:"Unpin column",action:"column-unpin",options:e},{label:"Pin column",children:[Qe(e),Je(e)]}):t==="floating"&&r.push({label:"Unpin column",action:"column-unpin",options:e},{label:"Pin column",children:[Qe(e),Ze(e)]}),r}function mr(e,{groupBy:o}){let{column:t}=e,r=[];if(t===void 0)return r;let{name:n,label:l=n}=t;return o.length===0?r.push({label:`Group by ${l}`,action:"group",options:e}):r.push({label:`Add ${l} to group by`,action:"group-add",options:e}),r}import{removeColumnFromFilter as pr}from"@vuu-ui/vuu-utils";import{addGroupColumn as Fo,addSortColumn as Ko,AggregationType as dr,setAggregations as ge,setSortColumn as Oo}from"@vuu-ui/vuu-utils";var br=(e,o)=>{if(e.filterStruct&&o){let[t,r]=pr(o,e.filterStruct);return{filter:r,filterStruct:t}}else return e},{Average:fr,Count:gr,Distinct:Cr,High:vr,Low:hr,Sum:xr}=dr,$o=({dataSource:e,onPersistentColumnOperation:o})=>r=>{let n=r.options;if(n.column&&e){let{column:l}=n;switch(r.menuId){case"sort-asc":return e.sort=Oo(e.sort,l,"A"),!0;case"sort-dsc":return e.sort=Oo(e.sort,l,"D"),!0;case"sort-add-asc":return e.sort=Ko(e.sort,l,"A"),!0;case"sort-add-dsc":return e.sort=Ko(e.sort,l,"D"),!0;case"group":return e.groupBy=Fo(e.groupBy,l),!0;case"group-add":return e.groupBy=Fo(e.groupBy,l),!0;case"column-hide":return o({type:"hideColumns",columns:[l]}),!0;case"column-remove":return e.columns=e.columns.filter(s=>s!==l.name),!0;case"filter-remove-column":return e.filter=br(e.filter,l),!0;case"remove-filters":return e.filter={filter:""},!0;case"agg-avg":return e.aggregations=ge(e.aggregations,l,fr),!0;case"agg-high":return e.aggregations=ge(e.aggregations,l,vr),!0;case"agg-low":return e.aggregations=ge(e.aggregations,l,hr),!0;case"agg-count":return e.aggregations=ge(e.aggregations,l,gr),!0;case"agg-distinct":return e.aggregations=ge(e.aggregations,l,Cr),!0;case"agg-sum":return e.aggregations=ge(e.aggregations,l,xr),!0;case"column-pin-floating":return o({type:"pinColumn",column:l,pin:"floating"}),!0;case"column-pin-left":return o({type:"pinColumn",column:l,pin:"left"}),!0;case"column-pin-right":return o({type:"pinColumn",column:l,pin:"right"}),!0;case"column-unpin":return o({type:"pinColumn",column:l,pin:void 0}),!0;case"column-settings":return o({type:"columnSettings",column:l}),!0;case"table-settings":return o({type:"tableSettings"}),!0;default:}}return!1};var Go=(e,o)=>{switch(o.type){case"col-size":return{...e,columns:e.columns.map(t=>t.name===o.column.name?{...t,width:o.width}:t)};case"column-prop":return{...e,columns:e.columns.map(t=>t.name===o.column.name?{...t,[o.property]:o.value}:t)};default:return e}};import{isCharacterKey as Dr}from"@vuu-ui/vuu-utils";import{useCallback as ce}from"react";var je=e=>`.vuuTable-col-headers .vuuTableHeaderCell:nth-child(${e})`,qe=(e,o)=>`.vuuTable-body > [aria-rowindex='${e+1}'] > [role='cell']:nth-child(${o+1})`,Bo=(e,[o,t])=>{var l;let r=o===-1?je(t):qe(o,t),n=(l=e.current)==null?void 0:l.querySelector(r);return wr(n)&&n.querySelector("button")||n},wr=e=>e==null?void 0:e.classList.contains("vuuTableCell-editable"),Vo=e=>e.querySelector(".vuuTableInputCell")!==null;function Tr(e){if(e){let o=e.ariaRowIndex;if(o!==null)return parseInt(o,10)-1}return-1}var Rr=e=>e.closest('[role="row"]'),Wo=e=>Tr(Rr(e)),yr=[void 0,void 0],Uo=(e,o,t=e.closest(".vuuTable-contentContainer"))=>{if(t){let r=t==null?void 0:t.getBoundingClientRect(),n=r.top+o,l=e.getBoundingClientRect();if(l)return l.bottom>r.bottom?["down",l.bottom-r.bottom]:l.top<n?["up",l.top-n]:yr;throw Error("Whats going on, row not found")}else throw Error("Whats going on, scrollbar container not found")};var _o=({navigate:e})=>{let o=ce(()=>{e()},[e]),t=ce(a=>{let u=a.target,c=u.matches("input")?u:u.querySelector("input");c&&(c.focus(),c.select())},[]),r=ce(a=>{let c=a.target.querySelector("input");c&&(c.focus(),c.select())},[]),n=ce(a=>{let u=a.target;Vo(u)&&(Dr(a.key)?t(a):a.key==="Enter"&&r(a))},[t,r]),l=ce(a=>{let u=a.target;(u.matches("input")||u.querySelector("input"))&&(t(a),a.stopPropagation())},[t]),s=ce(a=>{a.target.removeEventListener("vuu-commit",o,!0)},[o]),i=ce(a=>{a.target.addEventListener("vuu-commit",o,!0)},[o]);return{onBlur:s,onDoubleClick:l,onFocus:i,onKeyDown:n}};import{getFullRange as oo,NULL_RANGE as Er,rangesAreSame as Sr}from"@vuu-ui/vuu-utils";import{useCallback as Me,useEffect as Xo,useMemo as kr,useRef as He,useState as Lr}from"react";import{isRowSelectedLast as Mr,metadataKeys as Hr,WindowRange as Pr}from"@vuu-ui/vuu-utils";var{SELECTED:eo}=Hr,De=class{constructor({from:o,to:t}){this.rowCount=0;this.setRowCount=o=>{o<this.data.length&&(this.data.length=o),this.rowCount=o};this.range=new Pr(o,t),this.data=new Array(Math.max(0,t-o)),this.rowCount=0}add(o){let[t]=o;if(this.isWithinRange(t)){let r=t-this.range.from;if(this.data[r]=o,o[eo]){let n=this.data[r-1];Mr(n)&&(this.data[r-1]=n.slice(),this.data[r-1][eo]-=4)}}}getAtIndex(o){return this.range.isWithin(o)&&this.data[o-this.range.from]!=null?this.data[o-this.range.from]:void 0}isWithinRange(o){return this.range.isWithin(o)}setRange({from:o,to:t}){if(o!==this.range.from||t!==this.range.to){let[r,n]=this.range.overlap(o,t),l=new Array(Math.max(0,t-o));for(let s=r;s<n;s++){let i=this.getAtIndex(s);if(i){let a=s-o;l[a]=i}}this.data=l,this.range.from=o,this.range.to=t}}getSelectedRows(){return this.data.filter(o=>o[eo]!==0)}};var Ar=e=>e.type==="vuu-link-created"||e.type==="vuu-link-removed",Qo=({dataSource:e,onFeatureInvocation:o,onSizeChange:t,onSubscribed:r,range:n=Er,renderBufferSize:l=0})=>{let[,s]=Lr(null),i=He([]),a=He(!0),u=He(!1),c=He(n),p=kr(()=>new De(oo(n,l)),[]),f=Me(m=>{for(let h of m)p.add(h);i.current=p.data,a.current?s({}):console.log("ignore update as we're not mounted")},[p]),g=Me(m=>{m.type==="subscribed"?r==null||r(m):m.type==="viewport-update"?(typeof m.size=="number"&&(t==null||t(m.size),p.setRowCount(m.size)),m.rows?f(m.rows):typeof m.size=="number"&&(i.current=p.data,u.current=!0)):Ar(m)?o==null||o(m):console.log(`useDataSource unexpected message ${m.type}`)},[p,o,t,r,f]),C=Me(()=>p.getSelectedRows(),[p]);Xo(()=>{var m;return a.current=!0,(m=e.resume)==null||m.call(e),()=>{var h;a.current=!1,(h=e.suspend)==null||h.call(e)}},[e]),Xo(()=>{var m;e.status==="disabled"?(m=e.enable)==null||m.call(e,g):e==null||e.subscribe({range:oo(n,l)},g)},[e,g,n,l]);let T=Me(m=>{if(!Sr(m,c.current)){let h=oo(m,l);p.setRange(h),e.range=c.current=h,e.emit("range",m)}},[e,p,l]);return{data:i.current,dataRef:i,getSelectedRows:C,range:c.current,setRange:T}};import{useMemo as Ir,useRef as zr}from"react";var Jo=e=>{let o=zr(e);return Ir(()=>o.current,[])};import{getIndexFromRowElement as Nr}from"@vuu-ui/vuu-utils";import{useControlled as Fr}from"@salt-ds/core";import{useCallback as Q,useEffect as Zo,useRef as Pe}from"react";var qo=new Set(["Home","End","PageUp","PageDown","ArrowDown","ArrowUp"]),to=new Set(qo);to.add("ArrowLeft");to.add("ArrowRight");var Kr=(e,o)=>{switch(o){case"cell":return to.has(e);case"row":return qo.has(e);default:return!1}},Or=["Home","End","PageUp","PageDown"],Yo=e=>Or.includes(e),$r=[-1,-1];function jo(e,[o,t],r,n){return e==="ArrowUp"?o>-1?[o-1,t]:[o,t]:e==="ArrowDown"?o===-1?[0,t]:o===n-1?[o,t]:[o+1,t]:e==="ArrowRight"?t<r?[o,t+1]:[o,t]:e==="ArrowLeft"?t>1?[o,t-1]:[o,t]:[o,t]}var et=({columnCount:e=0,containerRef:o,disableFocus:t=!1,defaultHighlightedIndex:r,disableHighlightOnFocus:n,highlightedIndex:l,navigationStyle:s,requestScroll:i,onHighlight:a,rowCount:u=0,viewportRowCount:c})=>{var I;let p=Pe([-1,-1]),f=Pe(),g=Pe([-1,0]),C=Pe(),[T,m]=Fr({controlled:l,default:r,name:"UseKeyboardNavigation"});C.current=T;let h=Q((v,w=!1)=>{a==null||a(v),m(v)},[a,m]),x=v=>v==null?void 0:v.closest("[role='columnHeader'],[role='cell']"),P=v=>{var w;if(v.role==="columnHeader")return[-1,parseInt((w=v.dataset.idx)!=null?w:"-1",10)];{let b=v.closest("[role='row']");if(b){let R=Nr(b),y=Array.from(b.childNodes).indexOf(v);return[R,y]}}return $r},E=Q(v=>{var w;if(o.current){let b=Bo(o,v);b&&(b!==f.current&&((w=f.current)==null||w.removeAttribute("tabindex"),f.current=b,b.setAttribute("tabindex","0")),i==null||i({type:"scroll-row",rowIndex:v[0]}),b.focus({preventScroll:!0}))}},[o,i]),H=Q((v,w,b=!1)=>{let R=[v,w];g.current=R,s==="row"?m(v):E(R),b&&(p.current=R)},[E,s,m]),M=Q((v,[w,b])=>new Promise(R=>{let y=w;switch(v){case"PageDown":{y=Math.min(u-1,w+c),y!==w&&(i==null||i({type:"scroll-page",direction:"down"}));break}case"PageUp":{y=Math.max(0,w-c),y!==w&&(i==null||i({type:"scroll-page",direction:"up"}));break}case"Home":{y=0,y!==w&&(i==null||i({type:"scroll-end",direction:"home"}));break}case"End":{y=u-1,y!==w&&(i==null||i({type:"scroll-end",direction:"end"}));break}}setTimeout(()=>{R([y,b])},35)}),[i,u,c]),k=Q(()=>{var v;if(n!==!0&&(v=o.current)!=null&&v.contains(document.activeElement)){let w=x(document.activeElement);w&&(p.current=P(w),s==="row"&&m(p.current[0]))}},[n,o,s,m]),N=Q(async v=>{let[w,b]=Yo(v)?await M(v,g.current):jo(v,g.current,e,u),[R,y]=g.current;(w!==R||b!==y)&&H(w,b,!0)},[e,M,u,H]),K=Q(v=>{i==null||i({type:"scroll-row",rowIndex:v})},[i]),$=Q(async v=>{let{current:w}=C,[b]=Yo(v)?await M(v,[w!=null?w:-1,0]):jo(v,[w!=null?w:-1,0],e,u);b!==w&&(h(b),K(b))},[e,M,u,K,h]);Zo(()=>{l!==void 0&&l!==-1&&K(l)},[l,K]);let B=Q(v=>{u>0&&Kr(v.key,s)&&(v.preventDefault(),v.stopPropagation(),s==="row"?$(v.key):N(v.key))},[u,s,$,N]),ee=Q(v=>{let w=v.target,b=x(w);if(b){let[R,y]=P(b);H(R,y)}},[H]),L=Q(()=>{h(-1)},[h]),D=Q(v=>{let w=Wo(v.target);w!==-1&&w!==C.current&&h(w)},[h]),oe=Q(()=>{N("ArrowDown")},[N]),le=((I=o.current)==null?void 0:I.firstChild)!=null;return Zo(()=>{if(le&&f.current===void 0&&!t){let{current:v}=o,w=(v==null?void 0:v.querySelector(je(0)))||(v==null?void 0:v.querySelector(qe(0,0)));w&&(w.setAttribute("tabindex","0"),f.current=w)}},[o,t,le]),{highlightedIndexRef:C,navigate:oe,onClick:ee,onFocus:k,onKeyDown:B,onMouseLeave:s==="row"?L:void 0,onMouseMove:s==="row"?D:void 0}};import{deselectItem as Gr,dispatchMouseEvent as Br,isRowSelected as Vr,metadataKeys as Wr,selectItem as Ur}from"@vuu-ui/vuu-utils";import{useCallback as no,useRef as ot}from"react";var{IDX:_r}=Wr,Xr=[],Qr=["Enter"," "],tt=({highlightedIndexRef:e,selectionKeys:o=Qr,selectionModel:t,onSelect:r,onSelectionChange:n})=>{let l=ot(-1),s=ot(Xr),i=no(c=>o.includes(c.key),[o]),a=no((c,p,f)=>{let{[_r]:g}=c,{current:C}=l,{current:T}=s,h=(Vr(c)?Gr:Ur)(t,T,g,p,f,C);s.current=h,l.current=g,r==null||r(c),n==null||n(h)},[r,n,t]);return{onKeyDown:no(c=>{if(i(c)){let{current:p}=e;if(p!==void 0&&p!==-1){let f=c.target.querySelector(`[aria-rowindex="${p}"]`);f&&Br(f,"click")}}},[e,i]),onRowClick:a}};import{useContextMenu as Jr}from"@vuu-ui/vuu-popups";import{buildColumnMap as Zr,getIndexFromRowElement as Yr}from"@vuu-ui/vuu-utils";import{useCallback as jr}from"react";var qr=[],nt=({columns:e,data:o,dataSource:t,getSelectedRows:r})=>{let[n]=Jr();return jr(s=>{let i=s.target,a=i==null?void 0:i.closest("div[role='cell']"),u=i==null?void 0:i.closest("div[role='row']");if(a&&u){let{selectedRowsCount:c}=t,p=Zr(e),f=Yr(u),g=Array.from(u.childNodes).indexOf(a),C=o.find(([m])=>m===f),T=e[g];n(s,"grid",{columnMap:p,columnName:T,row:C,selectedRows:c===0?qr:r(),viewport:t.viewport})}},[e,o,t,r,n])};import{applyFilterToColumns as el,applyGroupByToColumns as ol,applySortToColumns as tl,getCellRenderer as nl,getColumnHeaderContentRenderer as rl,getColumnHeaderLabelRenderer as ll,getColumnLabel as il,getTableHeadings as sl,getValueFormatter as al,hasValidationRules as ul,isFilteredColumn as cl,isGroupColumn as ml,isPinned as pl,logger as dl,replaceColumn as me,sortPinnedColumns as rt,stripFilterFromColumns as bl,subscribedOnly as fl}from"@vuu-ui/vuu-utils";import{buildValidationChecker as gl}from"@vuu-ui/vuu-ui-controls";import{useReducer as Cl}from"react";var{info:ro}=dl("useTableModel"),vl=100,hl=({serverDataType:e})=>e===void 0,lt=(e,o)=>{let t=o==null?void 0:o.columns.find(({name:r})=>r===e.name);return t?t.serverDataType:e.serverDataType},xl=["int","long","double"],it=e=>e===void 0?void 0:xl.includes(e)?"right":"left",st=e=>e.type==="columnSettings",at=e=>e.type==="tableSettings",wl=(e,o)=>{switch(ro==null||ro(`TableModelReducer ${o.type}`),o.type){case"init":return ct(o);case"moveColumn":return Rl(e,o);case"resizeColumn":return Ml(e,o);case"setTableSchema":return Hl(e,o);case"hideColumns":return yl(e,o);case"showColumns":return Dl(e,o);case"pinColumn":return Pl(e,o);case"updateColumnProp":return Ce(e,o);case"tableConfig":return pt(e,o);default:return console.log(`unhandled action ${o.type}`),e}},ut=(e,o)=>{let[t,r]=Cl(wl,{tableConfig:e,dataSource:o},ct),{columns:n,headings:l,tableConfig:s,...i}=t;return{columns:n,dispatchColumnAction:r,headings:l,tableAttributes:i,tableConfig:s}};function ct({dataSource:e,tableConfig:o}){let{columns:t,...r}=o,{config:n,tableSchema:l}=e,s=t.filter(fl(n==null?void 0:n.columns)).map(mt(r,l)),i=s.some(pl)?rt(s):s,a={columns:i,headings:sl(i),tableConfig:o,...r};if(n){let{columns:u,...c}=n;a=pt(a,{type:"tableConfig",...c})}return a}var Tl=(e,o)=>o==="uppercase"?e.toUpperCase():o==="capitalize"?e[0].toUpperCase()+e.slice(1).toLowerCase():e,mt=(e,o)=>(t,r)=>{let{columnDefaultWidth:n=vl,columnFormatHeader:l}=e,s=lt(t,o),{align:i=it(s),name:a,label:u=il(t),width:c=n,...p}=t,f={...p,align:i,CellRenderer:nl(t),HeaderCellContentRenderer:rl(t),HeaderCellLabelRenderer:ll(t),clientSideEditValidationCheck:ul(t.type)?gl(t.type.renderer.rules):void 0,index:r+1,label:Tl(u,l),name:a,originalIdx:r,serverDataType:s,valueFormatter:al(t,s),width:c};return ml(f)&&(f.columns=f.columns.map(g=>mt(e)(g,r))),f};function Rl(e,{column:o,moveBy:t}){let{columns:r}=e;if(typeof t=="number"){let n=r.indexOf(o),l=r.slice(),[s]=l.splice(n,1);return l.splice(n+t,0,s),{...e,columns:l}}return e}function yl(e,{columns:o}){return o.some(t=>t.hidden!==!0)?o.reduce((t,r)=>r.hidden!==!0?Ce(t,{type:"updateColumnProp",column:r,hidden:!0}):t,e):e}function Dl(e,{columns:o}){return o.some(t=>t.hidden)?o.reduce((t,r)=>r.hidden?Ce(t,{type:"updateColumnProp",column:r,hidden:!1}):t,e):e}function Ml(e,{column:o,phase:t,width:r}){let n="updateColumnProp",l=t!=="end";switch(t){case"begin":return Ce(e,{type:n,column:o,resizing:l});case"end":return Ce(e,{type:n,column:o,resizing:l,width:r});case"resize":return Ce(e,{type:n,column:o,width:r});default:throw Error(`useTableModel.resizeColumn, invalid resizePhase ${t}`)}}function Hl(e,{tableSchema:o}){let{columns:t}=e;if(t.some(hl)){let r=t.map(n=>{var s;let l=lt(n,o);return{...n,align:(s=n.align)!=null?s:it(l),serverDataType:l}});return{...e,columns:r}}else return e}function Pl(e,o){let{columns:t}=e,{column:r,pin:n}=o,l=t.find(s=>s.name===r.name);return l?(t=me(t,{...l,pin:n}),t=rt(t),{...e,columns:t}):e}function Ce(e,o){let{columns:t,tableConfig:r}=e,{align:n,column:l,hidden:s,label:i,resizing:a,width:u}=o,c=t.find(p=>p.name===l.name);if(c&&((n==="left"||n==="right")&&(t=me(t,{...c,align:n})),typeof i=="string"&&(t=me(t,{...c,label:i})),typeof a=="boolean"&&(t=me(t,{...c,resizing:a})),typeof s=="boolean"&&(t=me(t,{...c,hidden:s})),typeof u=="number")){t=me(t,{...c,width:u});let p=r.columns.find(f=>f.name===l.name);p&&(r={...r,columns:me(r.columns,{...p,width:u})})}return{...e,columns:t,tableConfig:r}}function pt(e,{confirmed:o,filter:t,groupBy:r,sort:n}){let l=r!==void 0,s=typeof(t==null?void 0:t.filter)=="string",i=n&&n.sortDefs.length>0,a=e;return l&&(a={...e,columns:ol(a.columns,r,o)}),i&&(a={...e,columns:tl(a.columns,n)}),s?a={...e,columns:el(a.columns,t)}:a.columns.some(cl)&&(a={...e,columns:bl(a.columns)}),a}import{getColumnsInViewport as dt,getRowElementAtIndex as El,itemsChanged as Sl}from"@vuu-ui/vuu-utils";import{useCallback as te,useEffect as kl,useImperativeHandle as Ll,useMemo as bt,useRef as q,useState as Al}from"react";var Il=100,ft=200,gt=e=>{let{clientHeight:o,clientWidth:t,scrollHeight:r,scrollWidth:n}=e;return[n-t,r-o]},zl=(e,o)=>{if(e!==void 0){let{scrollTop:t}=e;return o>t?"fwd":"bwd"}},Ct=(e,o)=>{let{clientHeight:t,clientWidth:r,scrollHeight:n,scrollLeft:l,scrollTop:s,scrollWidth:i}=e,a=i-r,u=l/(i-r),c=n-t,p=s/(n-t),f=zl(o,s);return f==="fwd"&&p>.99?p=1:f==="bwd"&&p<.02&&(p=0),[l,u,a,s,p,c]},Nl={scrollToIndex:()=>{},scrollToKey:()=>{}},vt=({onAttach:e,onDetach:o})=>{let t=q(null);return te(n=>{if(n)t.current=n,e==null||e(n);else if(t.current){let{current:l}=t;t.current=n,o==null||o(l)}},[e,o])},ht=({columns:e,getRowAtPosition:o,onHorizontalScroll:t,onVerticalScroll:r,onVerticalScrollInSitu:n,scrollingApiRef:l,setRange:s,viewportMeasurements:i})=>{let a=q(0),u=q(!1),c=q({scrollTop:0,scrollLeft:0}),p=q(!1),f=q({scrollTop:0,scrollLeft:0}),g=q(null),C=q(null),T=q(0),{appliedPageSize:m,isVirtualScroll:h,rowCount:x,totalHeaderHeight:P,viewportWidth:E}=i,H=q([]),[,M]=Al({}),k=q(0);bt(()=>{let[b,R]=dt(e,c.current.scrollLeft,c.current.scrollLeft+E+ft);k.current=R,H.current=b},[E,e]);let N=te(b=>{if(c.current.scrollLeft=b,t==null||t(b),Math.abs(b-T.current)>Il){T.current=b;let[R,y]=dt(e,b,b+E+ft);Sl(H.current,R)&&(k.current=y,H.current=R,M({}))}},[e,t,E]),K=te((b,R)=>{c.current.scrollTop=b,r==null||r(b,R);let y=o(b);y!==a.current&&(a.current=y,s({from:y,to:y+x})),n==null||n(0)},[o,r,n,s,x]),$=te(()=>{let{current:b}=C,{current:R}=g,{current:y}=u,{current:W}=f;if(y)u.current=!1;else if(b&&R){p.current=!0;let[J,U,,V,F]=Ct(R,W);W.scrollLeft=J,W.scrollTop=V;let[A,G]=gt(R),Z=Math.round(U*A),Y=F*G;b.scrollTo({left:Z,top:Y,behavior:"auto"})}n==null||n(0)},[n]),B=te(()=>{let{current:b}=p,{current:R}=C,{current:y}=g,{current:W}=c;if(R&&y){let[J,U,V,F,A,G]=Ct(R);u.current=!0,b?p.current=!1:(y.scrollLeft=Math.round(U*V),y.scrollTop=A*G),W.scrollTop!==F&&K(F,A),W.scrollLeft!==J&&N(J)}},[K,N]),ee=te(b=>{g.current=b,b.addEventListener("scroll",$,{passive:!0})},[$]),L=te(b=>{g.current=null,b.removeEventListener("scroll",$)},[$]),D=te(b=>{C.current=b,b.addEventListener("scroll",B,{passive:!0})},[B]),oe=te(b=>{C.current=null,b.removeEventListener("scroll",B)},[B]),le=vt({onAttach:D,onDetach:oe}),I=vt({onAttach:ee,onDetach:L}),v=te(b=>{let{current:R}=C;if(R){let[y,W]=gt(R),{scrollLeft:J,scrollTop:U}=R;if(u.current=!1,b.type==="scroll-row"){let V=El(R,b.rowIndex);if(V!==null){let[F,A]=Uo(V,P);if(F&&A)if(h){let G=F==="down"?1:-1;n==null||n(G);let Z=a.current+G;a.current=Z,s({from:Z,to:Z+x})}else{let G=J,Z=U;F==="up"||F==="down"?Z=Math.min(Math.max(0,U+A),W):G=Math.min(Math.max(0,J+A),y),R.scrollTo({top:Z,left:G,behavior:"smooth"})}}}else if(b.type==="scroll-page"){let{direction:V}=b;if(h){let F=V==="down"?x:-x;n==null||n(F);let A=a.current+F;a.current=A,s({from:A,to:A+x})}else{let F=V==="down"?m:-m,A=Math.min(Math.max(0,U+F),W);R.scrollTo({top:A,left:J,behavior:"auto"})}}else if(b.type==="scroll-end"){let{direction:V}=b,F=V==="end"?W:0;R.scrollTo({top:F,left:R.scrollLeft,behavior:"auto"})}}},[m,h,n,s,P,x]),w=bt(()=>({scrollToIndex:b=>{if(g.current){let R=(b-30)*20;g.current.scrollTop=R}},scrollToKey:b=>{console.log(`scrollToKey ${b}`)}}),[]);return Ll(l,()=>g.current?w:Nl,[w]),kl(()=>{let{current:b}=a,R={from:b,to:b+x};s(R)},[s,x]),{columnsWithinViewport:H.current,scrollbarContainerRef:I,contentContainerRef:le,requestScroll:v,virtualColSpan:k.current}};import{actualRowPositioning as Fl,measurePinnedColumns as Kl,virtualRowPositioning as Ol}from"@vuu-ui/vuu-utils";import{useCallback as xt,useMemo as Ee,useRef as lo}from"react";var $l=1e7,Gl={appliedPageSize:0,contentHeight:0,contentWidth:0,getRowAtPosition:()=>-1,getRowOffset:()=>-1,horizontalScrollbarHeight:0,isVirtualScroll:!1,pinnedWidthLeft:0,pinnedWidthRight:0,rowCount:0,setInSituRowOffset:()=>{},setScrollTop:()=>{},totalHeaderHeight:0,verticalScrollbarWidth:0,viewportBodyHeight:0,viewportWidth:0},wt=({columns:e,headerHeight:o,headings:t,rowCount:r,rowHeight:n,selectionEndSize:l=4,size:s})=>{let i=lo(0),a=lo(0),u=Math.min(n*r,$l),c=r*n,p=c-u,{pinnedWidthLeft:f,pinnedWidthRight:g,unpinnedWidth:C}=Ee(()=>Kl(e,l),[e,l]),T=lo(o);Ee(()=>{T.current=o*(1+t.length)},[o,t.length]);let[m,h,x]=Ee(()=>{if(p){let[H,M,k]=Ol(n,p,a);return[K=>H(K,i.current),M,k]}else return Fl(n)},[p,n]),P=xt((H,M)=>{a.current=M},[]),E=xt(H=>{H===0?i.current=0:i.current=Math.max(0,i.current+H)},[]);return Ee(()=>{if(s){let{current:H}=T,M=15,k=f+C+g,N=k>s.width?M:0,K=(s.height-o)/n,$=Number.isInteger(K)?K:Math.ceil(K),B=s.height-H,ee=u>B?M:0,L=$*n*(u/c),D=s.width;return{appliedPageSize:L,contentHeight:u,contentWidth:k,getRowAtPosition:h,getRowOffset:m,isVirtualScroll:x,horizontalScrollbarHeight:N,pinnedWidthLeft:f,pinnedWidthRight:g,rowCount:$,setInSituRowOffset:E,setScrollTop:P,totalHeaderHeight:H,verticalScrollbarWidth:ee,viewportBodyHeight:B,viewportWidth:D}}else return Gl},[h,m,o,x,f,C,g,u,n,E,P,s,c])};import{useLayoutProviderDispatch as Bl}from"@vuu-ui/vuu-layout";import{getCalculatedColumnType as Vl}from"@vuu-ui/vuu-utils";import{useCallback as pe,useRef as Wl,useState as Ul}from"react";var Tt=({availableColumns:e,onAvailableColumnsChange:o,onConfigChange:t,onCreateCalculatedColumn:r,onDataSourceConfigChange:n,tableConfig:l})=>{let s=Bl(),i=Wl(),[a,u]=Ul(e),c=pe((m,h,x)=>{s({type:"set-props",path:"#context-panel",props:{expanded:!0,content:{type:m,props:x},title:h}})},[s]),p=pe(()=>{requestAnimationFrame(()=>{var m;(m=i.current)==null||m.call(i)})},[]),f=pe(m=>{let h=a.concat({name:m.name,serverDataType:Vl(m)});u(h),o==null||o(h),requestAnimationFrame(()=>{var x;(x=i.current)==null||x.call(i)}),r(m)},[a,o,r]),g=pe(m=>{c("ColumnSettings","Column Settings",{column:m.column,onCancelCreateColumn:p,onConfigChange:t,onCreateCalculatedColumn:f,tableConfig:l,vuuTable:m.vuuTable})},[p,f,t,c,l]),C=pe(()=>{g({column:{name:"::",serverDataType:"string"},type:"columnSettings",vuuTable:{module:"SIMUL",table:"instruments"}})},[g]),T=pe(m=>{let h=l.columns.find(x=>x.name===m);h&&g({type:"columnSettings",column:h,vuuTable:{module:"SIMUL",table:"instruments"}})},[g,l.columns]);return i.current=pe(()=>{c("TableSettings","DataGrid Settings",{availableColumns:a!=null?a:l.columns.map(({name:m,serverDataType:h})=>({name:m,serverDataType:h})),onAddCalculatedColumn:C,onConfigChange:t,onDataSourceConfigChange:n,onNavigateToColumn:T,tableConfig:l})},[a,C,T,t,n,c,l]),{showColumnSettingsPanel:g,showTableSettingsPanel:i.current}};var Se=e=>e,{KEY:li,IS_EXPANDED:yt,IS_LEAF:Dt}=ql,ii={draggable:void 0,onMouseDown:void 0},si=()=>ii,ai=(e,o)=>({...e,columns:e.columns.concat(o)}),Mt=({allowDragDrop:e=!1,availableColumns:o,config:t,containerRef:r,dataSource:n,disableFocus:l,headerHeight:s=25,highlightedIndex:i,id:a,navigationStyle:u="cell",onAvailableColumnsChange:c,onConfigChange:p,onDragStart:f,onDrop:g,onFeatureInvocation:C,onHighlight:T,onRowClick:m,onSelect:h,onSelectionChange:x,renderBufferSize:P=0,rowHeight:E=20,scrollingApiRef:H,selectionModel:M,size:k})=>{let[N,K]=ri(n.size);if(n===void 0)throw Error("no data source provided to Vuu Table");let $=e?_l:si,B=Rt(()=>No(n),[n]),ee=z(d=>{K(d)},[]),{columns:L,dispatchColumnAction:D,headings:oe,tableAttributes:le,tableConfig:I}=ut(t,n);oi(()=>{D({type:"init",tableConfig:t,dataSource:n})},[t,n,D]);let v=z(d=>{D({type:"init",tableConfig:d,dataSource:n}),p==null||p(Se(d))},[n,D,p]),w=Rt(()=>Ql(n.columns),[n.columns]),b=z(({tableSchema:d})=>{d?D({type:"setTableSchema",tableSchema:d}):console.log("subscription message with no schema")},[D]),{getRowAtPosition:R,getRowOffset:y,setInSituRowOffset:W,setScrollTop:J,...U}=wt({columns:L,headerHeight:s,headings:oe,rowCount:N,rowHeight:E,size:k}),V=Jo({from:0,to:U.rowCount}),{data:F,dataRef:A,getSelectedRows:G,range:Z,setRange:Y}=Qo({dataSource:n,onFeatureInvocation:C,renderBufferSize:P,onSizeChange:ee,onSubscribed:b,range:V}),{requestScroll:Le,...Ae}=ht({columns:L,getRowAtPosition:R,rowHeight:E,scrollingApiRef:H,setRange:Y,onVerticalScroll:J,onVerticalScrollInSitu:W,viewportMeasurements:U}),xe=z(d=>{D({type:"init",tableConfig:d,dataSource:n}),p==null||p(Se(d))},[n,D,p]),ue=z(d=>{n.config={...n.config,...d}},[n]);ti(()=>{n.on("config",(d,S)=>{D({type:"tableConfig",...d,confirmed:S})})},[n,D]);let At=z(d=>{n.columns=n.columns.concat(d.name),v(ai(I,d))},[n,I,v]),so=z(d=>{let{columns:S}=d,O=S.map(X=>X.name),_={...I,columns:I.columns.map(X=>O.includes(X.name)?{...X,hidden:!0}:X)};v(_)},[I,v]),ao=z(d=>{v({...I,columns:ei(I.columns,{...d.column,pin:d.pin})})},[I,v]),{showColumnSettingsPanel:uo,showTableSettingsPanel:co}=Tt({availableColumns:o!=null?o:I.columns.map(({name:d,serverDataType:S="string"})=>({name:d,serverDataType:S})),onAvailableColumnsChange:c,onConfigChange:xe,onCreateCalculatedColumn:At,onDataSourceConfigChange:ue,tableConfig:I}),It=z(d=>{if(st(d))uo(d);else if(at(d))co();else switch(d.type){case"hideColumns":return so(d);case"pinColumn":return ao(d);default:D(d)}},[D,so,ao,uo,co]),zt=$o({dataSource:n,onPersistentColumnOperation:It}),Nt=z((d,S=!1,O)=>{n&&(n.sort=Xl(n.sort,d,S,O))},[n]),Ie=ni(),Ft=z((d,S,O)=>{var X,ve,ie;let _=L.find(j=>j.name===S);if(_)if(d==="resize")(X=Ie.current)==null||X.forEach(j=>{j.style.width=`${O}px`});else if(d==="end")Ie.current=void 0,jl(O)&&(D({type:"resizeColumn",phase:d,column:_,width:O}),p==null||p(Se(Go(I,{type:"col-size",column:_,width:O}))));else{let j=`[aria-colindex='${_.index}']`;Ie.current=Array.from((ie=(ve=r.current)==null?void 0:ve.querySelectorAll(`.vuuTableCell${j},.vuuTableHeaderCell${j}`))!=null?ie:[]),D({type:"resizeColumn",phase:d,column:_,width:O})}else throw Error(`useDataTable.handleColumnResize, column ${S} not found`)},[L,D,p,I,r]),Kt=z((d,S)=>{var X,ve;let O=Yl(S,d,w),_=d[li];if(d[yt]){if(n.closeTreeNode(_,!0),O){let ie=L.indexOf(S),j=(X=n.getRowsAtDepth)==null?void 0:X.call(n,ie+1);j&&!j.some(de=>de[yt]||de[Dt])&&D({type:"hideColumns",columns:L.slice(ie+2)})}}else if(n.openTreeNode(_),O){let ie=(ve=n.getChildRows)==null?void 0:ve.call(n,_),j=L.indexOf(S)+1,de=[L[j]];ie&&ie.some(ze=>ze[Dt])&&de.push(L[j+1]),de.some(ze=>ze.hidden)&&D({type:"showColumns",columns:de})}},[w,L,n,D]),{highlightedIndexRef:mo,navigate:Ot,onFocus:po,onKeyDown:bo,...$t}=et({columnCount:L.filter(d=>d.hidden!==!0).length,containerRef:r,disableFocus:l,highlightedIndex:i,navigationStyle:u,requestScroll:Le,rowCount:n==null?void 0:n.size,onHighlight:T,viewportRange:Z,viewportRowCount:U.rowCount}),{onBlur:Gt,onDoubleClick:Bt,onKeyDown:fo,onFocus:go}=_o({navigate:Ot}),Vt=z(d=>{po(),d.defaultPrevented||go(d)},[go,po]),Wt=nt({columns:L,data:F,dataSource:n,getSelectedRows:G}),Ut=z(d=>{n.groupBy=d.map(S=>S.name)},[n]),_t=z(d=>{Zl(d)?n.groupBy=[]:n&&n.groupBy.includes(d.name)&&(n.groupBy=n.groupBy.filter(S=>S!==d.name))},[n]),Xt=z(d=>{n.select(d),x==null||x(d)},[n,x]),{onKeyDown:Co,onRowClick:vo}=tt({highlightedIndexRef:mo,onSelect:h,onSelectionChange:Xt,selectionModel:M}),Qt=z(d=>{bo(d),d.defaultPrevented||fo(d),d.defaultPrevented||Co(d)},[bo,fo,Co]),Jt=z((d,S,O)=>{vo(d,S,O),m==null||m(d)},[m,vo]),Zt=z(d=>{let S={...I,columns:d};D({type:"init",tableConfig:S,dataSource:n}),p==null||p(Se(S))},[n,D,p,I]),Yt=z(d=>{g==null||g(d)},[g]),jt=z(async(d,S,O)=>n.applyEdit(d,S,O),[n]),qt=z(d=>{let{initialDragElement:S}=d,O=Jl(S),_=A.current.find(X=>X[0]===O);_&&d.setPayload(_),f==null||f(d)},[A,f]),{onMouseDown:en,draggable:on}=$({allowDragDrop:e,containerRef:r,draggableClassName:"vuuTable",id:a,onDragStart:qt,onDrop:Yt,orientation:"vertical",itemQuery:".vuuTableRow"});return{...$t,"aria-rowcount":n.size,draggableRow:on,onBlur:Gt,onDoubleClick:Bt,onFocus:Vt,onKeyDown:Qt,onMouseDown:en,columnMap:w,columns:L,data:F,getRowOffset:y,handleContextMenuAction:zt,headings:oe,highlightedIndex:mo.current,menuBuilder:B,onContextMenu:Wt,onDataEdited:jt,onMoveColumn:Zt,onMoveGroupColumn:Ut,onRemoveGroupColumn:_t,onRowClick:Jt,onSortColumn:Nt,onResizeColumn:Ft,onToggleGroup:Kt,scrollProps:Ae,tableAttributes:le,tableConfig:I,viewportMeasurements:U}};import{jsx as ae,jsxs as Ht}from"react/jsx-runtime";var re="vuuTable",{IDX:Ci,RENDER_IDX:vi}=mi,hi=({Row:e=We,allowDragDrop:o,availableColumns:t,config:r,containerRef:n,dataSource:l,disableFocus:s=!1,highlightedIndex:i,id:a,navigationStyle:u="cell",onAvailableColumnsChange:c,onConfigChange:p,onDragStart:f,onDrop:g,onFeatureInvocation:C,onHighlight:T,onRowClick:m,onSelect:h,onSelectionChange:x,renderBufferSize:P=5,rowHeight:E=20,scrollingApiRef:H,selectionModel:M="extended",showColumnHeaders:k=!0,headerHeight:N=k?25:0,size:K})=>{let $=pi(a),{columnMap:B,columns:ee,data:L,draggableRow:D,getRowOffset:oe,handleContextMenuAction:le,headings:I,highlightedIndex:v,onDataEdited:w,onMoveColumn:b,onMoveGroupColumn:R,onRemoveGroupColumn:y,onResizeColumn:W,onRowClick:J,onSortColumn:U,onToggleGroup:V,menuBuilder:F,scrollProps:A,tableAttributes:G,tableConfig:Z,viewportMeasurements:Y,...Le}=Mt({allowDragDrop:o,availableColumns:t,config:r,containerRef:n,dataSource:l,disableFocus:s,headerHeight:N,highlightedIndex:i,id:$,navigationStyle:u,onAvailableColumnsChange:c,onConfigChange:p,onDragStart:f,onDrop:g,onFeatureInvocation:C,onHighlight:T,onRowClick:m,onSelect:h,onSelectionChange:x,renderBufferSize:P,rowHeight:E,scrollingApiRef:H,selectionModel:M,size:K}),Ae=Pt(`${re}-contentContainer`,{[`${re}-colLines`]:G.columnSeparators,[`${re}-rowLines`]:G.rowSeparators,[`${re}-zebra`]:G.zebraStripes}),xe={"--content-height":`${Y.contentHeight}px`,"--content-width":`${Y.contentWidth}px`,"--horizontal-scrollbar-height":`${Y.horizontalScrollbarHeight}px`,"--pinned-width-left":`${Y.pinnedWidthLeft}px`,"--pinned-width-right":`${Y.pinnedWidthRight}px`,"--header-height":`${N}px`,"--row-height":`${E}px`,"--total-header-height":`${Y.totalHeaderHeight}px`,"--vertical-scrollbar-width":`${Y.verticalScrollbarWidth}px`,"--viewport-body-height":`${Y.viewportBodyHeight}px`};return Ht(ui,{menuActionHandler:le,menuBuilder:F,children:[ae("div",{className:`${re}-scrollbarContainer`,ref:A.scrollbarContainerRef,style:xe,children:ae("div",{className:`${re}-scrollbarContent`})}),ae("div",{className:Ae,ref:A.contentContainerRef,style:xe,children:Ht("div",{...Le,className:`${re}-table`,role:"table",tabIndex:s?void 0:-1,children:[k?ae(Xe,{columns:A.columnsWithinViewport,headings:I,onMoveColumn:b,onMoveGroupColumn:R,onRemoveGroupColumn:y,onResizeColumn:W,onSortColumn:U,tableConfig:Z,tableId:$,virtualColSpan:A.virtualColSpan}):null,ae("div",{className:`${re}-body`,children:L.map(ue=>ae(e,{"aria-rowindex":ue[0]+1,columnMap:B,columns:A.columnsWithinViewport,highlighted:v===ue[Ci],onClick:J,onDataEdited:w,row:ue,offset:oe(ue),onToggleGroup:V,virtualColSpan:A.virtualColSpan,zebraStripes:G.zebraStripes},ue[vi]))})]})}),D]})},Tm=bi(function({Row:o,allowDragDrop:t,availableColumns:r,className:n,config:l,dataSource:s,disableFocus:i,highlightedIndex:a,id:u,navigationStyle:c,onAvailableColumnsChange:p,onConfigChange:f,onDragStart:g,onDrop:C,onFeatureInvocation:T,onHighlight:m,onRowClick:h,onSelect:x,onSelectionChange:P,renderBufferSize:E,rowHeight:H,scrollingApiRef:M,selectionModel:k,showColumnHeaders:N,headerHeight:K,style:$,...B},ee){let L=fi(null),[D,oe]=gi();if(l===void 0)throw Error("vuu Table requires config prop. Minimum config is list of Column Descriptors");if(s===void 0)throw Error("vuu Table requires dataSource prop");return ae(ci,{...B,className:Pt(re,n),id:u,onResize:oe,ref:di(L,ee),children:D?ae(hi,{Row:o,allowDragDrop:t,availableColumns:r,config:l,containerRef:L,dataSource:s,disableFocus:i,headerHeight:K,highlightedIndex:a,id:u,navigationStyle:c,onAvailableColumnsChange:p,onConfigChange:f,onDragStart:g,onDrop:C,onFeatureInvocation:T,onHighlight:m,onRowClick:h,onSelect:x,onSelectionChange:P,renderBufferSize:E,rowHeight:H,scrollingApiRef:M,selectionModel:k,showColumnHeaders:N,size:D}):null})});import{memo as xi,useCallback as wi}from"react";import{CheckboxIcon as Ti,WarnCommit as Ri}from"@vuu-ui/vuu-ui-controls";import{Checkbox as yi}from"@salt-ds/core";import{dataAndColumnUnchanged as Di,dispatchCustomEvent as Mi,registerComponent as Hi}from"@vuu-ui/vuu-utils";import{jsx as Et}from"react/jsx-runtime";var St=xi(({column:e,columnMap:o,onCommit:t=Ri,row:r})=>{let n=o[e.name],l=r[n],s=wi(i=>async a=>{let u=await t(i);return u===!0&&Mi(a.target,"vuu-commit"),u},[t]);return e.editable?Et(yi,{checked:l,onClick:s(!l)}):Et(Ti,{checked:l,disabled:!0})},Di);St.displayName="CheckboxCell";Hi("checkbox-cell",St,"cell-renderer",{serverDataType:"boolean"});import{registerComponent as Pi}from"@vuu-ui/vuu-utils";import{Input as Ei}from"@salt-ds/core";import{useEditableText as Si}from"@vuu-ui/vuu-ui-controls";import ki from"clsx";import{jsx as io}from"react/jsx-runtime";var ke="vuuTableInputCell",Li=()=>(console.warn("onCommit handler has not been provided to InputCell cell renderer"),Promise.resolve(!0)),Ai=({column:e,columnMap:o,onCommit:t=Li,row:r})=>{let n=o[e.name],{align:l="left",clientSideEditValidationCheck:s}=e,{warningMessage:i,...a}=Si({initialValue:r[n],onCommit:t,clientSideEditValidationCheck:s}),u=i&&l==="left"?io("span",{className:`${ke}-icon`,"data-icon":"error"}):void 0,c=i&&l==="right"?io("span",{className:`${ke}-icon`,"data-icon":"error"}):void 0;return io(Ei,{...a,className:ki(ke,{[`${ke}-error`]:i!==void 0}),endAdornment:u,startAdornment:c})};Pi("input-cell",Ai,"cell-renderer",{});import{WarnCommit as Ii}from"@vuu-ui/vuu-ui-controls";import{dataAndColumnUnchanged as zi,dispatchCustomEvent as Ni,isTypeDescriptor as Fi,isValueListRenderer as Ki,registerComponent as Oi}from"@vuu-ui/vuu-utils";import $i from"clsx";import{memo as Gi,useCallback as Bi}from"react";import{CycleStateButton as Vi}from"@vuu-ui/vuu-ui-controls";import{jsx as _i}from"react/jsx-runtime";var kt="vuuTableToggleCell",Wi=({name:e,type:o})=>{if(Fi(o)&&Ki(o.renderer))return o.renderer.values;throw Error(`useLookupValues column ${e} has not been configured with a values list`)},Ui=Gi(function({column:o,columnMap:t,onCommit:r=Ii,row:n}){let l=Wi(o),s=t[o.name],i=n[s],a=Bi((u,c)=>r(c).then(p=>(p===!0&&Ni(u.target,"vuu-commit"),p)),[r]);return _i(Vi,{className:$i(kt,`${kt}-${o.name}`),onCommit:a,value:i,values:l,variant:"cta",children:i})},zi);Oi("toggle-cell",Ui,"cell-renderer",{});import{useStateRef as Xi}from"@vuu-ui/vuu-ui-controls";import{dispatchMouseEvent as Qi}from"@vuu-ui/vuu-utils";import{useCallback as Lt,useRef as Ji}from"react";var pp=(e,o)=>{let t=Ji(null),[r,n]=Xi(e),l=Lt(i=>{var a;if(i.key==="ArrowDown")n((u=-1)=>Math.min(o-1,u+1));else if(i.key==="ArrowUp")n((u=-1)=>Math.max(0,u-1));else if(i.key==="Enter"||i.key===" "){let{current:u}=r,c=(a=t.current)==null?void 0:a.querySelector(`[aria-rowindex="${u}"]`);c&&Qi(c,"click")}},[r,o,n]),s=Lt(i=>{n(i)},[n]);return{highlightedIndexRef:r,onHighlight:s,onKeyDown:l,tableRef:t}};export{St as CheckboxCell,Ge as GroupHeaderCellNext,Mo as HeaderCell,Ai as InputCell,Tm as Table,Eo as TableCell,So as TableGroupCell,Ui as ToggleCell,st as isShowColumnSettings,at as isShowTableSettings,Nl as noScrolling,Go as updateTableConfig,pp as useControlledTableNavigation,ut as useTableModel,ht as useTableScroll,wt as useTableViewport};
1
+ // src/header-cell/GroupHeaderCellNext.tsx
2
+ import { OverflowContainer } from "@vuu-ui/vuu-ui-controls";
3
+ import { useLayoutEffectSkipFirst } from "@vuu-ui/vuu-utils";
4
+ import cx3 from "clsx";
5
+ import { useCallback as useCallback4, useRef as useRef3, useState as useState2 } from "react";
6
+
7
+ // src/column-header-pill/ColumnHeaderPill.tsx
8
+ import cx from "clsx";
9
+ import { useCallback } from "react";
10
+ import { jsx, jsxs } from "react/jsx-runtime";
11
+ var classBase = "vuuColumnHeaderPill";
12
+ var ColumnHeaderPill = ({
13
+ children,
14
+ className,
15
+ column,
16
+ onRemove,
17
+ removable,
18
+ ...htmlAttributes
19
+ }) => {
20
+ if (removable && typeof onRemove !== "function") {
21
+ throw Error(
22
+ "ColumnHeaderPill onRemove prop must be provided if Pill is removable"
23
+ );
24
+ }
25
+ const handleClickRemove = useCallback(
26
+ (evt) => {
27
+ evt.preventDefault();
28
+ evt.stopPropagation();
29
+ onRemove == null ? void 0 : onRemove(column);
30
+ },
31
+ [column, onRemove]
32
+ );
33
+ return /* @__PURE__ */ jsxs("div", { ...htmlAttributes, className: cx(classBase, className), children: [
34
+ children,
35
+ removable ? /* @__PURE__ */ jsx(
36
+ "span",
37
+ {
38
+ className: `${classBase}-removeButton`,
39
+ role: "button",
40
+ "data-icon": "cross",
41
+ onClick: handleClickRemove
42
+ }
43
+ ) : null
44
+ ] });
45
+ };
46
+
47
+ // src/column-header-pill/GroupColumnPill.tsx
48
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
49
+ var GroupColumnPill = ({
50
+ column,
51
+ ...columnHeaderProps
52
+ }) => {
53
+ const { name, sorted } = column;
54
+ const icon = typeof sorted === "number" ? sorted < 0 ? "arrow-down" : "arrow-up" : sorted === "A" ? "arrow-up" : sorted === "D" ? "arrow-down" : void 0;
55
+ return /* @__PURE__ */ jsxs2(ColumnHeaderPill, { ...columnHeaderProps, column, children: [
56
+ /* @__PURE__ */ jsx2("span", { className: "vuuGroupColumnPill-label", children: name }),
57
+ icon !== void 0 ? /* @__PURE__ */ jsx2("span", { "data-icon": icon }) : null,
58
+ typeof sorted === "number" ? /* @__PURE__ */ jsx2("span", { className: "vuuSortPosition", children: Math.abs(sorted) }) : null
59
+ ] });
60
+ };
61
+
62
+ // src/column-header-pill/SortIndicator.tsx
63
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
64
+ var SortIndicator = ({ column }) => {
65
+ if (!column.sorted) {
66
+ return null;
67
+ }
68
+ const icon = typeof column.sorted === "number" ? column.sorted < 0 ? "arrow-down" : "arrow-up" : column.sorted === "A" ? "arrow-up" : "arrow-down";
69
+ return /* @__PURE__ */ jsxs3(ColumnHeaderPill, { column, children: [
70
+ /* @__PURE__ */ jsx3("span", { "data-icon": icon }),
71
+ typeof column.sorted === "number" ? /* @__PURE__ */ jsx3("span", { className: "vuuSortPosition", children: Math.abs(column.sorted) }) : null
72
+ ] });
73
+ };
74
+
75
+ // src/column-resizing/ColumnResizer.tsx
76
+ import { useCallback as useCallback2, useRef } from "react";
77
+ import { jsx as jsx4 } from "react/jsx-runtime";
78
+ var NOOP = () => void 0;
79
+ var baseClass = "vuuColumnResizerNext";
80
+ var ColumnResizer = ({
81
+ onDrag,
82
+ onDragEnd = NOOP,
83
+ onDragStart = NOOP
84
+ }) => {
85
+ const positionRef = useRef({ start: 0, now: 0 });
86
+ const onMouseMove = useCallback2(
87
+ (e) => {
88
+ if (e.stopPropagation) {
89
+ e.stopPropagation();
90
+ }
91
+ if (e.preventDefault) {
92
+ e.preventDefault();
93
+ }
94
+ const { current: position } = positionRef;
95
+ const x = Math.round(e.clientX);
96
+ const moveBy = x - position.now;
97
+ const distanceMoved = position.now - position.start;
98
+ positionRef.current.now = x;
99
+ if (moveBy !== 0) {
100
+ onDrag(e, moveBy, distanceMoved);
101
+ }
102
+ },
103
+ [onDrag]
104
+ );
105
+ const onMouseUp = useCallback2(
106
+ (e) => {
107
+ window.removeEventListener("mouseup", onMouseUp);
108
+ window.removeEventListener("mousemove", onMouseMove);
109
+ const { current: position } = positionRef;
110
+ const distanceMoved = position.now - position.start;
111
+ onDragEnd(e, distanceMoved);
112
+ },
113
+ [onDragEnd, onMouseMove]
114
+ );
115
+ const handleMouseDown = useCallback2(
116
+ (e) => {
117
+ const { current: position } = positionRef;
118
+ onDragStart(e);
119
+ position.now = position.start = Math.round(e.clientX);
120
+ window.addEventListener("mouseup", onMouseUp);
121
+ window.addEventListener("mousemove", onMouseMove);
122
+ if (e.stopPropagation) {
123
+ e.stopPropagation();
124
+ }
125
+ if (e.preventDefault) {
126
+ e.preventDefault();
127
+ }
128
+ },
129
+ [onDragStart, onMouseMove, onMouseUp]
130
+ );
131
+ return /* @__PURE__ */ jsx4("div", { className: baseClass, onMouseDown: handleMouseDown });
132
+ };
133
+
134
+ // src/column-resizing/useTableColumnResize.tsx
135
+ import { useCallback as useCallback3, useRef as useRef2, useState } from "react";
136
+ var useTableColumnResize = ({
137
+ column,
138
+ onResize,
139
+ rootRef
140
+ }) => {
141
+ const widthRef = useRef2({ start: 0, now: 0 });
142
+ const [isResizing, setResizing] = useState(false);
143
+ const { name } = column;
144
+ const handleResizeStart = useCallback3(() => {
145
+ if (onResize && rootRef.current) {
146
+ const { current: width } = widthRef;
147
+ const { width: measuredWidth } = rootRef.current.getBoundingClientRect();
148
+ width.start = width.now = Math.round(measuredWidth);
149
+ setResizing(true);
150
+ onResize == null ? void 0 : onResize("begin", name);
151
+ }
152
+ }, [name, onResize, rootRef]);
153
+ const handleResize = useCallback3(
154
+ (_evt, moveBy, totalDistanceMoved) => {
155
+ if (rootRef.current) {
156
+ if (onResize) {
157
+ const { current: width } = widthRef;
158
+ const newWidth = width.start + totalDistanceMoved;
159
+ if (newWidth !== width.now && newWidth > 0) {
160
+ onResize("resize", name, newWidth);
161
+ width.now = newWidth;
162
+ }
163
+ }
164
+ }
165
+ },
166
+ [name, onResize, rootRef]
167
+ );
168
+ const handleResizeEnd = useCallback3(() => {
169
+ if (onResize) {
170
+ const { current: width } = widthRef;
171
+ onResize("end", name, width.now);
172
+ setTimeout(() => {
173
+ setResizing(false);
174
+ }, 80);
175
+ }
176
+ }, [name, onResize]);
177
+ return {
178
+ isResizing,
179
+ onDrag: handleResize,
180
+ onDragStart: handleResizeStart,
181
+ onDragEnd: handleResizeEnd
182
+ };
183
+ };
184
+
185
+ // src/useCell.ts
186
+ import { getColumnStyle } from "@vuu-ui/vuu-utils";
187
+ import cx2 from "clsx";
188
+ import { useMemo } from "react";
189
+ var useCell = (column, classBase10, isHeader) => (
190
+ // TODO measure perf without the memo, might not be worth the cost
191
+ useMemo(() => {
192
+ const className = cx2(classBase10, {
193
+ vuuPinFloating: column.pin === "floating",
194
+ vuuPinLeft: column.pin === "left",
195
+ vuuPinRight: column.pin === "right",
196
+ vuuEndPin: isHeader && column.endPin,
197
+ // [`${classBase}-resizing`]: column.resizing,
198
+ [`${classBase10}-editable`]: column.editable,
199
+ [`${classBase10}-right`]: column.align === "right"
200
+ });
201
+ const style = getColumnStyle(column);
202
+ return {
203
+ className,
204
+ style
205
+ };
206
+ }, [column, classBase10, isHeader])
207
+ );
208
+
209
+ // src/header-cell/GroupHeaderCellNext.tsx
210
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
211
+ import { createElement } from "react";
212
+ var classBase2 = "vuuTableGroupHeaderCell";
213
+ var switchIfChanged = (columns, newColumns) => {
214
+ if (columns === newColumns) {
215
+ return columns;
216
+ } else {
217
+ return newColumns;
218
+ }
219
+ };
220
+ var GroupHeaderCellNext = ({
221
+ column: groupColumn,
222
+ className: classNameProp,
223
+ onMoveColumn,
224
+ onRemoveColumn,
225
+ onResize,
226
+ ...htmlAttributes
227
+ }) => {
228
+ const rootRef = useRef3(null);
229
+ const { isResizing, ...resizeProps } = useTableColumnResize({
230
+ column: groupColumn,
231
+ onResize,
232
+ rootRef
233
+ });
234
+ const [columns, setColumns] = useState2(groupColumn.columns);
235
+ const { className, style } = useCell(groupColumn, classBase2, true);
236
+ const columnPillProps = columns.length > 1 ? {
237
+ removable: true,
238
+ onRemove: onRemoveColumn
239
+ } : void 0;
240
+ const handleMoveItem = useCallback4(
241
+ (fromIndex, toIndex) => {
242
+ setColumns((cols) => {
243
+ const newCols = cols.slice();
244
+ const [tab] = newCols.splice(fromIndex, 1);
245
+ if (toIndex === -1) {
246
+ const result = newCols.concat(tab);
247
+ onMoveColumn == null ? void 0 : onMoveColumn(result);
248
+ return result;
249
+ } else {
250
+ newCols.splice(toIndex, 0, tab);
251
+ onMoveColumn == null ? void 0 : onMoveColumn(newCols);
252
+ return newCols;
253
+ }
254
+ });
255
+ },
256
+ [onMoveColumn]
257
+ );
258
+ useLayoutEffectSkipFirst(() => {
259
+ setColumns((cols) => switchIfChanged(cols, groupColumn.columns));
260
+ }, [groupColumn.columns]);
261
+ return /* @__PURE__ */ jsxs4(
262
+ "div",
263
+ {
264
+ ...htmlAttributes,
265
+ className: cx3(className, classNameProp, {
266
+ [`${classBase2}-pending`]: groupColumn.groupConfirmed === false
267
+ }),
268
+ ref: rootRef,
269
+ role: "columnheader",
270
+ style,
271
+ children: [
272
+ /* @__PURE__ */ jsx5(
273
+ OverflowContainer,
274
+ {
275
+ allowDragDrop: true,
276
+ className: `${classBase2}-inner`,
277
+ height: 24,
278
+ onMoveItem: handleMoveItem,
279
+ overflowPosition: "start",
280
+ children: columns.map((column) => {
281
+ return /* @__PURE__ */ createElement(
282
+ GroupColumnPill,
283
+ {
284
+ ...columnPillProps,
285
+ column,
286
+ key: column.name
287
+ }
288
+ );
289
+ })
290
+ }
291
+ ),
292
+ /* @__PURE__ */ jsx5(
293
+ ColumnHeaderPill,
294
+ {
295
+ column: groupColumn,
296
+ removable: true,
297
+ onRemove: onRemoveColumn
298
+ }
299
+ ),
300
+ groupColumn.resizeable !== false ? /* @__PURE__ */ jsx5(ColumnResizer, { ...resizeProps }) : null
301
+ ]
302
+ }
303
+ );
304
+ };
305
+
306
+ // src/header-cell/HeaderCell.tsx
307
+ import cx5 from "clsx";
308
+ import { useCallback as useCallback6, useRef as useRef5 } from "react";
309
+
310
+ // src/column-menu/ColumnMenu.tsx
311
+ import { useContextMenu } from "@vuu-ui/vuu-popups";
312
+ import cx4 from "clsx";
313
+ import {
314
+ useCallback as useCallback5,
315
+ useRef as useRef4,
316
+ useState as useState3
317
+ } from "react";
318
+ import { jsx as jsx6 } from "react/jsx-runtime";
319
+ var getPosition = (element) => {
320
+ if (element) {
321
+ const { bottom, left } = element.getBoundingClientRect();
322
+ return { x: left, y: bottom + 6 };
323
+ }
324
+ };
325
+ var ColumnMenu = ({
326
+ className,
327
+ column,
328
+ ...props
329
+ }) => {
330
+ const rootRef = useRef4(null);
331
+ const [menuOpen, setMenuOpen] = useState3(false);
332
+ const [showContextMenu] = useContextMenu();
333
+ const handleMenuClose = useCallback5(() => {
334
+ setMenuOpen(false);
335
+ }, []);
336
+ const showColumnMenu = useCallback5(
337
+ (e) => {
338
+ setMenuOpen(true);
339
+ showContextMenu(e, "column-menu", {
340
+ column,
341
+ ContextMenuProps: {
342
+ onClose: handleMenuClose,
343
+ position: getPosition(rootRef.current)
344
+ }
345
+ });
346
+ },
347
+ [column, handleMenuClose, showContextMenu]
348
+ );
349
+ return /* @__PURE__ */ jsx6(
350
+ "span",
351
+ {
352
+ ...props,
353
+ className: cx4("vuuTable-columnMenu", className, {
354
+ "vuuTable-columnMenu-open": menuOpen
355
+ }),
356
+ "data-icon": "more-vert",
357
+ onClick: showColumnMenu,
358
+ ref: rootRef
359
+ }
360
+ );
361
+ };
362
+
363
+ // src/header-cell/HeaderCell.tsx
364
+ import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
365
+ var classBase3 = "vuuTableHeaderCell";
366
+ var HeaderCell = ({
367
+ className: classNameProp,
368
+ column,
369
+ onClick,
370
+ onResize,
371
+ ...htmlAttributes
372
+ }) => {
373
+ var _a;
374
+ const { HeaderCellContentRenderer, HeaderCellLabelRenderer } = column;
375
+ const rootRef = useRef5(null);
376
+ const { isResizing, ...resizeProps } = useTableColumnResize({
377
+ column,
378
+ onResize,
379
+ rootRef
380
+ });
381
+ const handleClick = useCallback6(
382
+ (evt) => {
383
+ !isResizing && (onClick == null ? void 0 : onClick(evt));
384
+ },
385
+ [isResizing, onClick]
386
+ );
387
+ const { className, style } = useCell(column, classBase3, true);
388
+ const columnMenu = /* @__PURE__ */ jsx7(ColumnMenu, { column });
389
+ const columnLabel = HeaderCellLabelRenderer ? /* @__PURE__ */ jsx7(HeaderCellLabelRenderer, { className: `${classBase3}-label`, column }) : /* @__PURE__ */ jsx7("div", { className: `${classBase3}-label`, children: (_a = column.label) != null ? _a : column.name });
390
+ const columnContent = HeaderCellContentRenderer ? [/* @__PURE__ */ jsx7(HeaderCellContentRenderer, { column }, "content")] : [];
391
+ const sortIndicator = /* @__PURE__ */ jsx7(SortIndicator, { column });
392
+ const headerItems = column.align === "right" ? [sortIndicator, columnLabel].concat(columnContent).concat(columnMenu) : [columnMenu, columnLabel, sortIndicator].concat(columnContent);
393
+ return /* @__PURE__ */ jsxs5(
394
+ "div",
395
+ {
396
+ ...htmlAttributes,
397
+ className: cx5(className, classNameProp, {
398
+ [`${classBase3}-resizing`]: isResizing
399
+ }),
400
+ onClick: handleClick,
401
+ ref: rootRef,
402
+ role: "columnheader",
403
+ style,
404
+ children: [
405
+ ...headerItems,
406
+ column.resizeable !== false ? /* @__PURE__ */ jsx7(ColumnResizer, { ...resizeProps }) : null
407
+ ]
408
+ }
409
+ );
410
+ };
411
+
412
+ // src/Table.tsx
413
+ import { ContextMenuProvider } from "@vuu-ui/vuu-popups";
414
+ import {
415
+ MeasuredContainer
416
+ } from "@vuu-ui/vuu-ui-controls";
417
+ import { metadataKeys as metadataKeys6, useId } from "@vuu-ui/vuu-utils";
418
+ import { useForkRef } from "@salt-ds/core";
419
+ import cx9 from "clsx";
420
+ import {
421
+ forwardRef as forwardRef2,
422
+ useRef as useRef16,
423
+ useState as useState9
424
+ } from "react";
425
+
426
+ // src/Row.tsx
427
+ import {
428
+ isGroupColumn,
429
+ isJsonColumn,
430
+ isJsonGroup,
431
+ metadataKeys as metadataKeys2,
432
+ isNotHidden,
433
+ RowSelected
434
+ } from "@vuu-ui/vuu-utils";
435
+ import cx7 from "clsx";
436
+ import {
437
+ forwardRef,
438
+ memo,
439
+ useCallback as useCallback9
440
+ } from "react";
441
+
442
+ // src/table-cell/TableCell.tsx
443
+ import { isNumericColumn } from "@vuu-ui/vuu-utils";
444
+ import { useCallback as useCallback7 } from "react";
445
+ import { jsx as jsx8 } from "react/jsx-runtime";
446
+ var classBase4 = "vuuTableCell";
447
+ var TableCell = ({
448
+ column,
449
+ columnMap,
450
+ onClick,
451
+ onDataEdited,
452
+ row
453
+ }) => {
454
+ const { className, style } = useCell(column, classBase4);
455
+ const { CellRenderer, index, name, valueFormatter } = column;
456
+ const dataIdx = columnMap[name];
457
+ const handleDataItemEdited = useCallback7(
458
+ (value) => {
459
+ if (onDataEdited) {
460
+ let typedValue = value;
461
+ if (isNumericColumn(column) && typeof value === "string") {
462
+ typedValue = column.serverDataType === "double" ? parseFloat(value) : parseInt(value);
463
+ }
464
+ return onDataEdited == null ? void 0 : onDataEdited(row, name, typedValue);
465
+ } else {
466
+ throw Error(
467
+ "TableCell onDataEdited prop not supplied for an editable cell"
468
+ );
469
+ }
470
+ },
471
+ [column, name, onDataEdited, row]
472
+ );
473
+ const handleClick = useCallback7(
474
+ (evt) => {
475
+ onClick == null ? void 0 : onClick(evt, column);
476
+ },
477
+ [column, onClick]
478
+ );
479
+ return /* @__PURE__ */ jsx8(
480
+ "div",
481
+ {
482
+ "aria-colindex": index,
483
+ className,
484
+ onClick: onClick ? handleClick : void 0,
485
+ role: "cell",
486
+ style,
487
+ children: CellRenderer ? /* @__PURE__ */ jsx8(
488
+ CellRenderer,
489
+ {
490
+ column,
491
+ columnMap,
492
+ onCommit: handleDataItemEdited,
493
+ row
494
+ }
495
+ ) : valueFormatter(row[dataIdx])
496
+ }
497
+ );
498
+ };
499
+
500
+ // src/table-cell/TableGroupCell.tsx
501
+ import { getGroupValueAndOffset, metadataKeys } from "@vuu-ui/vuu-utils";
502
+ import { useCallback as useCallback8 } from "react";
503
+ import cx6 from "clsx";
504
+ import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
505
+ var { IS_LEAF } = metadataKeys;
506
+ var classBase5 = "vuuTableGroupCell";
507
+ var TableGroupCell = ({
508
+ column,
509
+ columnMap,
510
+ onClick,
511
+ row
512
+ }) => {
513
+ const { columns } = column;
514
+ const [value, offset] = getGroupValueAndOffset(columns, row, columnMap);
515
+ const { className, style } = useCell(column, classBase5);
516
+ const handleClick = useCallback8(
517
+ (evt) => {
518
+ onClick == null ? void 0 : onClick(evt, column);
519
+ },
520
+ [column, onClick]
521
+ );
522
+ const isLeaf = row[IS_LEAF];
523
+ const spacers = Array(offset).fill(0).map((n, i) => /* @__PURE__ */ jsx9("span", { className: `${classBase5}-spacer` }, i));
524
+ return /* @__PURE__ */ jsxs6(
525
+ "div",
526
+ {
527
+ className: cx6(className, "vuuTableCell"),
528
+ role: "cell",
529
+ style,
530
+ onClick: isLeaf ? void 0 : handleClick,
531
+ children: [
532
+ spacers,
533
+ isLeaf ? null : /* @__PURE__ */ jsx9("span", { className: `${classBase5}-toggle`, "data-icon": "triangle-right" }),
534
+ /* @__PURE__ */ jsx9("span", { children: value })
535
+ ]
536
+ }
537
+ );
538
+ };
539
+
540
+ // src/Row.tsx
541
+ import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
542
+ var { IDX, IS_EXPANDED, SELECTED } = metadataKeys2;
543
+ var classBase6 = "vuuTableRow";
544
+ var RowProxy = forwardRef(
545
+ function RowProxy2({ height }, forwardedRef) {
546
+ return /* @__PURE__ */ jsx10(
547
+ "div",
548
+ {
549
+ "aria-hidden": true,
550
+ className: cx7(classBase6, `${classBase6}-proxy`),
551
+ ref: forwardedRef,
552
+ style: { height }
553
+ }
554
+ );
555
+ }
556
+ );
557
+ var Row = memo(
558
+ ({
559
+ className: classNameProp,
560
+ classNameGenerator,
561
+ columnMap,
562
+ columns,
563
+ highlighted,
564
+ row,
565
+ offset,
566
+ onClick,
567
+ onDataEdited,
568
+ onToggleGroup,
569
+ virtualColSpan = 0,
570
+ zebraStripes = false,
571
+ ...htmlAttributes
572
+ }) => {
573
+ const {
574
+ [IDX]: rowIndex,
575
+ [IS_EXPANDED]: isExpanded,
576
+ [SELECTED]: selectionStatus
577
+ } = row;
578
+ const handleRowClick = useCallback9(
579
+ (evt) => {
580
+ const rangeSelect = evt.shiftKey;
581
+ const keepExistingSelection = evt.ctrlKey || evt.metaKey;
582
+ onClick == null ? void 0 : onClick(row, rangeSelect, keepExistingSelection);
583
+ },
584
+ [onClick, row]
585
+ );
586
+ const { True, First, Last } = RowSelected;
587
+ const className = cx7(
588
+ classBase6,
589
+ classNameProp,
590
+ classNameGenerator == null ? void 0 : classNameGenerator(row, columnMap),
591
+ {
592
+ [`${classBase6}-even`]: zebraStripes && rowIndex % 2 === 0,
593
+ [`${classBase6}-expanded`]: isExpanded,
594
+ [`${classBase6}-highlighted`]: highlighted,
595
+ [`${classBase6}-selected`]: selectionStatus & True,
596
+ [`${classBase6}-selectedStart`]: selectionStatus & First,
597
+ [`${classBase6}-selectedEnd`]: selectionStatus & Last
598
+ }
599
+ );
600
+ const style = { transform: `translate3d(0px, ${offset}px, 0px)` };
601
+ const handleGroupCellClick = useCallback9(
602
+ (evt, column) => {
603
+ if (isGroupColumn(column) || isJsonGroup(column, row, columnMap)) {
604
+ evt.stopPropagation();
605
+ onToggleGroup == null ? void 0 : onToggleGroup(row, column);
606
+ }
607
+ },
608
+ [columnMap, onToggleGroup, row]
609
+ );
610
+ return /* @__PURE__ */ jsxs7(
611
+ "div",
612
+ {
613
+ ...htmlAttributes,
614
+ role: "row",
615
+ className,
616
+ onClick: handleRowClick,
617
+ style,
618
+ children: [
619
+ /* @__PURE__ */ jsx10("span", { className: `${classBase6}-selectionDecorator vuuStickyLeft` }),
620
+ virtualColSpan > 0 ? /* @__PURE__ */ jsx10("div", { className: "vuuTableCell", style: { width: virtualColSpan } }) : null,
621
+ columns.filter(isNotHidden).map((column) => {
622
+ const isGroup = isGroupColumn(column);
623
+ const isJsonCell = isJsonColumn(column);
624
+ const Cell = isGroup ? TableGroupCell : TableCell;
625
+ return /* @__PURE__ */ jsx10(
626
+ Cell,
627
+ {
628
+ column,
629
+ columnMap,
630
+ onClick: isGroup || isJsonCell ? handleGroupCellClick : void 0,
631
+ onDataEdited,
632
+ row
633
+ },
634
+ column.name
635
+ );
636
+ }),
637
+ /* @__PURE__ */ jsx10("span", { className: `${classBase6}-selectionDecorator vuuStickyRight` })
638
+ ]
639
+ }
640
+ );
641
+ }
642
+ );
643
+ Row.displayName = "Row";
644
+
645
+ // src/table-header/TableHeader.tsx
646
+ import { isGroupColumn as isGroupColumn2, isNotHidden as isNotHidden2 } from "@vuu-ui/vuu-utils";
647
+ import cx8 from "clsx";
648
+ import { memo as memo2 } from "react";
649
+
650
+ // src/table-header/useTableHeader.ts
651
+ import {
652
+ useDragDrop
653
+ } from "@vuu-ui/vuu-ui-controls";
654
+ import { moveColumnTo, visibleColumnAtIndex } from "@vuu-ui/vuu-utils";
655
+ import { useCallback as useCallback10, useRef as useRef6 } from "react";
656
+ var useTableHeader = ({
657
+ columns,
658
+ onMoveColumn,
659
+ onSortColumn,
660
+ tableConfig
661
+ }) => {
662
+ const containerRef = useRef6(null);
663
+ const scrollingContainerRef = useRef6(null);
664
+ const setContainerRef = useCallback10((el) => {
665
+ containerRef.current = el;
666
+ if (el) {
667
+ scrollingContainerRef.current = el.closest(".vuuTable-contentContainer");
668
+ } else {
669
+ scrollingContainerRef.current = null;
670
+ }
671
+ }, []);
672
+ const handleDropColumnHeader = useCallback10(
673
+ ({ fromIndex: moveFrom, toIndex: moveTo }) => {
674
+ const column = columns[moveFrom];
675
+ const orderedColumns = moveColumnTo(columns, column, moveTo);
676
+ const ofColumn = ({ name }) => (col) => col.name === name;
677
+ const targetIndex = orderedColumns.findIndex(ofColumn(column));
678
+ const nextColumn = orderedColumns[targetIndex + 1];
679
+ const insertPos = nextColumn ? tableConfig.columns.findIndex(ofColumn(nextColumn)) : -1;
680
+ if (moveTo > moveFrom && insertPos !== -1) {
681
+ onMoveColumn(moveColumnTo(tableConfig.columns, column, insertPos - 1));
682
+ } else {
683
+ onMoveColumn(moveColumnTo(tableConfig.columns, column, insertPos));
684
+ }
685
+ },
686
+ [columns, onMoveColumn, tableConfig.columns]
687
+ );
688
+ const handleColumnHeaderClick = useCallback10(
689
+ (evt) => {
690
+ var _a;
691
+ const targetElement = evt.target;
692
+ const headerCell = targetElement.closest(
693
+ ".vuuTableHeaderCell"
694
+ );
695
+ const colIdx = parseInt((_a = headerCell == null ? void 0 : headerCell.dataset.index) != null ? _a : "-1");
696
+ const column = visibleColumnAtIndex(columns, colIdx);
697
+ const isAdditive = evt.shiftKey;
698
+ column && onSortColumn(column, isAdditive);
699
+ },
700
+ [columns, onSortColumn]
701
+ );
702
+ const {
703
+ onMouseDown: columnHeaderDragMouseDown,
704
+ draggable: draggableColumn,
705
+ ...dragDropHook
706
+ } = useDragDrop({
707
+ allowDragDrop: true,
708
+ containerRef,
709
+ draggableClassName: `vuuTable`,
710
+ itemQuery: ".vuuTableHeaderCell",
711
+ onDrop: handleDropColumnHeader,
712
+ orientation: "horizontal",
713
+ scrollingContainerRef
714
+ });
715
+ return {
716
+ draggableColumn,
717
+ draggedColumnIndex: dragDropHook.draggedItemIndex,
718
+ onClick: handleColumnHeaderClick,
719
+ onMouseDown: columnHeaderDragMouseDown,
720
+ setContainerRef
721
+ };
722
+ };
723
+
724
+ // src/table-header/TableHeader.tsx
725
+ import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
726
+ var TableHeader = memo2(
727
+ ({
728
+ classBase: classBase10 = "vuuTable",
729
+ columns,
730
+ headings,
731
+ onMoveColumn,
732
+ onMoveGroupColumn,
733
+ onRemoveGroupColumn,
734
+ onResizeColumn,
735
+ onSortColumn,
736
+ tableConfig,
737
+ tableId,
738
+ virtualColSpan = 0
739
+ }) => {
740
+ const {
741
+ draggableColumn,
742
+ draggedColumnIndex,
743
+ onClick,
744
+ onMouseDown,
745
+ setContainerRef
746
+ } = useTableHeader({
747
+ columns,
748
+ onMoveColumn,
749
+ onSortColumn,
750
+ tableConfig
751
+ });
752
+ return /* @__PURE__ */ jsxs8("div", { className: `${classBase10}-col-headings`, ref: setContainerRef, children: [
753
+ headings.map((colHeaders, i) => /* @__PURE__ */ jsx11("div", { className: "vuuTable-heading", children: colHeaders.map(({ label, width }, j) => /* @__PURE__ */ jsx11("div", { className: "vuuTable-headingCell", style: { width }, children: label }, j)) }, i)),
754
+ /* @__PURE__ */ jsxs8("div", { className: `${classBase10}-col-headers`, role: "row", children: [
755
+ virtualColSpan > 0 ? /* @__PURE__ */ jsx11(
756
+ "div",
757
+ {
758
+ role: "cell",
759
+ className: "vuuTableCell",
760
+ style: { width: virtualColSpan }
761
+ }
762
+ ) : null,
763
+ columns.filter(isNotHidden2).map(
764
+ (col, i) => isGroupColumn2(col) ? /* @__PURE__ */ jsx11(
765
+ GroupHeaderCellNext,
766
+ {
767
+ "aria-colindex": col.index,
768
+ column: col,
769
+ "data-index": i,
770
+ onMoveColumn: onMoveGroupColumn,
771
+ onRemoveColumn: onRemoveGroupColumn,
772
+ onResize: onResizeColumn
773
+ },
774
+ col.name
775
+ ) : /* @__PURE__ */ jsx11(
776
+ HeaderCell,
777
+ {
778
+ "aria-colindex": col.index,
779
+ className: cx8({
780
+ "vuuDraggable-dragAway": i === draggedColumnIndex
781
+ }),
782
+ column: col,
783
+ "data-index": i,
784
+ id: `${tableId}-col-${i}`,
785
+ onClick,
786
+ onMouseDown,
787
+ onResize: onResizeColumn
788
+ },
789
+ col.name
790
+ )
791
+ ),
792
+ draggableColumn
793
+ ] })
794
+ ] });
795
+ }
796
+ );
797
+ TableHeader.displayName = "TableHeader";
798
+
799
+ // src/useTable.ts
800
+ import {
801
+ useDragDrop as useDragDrop2
802
+ } from "@vuu-ui/vuu-ui-controls";
803
+ import {
804
+ applySort,
805
+ buildColumnMap as buildColumnMap2,
806
+ getIndexFromRowElement as getIndexFromRowElement3,
807
+ isGroupColumn as isGroupColumn4,
808
+ isJsonGroup as isJsonGroup2,
809
+ isValidNumber,
810
+ metadataKeys as metadataKeys5,
811
+ updateColumn,
812
+ useLayoutEffectSkipFirst as useLayoutEffectSkipFirst2
813
+ } from "@vuu-ui/vuu-utils";
814
+ import {
815
+ useCallback as useCallback19,
816
+ useEffect as useEffect4,
817
+ useMemo as useMemo7,
818
+ useRef as useRef14,
819
+ useState as useState7
820
+ } from "react";
821
+
822
+ // src/context-menu/buildContextMenuDescriptors.ts
823
+ import { isNumericColumn as isNumericColumn2 } from "@vuu-ui/vuu-utils";
824
+ var buildContextMenuDescriptors = (dataSource) => (location, options) => {
825
+ const descriptors = [];
826
+ if (dataSource === void 0) {
827
+ return descriptors;
828
+ }
829
+ if (location === "header" || location === "column-menu") {
830
+ descriptors.push(
831
+ ...buildSortMenuItems(options, dataSource)
832
+ );
833
+ descriptors.push(
834
+ ...buildGroupMenuItems(options, dataSource)
835
+ );
836
+ descriptors.push(
837
+ ...buildAggregationMenuItems(options, dataSource)
838
+ );
839
+ descriptors.push(...buildColumnDisplayMenuItems(options));
840
+ descriptors.push({
841
+ action: "column-settings",
842
+ icon: "cog",
843
+ label: `Column Settings`,
844
+ options
845
+ });
846
+ descriptors.push({
847
+ action: "table-settings",
848
+ icon: "cog",
849
+ label: `DataGrid Settings`,
850
+ options
851
+ });
852
+ }
853
+ return descriptors;
854
+ };
855
+ function buildSortMenuItems(options, { sort: { sortDefs } }) {
856
+ const { column } = options;
857
+ const menuItems = [];
858
+ if (column === void 0) {
859
+ return menuItems;
860
+ }
861
+ const hasSort = sortDefs.length > 0;
862
+ if (column.sorted === "A") {
863
+ menuItems.push({
864
+ label: "Reverse Sort (DSC)",
865
+ action: "sort-dsc",
866
+ options
867
+ });
868
+ } else if (column.sorted === "D") {
869
+ menuItems.push({
870
+ label: "Reverse Sort (ASC)",
871
+ action: "sort-asc",
872
+ options
873
+ });
874
+ } else if (typeof column.sorted === "number") {
875
+ if (column.sorted > 0) {
876
+ menuItems.push({
877
+ label: "Reverse Sort (DSC)",
878
+ action: "sort-add-dsc",
879
+ options
880
+ });
881
+ } else {
882
+ menuItems.push({
883
+ label: "Reverse Sort (ASC)",
884
+ action: "sort-add-asc",
885
+ options
886
+ });
887
+ }
888
+ if (hasSort && Math.abs(column.sorted) < sortDefs.length) {
889
+ menuItems.push({
890
+ label: "Remove from sort",
891
+ action: "sort-remove",
892
+ options
893
+ });
894
+ }
895
+ menuItems.push({
896
+ label: "New Sort",
897
+ children: [
898
+ { label: "Ascending", action: "sort-asc", options },
899
+ { label: "Descending", action: "sort-dsc", options }
900
+ ]
901
+ });
902
+ } else if (hasSort) {
903
+ menuItems.push({
904
+ label: "Add to sort",
905
+ children: [
906
+ { label: "Ascending", action: "sort-add-asc", options },
907
+ { label: "Descending", action: "sort-add-dsc", options }
908
+ ]
909
+ });
910
+ menuItems.push({
911
+ label: "New Sort",
912
+ children: [
913
+ { label: "Ascending", action: "sort-asc", options },
914
+ { label: "Descending", action: "sort-dsc", options }
915
+ ]
916
+ });
917
+ } else {
918
+ menuItems.push({
919
+ label: "Sort",
920
+ children: [
921
+ { label: "Ascending", action: "sort-asc", options },
922
+ { label: "Descending", action: "sort-dsc", options }
923
+ ]
924
+ });
925
+ }
926
+ return menuItems;
927
+ }
928
+ function buildAggregationMenuItems(options, dataSource) {
929
+ const { column } = options;
930
+ if (column === void 0 || dataSource.groupBy.length === 0) {
931
+ return [];
932
+ }
933
+ const { name, label = name } = column;
934
+ return [
935
+ {
936
+ label: `Aggregate ${label}`,
937
+ children: [
938
+ { label: "Count", action: "agg-count", options },
939
+ { label: "Distinct", action: "agg-distinct", options }
940
+ ].concat(
941
+ isNumericColumn2(column) ? [
942
+ { label: "Sum", action: "agg-sum", options },
943
+ { label: "Avg", action: "agg-avg", options },
944
+ { label: "High", action: "agg-high", options },
945
+ { label: "Low", action: "agg-low", options }
946
+ ] : []
947
+ )
948
+ }
949
+ ];
950
+ }
951
+ var pinColumn = (options, pinLocation) => ({
952
+ label: `Pin ${pinLocation}`,
953
+ action: `column-pin-${pinLocation}`,
954
+ options
955
+ });
956
+ var pinLeft = (options) => pinColumn(options, "left");
957
+ var pinFloating = (options) => pinColumn(options, "floating");
958
+ var pinRight = (options) => pinColumn(options, "right");
959
+ function buildColumnDisplayMenuItems(options) {
960
+ const { column } = options;
961
+ if (column === void 0) {
962
+ return [];
963
+ }
964
+ const { pin } = column;
965
+ const menuItems = [
966
+ {
967
+ label: `Hide column`,
968
+ action: "column-hide",
969
+ options
970
+ },
971
+ {
972
+ label: `Remove column`,
973
+ action: "column-remove",
974
+ options
975
+ }
976
+ ];
977
+ if (pin === void 0) {
978
+ menuItems.push({
979
+ label: `Pin column`,
980
+ children: [pinLeft(options), pinFloating(options), pinRight(options)]
981
+ });
982
+ } else if (pin === "left") {
983
+ menuItems.push(
984
+ { label: "Unpin column", action: "column-unpin", options },
985
+ {
986
+ label: `Pin column`,
987
+ children: [pinFloating(options), pinRight(options)]
988
+ }
989
+ );
990
+ } else if (pin === "right") {
991
+ menuItems.push(
992
+ { label: "Unpin column", action: "column-unpin", options },
993
+ {
994
+ label: `Pin column`,
995
+ children: [pinLeft(options), pinFloating(options)]
996
+ }
997
+ );
998
+ } else if (pin === "floating") {
999
+ menuItems.push(
1000
+ { label: "Unpin column", action: "column-unpin", options },
1001
+ {
1002
+ label: `Pin column`,
1003
+ children: [pinLeft(options), pinRight(options)]
1004
+ }
1005
+ );
1006
+ }
1007
+ return menuItems;
1008
+ }
1009
+ function buildGroupMenuItems(options, { groupBy }) {
1010
+ const { column } = options;
1011
+ const menuItems = [];
1012
+ if (column === void 0) {
1013
+ return menuItems;
1014
+ }
1015
+ const { name, label = name } = column;
1016
+ if (groupBy.length === 0) {
1017
+ menuItems.push({
1018
+ label: `Group by ${label}`,
1019
+ action: "group",
1020
+ options
1021
+ });
1022
+ } else {
1023
+ menuItems.push({
1024
+ label: `Add ${label} to group by`,
1025
+ action: "group-add",
1026
+ options
1027
+ });
1028
+ }
1029
+ return menuItems;
1030
+ }
1031
+
1032
+ // src/context-menu/useHandleTableContextMenu.ts
1033
+ import { removeColumnFromFilter } from "@vuu-ui/vuu-utils";
1034
+ import {
1035
+ addGroupColumn,
1036
+ addSortColumn,
1037
+ AggregationType,
1038
+ setAggregations,
1039
+ setSortColumn
1040
+ } from "@vuu-ui/vuu-utils";
1041
+ var removeFilterColumn = (dataSourceFilter, column) => {
1042
+ if (dataSourceFilter.filterStruct && column) {
1043
+ const [filterStruct, filter] = removeColumnFromFilter(
1044
+ column,
1045
+ dataSourceFilter.filterStruct
1046
+ );
1047
+ return {
1048
+ filter,
1049
+ filterStruct
1050
+ };
1051
+ } else {
1052
+ return dataSourceFilter;
1053
+ }
1054
+ };
1055
+ var { Average, Count, Distinct, High, Low, Sum } = AggregationType;
1056
+ var useHandleTableContextMenu = ({
1057
+ dataSource,
1058
+ onPersistentColumnOperation
1059
+ }) => {
1060
+ const handleContextMenuAction = (action) => {
1061
+ const gridOptions = action.options;
1062
+ if (gridOptions.column && dataSource) {
1063
+ const { column } = gridOptions;
1064
+ switch (action.menuId) {
1065
+ case "sort-asc":
1066
+ return dataSource.sort = setSortColumn(dataSource.sort, column, "A"), true;
1067
+ case "sort-dsc":
1068
+ return dataSource.sort = setSortColumn(dataSource.sort, column, "D"), true;
1069
+ case "sort-add-asc":
1070
+ return dataSource.sort = addSortColumn(dataSource.sort, column, "A"), true;
1071
+ case "sort-add-dsc":
1072
+ return dataSource.sort = addSortColumn(dataSource.sort, column, "D"), true;
1073
+ case "group":
1074
+ return dataSource.groupBy = addGroupColumn(dataSource.groupBy, column), true;
1075
+ case "group-add":
1076
+ return dataSource.groupBy = addGroupColumn(dataSource.groupBy, column), true;
1077
+ case "column-hide":
1078
+ return onPersistentColumnOperation({ type: "hideColumns", columns: [column] }), true;
1079
+ case "column-remove":
1080
+ return dataSource.columns = dataSource.columns.filter((name) => name !== column.name), true;
1081
+ case "filter-remove-column":
1082
+ return dataSource.filter = removeFilterColumn(dataSource.filter, column), true;
1083
+ case "remove-filters":
1084
+ return dataSource.filter = { filter: "" }, true;
1085
+ case "agg-avg":
1086
+ return dataSource.aggregations = setAggregations(dataSource.aggregations, column, Average), true;
1087
+ case "agg-high":
1088
+ return dataSource.aggregations = setAggregations(dataSource.aggregations, column, High), true;
1089
+ case "agg-low":
1090
+ return dataSource.aggregations = setAggregations(dataSource.aggregations, column, Low), true;
1091
+ case "agg-count":
1092
+ return dataSource.aggregations = setAggregations(dataSource.aggregations, column, Count), true;
1093
+ case "agg-distinct":
1094
+ return dataSource.aggregations = setAggregations(dataSource.aggregations, column, Distinct), true;
1095
+ case "agg-sum":
1096
+ return dataSource.aggregations = setAggregations(dataSource.aggregations, column, Sum), true;
1097
+ case "column-pin-floating":
1098
+ return onPersistentColumnOperation({ type: "pinColumn", column, pin: "floating" }), true;
1099
+ case "column-pin-left":
1100
+ return onPersistentColumnOperation({ type: "pinColumn", column, pin: "left" }), true;
1101
+ case "column-pin-right":
1102
+ return onPersistentColumnOperation({ type: "pinColumn", column, pin: "right" }), true;
1103
+ case "column-unpin":
1104
+ return onPersistentColumnOperation({ type: "pinColumn", column, pin: void 0 }), true;
1105
+ case "column-settings":
1106
+ return onPersistentColumnOperation({ type: "columnSettings", column }), true;
1107
+ case "table-settings":
1108
+ return onPersistentColumnOperation({ type: "tableSettings" }), true;
1109
+ default:
1110
+ }
1111
+ }
1112
+ return false;
1113
+ };
1114
+ return handleContextMenuAction;
1115
+ };
1116
+
1117
+ // src/table-config.ts
1118
+ var updateTableConfig = (config, action) => {
1119
+ switch (action.type) {
1120
+ case "col-size":
1121
+ return {
1122
+ ...config,
1123
+ columns: config.columns.map(
1124
+ (col) => col.name === action.column.name ? { ...col, width: action.width } : col
1125
+ )
1126
+ };
1127
+ case "column-prop":
1128
+ return {
1129
+ ...config,
1130
+ columns: config.columns.map(
1131
+ (col) => col.name === action.column.name ? { ...col, [action.property]: action.value } : col
1132
+ )
1133
+ };
1134
+ default:
1135
+ return config;
1136
+ }
1137
+ };
1138
+
1139
+ // src/useCellEditing.ts
1140
+ import { isCharacterKey } from "@vuu-ui/vuu-utils";
1141
+ import {
1142
+ useCallback as useCallback11
1143
+ } from "react";
1144
+
1145
+ // src/table-dom-utils.ts
1146
+ var headerCellQuery = (colIdx) => `.vuuTable-col-headers .vuuTableHeaderCell:nth-child(${colIdx})`;
1147
+ var dataCellQuery = (rowIdx, colIdx) => `.vuuTable-body > [aria-rowindex='${rowIdx + 1}'] > [role='cell']:nth-child(${colIdx + 1})`;
1148
+ var getTableCell = (containerRef, [rowIdx, colIdx]) => {
1149
+ var _a;
1150
+ const cssQuery = rowIdx === -1 ? headerCellQuery(colIdx) : dataCellQuery(rowIdx, colIdx);
1151
+ const cell = (_a = containerRef.current) == null ? void 0 : _a.querySelector(
1152
+ cssQuery
1153
+ );
1154
+ if (cellIsEditable(cell)) {
1155
+ const focusableContent = cell.querySelector("button");
1156
+ return focusableContent || cell;
1157
+ } else {
1158
+ return cell;
1159
+ }
1160
+ };
1161
+ var cellIsEditable = (cell) => cell == null ? void 0 : cell.classList.contains("vuuTableCell-editable");
1162
+ var cellIsTextInput = (cell) => cell.querySelector(".vuuTableInputCell") !== null;
1163
+ function getRowIndex(rowEl) {
1164
+ if (rowEl) {
1165
+ const idx = rowEl.ariaRowIndex;
1166
+ if (idx !== null) {
1167
+ return parseInt(idx, 10) - 1;
1168
+ }
1169
+ }
1170
+ return -1;
1171
+ }
1172
+ var closestRow = (el) => el.closest('[role="row"]');
1173
+ var closestRowIndex = (el) => getRowIndex(closestRow(el));
1174
+ var NO_SCROLL_NECESSARY = [void 0, void 0];
1175
+ var howFarIsRowOutsideViewport = (rowEl, totalHeaderHeight, contentContainer = rowEl.closest(".vuuTable-contentContainer")) => {
1176
+ if (contentContainer) {
1177
+ const viewport = contentContainer == null ? void 0 : contentContainer.getBoundingClientRect();
1178
+ const upperBoundary = viewport.top + totalHeaderHeight;
1179
+ const row = rowEl.getBoundingClientRect();
1180
+ if (row) {
1181
+ if (row.bottom > viewport.bottom) {
1182
+ return ["down", row.bottom - viewport.bottom];
1183
+ } else if (row.top < upperBoundary) {
1184
+ return ["up", row.top - upperBoundary];
1185
+ } else {
1186
+ return NO_SCROLL_NECESSARY;
1187
+ }
1188
+ } else {
1189
+ throw Error("Whats going on, row not found");
1190
+ }
1191
+ } else {
1192
+ throw Error("Whats going on, scrollbar container not found");
1193
+ }
1194
+ };
1195
+
1196
+ // src/useCellEditing.ts
1197
+ var useCellEditing = ({ navigate }) => {
1198
+ const commitHandler = useCallback11(() => {
1199
+ navigate();
1200
+ }, [navigate]);
1201
+ const editInput = useCallback11(
1202
+ (evt) => {
1203
+ const cellEl = evt.target;
1204
+ const input = cellEl.matches("input") ? cellEl : cellEl.querySelector("input");
1205
+ if (input) {
1206
+ input.focus();
1207
+ input.select();
1208
+ }
1209
+ },
1210
+ []
1211
+ );
1212
+ const focusInput = useCallback11(
1213
+ (evt) => {
1214
+ const cellEl = evt.target;
1215
+ const input = cellEl.querySelector("input");
1216
+ if (input) {
1217
+ input.focus();
1218
+ input.select();
1219
+ }
1220
+ },
1221
+ []
1222
+ );
1223
+ const handleKeyDown = useCallback11(
1224
+ (e) => {
1225
+ const el = e.target;
1226
+ if (cellIsTextInput(el)) {
1227
+ if (isCharacterKey(e.key)) {
1228
+ editInput(e);
1229
+ } else if (e.key === "Enter") {
1230
+ focusInput(e);
1231
+ }
1232
+ }
1233
+ },
1234
+ [editInput, focusInput]
1235
+ );
1236
+ const handleDoubleClick = useCallback11(
1237
+ (e) => {
1238
+ const el = e.target;
1239
+ if (el.matches("input") || el.querySelector("input")) {
1240
+ editInput(e);
1241
+ e.stopPropagation();
1242
+ }
1243
+ },
1244
+ [editInput]
1245
+ );
1246
+ const handleBlur = useCallback11(
1247
+ (e) => {
1248
+ const el = e.target;
1249
+ el.removeEventListener("vuu-commit", commitHandler, true);
1250
+ },
1251
+ [commitHandler]
1252
+ );
1253
+ const handleFocus = useCallback11(
1254
+ (e) => {
1255
+ const el = e.target;
1256
+ el.addEventListener("vuu-commit", commitHandler, true);
1257
+ },
1258
+ [commitHandler]
1259
+ );
1260
+ return {
1261
+ onBlur: handleBlur,
1262
+ onDoubleClick: handleDoubleClick,
1263
+ onFocus: handleFocus,
1264
+ onKeyDown: handleKeyDown
1265
+ };
1266
+ };
1267
+
1268
+ // src/useDataSource.ts
1269
+ import { getFullRange, NULL_RANGE, rangesAreSame } from "@vuu-ui/vuu-utils";
1270
+ import { useCallback as useCallback12, useEffect, useMemo as useMemo2, useRef as useRef7, useState as useState4 } from "react";
1271
+
1272
+ // src/moving-window.ts
1273
+ import {
1274
+ isRowSelectedLast,
1275
+ metadataKeys as metadataKeys3,
1276
+ WindowRange
1277
+ } from "@vuu-ui/vuu-utils";
1278
+ var { SELECTED: SELECTED2 } = metadataKeys3;
1279
+ var MovingWindow = class {
1280
+ constructor({ from, to }) {
1281
+ this.rowCount = 0;
1282
+ this.setRowCount = (rowCount) => {
1283
+ if (rowCount < this.data.length) {
1284
+ this.data.length = rowCount;
1285
+ }
1286
+ this.rowCount = rowCount;
1287
+ };
1288
+ this.range = new WindowRange(from, to);
1289
+ this.data = new Array(Math.max(0, to - from));
1290
+ this.rowCount = 0;
1291
+ }
1292
+ add(data) {
1293
+ const [index] = data;
1294
+ if (this.isWithinRange(index)) {
1295
+ const internalIndex = index - this.range.from;
1296
+ this.data[internalIndex] = data;
1297
+ if (data[SELECTED2]) {
1298
+ const previousRow = this.data[internalIndex - 1];
1299
+ if (isRowSelectedLast(previousRow)) {
1300
+ this.data[internalIndex - 1] = previousRow.slice();
1301
+ this.data[internalIndex - 1][SELECTED2] -= 4;
1302
+ }
1303
+ }
1304
+ }
1305
+ }
1306
+ getAtIndex(index) {
1307
+ return this.range.isWithin(index) && this.data[index - this.range.from] != null ? this.data[index - this.range.from] : void 0;
1308
+ }
1309
+ isWithinRange(index) {
1310
+ return this.range.isWithin(index);
1311
+ }
1312
+ setRange({ from, to }) {
1313
+ if (from !== this.range.from || to !== this.range.to) {
1314
+ const [overlapFrom, overlapTo] = this.range.overlap(from, to);
1315
+ const newData = new Array(Math.max(0, to - from));
1316
+ for (let i = overlapFrom; i < overlapTo; i++) {
1317
+ const data = this.getAtIndex(i);
1318
+ if (data) {
1319
+ const index = i - from;
1320
+ newData[index] = data;
1321
+ }
1322
+ }
1323
+ this.data = newData;
1324
+ this.range.from = from;
1325
+ this.range.to = to;
1326
+ }
1327
+ }
1328
+ getSelectedRows() {
1329
+ return this.data.filter((row) => row[SELECTED2] !== 0);
1330
+ }
1331
+ };
1332
+
1333
+ // src/useDataSource.ts
1334
+ var isVuuFeatureInvocation = (action) => action.type === "vuu-link-created" || action.type === "vuu-link-removed";
1335
+ var useDataSource = ({
1336
+ dataSource,
1337
+ onFeatureInvocation,
1338
+ onSizeChange,
1339
+ onSubscribed,
1340
+ range = NULL_RANGE,
1341
+ renderBufferSize = 0
1342
+ }) => {
1343
+ const [, forceUpdate] = useState4(null);
1344
+ const data = useRef7([]);
1345
+ const isMounted = useRef7(true);
1346
+ const hasUpdated = useRef7(false);
1347
+ const rangeRef = useRef7(range);
1348
+ const dataWindow = useMemo2(
1349
+ () => new MovingWindow(getFullRange(range, renderBufferSize)),
1350
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1351
+ []
1352
+ );
1353
+ const setData = useCallback12(
1354
+ (updates) => {
1355
+ for (const row of updates) {
1356
+ dataWindow.add(row);
1357
+ }
1358
+ data.current = dataWindow.data;
1359
+ if (isMounted.current) {
1360
+ forceUpdate({});
1361
+ } else {
1362
+ }
1363
+ },
1364
+ [dataWindow]
1365
+ );
1366
+ const datasourceMessageHandler = useCallback12(
1367
+ (message) => {
1368
+ if (message.type === "subscribed") {
1369
+ onSubscribed == null ? void 0 : onSubscribed(message);
1370
+ } else if (message.type === "viewport-update") {
1371
+ if (typeof message.size === "number") {
1372
+ onSizeChange == null ? void 0 : onSizeChange(message.size);
1373
+ dataWindow.setRowCount(message.size);
1374
+ }
1375
+ if (message.rows) {
1376
+ setData(message.rows);
1377
+ } else if (typeof message.size === "number") {
1378
+ data.current = dataWindow.data;
1379
+ hasUpdated.current = true;
1380
+ }
1381
+ } else if (isVuuFeatureInvocation(message)) {
1382
+ onFeatureInvocation == null ? void 0 : onFeatureInvocation(message);
1383
+ } else {
1384
+ console.log(`useDataSource unexpected message ${message.type}`);
1385
+ }
1386
+ },
1387
+ [dataWindow, onFeatureInvocation, onSizeChange, onSubscribed, setData]
1388
+ );
1389
+ const getSelectedRows = useCallback12(() => {
1390
+ return dataWindow.getSelectedRows();
1391
+ }, [dataWindow]);
1392
+ useEffect(() => {
1393
+ var _a;
1394
+ isMounted.current = true;
1395
+ (_a = dataSource.resume) == null ? void 0 : _a.call(dataSource);
1396
+ return () => {
1397
+ var _a2;
1398
+ isMounted.current = false;
1399
+ (_a2 = dataSource.suspend) == null ? void 0 : _a2.call(dataSource);
1400
+ };
1401
+ }, [dataSource]);
1402
+ useEffect(() => {
1403
+ var _a;
1404
+ if (dataSource.status === "disabled") {
1405
+ (_a = dataSource.enable) == null ? void 0 : _a.call(dataSource, datasourceMessageHandler);
1406
+ } else {
1407
+ dataSource == null ? void 0 : dataSource.subscribe(
1408
+ { range: getFullRange(range, renderBufferSize) },
1409
+ datasourceMessageHandler
1410
+ );
1411
+ }
1412
+ }, [dataSource, datasourceMessageHandler, range, renderBufferSize]);
1413
+ const setRange = useCallback12(
1414
+ (range2) => {
1415
+ if (!rangesAreSame(range2, rangeRef.current)) {
1416
+ const fullRange = getFullRange(range2, renderBufferSize);
1417
+ dataWindow.setRange(fullRange);
1418
+ dataSource.range = rangeRef.current = fullRange;
1419
+ dataSource.emit("range", range2);
1420
+ }
1421
+ },
1422
+ [dataSource, dataWindow, renderBufferSize]
1423
+ );
1424
+ return {
1425
+ data: data.current,
1426
+ dataRef: data,
1427
+ getSelectedRows,
1428
+ range: rangeRef.current,
1429
+ setRange
1430
+ };
1431
+ };
1432
+
1433
+ // src/useInitialValue.ts
1434
+ import { useMemo as useMemo3, useRef as useRef8 } from "react";
1435
+ var useInitialValue = (value) => {
1436
+ const ref = useRef8(value);
1437
+ return useMemo3(() => ref.current, []);
1438
+ };
1439
+
1440
+ // src/useKeyboardNavigation.ts
1441
+ import { getIndexFromRowElement } from "@vuu-ui/vuu-utils";
1442
+ import { useControlled } from "@salt-ds/core";
1443
+ import {
1444
+ useCallback as useCallback13,
1445
+ useEffect as useEffect2,
1446
+ useRef as useRef9
1447
+ } from "react";
1448
+ var rowNavigationKeys = /* @__PURE__ */ new Set([
1449
+ "Home",
1450
+ "End",
1451
+ "PageUp",
1452
+ "PageDown",
1453
+ "ArrowDown",
1454
+ "ArrowUp"
1455
+ ]);
1456
+ var cellNavigationKeys = new Set(rowNavigationKeys);
1457
+ cellNavigationKeys.add("ArrowLeft");
1458
+ cellNavigationKeys.add("ArrowRight");
1459
+ var isNavigationKey = (key, navigationStyle) => {
1460
+ switch (navigationStyle) {
1461
+ case "cell":
1462
+ return cellNavigationKeys.has(key);
1463
+ case "row":
1464
+ return rowNavigationKeys.has(key);
1465
+ default:
1466
+ return false;
1467
+ }
1468
+ };
1469
+ var PageKeys = ["Home", "End", "PageUp", "PageDown"];
1470
+ var isPagingKey = (key) => PageKeys.includes(key);
1471
+ var NULL_CELL_POS = [-1, -1];
1472
+ function nextCellPos(key, [rowIdx, colIdx], columnCount, rowCount) {
1473
+ if (key === "ArrowUp") {
1474
+ if (rowIdx > -1) {
1475
+ return [rowIdx - 1, colIdx];
1476
+ } else {
1477
+ return [rowIdx, colIdx];
1478
+ }
1479
+ } else if (key === "ArrowDown") {
1480
+ if (rowIdx === -1) {
1481
+ return [0, colIdx];
1482
+ } else if (rowIdx === rowCount - 1) {
1483
+ return [rowIdx, colIdx];
1484
+ } else {
1485
+ return [rowIdx + 1, colIdx];
1486
+ }
1487
+ } else if (key === "ArrowRight") {
1488
+ if (colIdx < columnCount) {
1489
+ return [rowIdx, colIdx + 1];
1490
+ } else {
1491
+ return [rowIdx, colIdx];
1492
+ }
1493
+ } else if (key === "ArrowLeft") {
1494
+ if (colIdx > 1) {
1495
+ return [rowIdx, colIdx - 1];
1496
+ } else {
1497
+ return [rowIdx, colIdx];
1498
+ }
1499
+ }
1500
+ return [rowIdx, colIdx];
1501
+ }
1502
+ var useKeyboardNavigation = ({
1503
+ columnCount = 0,
1504
+ containerRef,
1505
+ disableFocus = false,
1506
+ defaultHighlightedIndex,
1507
+ disableHighlightOnFocus,
1508
+ highlightedIndex: highlightedIndexProp,
1509
+ navigationStyle,
1510
+ requestScroll,
1511
+ onHighlight,
1512
+ rowCount = 0,
1513
+ viewportRowCount
1514
+ }) => {
1515
+ var _a;
1516
+ const focusedCellPos = useRef9([-1, -1]);
1517
+ const focusableCell = useRef9();
1518
+ const activeCellPos = useRef9([-1, 0]);
1519
+ const highlightedIndexRef = useRef9();
1520
+ const [highlightedIndex, setHighlightedIdx] = useControlled({
1521
+ controlled: highlightedIndexProp,
1522
+ default: defaultHighlightedIndex,
1523
+ name: "UseKeyboardNavigation"
1524
+ });
1525
+ highlightedIndexRef.current = highlightedIndex;
1526
+ const setHighlightedIndex = useCallback13(
1527
+ (idx, fromKeyboard = false) => {
1528
+ onHighlight == null ? void 0 : onHighlight(idx);
1529
+ setHighlightedIdx(idx);
1530
+ if (fromKeyboard) {
1531
+ }
1532
+ },
1533
+ [onHighlight, setHighlightedIdx]
1534
+ );
1535
+ const getFocusedCell = (element) => element == null ? void 0 : element.closest(
1536
+ "[role='columnHeader'],[role='cell']"
1537
+ );
1538
+ const getTableCellPos = (tableCell) => {
1539
+ var _a2;
1540
+ if (tableCell.role === "columnHeader") {
1541
+ const colIdx = parseInt((_a2 = tableCell.dataset.idx) != null ? _a2 : "-1", 10);
1542
+ return [-1, colIdx];
1543
+ } else {
1544
+ const focusedRow = tableCell.closest("[role='row']");
1545
+ if (focusedRow) {
1546
+ const rowIdx = getIndexFromRowElement(focusedRow);
1547
+ const colIdx = Array.from(focusedRow.childNodes).indexOf(tableCell);
1548
+ return [rowIdx, colIdx];
1549
+ }
1550
+ }
1551
+ return NULL_CELL_POS;
1552
+ };
1553
+ const focusCell = useCallback13(
1554
+ (cellPos) => {
1555
+ var _a2;
1556
+ if (containerRef.current) {
1557
+ const activeCell = getTableCell(containerRef, cellPos);
1558
+ if (activeCell) {
1559
+ if (activeCell !== focusableCell.current) {
1560
+ (_a2 = focusableCell.current) == null ? void 0 : _a2.removeAttribute("tabindex");
1561
+ focusableCell.current = activeCell;
1562
+ activeCell.setAttribute("tabindex", "0");
1563
+ }
1564
+ requestScroll == null ? void 0 : requestScroll({ type: "scroll-row", rowIndex: cellPos[0] });
1565
+ activeCell.focus({ preventScroll: true });
1566
+ }
1567
+ }
1568
+ },
1569
+ // TODO we recreate this function whenever viewportRange changes, which will
1570
+ // be often whilst scrolling - store range in a a ref ?
1571
+ [containerRef, requestScroll]
1572
+ );
1573
+ const setActiveCell = useCallback13(
1574
+ (rowIdx, colIdx, fromKeyboard = false) => {
1575
+ const pos = [rowIdx, colIdx];
1576
+ activeCellPos.current = pos;
1577
+ if (navigationStyle === "row") {
1578
+ setHighlightedIdx(rowIdx);
1579
+ } else {
1580
+ focusCell(pos);
1581
+ }
1582
+ if (fromKeyboard) {
1583
+ focusedCellPos.current = pos;
1584
+ }
1585
+ },
1586
+ [focusCell, navigationStyle, setHighlightedIdx]
1587
+ );
1588
+ const nextPageItemIdx = useCallback13(
1589
+ (key, [rowIdx, colIdx]) => new Promise((resolve) => {
1590
+ let newRowIdx = rowIdx;
1591
+ switch (key) {
1592
+ case "PageDown": {
1593
+ newRowIdx = Math.min(rowCount - 1, rowIdx + viewportRowCount);
1594
+ if (newRowIdx !== rowIdx) {
1595
+ requestScroll == null ? void 0 : requestScroll({ type: "scroll-page", direction: "down" });
1596
+ }
1597
+ break;
1598
+ }
1599
+ case "PageUp": {
1600
+ newRowIdx = Math.max(0, rowIdx - viewportRowCount);
1601
+ if (newRowIdx !== rowIdx) {
1602
+ requestScroll == null ? void 0 : requestScroll({ type: "scroll-page", direction: "up" });
1603
+ }
1604
+ break;
1605
+ }
1606
+ case "Home": {
1607
+ newRowIdx = 0;
1608
+ if (newRowIdx !== rowIdx) {
1609
+ requestScroll == null ? void 0 : requestScroll({ type: "scroll-end", direction: "home" });
1610
+ }
1611
+ break;
1612
+ }
1613
+ case "End": {
1614
+ newRowIdx = rowCount - 1;
1615
+ if (newRowIdx !== rowIdx) {
1616
+ requestScroll == null ? void 0 : requestScroll({ type: "scroll-end", direction: "end" });
1617
+ }
1618
+ break;
1619
+ }
1620
+ }
1621
+ setTimeout(() => {
1622
+ resolve([newRowIdx, colIdx]);
1623
+ }, 35);
1624
+ }),
1625
+ [requestScroll, rowCount, viewportRowCount]
1626
+ );
1627
+ const handleFocus = useCallback13(() => {
1628
+ var _a2;
1629
+ if (disableHighlightOnFocus !== true) {
1630
+ if ((_a2 = containerRef.current) == null ? void 0 : _a2.contains(document.activeElement)) {
1631
+ const focusedCell = getFocusedCell(document.activeElement);
1632
+ if (focusedCell) {
1633
+ focusedCellPos.current = getTableCellPos(focusedCell);
1634
+ if (navigationStyle === "row") {
1635
+ setHighlightedIdx(focusedCellPos.current[0]);
1636
+ }
1637
+ }
1638
+ }
1639
+ }
1640
+ }, [
1641
+ disableHighlightOnFocus,
1642
+ containerRef,
1643
+ navigationStyle,
1644
+ setHighlightedIdx
1645
+ ]);
1646
+ const navigateChildItems = useCallback13(
1647
+ async (key) => {
1648
+ const [nextRowIdx, nextColIdx] = isPagingKey(key) ? await nextPageItemIdx(key, activeCellPos.current) : nextCellPos(key, activeCellPos.current, columnCount, rowCount);
1649
+ const [rowIdx, colIdx] = activeCellPos.current;
1650
+ if (nextRowIdx !== rowIdx || nextColIdx !== colIdx) {
1651
+ setActiveCell(nextRowIdx, nextColIdx, true);
1652
+ }
1653
+ },
1654
+ [columnCount, nextPageItemIdx, rowCount, setActiveCell]
1655
+ );
1656
+ const scrollRowIntoViewIfNecessary = useCallback13(
1657
+ (rowIndex) => {
1658
+ requestScroll == null ? void 0 : requestScroll({ type: "scroll-row", rowIndex });
1659
+ },
1660
+ [requestScroll]
1661
+ );
1662
+ const moveHighlightedRow = useCallback13(
1663
+ async (key) => {
1664
+ const { current: highlighted } = highlightedIndexRef;
1665
+ const [nextRowIdx] = isPagingKey(key) ? await nextPageItemIdx(key, [highlighted != null ? highlighted : -1, 0]) : nextCellPos(key, [highlighted != null ? highlighted : -1, 0], columnCount, rowCount);
1666
+ if (nextRowIdx !== highlighted) {
1667
+ setHighlightedIndex(nextRowIdx);
1668
+ scrollRowIntoViewIfNecessary(nextRowIdx);
1669
+ }
1670
+ },
1671
+ [
1672
+ columnCount,
1673
+ nextPageItemIdx,
1674
+ rowCount,
1675
+ scrollRowIntoViewIfNecessary,
1676
+ setHighlightedIndex
1677
+ ]
1678
+ );
1679
+ useEffect2(() => {
1680
+ if (highlightedIndexProp !== void 0 && highlightedIndexProp !== -1) {
1681
+ scrollRowIntoViewIfNecessary(highlightedIndexProp);
1682
+ }
1683
+ }, [highlightedIndexProp, scrollRowIntoViewIfNecessary]);
1684
+ const handleKeyDown = useCallback13(
1685
+ (e) => {
1686
+ if (rowCount > 0 && isNavigationKey(e.key, navigationStyle)) {
1687
+ e.preventDefault();
1688
+ e.stopPropagation();
1689
+ if (navigationStyle === "row") {
1690
+ moveHighlightedRow(e.key);
1691
+ } else {
1692
+ void navigateChildItems(e.key);
1693
+ }
1694
+ }
1695
+ },
1696
+ [rowCount, navigationStyle, moveHighlightedRow, navigateChildItems]
1697
+ );
1698
+ const handleClick = useCallback13(
1699
+ // Might not be a cell e.g the Settings button
1700
+ (evt) => {
1701
+ const target = evt.target;
1702
+ const focusedCell = getFocusedCell(target);
1703
+ if (focusedCell) {
1704
+ const [rowIdx, colIdx] = getTableCellPos(focusedCell);
1705
+ setActiveCell(rowIdx, colIdx);
1706
+ }
1707
+ },
1708
+ [setActiveCell]
1709
+ );
1710
+ const handleMouseLeave = useCallback13(() => {
1711
+ setHighlightedIndex(-1);
1712
+ }, [setHighlightedIndex]);
1713
+ const handleMouseMove = useCallback13(
1714
+ (evt) => {
1715
+ const idx = closestRowIndex(evt.target);
1716
+ if (idx !== -1 && idx !== highlightedIndexRef.current) {
1717
+ setHighlightedIndex(idx);
1718
+ }
1719
+ },
1720
+ [setHighlightedIndex]
1721
+ );
1722
+ const navigate = useCallback13(() => {
1723
+ navigateChildItems("ArrowDown");
1724
+ }, [navigateChildItems]);
1725
+ const fullyRendered = ((_a = containerRef.current) == null ? void 0 : _a.firstChild) != null;
1726
+ useEffect2(() => {
1727
+ if (fullyRendered && focusableCell.current === void 0 && !disableFocus) {
1728
+ const { current: container } = containerRef;
1729
+ const cell = (container == null ? void 0 : container.querySelector(headerCellQuery(0))) || (container == null ? void 0 : container.querySelector(dataCellQuery(0, 0)));
1730
+ if (cell) {
1731
+ cell.setAttribute("tabindex", "0");
1732
+ focusableCell.current = cell;
1733
+ }
1734
+ }
1735
+ }, [containerRef, disableFocus, fullyRendered]);
1736
+ return {
1737
+ highlightedIndexRef,
1738
+ navigate,
1739
+ onClick: handleClick,
1740
+ onFocus: handleFocus,
1741
+ onKeyDown: handleKeyDown,
1742
+ onMouseLeave: navigationStyle === "row" ? handleMouseLeave : void 0,
1743
+ onMouseMove: navigationStyle === "row" ? handleMouseMove : void 0
1744
+ };
1745
+ };
1746
+
1747
+ // src/useSelection.ts
1748
+ import {
1749
+ deselectItem,
1750
+ dispatchMouseEvent,
1751
+ isRowSelected,
1752
+ metadataKeys as metadataKeys4,
1753
+ selectItem
1754
+ } from "@vuu-ui/vuu-utils";
1755
+ import {
1756
+ useCallback as useCallback14,
1757
+ useRef as useRef10
1758
+ } from "react";
1759
+ var { IDX: IDX2 } = metadataKeys4;
1760
+ var NO_SELECTION = [];
1761
+ var defaultSelectionKeys = ["Enter", " "];
1762
+ var useSelection = ({
1763
+ highlightedIndexRef,
1764
+ selectionKeys = defaultSelectionKeys,
1765
+ selectionModel,
1766
+ onSelect,
1767
+ onSelectionChange
1768
+ }) => {
1769
+ selectionModel === "extended" || selectionModel === "checkbox";
1770
+ const lastActiveRef = useRef10(-1);
1771
+ const selectedRef = useRef10(NO_SELECTION);
1772
+ const isSelectionEvent = useCallback14(
1773
+ (evt) => selectionKeys.includes(evt.key),
1774
+ [selectionKeys]
1775
+ );
1776
+ const handleRowClick = useCallback14(
1777
+ (row, rangeSelect, keepExistingSelection) => {
1778
+ const { [IDX2]: idx } = row;
1779
+ const { current: active } = lastActiveRef;
1780
+ const { current: selected } = selectedRef;
1781
+ const selectOperation = isRowSelected(row) ? deselectItem : selectItem;
1782
+ const newSelected = selectOperation(
1783
+ selectionModel,
1784
+ selected,
1785
+ idx,
1786
+ rangeSelect,
1787
+ keepExistingSelection,
1788
+ active
1789
+ );
1790
+ selectedRef.current = newSelected;
1791
+ lastActiveRef.current = idx;
1792
+ onSelect == null ? void 0 : onSelect(row);
1793
+ onSelectionChange == null ? void 0 : onSelectionChange(newSelected);
1794
+ },
1795
+ [onSelect, onSelectionChange, selectionModel]
1796
+ );
1797
+ const handleKeyDown = useCallback14(
1798
+ (e) => {
1799
+ if (isSelectionEvent(e)) {
1800
+ const { current: rowIndex } = highlightedIndexRef;
1801
+ if (rowIndex !== void 0 && rowIndex !== -1) {
1802
+ const rowEl = e.target.querySelector(
1803
+ `[aria-rowindex="${rowIndex}"]`
1804
+ );
1805
+ if (rowEl) {
1806
+ dispatchMouseEvent(rowEl, "click");
1807
+ }
1808
+ }
1809
+ }
1810
+ },
1811
+ [highlightedIndexRef, isSelectionEvent]
1812
+ );
1813
+ return {
1814
+ onKeyDown: handleKeyDown,
1815
+ onRowClick: handleRowClick
1816
+ };
1817
+ };
1818
+
1819
+ // src/useTableContextMenu.ts
1820
+ import { useContextMenu as usePopupContextMenu } from "@vuu-ui/vuu-popups";
1821
+ import { buildColumnMap, getIndexFromRowElement as getIndexFromRowElement2 } from "@vuu-ui/vuu-utils";
1822
+ import { useCallback as useCallback15 } from "react";
1823
+ var NO_ROWS = [];
1824
+ var useTableContextMenu = ({
1825
+ columns,
1826
+ data,
1827
+ dataSource,
1828
+ getSelectedRows
1829
+ }) => {
1830
+ const [showContextMenu] = usePopupContextMenu();
1831
+ const onContextMenu = useCallback15(
1832
+ (evt) => {
1833
+ const target = evt.target;
1834
+ const cellEl = target == null ? void 0 : target.closest("div[role='cell']");
1835
+ const rowEl = target == null ? void 0 : target.closest("div[role='row']");
1836
+ if (cellEl && rowEl) {
1837
+ const { selectedRowsCount } = dataSource;
1838
+ const columnMap = buildColumnMap(columns);
1839
+ const rowIndex = getIndexFromRowElement2(rowEl);
1840
+ const cellIndex = Array.from(rowEl.childNodes).indexOf(cellEl);
1841
+ const row = data.find(([idx]) => idx === rowIndex);
1842
+ const columnName = columns[cellIndex];
1843
+ showContextMenu(evt, "grid", {
1844
+ columnMap,
1845
+ columnName,
1846
+ row,
1847
+ selectedRows: selectedRowsCount === 0 ? NO_ROWS : getSelectedRows(),
1848
+ viewport: dataSource.viewport
1849
+ });
1850
+ }
1851
+ },
1852
+ [columns, data, dataSource, getSelectedRows, showContextMenu]
1853
+ );
1854
+ return onContextMenu;
1855
+ };
1856
+
1857
+ // src/useTableModel.ts
1858
+ import {
1859
+ applyFilterToColumns,
1860
+ applyGroupByToColumns,
1861
+ applySortToColumns,
1862
+ getCellRenderer,
1863
+ getColumnHeaderContentRenderer,
1864
+ getColumnHeaderLabelRenderer,
1865
+ getColumnLabel,
1866
+ getTableHeadings,
1867
+ getValueFormatter,
1868
+ hasValidationRules,
1869
+ isFilteredColumn,
1870
+ isGroupColumn as isGroupColumn3,
1871
+ isPinned,
1872
+ logger,
1873
+ replaceColumn,
1874
+ sortPinnedColumns,
1875
+ stripFilterFromColumns,
1876
+ subscribedOnly
1877
+ } from "@vuu-ui/vuu-utils";
1878
+ import { buildValidationChecker } from "@vuu-ui/vuu-ui-controls";
1879
+ import { useReducer } from "react";
1880
+ var { info } = logger("useTableModel");
1881
+ var DEFAULT_COLUMN_WIDTH = 100;
1882
+ var columnWithoutDataType = ({ serverDataType }) => serverDataType === void 0;
1883
+ var getDataType = (column, tableSchema) => {
1884
+ const schemaColumn = tableSchema == null ? void 0 : tableSchema.columns.find(
1885
+ ({ name }) => name === column.name
1886
+ );
1887
+ if (schemaColumn) {
1888
+ return schemaColumn.serverDataType;
1889
+ } else {
1890
+ return column.serverDataType;
1891
+ }
1892
+ };
1893
+ var numericTypes = ["int", "long", "double"];
1894
+ var getDefaultAlignment = (serverDataType) => serverDataType === void 0 ? void 0 : numericTypes.includes(serverDataType) ? "right" : "left";
1895
+ var isShowColumnSettings = (action) => action.type === "columnSettings";
1896
+ var isShowTableSettings = (action) => action.type === "tableSettings";
1897
+ var columnReducer = (state, action) => {
1898
+ info == null ? void 0 : info(`TableModelReducer ${action.type}`);
1899
+ switch (action.type) {
1900
+ case "init":
1901
+ return init(action);
1902
+ case "moveColumn":
1903
+ return moveColumn(state, action);
1904
+ case "resizeColumn":
1905
+ return resizeColumn(state, action);
1906
+ case "setTableSchema":
1907
+ return setTableSchema(state, action);
1908
+ case "hideColumns":
1909
+ return hideColumns(state, action);
1910
+ case "showColumns":
1911
+ return showColumns(state, action);
1912
+ case "pinColumn":
1913
+ return pinColumn2(state, action);
1914
+ case "updateColumnProp":
1915
+ return updateColumnProp(state, action);
1916
+ case "tableConfig":
1917
+ return updateTableConfig2(state, action);
1918
+ default:
1919
+ console.log(`unhandled action ${action.type}`);
1920
+ return state;
1921
+ }
1922
+ };
1923
+ var useTableModel = (tableConfigProp, dataSource) => {
1924
+ const [state, dispatchTableModelAction] = useReducer(columnReducer, { tableConfig: tableConfigProp, dataSource }, init);
1925
+ const { columns, headings, tableConfig, ...tableAttributes } = state;
1926
+ return {
1927
+ columns,
1928
+ dispatchTableModelAction,
1929
+ headings,
1930
+ tableAttributes,
1931
+ tableConfig
1932
+ };
1933
+ };
1934
+ function init({ dataSource, tableConfig }) {
1935
+ const { columns, ...tableAttributes } = tableConfig;
1936
+ const { config: dataSourceConfig, tableSchema } = dataSource;
1937
+ const runtimeColumns = columns.filter(subscribedOnly(dataSourceConfig == null ? void 0 : dataSourceConfig.columns)).map(
1938
+ columnDescriptorToRuntimeColumDescriptor(tableAttributes, tableSchema)
1939
+ );
1940
+ const maybePinnedColumns = runtimeColumns.some(isPinned) ? sortPinnedColumns(runtimeColumns) : runtimeColumns;
1941
+ let state = {
1942
+ columns: maybePinnedColumns,
1943
+ headings: getTableHeadings(maybePinnedColumns),
1944
+ tableConfig,
1945
+ ...tableAttributes
1946
+ };
1947
+ if (dataSourceConfig) {
1948
+ const { columns: _, ...rest } = dataSourceConfig;
1949
+ state = updateTableConfig2(state, {
1950
+ type: "tableConfig",
1951
+ ...rest
1952
+ });
1953
+ }
1954
+ return state;
1955
+ }
1956
+ var getLabel = (label, columnFormatHeader) => {
1957
+ if (columnFormatHeader === "uppercase") {
1958
+ return label.toUpperCase();
1959
+ } else if (columnFormatHeader === "capitalize") {
1960
+ return label[0].toUpperCase() + label.slice(1).toLowerCase();
1961
+ }
1962
+ return label;
1963
+ };
1964
+ var columnDescriptorToRuntimeColumDescriptor = (tableAttributes, tableSchema) => (column, index) => {
1965
+ const { columnDefaultWidth = DEFAULT_COLUMN_WIDTH, columnFormatHeader } = tableAttributes;
1966
+ const serverDataType = getDataType(column, tableSchema);
1967
+ const {
1968
+ align = getDefaultAlignment(serverDataType),
1969
+ name,
1970
+ label = getColumnLabel(column),
1971
+ width = columnDefaultWidth,
1972
+ ...rest
1973
+ } = column;
1974
+ const runtimeColumnWithDefaults = {
1975
+ ...rest,
1976
+ align,
1977
+ CellRenderer: getCellRenderer(column),
1978
+ HeaderCellContentRenderer: getColumnHeaderContentRenderer(column),
1979
+ HeaderCellLabelRenderer: getColumnHeaderLabelRenderer(column),
1980
+ clientSideEditValidationCheck: hasValidationRules(column.type) ? buildValidationChecker(column.type.renderer.rules) : void 0,
1981
+ index: index + 1,
1982
+ label: getLabel(label, columnFormatHeader),
1983
+ name,
1984
+ originalIdx: index,
1985
+ serverDataType,
1986
+ valueFormatter: getValueFormatter(column, serverDataType),
1987
+ width
1988
+ };
1989
+ if (isGroupColumn3(runtimeColumnWithDefaults)) {
1990
+ runtimeColumnWithDefaults.columns = runtimeColumnWithDefaults.columns.map(
1991
+ (col) => columnDescriptorToRuntimeColumDescriptor(tableAttributes)(col, index)
1992
+ );
1993
+ }
1994
+ return runtimeColumnWithDefaults;
1995
+ };
1996
+ function moveColumn(state, { column, moveBy }) {
1997
+ const { columns } = state;
1998
+ if (typeof moveBy === "number") {
1999
+ const idx = columns.indexOf(column);
2000
+ const newColumns = columns.slice();
2001
+ const [movedColumns] = newColumns.splice(idx, 1);
2002
+ newColumns.splice(idx + moveBy, 0, movedColumns);
2003
+ return {
2004
+ ...state,
2005
+ columns: newColumns
2006
+ };
2007
+ }
2008
+ return state;
2009
+ }
2010
+ function hideColumns(state, { columns }) {
2011
+ if (columns.some((col) => col.hidden !== true)) {
2012
+ return columns.reduce((s, c) => {
2013
+ if (c.hidden !== true) {
2014
+ return updateColumnProp(s, {
2015
+ type: "updateColumnProp",
2016
+ column: c,
2017
+ hidden: true
2018
+ });
2019
+ } else {
2020
+ return s;
2021
+ }
2022
+ }, state);
2023
+ } else {
2024
+ return state;
2025
+ }
2026
+ }
2027
+ function showColumns(state, { columns }) {
2028
+ if (columns.some((col) => col.hidden)) {
2029
+ return columns.reduce((s, c) => {
2030
+ if (c.hidden) {
2031
+ return updateColumnProp(s, {
2032
+ type: "updateColumnProp",
2033
+ column: c,
2034
+ hidden: false
2035
+ });
2036
+ } else {
2037
+ return s;
2038
+ }
2039
+ }, state);
2040
+ } else {
2041
+ return state;
2042
+ }
2043
+ }
2044
+ function resizeColumn(state, { column, phase, width }) {
2045
+ const type = "updateColumnProp";
2046
+ const resizing = phase !== "end";
2047
+ switch (phase) {
2048
+ case "begin":
2049
+ return updateColumnProp(state, { type, column, resizing });
2050
+ case "end":
2051
+ return updateColumnProp(state, { type, column, resizing, width });
2052
+ case "resize":
2053
+ return updateColumnProp(state, { type, column, width });
2054
+ default:
2055
+ throw Error(`useTableModel.resizeColumn, invalid resizePhase ${phase}`);
2056
+ }
2057
+ }
2058
+ function setTableSchema(state, { tableSchema }) {
2059
+ const { columns } = state;
2060
+ if (columns.some(columnWithoutDataType)) {
2061
+ const cols = columns.map((column) => {
2062
+ var _a;
2063
+ const serverDataType = getDataType(column, tableSchema);
2064
+ return {
2065
+ ...column,
2066
+ align: (_a = column.align) != null ? _a : getDefaultAlignment(serverDataType),
2067
+ serverDataType
2068
+ };
2069
+ });
2070
+ return {
2071
+ ...state,
2072
+ columns: cols
2073
+ };
2074
+ } else {
2075
+ return state;
2076
+ }
2077
+ }
2078
+ function pinColumn2(state, action) {
2079
+ let { columns } = state;
2080
+ const { column, pin } = action;
2081
+ const targetColumn = columns.find((col) => col.name === column.name);
2082
+ if (targetColumn) {
2083
+ columns = replaceColumn(columns, { ...targetColumn, pin });
2084
+ columns = sortPinnedColumns(columns);
2085
+ return {
2086
+ ...state,
2087
+ columns
2088
+ };
2089
+ } else {
2090
+ return state;
2091
+ }
2092
+ }
2093
+ function updateColumnProp(state, action) {
2094
+ let { columns, tableConfig } = state;
2095
+ const { align, column, hidden, label, resizing, width } = action;
2096
+ const targetColumn = columns.find((col) => col.name === column.name);
2097
+ if (targetColumn) {
2098
+ if (align === "left" || align === "right") {
2099
+ columns = replaceColumn(columns, { ...targetColumn, align });
2100
+ }
2101
+ if (typeof label === "string") {
2102
+ columns = replaceColumn(columns, { ...targetColumn, label });
2103
+ }
2104
+ if (typeof resizing === "boolean") {
2105
+ columns = replaceColumn(columns, { ...targetColumn, resizing });
2106
+ }
2107
+ if (typeof hidden === "boolean") {
2108
+ columns = replaceColumn(columns, { ...targetColumn, hidden });
2109
+ }
2110
+ if (typeof width === "number") {
2111
+ columns = replaceColumn(columns, { ...targetColumn, width });
2112
+ const targetConfigColumn = tableConfig.columns.find(
2113
+ (col) => col.name === column.name
2114
+ );
2115
+ if (targetConfigColumn) {
2116
+ tableConfig = {
2117
+ ...tableConfig,
2118
+ columns: replaceColumn(tableConfig.columns, {
2119
+ ...targetConfigColumn,
2120
+ width
2121
+ })
2122
+ };
2123
+ }
2124
+ }
2125
+ }
2126
+ return {
2127
+ ...state,
2128
+ columns,
2129
+ tableConfig
2130
+ };
2131
+ }
2132
+ function updateTableConfig2(state, { confirmed, filter, groupBy, sort }) {
2133
+ const hasGroupBy = groupBy !== void 0;
2134
+ const hasFilter = typeof (filter == null ? void 0 : filter.filter) === "string";
2135
+ const hasSort = sort && sort.sortDefs.length > 0;
2136
+ let result = state;
2137
+ if (hasGroupBy) {
2138
+ result = {
2139
+ ...state,
2140
+ columns: applyGroupByToColumns(result.columns, groupBy, confirmed)
2141
+ };
2142
+ }
2143
+ if (hasSort) {
2144
+ result = {
2145
+ ...state,
2146
+ columns: applySortToColumns(result.columns, sort)
2147
+ };
2148
+ }
2149
+ if (hasFilter) {
2150
+ result = {
2151
+ ...state,
2152
+ columns: applyFilterToColumns(result.columns, filter)
2153
+ };
2154
+ } else if (result.columns.some(isFilteredColumn)) {
2155
+ result = {
2156
+ ...state,
2157
+ columns: stripFilterFromColumns(result.columns)
2158
+ };
2159
+ }
2160
+ return result;
2161
+ }
2162
+
2163
+ // src/useTableScroll.ts
2164
+ import {
2165
+ getColumnsInViewport,
2166
+ getRowElementAtIndex,
2167
+ itemsChanged
2168
+ } from "@vuu-ui/vuu-utils";
2169
+ import {
2170
+ useCallback as useCallback16,
2171
+ useEffect as useEffect3,
2172
+ useImperativeHandle,
2173
+ useMemo as useMemo4,
2174
+ useRef as useRef11,
2175
+ useState as useState5
2176
+ } from "react";
2177
+ var SCROLL_MOVE_CHECK_THRESHOLD = 100;
2178
+ var HORIZONTAL_SCROLL_BUFFER = 200;
2179
+ var getMaxScroll = (container) => {
2180
+ const { clientHeight, clientWidth, scrollHeight, scrollWidth } = container;
2181
+ return [scrollWidth - clientWidth, scrollHeight - clientHeight];
2182
+ };
2183
+ var getScrollDirection = (prevScrollPositions, scrollPos) => {
2184
+ if (prevScrollPositions === void 0) {
2185
+ return void 0;
2186
+ } else {
2187
+ const { scrollTop: prevTop } = prevScrollPositions;
2188
+ return scrollPos > prevTop ? "fwd" : "bwd";
2189
+ }
2190
+ };
2191
+ var getPctScroll = (container, currentScrollPos) => {
2192
+ const {
2193
+ clientHeight,
2194
+ clientWidth,
2195
+ scrollHeight,
2196
+ scrollLeft,
2197
+ scrollTop,
2198
+ scrollWidth
2199
+ } = container;
2200
+ const maxScrollLeft = scrollWidth - clientWidth;
2201
+ const pctScrollLeft = scrollLeft / (scrollWidth - clientWidth);
2202
+ const maxScrollTop = scrollHeight - clientHeight;
2203
+ let pctScrollTop = scrollTop / (scrollHeight - clientHeight);
2204
+ const scrollDirection = getScrollDirection(currentScrollPos, scrollTop);
2205
+ if (scrollDirection === "fwd" && pctScrollTop > 0.99) {
2206
+ pctScrollTop = 1;
2207
+ } else if (scrollDirection === "bwd" && pctScrollTop < 0.02) {
2208
+ pctScrollTop = 0;
2209
+ }
2210
+ return [
2211
+ scrollLeft,
2212
+ pctScrollLeft,
2213
+ maxScrollLeft,
2214
+ scrollTop,
2215
+ pctScrollTop,
2216
+ maxScrollTop
2217
+ ];
2218
+ };
2219
+ var noScrolling = {
2220
+ scrollToIndex: () => void 0,
2221
+ scrollToKey: () => void 0
2222
+ };
2223
+ var useCallbackRef = ({
2224
+ onAttach,
2225
+ onDetach
2226
+ }) => {
2227
+ const ref = useRef11(null);
2228
+ const callbackRef = useCallback16(
2229
+ (el) => {
2230
+ if (el) {
2231
+ ref.current = el;
2232
+ onAttach == null ? void 0 : onAttach(el);
2233
+ } else if (ref.current) {
2234
+ const { current: originalRef } = ref;
2235
+ ref.current = el;
2236
+ onDetach == null ? void 0 : onDetach(originalRef);
2237
+ }
2238
+ },
2239
+ [onAttach, onDetach]
2240
+ );
2241
+ return callbackRef;
2242
+ };
2243
+ var useTableScroll = ({
2244
+ columns,
2245
+ getRowAtPosition,
2246
+ onHorizontalScroll,
2247
+ onVerticalScroll,
2248
+ onVerticalScrollInSitu,
2249
+ rowHeight,
2250
+ scrollingApiRef,
2251
+ setRange,
2252
+ viewportMeasurements
2253
+ }) => {
2254
+ const firstRowRef = useRef11(0);
2255
+ const rowHeightRef = useRef11(rowHeight);
2256
+ const contentContainerScrolledRef = useRef11(false);
2257
+ const contentContainerPosRef = useRef11({
2258
+ scrollTop: 0,
2259
+ scrollLeft: 0
2260
+ });
2261
+ const scrollbarContainerScrolledRef = useRef11(false);
2262
+ const scrollbarContainerPosRef = useRef11({
2263
+ scrollTop: 0,
2264
+ scrollLeft: 0
2265
+ });
2266
+ const scrollbarContainerRef = useRef11(null);
2267
+ const contentContainerRef = useRef11(null);
2268
+ const lastHorizontalScrollCheckPoint = useRef11(0);
2269
+ const {
2270
+ appliedPageSize,
2271
+ isVirtualScroll,
2272
+ rowCount: viewportRowCount,
2273
+ totalHeaderHeight,
2274
+ viewportWidth
2275
+ } = viewportMeasurements;
2276
+ const columnsWithinViewportRef = useRef11([]);
2277
+ const [, forceRefresh] = useState5({});
2278
+ const preSpanRef = useRef11(0);
2279
+ useMemo4(() => {
2280
+ const [visibleColumns, offset] = getColumnsInViewport(
2281
+ columns,
2282
+ contentContainerPosRef.current.scrollLeft,
2283
+ contentContainerPosRef.current.scrollLeft + viewportWidth + HORIZONTAL_SCROLL_BUFFER
2284
+ );
2285
+ preSpanRef.current = offset;
2286
+ columnsWithinViewportRef.current = visibleColumns;
2287
+ }, [viewportWidth, columns]);
2288
+ const handleHorizontalScroll = useCallback16(
2289
+ (scrollLeft) => {
2290
+ contentContainerPosRef.current.scrollLeft = scrollLeft;
2291
+ onHorizontalScroll == null ? void 0 : onHorizontalScroll(scrollLeft);
2292
+ if (Math.abs(scrollLeft - lastHorizontalScrollCheckPoint.current) > SCROLL_MOVE_CHECK_THRESHOLD) {
2293
+ lastHorizontalScrollCheckPoint.current = scrollLeft;
2294
+ const [visibleColumns, pre] = getColumnsInViewport(
2295
+ columns,
2296
+ scrollLeft,
2297
+ scrollLeft + viewportWidth + HORIZONTAL_SCROLL_BUFFER
2298
+ );
2299
+ if (itemsChanged(columnsWithinViewportRef.current, visibleColumns)) {
2300
+ preSpanRef.current = pre;
2301
+ columnsWithinViewportRef.current = visibleColumns;
2302
+ forceRefresh({});
2303
+ }
2304
+ }
2305
+ },
2306
+ [columns, onHorizontalScroll, viewportWidth]
2307
+ );
2308
+ const handleVerticalScroll = useCallback16(
2309
+ (scrollTop, pctScrollTop) => {
2310
+ contentContainerPosRef.current.scrollTop = scrollTop;
2311
+ onVerticalScroll == null ? void 0 : onVerticalScroll(scrollTop, pctScrollTop);
2312
+ const firstRow = getRowAtPosition(scrollTop);
2313
+ if (firstRow !== firstRowRef.current) {
2314
+ firstRowRef.current = firstRow;
2315
+ setRange({ from: firstRow, to: firstRow + viewportRowCount });
2316
+ }
2317
+ onVerticalScrollInSitu == null ? void 0 : onVerticalScrollInSitu(0);
2318
+ },
2319
+ [
2320
+ getRowAtPosition,
2321
+ onVerticalScroll,
2322
+ onVerticalScrollInSitu,
2323
+ setRange,
2324
+ viewportRowCount
2325
+ ]
2326
+ );
2327
+ const handleScrollbarContainerScroll = useCallback16(() => {
2328
+ const { current: contentContainer } = contentContainerRef;
2329
+ const { current: scrollbarContainer } = scrollbarContainerRef;
2330
+ const { current: contentContainerScrolled } = contentContainerScrolledRef;
2331
+ const { current: scrollPos } = scrollbarContainerPosRef;
2332
+ if (contentContainerScrolled) {
2333
+ contentContainerScrolledRef.current = false;
2334
+ } else if (contentContainer && scrollbarContainer) {
2335
+ scrollbarContainerScrolledRef.current = true;
2336
+ const [scrollLeft, pctScrollLeft, , scrollTop, pctScrollTop] = getPctScroll(scrollbarContainer, scrollPos);
2337
+ scrollPos.scrollLeft = scrollLeft;
2338
+ scrollPos.scrollTop = scrollTop;
2339
+ const [maxScrollLeft, maxScrollTop] = getMaxScroll(scrollbarContainer);
2340
+ const contentScrollLeft = Math.round(pctScrollLeft * maxScrollLeft);
2341
+ const contentScrollTop = pctScrollTop * maxScrollTop;
2342
+ contentContainer.scrollTo({
2343
+ left: contentScrollLeft,
2344
+ top: contentScrollTop,
2345
+ behavior: "auto"
2346
+ });
2347
+ }
2348
+ onVerticalScrollInSitu == null ? void 0 : onVerticalScrollInSitu(0);
2349
+ }, [onVerticalScrollInSitu]);
2350
+ const handleContentContainerScroll = useCallback16(() => {
2351
+ const { current: scrollbarContainerScrolled } = scrollbarContainerScrolledRef;
2352
+ const { current: contentContainer } = contentContainerRef;
2353
+ const { current: scrollbarContainer } = scrollbarContainerRef;
2354
+ const { current: scrollPos } = contentContainerPosRef;
2355
+ if (contentContainer && scrollbarContainer) {
2356
+ const [
2357
+ scrollLeft,
2358
+ pctScrollLeft,
2359
+ maxScrollLeft,
2360
+ scrollTop,
2361
+ pctScrollTop,
2362
+ maxScrollTop
2363
+ ] = getPctScroll(contentContainer);
2364
+ contentContainerScrolledRef.current = true;
2365
+ if (scrollbarContainerScrolled) {
2366
+ scrollbarContainerScrolledRef.current = false;
2367
+ } else {
2368
+ scrollbarContainer.scrollLeft = Math.round(
2369
+ pctScrollLeft * maxScrollLeft
2370
+ );
2371
+ scrollbarContainer.scrollTop = pctScrollTop * maxScrollTop;
2372
+ }
2373
+ if (scrollPos.scrollTop !== scrollTop) {
2374
+ handleVerticalScroll(scrollTop, pctScrollTop);
2375
+ }
2376
+ if (scrollPos.scrollLeft !== scrollLeft) {
2377
+ handleHorizontalScroll(scrollLeft);
2378
+ }
2379
+ }
2380
+ }, [handleVerticalScroll, handleHorizontalScroll]);
2381
+ const handleAttachScrollbarContainer = useCallback16(
2382
+ (el) => {
2383
+ scrollbarContainerRef.current = el;
2384
+ el.addEventListener("scroll", handleScrollbarContainerScroll, {
2385
+ passive: true
2386
+ });
2387
+ },
2388
+ [handleScrollbarContainerScroll]
2389
+ );
2390
+ const handleDetachScrollbarContainer = useCallback16(
2391
+ (el) => {
2392
+ scrollbarContainerRef.current = null;
2393
+ el.removeEventListener("scroll", handleScrollbarContainerScroll);
2394
+ },
2395
+ [handleScrollbarContainerScroll]
2396
+ );
2397
+ const handleAttachContentContainer = useCallback16(
2398
+ (el) => {
2399
+ contentContainerRef.current = el;
2400
+ el.addEventListener("scroll", handleContentContainerScroll, {
2401
+ passive: true
2402
+ });
2403
+ },
2404
+ [handleContentContainerScroll]
2405
+ );
2406
+ const handleDetachContentContainer = useCallback16(
2407
+ (el) => {
2408
+ contentContainerRef.current = null;
2409
+ el.removeEventListener("scroll", handleContentContainerScroll);
2410
+ },
2411
+ [handleContentContainerScroll]
2412
+ );
2413
+ const contentContainerCallbackRef = useCallbackRef({
2414
+ onAttach: handleAttachContentContainer,
2415
+ onDetach: handleDetachContentContainer
2416
+ });
2417
+ const scrollbarContainerCallbackRef = useCallbackRef({
2418
+ onAttach: handleAttachScrollbarContainer,
2419
+ onDetach: handleDetachScrollbarContainer
2420
+ });
2421
+ const requestScroll = useCallback16(
2422
+ (scrollRequest) => {
2423
+ const { current: contentContainer } = contentContainerRef;
2424
+ if (contentContainer) {
2425
+ const [maxScrollLeft, maxScrollTop] = getMaxScroll(contentContainer);
2426
+ const { scrollLeft, scrollTop } = contentContainer;
2427
+ contentContainerScrolledRef.current = false;
2428
+ if (scrollRequest.type === "scroll-row") {
2429
+ const activeRow = getRowElementAtIndex(
2430
+ contentContainer,
2431
+ scrollRequest.rowIndex
2432
+ );
2433
+ if (activeRow !== null) {
2434
+ const [direction, distance] = howFarIsRowOutsideViewport(
2435
+ activeRow,
2436
+ totalHeaderHeight
2437
+ );
2438
+ if (direction && distance) {
2439
+ if (isVirtualScroll) {
2440
+ const offset = direction === "down" ? 1 : -1;
2441
+ onVerticalScrollInSitu == null ? void 0 : onVerticalScrollInSitu(offset);
2442
+ const firstRow = firstRowRef.current + offset;
2443
+ firstRowRef.current = firstRow;
2444
+ setRange({
2445
+ from: firstRow,
2446
+ to: firstRow + viewportRowCount
2447
+ });
2448
+ } else {
2449
+ let newScrollLeft = scrollLeft;
2450
+ let newScrollTop = scrollTop;
2451
+ if (direction === "up" || direction === "down") {
2452
+ newScrollTop = Math.min(
2453
+ Math.max(0, scrollTop + distance),
2454
+ maxScrollTop
2455
+ );
2456
+ } else {
2457
+ newScrollLeft = Math.min(
2458
+ Math.max(0, scrollLeft + distance),
2459
+ maxScrollLeft
2460
+ );
2461
+ }
2462
+ contentContainer.scrollTo({
2463
+ top: newScrollTop,
2464
+ left: newScrollLeft,
2465
+ behavior: "smooth"
2466
+ });
2467
+ }
2468
+ }
2469
+ }
2470
+ } else if (scrollRequest.type === "scroll-page") {
2471
+ const { direction } = scrollRequest;
2472
+ if (isVirtualScroll) {
2473
+ const offset = direction === "down" ? viewportRowCount : -viewportRowCount;
2474
+ onVerticalScrollInSitu == null ? void 0 : onVerticalScrollInSitu(offset);
2475
+ const firstRow = firstRowRef.current + offset;
2476
+ firstRowRef.current = firstRow;
2477
+ setRange({ from: firstRow, to: firstRow + viewportRowCount });
2478
+ } else {
2479
+ const scrollBy = direction === "down" ? appliedPageSize : -appliedPageSize;
2480
+ const newScrollTop = Math.min(
2481
+ Math.max(0, scrollTop + scrollBy),
2482
+ maxScrollTop
2483
+ );
2484
+ contentContainer.scrollTo({
2485
+ top: newScrollTop,
2486
+ left: scrollLeft,
2487
+ behavior: "auto"
2488
+ });
2489
+ }
2490
+ } else if (scrollRequest.type === "scroll-end") {
2491
+ const { direction } = scrollRequest;
2492
+ const scrollTo = direction === "end" ? maxScrollTop : 0;
2493
+ contentContainer.scrollTo({
2494
+ top: scrollTo,
2495
+ left: contentContainer.scrollLeft,
2496
+ behavior: "auto"
2497
+ });
2498
+ }
2499
+ }
2500
+ },
2501
+ [
2502
+ appliedPageSize,
2503
+ isVirtualScroll,
2504
+ onVerticalScrollInSitu,
2505
+ setRange,
2506
+ totalHeaderHeight,
2507
+ viewportRowCount
2508
+ ]
2509
+ );
2510
+ const scrollHandles = useMemo4(
2511
+ // TODO not complete yet
2512
+ () => ({
2513
+ scrollToIndex: (rowIndex) => {
2514
+ if (scrollbarContainerRef.current) {
2515
+ const scrollPos = (rowIndex - 30) * 20;
2516
+ scrollbarContainerRef.current.scrollTop = scrollPos;
2517
+ }
2518
+ },
2519
+ scrollToKey: (rowKey) => {
2520
+ console.log(`scrollToKey ${rowKey}`);
2521
+ }
2522
+ }),
2523
+ []
2524
+ );
2525
+ useImperativeHandle(
2526
+ scrollingApiRef,
2527
+ () => {
2528
+ if (scrollbarContainerRef.current) {
2529
+ return scrollHandles;
2530
+ } else {
2531
+ return noScrolling;
2532
+ }
2533
+ },
2534
+ [scrollHandles]
2535
+ );
2536
+ useEffect3(() => {
2537
+ if (rowHeight !== rowHeightRef.current) {
2538
+ rowHeightRef.current = rowHeight;
2539
+ if (contentContainerPosRef.current.scrollTop > 0) {
2540
+ if (contentContainerRef.current) {
2541
+ contentContainerRef.current.scrollTop = 0;
2542
+ }
2543
+ }
2544
+ } else {
2545
+ const { current: from } = firstRowRef;
2546
+ const rowRange = { from, to: from + viewportRowCount };
2547
+ setRange(rowRange);
2548
+ }
2549
+ }, [rowHeight, setRange, viewportRowCount]);
2550
+ return {
2551
+ columnsWithinViewport: columnsWithinViewportRef.current,
2552
+ /** Ref to be assigned to ScrollbarContainer */
2553
+ scrollbarContainerRef: scrollbarContainerCallbackRef,
2554
+ /** Ref to be assigned to ContentContainer */
2555
+ contentContainerRef: contentContainerCallbackRef,
2556
+ /** Scroll the table */
2557
+ requestScroll,
2558
+ /** number of leading columns not rendered because of virtualization */
2559
+ virtualColSpan: preSpanRef.current
2560
+ };
2561
+ };
2562
+
2563
+ // src/useTableViewport.ts
2564
+ import {
2565
+ actualRowPositioning,
2566
+ measurePinnedColumns,
2567
+ virtualRowPositioning
2568
+ } from "@vuu-ui/vuu-utils";
2569
+ import { useCallback as useCallback17, useMemo as useMemo5, useRef as useRef12 } from "react";
2570
+ var MAX_PIXEL_HEIGHT = 1e7;
2571
+ var UNMEASURED_VIEWPORT = {
2572
+ appliedPageSize: 0,
2573
+ contentHeight: 0,
2574
+ contentWidth: 0,
2575
+ getRowAtPosition: () => -1,
2576
+ getRowOffset: () => -1,
2577
+ horizontalScrollbarHeight: 0,
2578
+ isVirtualScroll: false,
2579
+ pinnedWidthLeft: 0,
2580
+ pinnedWidthRight: 0,
2581
+ rowCount: 0,
2582
+ setInSituRowOffset: () => void 0,
2583
+ setScrollTop: () => void 0,
2584
+ totalHeaderHeight: 0,
2585
+ verticalScrollbarWidth: 0,
2586
+ viewportBodyHeight: 0,
2587
+ viewportWidth: 0
2588
+ };
2589
+ var useTableViewport = ({
2590
+ columns,
2591
+ headerHeight,
2592
+ headings,
2593
+ rowCount,
2594
+ rowHeight,
2595
+ selectionEndSize = 4,
2596
+ size
2597
+ }) => {
2598
+ const inSituRowOffsetRef = useRef12(0);
2599
+ const pctScrollTopRef = useRef12(0);
2600
+ const pixelContentHeight = Math.min(rowHeight * rowCount, MAX_PIXEL_HEIGHT);
2601
+ const virtualContentHeight = rowCount * rowHeight;
2602
+ const virtualisedExtent = virtualContentHeight - pixelContentHeight;
2603
+ const { pinnedWidthLeft, pinnedWidthRight, unpinnedWidth } = useMemo5(
2604
+ () => measurePinnedColumns(columns, selectionEndSize),
2605
+ [columns, selectionEndSize]
2606
+ );
2607
+ const totalHeaderHeightRef = useRef12(headerHeight);
2608
+ useMemo5(() => {
2609
+ totalHeaderHeightRef.current = headerHeight * (1 + headings.length);
2610
+ }, [headerHeight, headings.length]);
2611
+ const [getRowOffset, getRowAtPosition, isVirtualScroll] = useMemo5(() => {
2612
+ if (virtualisedExtent) {
2613
+ const [_getRowOffset, getRowAtPosition2, _isVirtual] = virtualRowPositioning(rowHeight, virtualisedExtent, pctScrollTopRef);
2614
+ const getOffset = (row) => {
2615
+ return _getRowOffset(row, inSituRowOffsetRef.current);
2616
+ };
2617
+ return [getOffset, getRowAtPosition2, _isVirtual];
2618
+ } else {
2619
+ return actualRowPositioning(rowHeight);
2620
+ }
2621
+ }, [virtualisedExtent, rowHeight]);
2622
+ const setScrollTop = useCallback17((_, scrollPct) => {
2623
+ pctScrollTopRef.current = scrollPct;
2624
+ }, []);
2625
+ const setInSituRowOffset = useCallback17((rowIndexOffset) => {
2626
+ if (rowIndexOffset === 0) {
2627
+ inSituRowOffsetRef.current = 0;
2628
+ } else {
2629
+ inSituRowOffsetRef.current = Math.max(
2630
+ 0,
2631
+ inSituRowOffsetRef.current + rowIndexOffset
2632
+ );
2633
+ }
2634
+ }, []);
2635
+ return useMemo5(() => {
2636
+ if (size) {
2637
+ const { current: totalHeaderHeight } = totalHeaderHeightRef;
2638
+ const scrollbarSize = 15;
2639
+ const contentWidth = pinnedWidthLeft + unpinnedWidth + pinnedWidthRight;
2640
+ const horizontalScrollbarHeight = contentWidth > size.width ? scrollbarSize : 0;
2641
+ const visibleRows = (size.height - headerHeight) / rowHeight;
2642
+ const count = Number.isInteger(visibleRows) ? visibleRows : Math.ceil(visibleRows);
2643
+ const viewportBodyHeight = size.height - totalHeaderHeight;
2644
+ const verticalScrollbarWidth = pixelContentHeight > viewportBodyHeight ? scrollbarSize : 0;
2645
+ const appliedPageSize = count * rowHeight * (pixelContentHeight / virtualContentHeight);
2646
+ const viewportWidth = size.width;
2647
+ return {
2648
+ appliedPageSize,
2649
+ contentHeight: pixelContentHeight,
2650
+ contentWidth,
2651
+ getRowAtPosition,
2652
+ getRowOffset,
2653
+ isVirtualScroll,
2654
+ horizontalScrollbarHeight,
2655
+ pinnedWidthLeft,
2656
+ pinnedWidthRight,
2657
+ rowCount: count,
2658
+ setInSituRowOffset,
2659
+ setScrollTop,
2660
+ totalHeaderHeight,
2661
+ verticalScrollbarWidth,
2662
+ viewportBodyHeight,
2663
+ viewportWidth
2664
+ };
2665
+ } else {
2666
+ return UNMEASURED_VIEWPORT;
2667
+ }
2668
+ }, [
2669
+ getRowAtPosition,
2670
+ getRowOffset,
2671
+ headerHeight,
2672
+ isVirtualScroll,
2673
+ pinnedWidthLeft,
2674
+ unpinnedWidth,
2675
+ pinnedWidthRight,
2676
+ pixelContentHeight,
2677
+ rowHeight,
2678
+ setInSituRowOffset,
2679
+ setScrollTop,
2680
+ size,
2681
+ virtualContentHeight
2682
+ ]);
2683
+ };
2684
+
2685
+ // src/useTableAndColumnSettings.ts
2686
+ import { useLayoutProviderDispatch } from "@vuu-ui/vuu-layout";
2687
+ import { getCalculatedColumnType } from "@vuu-ui/vuu-utils";
2688
+ import { useCallback as useCallback18, useRef as useRef13, useState as useState6 } from "react";
2689
+ var useTableAndColumnSettings = ({
2690
+ availableColumns: availableColumnsProps,
2691
+ onAvailableColumnsChange,
2692
+ onConfigChange,
2693
+ onCreateCalculatedColumn,
2694
+ onDataSourceConfigChange,
2695
+ tableConfig
2696
+ }) => {
2697
+ const dispatchLayoutAction = useLayoutProviderDispatch();
2698
+ const showTableSettingsRef = useRef13();
2699
+ const [availableColumns, setAvailableColumns] = useState6(
2700
+ availableColumnsProps
2701
+ );
2702
+ const showContextPanel = useCallback18(
2703
+ (componentType, title, props) => {
2704
+ dispatchLayoutAction({
2705
+ type: "set-props",
2706
+ path: "#context-panel",
2707
+ props: {
2708
+ expanded: true,
2709
+ content: {
2710
+ type: componentType,
2711
+ props
2712
+ },
2713
+ title
2714
+ }
2715
+ });
2716
+ },
2717
+ [dispatchLayoutAction]
2718
+ );
2719
+ const handleCancelCreateColumn = useCallback18(() => {
2720
+ requestAnimationFrame(() => {
2721
+ var _a;
2722
+ (_a = showTableSettingsRef.current) == null ? void 0 : _a.call(showTableSettingsRef);
2723
+ });
2724
+ }, []);
2725
+ const handleCreateCalculatedColumn = useCallback18(
2726
+ (column) => {
2727
+ const newAvailableColumns = availableColumns.concat({
2728
+ name: column.name,
2729
+ serverDataType: getCalculatedColumnType(column)
2730
+ });
2731
+ setAvailableColumns(newAvailableColumns);
2732
+ onAvailableColumnsChange == null ? void 0 : onAvailableColumnsChange(newAvailableColumns);
2733
+ requestAnimationFrame(() => {
2734
+ var _a;
2735
+ (_a = showTableSettingsRef.current) == null ? void 0 : _a.call(showTableSettingsRef);
2736
+ });
2737
+ onCreateCalculatedColumn(column);
2738
+ },
2739
+ [availableColumns, onAvailableColumnsChange, onCreateCalculatedColumn]
2740
+ );
2741
+ const showColumnSettingsPanel = useCallback18(
2742
+ (action) => {
2743
+ showContextPanel("ColumnSettings", "Column Settings", {
2744
+ column: action.column,
2745
+ onCancelCreateColumn: handleCancelCreateColumn,
2746
+ onConfigChange,
2747
+ onCreateCalculatedColumn: handleCreateCalculatedColumn,
2748
+ tableConfig,
2749
+ vuuTable: action.vuuTable
2750
+ });
2751
+ },
2752
+ [
2753
+ handleCancelCreateColumn,
2754
+ handleCreateCalculatedColumn,
2755
+ onConfigChange,
2756
+ showContextPanel,
2757
+ tableConfig
2758
+ ]
2759
+ );
2760
+ const handleAddCalculatedColumn = useCallback18(() => {
2761
+ showColumnSettingsPanel({
2762
+ column: {
2763
+ name: "::",
2764
+ serverDataType: "string"
2765
+ },
2766
+ type: "columnSettings",
2767
+ vuuTable: { module: "SIMUL", table: "instruments" }
2768
+ });
2769
+ }, [showColumnSettingsPanel]);
2770
+ const handleNavigateToColumn = useCallback18(
2771
+ (columnName) => {
2772
+ const column = tableConfig.columns.find((c) => c.name === columnName);
2773
+ if (column) {
2774
+ showColumnSettingsPanel({
2775
+ type: "columnSettings",
2776
+ column,
2777
+ //TODO where do we get this from
2778
+ vuuTable: { module: "SIMUL", table: "instruments" }
2779
+ });
2780
+ }
2781
+ },
2782
+ [showColumnSettingsPanel, tableConfig.columns]
2783
+ );
2784
+ showTableSettingsRef.current = useCallback18(() => {
2785
+ showContextPanel("TableSettings", "DataGrid Settings", {
2786
+ availableColumns: availableColumns != null ? availableColumns : tableConfig.columns.map(({ name, serverDataType }) => ({
2787
+ name,
2788
+ serverDataType
2789
+ })),
2790
+ onAddCalculatedColumn: handleAddCalculatedColumn,
2791
+ onConfigChange,
2792
+ onDataSourceConfigChange,
2793
+ onNavigateToColumn: handleNavigateToColumn,
2794
+ tableConfig
2795
+ });
2796
+ }, [
2797
+ availableColumns,
2798
+ handleAddCalculatedColumn,
2799
+ handleNavigateToColumn,
2800
+ onConfigChange,
2801
+ onDataSourceConfigChange,
2802
+ showContextPanel,
2803
+ tableConfig
2804
+ ]);
2805
+ return {
2806
+ showColumnSettingsPanel,
2807
+ showTableSettingsPanel: showTableSettingsRef.current
2808
+ };
2809
+ };
2810
+
2811
+ // src/useRowClassNameGenerators.ts
2812
+ import {
2813
+ getRowClassNameGenerator
2814
+ } from "@vuu-ui/vuu-utils";
2815
+ import { useMemo as useMemo6 } from "react";
2816
+ var createClassNameGenerator = (ids) => {
2817
+ const functions = [];
2818
+ ids == null ? void 0 : ids.forEach((id) => {
2819
+ const fn = getRowClassNameGenerator(id);
2820
+ if (fn) {
2821
+ functions.push(fn.fn);
2822
+ }
2823
+ });
2824
+ return (row, columnMap) => {
2825
+ const classNames = [];
2826
+ functions == null ? void 0 : functions.forEach((fn) => {
2827
+ const className = fn(row, columnMap);
2828
+ if (className) {
2829
+ classNames.push(className);
2830
+ }
2831
+ });
2832
+ return classNames.join(" ");
2833
+ };
2834
+ };
2835
+ var useRowClassNameGenerators = ({
2836
+ rowClassNameGenerators
2837
+ }) => {
2838
+ return useMemo6(() => {
2839
+ return createClassNameGenerator(rowClassNameGenerators);
2840
+ }, [rowClassNameGenerators]);
2841
+ };
2842
+
2843
+ // src/useTable.ts
2844
+ var stripInternalProperties = (tableConfig) => {
2845
+ return tableConfig;
2846
+ };
2847
+ var { KEY, IS_EXPANDED: IS_EXPANDED2, IS_LEAF: IS_LEAF2 } = metadataKeys5;
2848
+ var NULL_DRAG_DROP = {
2849
+ draggable: void 0,
2850
+ onMouseDown: void 0
2851
+ };
2852
+ var useNullDragDrop = () => NULL_DRAG_DROP;
2853
+ var addColumn = (tableConfig, column) => ({
2854
+ ...tableConfig,
2855
+ columns: tableConfig.columns.concat(column)
2856
+ });
2857
+ var useTable = ({
2858
+ allowDragDrop = false,
2859
+ availableColumns,
2860
+ config,
2861
+ containerRef,
2862
+ dataSource,
2863
+ disableFocus,
2864
+ headerHeight = 25,
2865
+ highlightedIndex: highlightedIndexProp,
2866
+ id,
2867
+ navigationStyle = "cell",
2868
+ onAvailableColumnsChange,
2869
+ onConfigChange,
2870
+ onDragStart,
2871
+ onDrop,
2872
+ onFeatureInvocation,
2873
+ onHighlight,
2874
+ onRowClick: onRowClickProp,
2875
+ onSelect,
2876
+ onSelectionChange,
2877
+ renderBufferSize = 0,
2878
+ rowHeight = 20,
2879
+ scrollingApiRef,
2880
+ selectionModel,
2881
+ size
2882
+ }) => {
2883
+ const [rowCount, setRowCount] = useState7(dataSource.size);
2884
+ if (dataSource === void 0) {
2885
+ throw Error("no data source provided to Vuu Table");
2886
+ }
2887
+ const rowClassNameGenerator = useRowClassNameGenerators(config);
2888
+ const useRowDragDrop = allowDragDrop ? useDragDrop2 : useNullDragDrop;
2889
+ const menuBuilder = useMemo7(
2890
+ () => buildContextMenuDescriptors(dataSource),
2891
+ [dataSource]
2892
+ );
2893
+ const onDataRowcountChange = useCallback19((size2) => {
2894
+ setRowCount(size2);
2895
+ }, []);
2896
+ const {
2897
+ columns,
2898
+ dispatchTableModelAction,
2899
+ headings,
2900
+ tableAttributes,
2901
+ tableConfig
2902
+ } = useTableModel(config, dataSource);
2903
+ useLayoutEffectSkipFirst2(() => {
2904
+ dispatchTableModelAction({
2905
+ type: "init",
2906
+ tableConfig: config,
2907
+ dataSource
2908
+ });
2909
+ }, [config, dataSource, dispatchTableModelAction]);
2910
+ const applyTableConfigChange = useCallback19(
2911
+ (config2) => {
2912
+ dispatchTableModelAction({
2913
+ type: "init",
2914
+ tableConfig: config2,
2915
+ dataSource
2916
+ });
2917
+ onConfigChange == null ? void 0 : onConfigChange(stripInternalProperties(config2));
2918
+ },
2919
+ [dataSource, dispatchTableModelAction, onConfigChange]
2920
+ );
2921
+ const columnMap = useMemo7(
2922
+ () => buildColumnMap2(dataSource.columns),
2923
+ [dataSource.columns]
2924
+ );
2925
+ const onSubscribed = useCallback19(
2926
+ ({ tableSchema }) => {
2927
+ if (tableSchema) {
2928
+ dispatchTableModelAction({
2929
+ type: "setTableSchema",
2930
+ tableSchema
2931
+ });
2932
+ } else {
2933
+ console.log("subscription message with no schema");
2934
+ }
2935
+ },
2936
+ [dispatchTableModelAction]
2937
+ );
2938
+ const {
2939
+ getRowAtPosition,
2940
+ getRowOffset,
2941
+ setInSituRowOffset: viewportHookSetInSituRowOffset,
2942
+ setScrollTop: viewportHookSetScrollTop,
2943
+ ...viewportMeasurements
2944
+ } = useTableViewport({
2945
+ columns,
2946
+ headerHeight,
2947
+ headings,
2948
+ rowCount,
2949
+ rowHeight,
2950
+ size
2951
+ });
2952
+ const initialRange = useInitialValue({
2953
+ from: 0,
2954
+ to: viewportMeasurements.rowCount
2955
+ });
2956
+ const { data, dataRef, getSelectedRows, range, setRange } = useDataSource({
2957
+ dataSource,
2958
+ // We need to factor this out of Table
2959
+ onFeatureInvocation,
2960
+ renderBufferSize,
2961
+ onSizeChange: onDataRowcountChange,
2962
+ onSubscribed,
2963
+ range: initialRange
2964
+ });
2965
+ const { requestScroll, ...scrollProps } = useTableScroll({
2966
+ columns,
2967
+ getRowAtPosition,
2968
+ rowHeight,
2969
+ scrollingApiRef,
2970
+ setRange,
2971
+ onVerticalScroll: viewportHookSetScrollTop,
2972
+ onVerticalScrollInSitu: viewportHookSetInSituRowOffset,
2973
+ viewportMeasurements
2974
+ });
2975
+ const handleConfigEditedInSettingsPanel = useCallback19(
2976
+ (tableConfig2) => {
2977
+ dispatchTableModelAction({
2978
+ type: "init",
2979
+ tableConfig: tableConfig2,
2980
+ dataSource
2981
+ });
2982
+ onConfigChange == null ? void 0 : onConfigChange(stripInternalProperties(tableConfig2));
2983
+ },
2984
+ [dataSource, dispatchTableModelAction, onConfigChange]
2985
+ );
2986
+ const handleDataSourceConfigChanged = useCallback19(
2987
+ (dataSourceConfig) => {
2988
+ dataSource.config = {
2989
+ ...dataSource.config,
2990
+ ...dataSourceConfig
2991
+ };
2992
+ },
2993
+ [dataSource]
2994
+ );
2995
+ useEffect4(() => {
2996
+ dataSource.on("config", (config2, confirmed, changes) => {
2997
+ const scrollSensitiveChanges = (changes == null ? void 0 : changes.filterChanged) || (changes == null ? void 0 : changes.groupByChanged);
2998
+ if (scrollSensitiveChanges && dataSource.range.from > 0) {
2999
+ requestScroll({
3000
+ type: "scroll-end",
3001
+ direction: "home"
3002
+ });
3003
+ }
3004
+ dispatchTableModelAction({
3005
+ type: "tableConfig",
3006
+ ...config2,
3007
+ confirmed
3008
+ });
3009
+ });
3010
+ }, [dataSource, dispatchTableModelAction, requestScroll]);
3011
+ const handleCreateCalculatedColumn = useCallback19(
3012
+ (column) => {
3013
+ dataSource.columns = dataSource.columns.concat(column.name);
3014
+ applyTableConfigChange(addColumn(tableConfig, column));
3015
+ },
3016
+ [dataSource, tableConfig, applyTableConfigChange]
3017
+ );
3018
+ const hideColumns2 = useCallback19(
3019
+ (action) => {
3020
+ const { columns: columns2 } = action;
3021
+ const hiddenColumns = columns2.map((c) => c.name);
3022
+ const newTableConfig = {
3023
+ ...tableConfig,
3024
+ columns: tableConfig.columns.map(
3025
+ (col) => hiddenColumns.includes(col.name) ? { ...col, hidden: true } : col
3026
+ )
3027
+ };
3028
+ applyTableConfigChange(newTableConfig);
3029
+ },
3030
+ [tableConfig, applyTableConfigChange]
3031
+ );
3032
+ const pinColumn3 = useCallback19(
3033
+ (action) => {
3034
+ applyTableConfigChange({
3035
+ ...tableConfig,
3036
+ columns: updateColumn(tableConfig.columns, {
3037
+ ...action.column,
3038
+ pin: action.pin
3039
+ })
3040
+ });
3041
+ },
3042
+ [tableConfig, applyTableConfigChange]
3043
+ );
3044
+ const { showColumnSettingsPanel, showTableSettingsPanel } = useTableAndColumnSettings({
3045
+ availableColumns: availableColumns != null ? availableColumns : tableConfig.columns.map(({ name, serverDataType = "string" }) => ({
3046
+ name,
3047
+ serverDataType
3048
+ })),
3049
+ onAvailableColumnsChange,
3050
+ onConfigChange: handleConfigEditedInSettingsPanel,
3051
+ onCreateCalculatedColumn: handleCreateCalculatedColumn,
3052
+ onDataSourceConfigChange: handleDataSourceConfigChanged,
3053
+ tableConfig
3054
+ });
3055
+ const onPersistentColumnOperation = useCallback19(
3056
+ (action) => {
3057
+ if (isShowColumnSettings(action)) {
3058
+ showColumnSettingsPanel(action);
3059
+ } else if (isShowTableSettings(action)) {
3060
+ showTableSettingsPanel();
3061
+ } else {
3062
+ switch (action.type) {
3063
+ case "hideColumns":
3064
+ return hideColumns2(action);
3065
+ case "pinColumn":
3066
+ return pinColumn3(action);
3067
+ default:
3068
+ dispatchTableModelAction(action);
3069
+ }
3070
+ }
3071
+ },
3072
+ [
3073
+ dispatchTableModelAction,
3074
+ hideColumns2,
3075
+ pinColumn3,
3076
+ showColumnSettingsPanel,
3077
+ showTableSettingsPanel
3078
+ ]
3079
+ );
3080
+ const handleContextMenuAction = useHandleTableContextMenu({
3081
+ dataSource,
3082
+ onPersistentColumnOperation
3083
+ });
3084
+ const handleSort = useCallback19(
3085
+ (column, extendSort = false, sortType) => {
3086
+ if (dataSource) {
3087
+ dataSource.sort = applySort(
3088
+ dataSource.sort,
3089
+ column,
3090
+ extendSort,
3091
+ sortType
3092
+ );
3093
+ }
3094
+ },
3095
+ [dataSource]
3096
+ );
3097
+ const resizeCells = useRef14();
3098
+ const onResizeColumn = useCallback19(
3099
+ (phase, columnName, width) => {
3100
+ var _a, _b, _c;
3101
+ const column = columns.find((column2) => column2.name === columnName);
3102
+ if (column) {
3103
+ if (phase === "resize") {
3104
+ (_a = resizeCells.current) == null ? void 0 : _a.forEach((cell) => {
3105
+ cell.style.width = `${width}px`;
3106
+ });
3107
+ } else if (phase === "end") {
3108
+ resizeCells.current = void 0;
3109
+ if (isValidNumber(width)) {
3110
+ dispatchTableModelAction({
3111
+ type: "resizeColumn",
3112
+ phase,
3113
+ column,
3114
+ width
3115
+ });
3116
+ onConfigChange == null ? void 0 : onConfigChange(
3117
+ stripInternalProperties(
3118
+ updateTableConfig(tableConfig, {
3119
+ type: "col-size",
3120
+ column,
3121
+ width
3122
+ })
3123
+ )
3124
+ );
3125
+ }
3126
+ } else {
3127
+ const byColIndex = `[aria-colindex='${column.index}']`;
3128
+ resizeCells.current = Array.from(
3129
+ (_c = (_b = containerRef.current) == null ? void 0 : _b.querySelectorAll(
3130
+ `.vuuTableCell${byColIndex},.vuuTableHeaderCell${byColIndex}`
3131
+ )) != null ? _c : []
3132
+ );
3133
+ dispatchTableModelAction({
3134
+ type: "resizeColumn",
3135
+ phase,
3136
+ column,
3137
+ width
3138
+ });
3139
+ }
3140
+ } else {
3141
+ throw Error(
3142
+ `useDataTable.handleColumnResize, column ${columnName} not found`
3143
+ );
3144
+ }
3145
+ },
3146
+ [
3147
+ columns,
3148
+ dispatchTableModelAction,
3149
+ onConfigChange,
3150
+ tableConfig,
3151
+ containerRef
3152
+ ]
3153
+ );
3154
+ const onToggleGroup = useCallback19(
3155
+ (row, column) => {
3156
+ var _a, _b;
3157
+ const isJson = isJsonGroup2(column, row, columnMap);
3158
+ const key = row[KEY];
3159
+ if (row[IS_EXPANDED2]) {
3160
+ dataSource.closeTreeNode(key, true);
3161
+ if (isJson) {
3162
+ const idx = columns.indexOf(column);
3163
+ const rows = (_a = dataSource.getRowsAtDepth) == null ? void 0 : _a.call(dataSource, idx + 1);
3164
+ if (rows && !rows.some((row2) => row2[IS_EXPANDED2] || row2[IS_LEAF2])) {
3165
+ dispatchTableModelAction({
3166
+ type: "hideColumns",
3167
+ columns: columns.slice(idx + 2)
3168
+ });
3169
+ }
3170
+ }
3171
+ } else {
3172
+ dataSource.openTreeNode(key);
3173
+ if (isJson) {
3174
+ const childRows = (_b = dataSource.getChildRows) == null ? void 0 : _b.call(dataSource, key);
3175
+ const idx = columns.indexOf(column) + 1;
3176
+ const columnsToShow = [columns[idx]];
3177
+ if (childRows && childRows.some((row2) => row2[IS_LEAF2])) {
3178
+ columnsToShow.push(columns[idx + 1]);
3179
+ }
3180
+ if (columnsToShow.some((col) => col.hidden)) {
3181
+ dispatchTableModelAction({
3182
+ type: "showColumns",
3183
+ columns: columnsToShow
3184
+ });
3185
+ }
3186
+ }
3187
+ }
3188
+ },
3189
+ [columnMap, columns, dataSource, dispatchTableModelAction]
3190
+ );
3191
+ const {
3192
+ highlightedIndexRef,
3193
+ navigate,
3194
+ onFocus: navigationFocus,
3195
+ onKeyDown: navigationKeyDown,
3196
+ ...containerProps
3197
+ } = useKeyboardNavigation({
3198
+ columnCount: columns.filter((c) => c.hidden !== true).length,
3199
+ containerRef,
3200
+ disableFocus,
3201
+ highlightedIndex: highlightedIndexProp,
3202
+ navigationStyle,
3203
+ requestScroll,
3204
+ rowCount: dataSource == null ? void 0 : dataSource.size,
3205
+ onHighlight,
3206
+ viewportRange: range,
3207
+ viewportRowCount: viewportMeasurements.rowCount
3208
+ });
3209
+ const {
3210
+ onBlur: editingBlur,
3211
+ onDoubleClick: editingDoubleClick,
3212
+ onKeyDown: editingKeyDown,
3213
+ onFocus: editingFocus
3214
+ } = useCellEditing({
3215
+ navigate
3216
+ });
3217
+ const handleFocus = useCallback19(
3218
+ (e) => {
3219
+ navigationFocus();
3220
+ if (!e.defaultPrevented) {
3221
+ editingFocus(e);
3222
+ }
3223
+ },
3224
+ [editingFocus, navigationFocus]
3225
+ );
3226
+ const onContextMenu = useTableContextMenu({
3227
+ columns,
3228
+ data,
3229
+ dataSource,
3230
+ getSelectedRows
3231
+ });
3232
+ const onMoveGroupColumn = useCallback19(
3233
+ (columns2) => {
3234
+ dataSource.groupBy = columns2.map((col) => col.name);
3235
+ },
3236
+ [dataSource]
3237
+ );
3238
+ const onRemoveGroupColumn = useCallback19(
3239
+ (column) => {
3240
+ if (isGroupColumn4(column)) {
3241
+ dataSource.groupBy = [];
3242
+ } else {
3243
+ if (dataSource && dataSource.groupBy.includes(column.name)) {
3244
+ dataSource.groupBy = dataSource.groupBy.filter(
3245
+ (columnName) => columnName !== column.name
3246
+ );
3247
+ }
3248
+ }
3249
+ },
3250
+ [dataSource]
3251
+ );
3252
+ const handleSelectionChange = useCallback19(
3253
+ (selected) => {
3254
+ dataSource.select(selected);
3255
+ onSelectionChange == null ? void 0 : onSelectionChange(selected);
3256
+ },
3257
+ [dataSource, onSelectionChange]
3258
+ );
3259
+ const {
3260
+ onKeyDown: selectionHookKeyDown,
3261
+ onRowClick: selectionHookOnRowClick
3262
+ } = useSelection({
3263
+ highlightedIndexRef,
3264
+ onSelect,
3265
+ onSelectionChange: handleSelectionChange,
3266
+ selectionModel
3267
+ });
3268
+ const handleKeyDown = useCallback19(
3269
+ (e) => {
3270
+ navigationKeyDown(e);
3271
+ if (!e.defaultPrevented) {
3272
+ editingKeyDown(e);
3273
+ }
3274
+ if (!e.defaultPrevented) {
3275
+ selectionHookKeyDown(e);
3276
+ }
3277
+ },
3278
+ [navigationKeyDown, editingKeyDown, selectionHookKeyDown]
3279
+ );
3280
+ const handleRowClick = useCallback19(
3281
+ (row, rangeSelect, keepExistingSelection) => {
3282
+ selectionHookOnRowClick(row, rangeSelect, keepExistingSelection);
3283
+ onRowClickProp == null ? void 0 : onRowClickProp(row);
3284
+ },
3285
+ [onRowClickProp, selectionHookOnRowClick]
3286
+ );
3287
+ const onMoveColumn = useCallback19(
3288
+ (columns2) => {
3289
+ const newTableConfig = {
3290
+ ...tableConfig,
3291
+ columns: columns2
3292
+ };
3293
+ dispatchTableModelAction({
3294
+ type: "init",
3295
+ tableConfig: newTableConfig,
3296
+ dataSource
3297
+ });
3298
+ onConfigChange == null ? void 0 : onConfigChange(stripInternalProperties(newTableConfig));
3299
+ },
3300
+ [dataSource, dispatchTableModelAction, onConfigChange, tableConfig]
3301
+ );
3302
+ const handleDropRow = useCallback19(
3303
+ (dragDropState) => {
3304
+ onDrop == null ? void 0 : onDrop(dragDropState);
3305
+ },
3306
+ [onDrop]
3307
+ );
3308
+ const handleDataEdited = useCallback19(
3309
+ async (row, columnName, value) => dataSource.applyEdit(row, columnName, value),
3310
+ [dataSource]
3311
+ );
3312
+ const handleDragStartRow = useCallback19(
3313
+ (dragDropState) => {
3314
+ const { initialDragElement } = dragDropState;
3315
+ const rowIndex = getIndexFromRowElement3(initialDragElement);
3316
+ const row = dataRef.current.find((row2) => row2[0] === rowIndex);
3317
+ if (row) {
3318
+ dragDropState.setPayload(row);
3319
+ } else {
3320
+ }
3321
+ onDragStart == null ? void 0 : onDragStart(dragDropState);
3322
+ },
3323
+ [dataRef, onDragStart]
3324
+ );
3325
+ const { onMouseDown: rowDragMouseDown, draggable: draggableRow } = useRowDragDrop({
3326
+ allowDragDrop,
3327
+ containerRef,
3328
+ draggableClassName: `vuuTable`,
3329
+ id,
3330
+ onDragStart: handleDragStartRow,
3331
+ onDrop: handleDropRow,
3332
+ orientation: "vertical",
3333
+ itemQuery: ".vuuTableRow"
3334
+ });
3335
+ return {
3336
+ ...containerProps,
3337
+ "aria-rowcount": dataSource.size,
3338
+ rowClassNameGenerator,
3339
+ draggableRow,
3340
+ onBlur: editingBlur,
3341
+ onDoubleClick: editingDoubleClick,
3342
+ onFocus: handleFocus,
3343
+ onKeyDown: handleKeyDown,
3344
+ onMouseDown: rowDragMouseDown,
3345
+ columnMap,
3346
+ columns,
3347
+ data,
3348
+ getRowOffset,
3349
+ handleContextMenuAction,
3350
+ headings,
3351
+ highlightedIndex: highlightedIndexRef.current,
3352
+ menuBuilder,
3353
+ onContextMenu,
3354
+ onDataEdited: handleDataEdited,
3355
+ onMoveColumn,
3356
+ onMoveGroupColumn,
3357
+ onRemoveGroupColumn,
3358
+ onRowClick: handleRowClick,
3359
+ onSortColumn: handleSort,
3360
+ onResizeColumn,
3361
+ onToggleGroup,
3362
+ scrollProps,
3363
+ // TODO don't think we need these ...
3364
+ tableAttributes,
3365
+ tableConfig,
3366
+ viewportMeasurements
3367
+ };
3368
+ };
3369
+
3370
+ // src/useRowHeight.ts
3371
+ import { isValidNumber as isValidNumber2 } from "@vuu-ui/vuu-utils";
3372
+ import { useCallback as useCallback20, useMemo as useMemo8, useRef as useRef15, useState as useState8 } from "react";
3373
+ var useRowHeight = ({
3374
+ rowHeight: rowHeightProp = 0
3375
+ }) => {
3376
+ const [rowHeight, setRowHeight] = useState8(rowHeightProp);
3377
+ const heightRef = useRef15(rowHeight);
3378
+ const resizeObserver = useMemo8(() => {
3379
+ return new ResizeObserver((entries) => {
3380
+ for (const entry of entries) {
3381
+ const { height: measuredHeight } = entry.contentRect;
3382
+ const newHeight = Math.round(measuredHeight);
3383
+ if (isValidNumber2(newHeight) && heightRef.current !== newHeight) {
3384
+ heightRef.current = newHeight;
3385
+ setRowHeight(newHeight);
3386
+ }
3387
+ }
3388
+ });
3389
+ }, []);
3390
+ const rowRef = useCallback20(
3391
+ (el) => {
3392
+ if (el) {
3393
+ if (rowHeightProp === 0) {
3394
+ const { height } = el.getBoundingClientRect();
3395
+ console.log(`measured rowHeight = ${height}`);
3396
+ resizeObserver.observe(el);
3397
+ setRowHeight(height);
3398
+ }
3399
+ } else {
3400
+ resizeObserver.disconnect();
3401
+ }
3402
+ },
3403
+ [resizeObserver, rowHeightProp]
3404
+ );
3405
+ return { rowHeight, rowRef };
3406
+ };
3407
+
3408
+ // src/Table.tsx
3409
+ import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
3410
+ var classBase7 = "vuuTable";
3411
+ var { IDX: IDX3, RENDER_IDX } = metadataKeys6;
3412
+ var TableCore = ({
3413
+ Row: Row2 = Row,
3414
+ allowDragDrop,
3415
+ availableColumns,
3416
+ config,
3417
+ containerRef,
3418
+ dataSource,
3419
+ disableFocus = false,
3420
+ highlightedIndex: highlightedIndexProp,
3421
+ id: idProp,
3422
+ navigationStyle = "cell",
3423
+ onAvailableColumnsChange,
3424
+ onConfigChange,
3425
+ onDragStart,
3426
+ onDrop,
3427
+ onFeatureInvocation,
3428
+ onHighlight,
3429
+ onRowClick: onRowClickProp,
3430
+ onSelect,
3431
+ onSelectionChange,
3432
+ renderBufferSize = 5,
3433
+ rowHeight,
3434
+ scrollingApiRef,
3435
+ selectionModel = "extended",
3436
+ showColumnHeaders = true,
3437
+ headerHeight = showColumnHeaders ? rowHeight * 1.25 : 0,
3438
+ size
3439
+ }) => {
3440
+ const id = useId(idProp);
3441
+ const {
3442
+ columnMap,
3443
+ columns,
3444
+ data,
3445
+ draggableRow,
3446
+ getRowOffset,
3447
+ handleContextMenuAction,
3448
+ headings,
3449
+ highlightedIndex,
3450
+ menuBuilder,
3451
+ onDataEdited,
3452
+ onMoveColumn,
3453
+ onMoveGroupColumn,
3454
+ onRemoveGroupColumn,
3455
+ onResizeColumn,
3456
+ onRowClick,
3457
+ onSortColumn,
3458
+ onToggleGroup,
3459
+ rowClassNameGenerator,
3460
+ scrollProps,
3461
+ tableAttributes,
3462
+ tableConfig,
3463
+ viewportMeasurements,
3464
+ ...tableProps
3465
+ } = useTable({
3466
+ allowDragDrop,
3467
+ availableColumns,
3468
+ config,
3469
+ containerRef,
3470
+ dataSource,
3471
+ disableFocus,
3472
+ headerHeight,
3473
+ highlightedIndex: highlightedIndexProp,
3474
+ id,
3475
+ navigationStyle,
3476
+ onAvailableColumnsChange,
3477
+ onConfigChange,
3478
+ onDragStart,
3479
+ onDrop,
3480
+ onFeatureInvocation,
3481
+ onHighlight,
3482
+ onRowClick: onRowClickProp,
3483
+ onSelect,
3484
+ onSelectionChange,
3485
+ renderBufferSize,
3486
+ rowHeight,
3487
+ scrollingApiRef,
3488
+ selectionModel,
3489
+ size
3490
+ });
3491
+ const contentContainerClassName = cx9(`${classBase7}-contentContainer`, {
3492
+ [`${classBase7}-colLines`]: tableAttributes.columnSeparators,
3493
+ [`${classBase7}-rowLines`]: tableAttributes.rowSeparators,
3494
+ [`${classBase7}-zebra`]: tableAttributes.zebraStripes
3495
+ });
3496
+ const cssVariables = {
3497
+ "--content-height": `${viewportMeasurements.contentHeight}px`,
3498
+ "--content-width": `${viewportMeasurements.contentWidth}px`,
3499
+ "--horizontal-scrollbar-height": `${viewportMeasurements.horizontalScrollbarHeight}px`,
3500
+ "--pinned-width-left": `${viewportMeasurements.pinnedWidthLeft}px`,
3501
+ "--pinned-width-right": `${viewportMeasurements.pinnedWidthRight}px`,
3502
+ "--header-height": `${headerHeight}px`,
3503
+ "--row-height-prop": `${rowHeight}px`,
3504
+ "--total-header-height": `${viewportMeasurements.totalHeaderHeight}px`,
3505
+ "--vertical-scrollbar-width": `${viewportMeasurements.verticalScrollbarWidth}px`,
3506
+ "--viewport-body-height": `${viewportMeasurements.viewportBodyHeight}px`
3507
+ };
3508
+ return /* @__PURE__ */ jsxs9(
3509
+ ContextMenuProvider,
3510
+ {
3511
+ menuActionHandler: handleContextMenuAction,
3512
+ menuBuilder,
3513
+ children: [
3514
+ /* @__PURE__ */ jsx12(
3515
+ "div",
3516
+ {
3517
+ className: `${classBase7}-scrollbarContainer`,
3518
+ ref: scrollProps.scrollbarContainerRef,
3519
+ style: cssVariables,
3520
+ children: /* @__PURE__ */ jsx12("div", { className: `${classBase7}-scrollbarContent` })
3521
+ }
3522
+ ),
3523
+ /* @__PURE__ */ jsx12(
3524
+ "div",
3525
+ {
3526
+ className: contentContainerClassName,
3527
+ ref: scrollProps.contentContainerRef,
3528
+ style: cssVariables,
3529
+ children: /* @__PURE__ */ jsxs9(
3530
+ "div",
3531
+ {
3532
+ ...tableProps,
3533
+ className: `${classBase7}-table`,
3534
+ role: "table",
3535
+ tabIndex: disableFocus ? void 0 : -1,
3536
+ children: [
3537
+ showColumnHeaders ? /* @__PURE__ */ jsx12(
3538
+ TableHeader,
3539
+ {
3540
+ columns: scrollProps.columnsWithinViewport,
3541
+ headings,
3542
+ onMoveColumn,
3543
+ onMoveGroupColumn,
3544
+ onRemoveGroupColumn,
3545
+ onResizeColumn,
3546
+ onSortColumn,
3547
+ tableConfig,
3548
+ tableId: id,
3549
+ virtualColSpan: scrollProps.virtualColSpan
3550
+ }
3551
+ ) : null,
3552
+ /* @__PURE__ */ jsx12("div", { className: `${classBase7}-body`, children: data.map((data2) => /* @__PURE__ */ jsx12(
3553
+ Row2,
3554
+ {
3555
+ "aria-rowindex": data2[0] + 1,
3556
+ classNameGenerator: rowClassNameGenerator,
3557
+ columnMap,
3558
+ columns: scrollProps.columnsWithinViewport,
3559
+ highlighted: highlightedIndex === data2[IDX3],
3560
+ onClick: onRowClick,
3561
+ onDataEdited,
3562
+ row: data2,
3563
+ offset: getRowOffset(data2),
3564
+ onToggleGroup,
3565
+ virtualColSpan: scrollProps.virtualColSpan,
3566
+ zebraStripes: tableAttributes.zebraStripes
3567
+ },
3568
+ data2[RENDER_IDX]
3569
+ )) })
3570
+ ]
3571
+ }
3572
+ )
3573
+ }
3574
+ ),
3575
+ draggableRow
3576
+ ]
3577
+ }
3578
+ );
3579
+ };
3580
+ var Table = forwardRef2(function TableNext({
3581
+ Row: Row2,
3582
+ allowDragDrop,
3583
+ availableColumns,
3584
+ className: classNameProp,
3585
+ config,
3586
+ dataSource,
3587
+ disableFocus,
3588
+ highlightedIndex,
3589
+ id,
3590
+ navigationStyle,
3591
+ onAvailableColumnsChange,
3592
+ onConfigChange,
3593
+ onDragStart,
3594
+ onDrop,
3595
+ onFeatureInvocation,
3596
+ onHighlight,
3597
+ onRowClick,
3598
+ onSelect,
3599
+ onSelectionChange,
3600
+ renderBufferSize,
3601
+ rowHeight: rowHeightProp,
3602
+ scrollingApiRef,
3603
+ selectionModel,
3604
+ showColumnHeaders,
3605
+ headerHeight,
3606
+ style: styleProp,
3607
+ ...htmlAttributes
3608
+ }, forwardedRef) {
3609
+ const containerRef = useRef16(null);
3610
+ const [size, setSize] = useState9();
3611
+ const { rowHeight, rowRef } = useRowHeight({ rowHeight: rowHeightProp });
3612
+ if (config === void 0) {
3613
+ throw Error(
3614
+ "vuu Table requires config prop. Minimum config is list of Column Descriptors"
3615
+ );
3616
+ }
3617
+ if (dataSource === void 0) {
3618
+ throw Error("vuu Table requires dataSource prop");
3619
+ }
3620
+ return /* @__PURE__ */ jsxs9(
3621
+ MeasuredContainer,
3622
+ {
3623
+ ...htmlAttributes,
3624
+ className: cx9(classBase7, classNameProp),
3625
+ id,
3626
+ onResize: setSize,
3627
+ ref: useForkRef(containerRef, forwardedRef),
3628
+ children: [
3629
+ /* @__PURE__ */ jsx12(RowProxy, { ref: rowRef, height: rowHeightProp }),
3630
+ size && rowHeight ? /* @__PURE__ */ jsx12(
3631
+ TableCore,
3632
+ {
3633
+ Row: Row2,
3634
+ allowDragDrop,
3635
+ availableColumns,
3636
+ config,
3637
+ containerRef,
3638
+ dataSource,
3639
+ disableFocus,
3640
+ headerHeight,
3641
+ highlightedIndex,
3642
+ id,
3643
+ navigationStyle,
3644
+ onAvailableColumnsChange,
3645
+ onConfigChange,
3646
+ onDragStart,
3647
+ onDrop,
3648
+ onFeatureInvocation,
3649
+ onHighlight,
3650
+ onRowClick,
3651
+ onSelect,
3652
+ onSelectionChange,
3653
+ renderBufferSize,
3654
+ rowHeight,
3655
+ scrollingApiRef,
3656
+ selectionModel,
3657
+ showColumnHeaders,
3658
+ size
3659
+ }
3660
+ ) : null
3661
+ ]
3662
+ }
3663
+ );
3664
+ });
3665
+
3666
+ // src/cell-renderers/checkbox-cell/CheckboxCell.tsx
3667
+ import { memo as memo3, useCallback as useCallback21 } from "react";
3668
+ import { CheckboxIcon, WarnCommit } from "@vuu-ui/vuu-ui-controls";
3669
+ import { Checkbox } from "@salt-ds/core";
3670
+ import {
3671
+ dataColumnAndKeyUnchanged,
3672
+ dispatchCustomEvent,
3673
+ registerComponent
3674
+ } from "@vuu-ui/vuu-utils";
3675
+ import { jsx as jsx13 } from "react/jsx-runtime";
3676
+ var CheckboxCell = memo3(
3677
+ ({ column, columnMap, onCommit = WarnCommit, row }) => {
3678
+ const dataIdx = columnMap[column.name];
3679
+ const isChecked = !!row[dataIdx];
3680
+ const handleCommit = useCallback21(
3681
+ (value) => async (evt) => {
3682
+ const res = await onCommit(value);
3683
+ if (res === true) {
3684
+ dispatchCustomEvent(evt.target, "vuu-commit");
3685
+ }
3686
+ return res;
3687
+ },
3688
+ [onCommit]
3689
+ );
3690
+ return column.editable ? /* @__PURE__ */ jsx13(Checkbox, { checked: isChecked, onClick: handleCommit(!isChecked) }) : /* @__PURE__ */ jsx13(CheckboxIcon, { checked: isChecked, disabled: true });
3691
+ },
3692
+ dataColumnAndKeyUnchanged
3693
+ );
3694
+ CheckboxCell.displayName = "CheckboxCell";
3695
+ registerComponent("checkbox-cell", CheckboxCell, "cell-renderer", {
3696
+ serverDataType: "boolean"
3697
+ });
3698
+
3699
+ // src/cell-renderers/input-cell/InputCell.tsx
3700
+ import { registerComponent as registerComponent2 } from "@vuu-ui/vuu-utils";
3701
+ import { Input } from "@salt-ds/core";
3702
+ import { useEditableText } from "@vuu-ui/vuu-ui-controls";
3703
+ import cx10 from "clsx";
3704
+ import { jsx as jsx14 } from "react/jsx-runtime";
3705
+ var classBase8 = "vuuTableInputCell";
3706
+ var WarnCommit2 = () => {
3707
+ console.warn(
3708
+ "onCommit handler has not been provided to InputCell cell renderer"
3709
+ );
3710
+ return Promise.resolve(true);
3711
+ };
3712
+ var InputCell = ({
3713
+ column,
3714
+ columnMap,
3715
+ onCommit = WarnCommit2,
3716
+ row
3717
+ }) => {
3718
+ const dataIdx = columnMap[column.name];
3719
+ const dataValue = row[dataIdx];
3720
+ const { align = "left", clientSideEditValidationCheck } = column;
3721
+ const { warningMessage, ...editProps } = useEditableText({
3722
+ initialValue: dataValue,
3723
+ onCommit,
3724
+ clientSideEditValidationCheck
3725
+ });
3726
+ const endAdornment = warningMessage && align === "left" ? /* @__PURE__ */ jsx14("span", { className: `${classBase8}-icon`, "data-icon": "error" }) : void 0;
3727
+ const startAdornment = warningMessage && align === "right" ? /* @__PURE__ */ jsx14("span", { className: `${classBase8}-icon`, "data-icon": "error" }) : void 0;
3728
+ return /* @__PURE__ */ jsx14(
3729
+ Input,
3730
+ {
3731
+ ...editProps,
3732
+ className: cx10(classBase8, {
3733
+ [`${classBase8}-error`]: warningMessage !== void 0
3734
+ }),
3735
+ endAdornment,
3736
+ startAdornment
3737
+ }
3738
+ );
3739
+ };
3740
+ registerComponent2("input-cell", InputCell, "cell-renderer", {
3741
+ userCanAssign: false
3742
+ });
3743
+
3744
+ // src/cell-renderers/toggle-cell/ToggleCell.tsx
3745
+ import { WarnCommit as WarnCommit3 } from "@vuu-ui/vuu-ui-controls";
3746
+ import {
3747
+ dataColumnAndKeyUnchanged as dataColumnAndKeyUnchanged2,
3748
+ dispatchCustomEvent as dispatchCustomEvent2,
3749
+ isTypeDescriptor,
3750
+ isValueListRenderer,
3751
+ registerComponent as registerComponent3
3752
+ } from "@vuu-ui/vuu-utils";
3753
+ import cx11 from "clsx";
3754
+ import { memo as memo4, useCallback as useCallback22 } from "react";
3755
+ import { CycleStateButton } from "@vuu-ui/vuu-ui-controls";
3756
+ import { jsx as jsx15 } from "react/jsx-runtime";
3757
+ var classBase9 = "vuuTableToggleCell";
3758
+ var getValueList = ({ name, type }) => {
3759
+ if (isTypeDescriptor(type) && isValueListRenderer(type.renderer)) {
3760
+ return type.renderer.values;
3761
+ } else {
3762
+ throw Error(
3763
+ `useLookupValues column ${name} has not been configured with a values list`
3764
+ );
3765
+ }
3766
+ };
3767
+ var ToggleCell = memo4(
3768
+ function ToggleCell2({
3769
+ column,
3770
+ columnMap,
3771
+ onCommit = WarnCommit3,
3772
+ row
3773
+ }) {
3774
+ const values = getValueList(column);
3775
+ const dataIdx = columnMap[column.name];
3776
+ const value = row[dataIdx];
3777
+ const handleCommit = useCallback22(
3778
+ (evt, value2) => {
3779
+ return onCommit(value2).then((response) => {
3780
+ if (response === true) {
3781
+ dispatchCustomEvent2(evt.target, "vuu-commit");
3782
+ }
3783
+ return response;
3784
+ });
3785
+ },
3786
+ [onCommit]
3787
+ );
3788
+ return /* @__PURE__ */ jsx15(
3789
+ CycleStateButton,
3790
+ {
3791
+ className: cx11(classBase9, `${classBase9}-${column.name}`),
3792
+ onCommit: handleCommit,
3793
+ value,
3794
+ values,
3795
+ variant: "cta",
3796
+ children: value
3797
+ }
3798
+ );
3799
+ },
3800
+ dataColumnAndKeyUnchanged2
3801
+ );
3802
+ registerComponent3("toggle-cell", ToggleCell, "cell-renderer", {
3803
+ userCanAssign: false
3804
+ });
3805
+
3806
+ // src/useControlledTableNavigation.ts
3807
+ import { useStateRef } from "@vuu-ui/vuu-ui-controls";
3808
+ import { dispatchMouseEvent as dispatchMouseEvent2 } from "@vuu-ui/vuu-utils";
3809
+ import { useCallback as useCallback23, useRef as useRef17 } from "react";
3810
+ var useControlledTableNavigation = (initialValue, rowCount) => {
3811
+ const tableRef = useRef17(null);
3812
+ const [highlightedIndexRef, setHighlightedIndex] = useStateRef(initialValue);
3813
+ const handleKeyDown = useCallback23(
3814
+ (e) => {
3815
+ var _a;
3816
+ if (e.key === "ArrowDown") {
3817
+ setHighlightedIndex((index = -1) => Math.min(rowCount - 1, index + 1));
3818
+ } else if (e.key === "ArrowUp") {
3819
+ setHighlightedIndex((index = -1) => Math.max(0, index - 1));
3820
+ } else if (e.key === "Enter" || e.key === " ") {
3821
+ const { current: rowIdx } = highlightedIndexRef;
3822
+ const rowEl = (_a = tableRef.current) == null ? void 0 : _a.querySelector(
3823
+ `[aria-rowindex="${rowIdx}"]`
3824
+ );
3825
+ if (rowEl) {
3826
+ dispatchMouseEvent2(rowEl, "click");
3827
+ }
3828
+ }
3829
+ },
3830
+ [highlightedIndexRef, rowCount, setHighlightedIndex]
3831
+ );
3832
+ const handleHighlight = useCallback23(
3833
+ (idx) => {
3834
+ setHighlightedIndex(idx);
3835
+ },
3836
+ [setHighlightedIndex]
3837
+ );
3838
+ return {
3839
+ highlightedIndexRef,
3840
+ onHighlight: handleHighlight,
3841
+ onKeyDown: handleKeyDown,
3842
+ tableRef
3843
+ };
3844
+ };
3845
+ export {
3846
+ CheckboxCell,
3847
+ GroupHeaderCellNext,
3848
+ HeaderCell,
3849
+ InputCell,
3850
+ Table,
3851
+ TableCell,
3852
+ TableGroupCell,
3853
+ ToggleCell,
3854
+ isShowColumnSettings,
3855
+ isShowTableSettings,
3856
+ noScrolling,
3857
+ updateTableConfig,
3858
+ useControlledTableNavigation,
3859
+ useTableModel,
3860
+ useTableScroll,
3861
+ useTableViewport
3862
+ };
2
3863
  //# sourceMappingURL=index.js.map