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