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