@progress/kendo-react-treelist
Version:
React TreeList enables the display of self-referencing tabular data. KendoReact TreeList package
9 lines (8 loc) • 16.6 kB
JavaScript
/**
* @license
*-------------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the package root for more information
*-------------------------------------------------------------------------------------------
*/
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const J=require("react"),a=require("prop-types"),g=require("@progress/kendo-react-common"),h=require("@progress/kendo-react-data-tools"),H=require("./utils/index.js"),Q=require("./cells/TreeListCell.js"),X=require("./TreeListNoRecords.js"),Y=require("./rows/TreeListRow.js"),P=require("./package-metadata.js");function Z(y){const l=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(y){for(const e in y)if(e!=="default"){const t=Object.getOwnPropertyDescriptor(y,e);Object.defineProperty(l,e,t.get?t:{enumerable:!0,get:()=>y[e]})}}return l.default=y,Object.freeze(l)}const c=Z(J),F=class F extends c.Component{constructor(l){super(l),this.element=null,this.wrapperScrollLeft=0,this.wrapperScrollTop=0,this.updateOnScroll=!1,this.tbodyOffsetTop=0,this.prevData=[],this.flattedData=[],this.extendedColumn=[],this.columnsMap=[],this.contextStateRef={current:void 0},this.navigationStateRef={current:void 0},this.showLicenseWatermark=!1,this.licenseMessage=void 0,this.scrollIntoView=e=>{if(!this.element)return;const{rowIndex:t=0}=e,{scrollable:o,rowHeight:s=0}=this.props;if(o==="virtual"||s)this.element.scroll(0,(t-1)*s);else{const r=this.element.querySelector(`tbody > tr:nth-child(${t})`);if(r){const i=r.offsetTop-this.tbodyOffsetTop;this.element.scroll(0,i)}}},this.getExtendedColumn=g.memoizeOne((e,t)=>h.readColumns(e,{prevId:0,idPrefix:t})),this.getColumnsMap=g.memoizeOne((e,t)=>h.mapColumns(e,t)),this.onKeyDown=e=>{if(h.tableKeyboardNavigation.onKeyDown(e,{navigatable:!1,contextStateRef:this.contextStateRef,navigationStateRef:this.navigationStateRef}),this.props.onKeyDown){const{mode:t,cell:o}=h.getSelectionOptions(this.props.selectable),s={dataItems:this.getLeafDataItems(),mode:t,cell:o,componentId:this._treeListId,selectedField:this.props.selectedField,...this.getArguments(e)};this.props.onKeyDown.call(void 0,s)}},this.onFocus=e=>{h.tableKeyboardNavigation.onFocus(e,{contextStateRef:this.contextStateRef})},this.onRowDrag=e=>{this.props.onRowDrag&&this.props.onRowDrag.call(void 0,{...e,target:this})},this.onRowDrop=e=>{this.props.onRowDrop&&this.props.onRowDrop.call(void 0,{...e,target:this})},this.columnReorder=(e,t,o)=>{const s=this.extendedColumn[e].depth,r=p=>{do p++;while(p<this.extendedColumn.length&&this.extendedColumn[p].depth>s);return p},i=this.extendedColumn.splice(e,r(e)-e);if(this.extendedColumn.splice(e<t?r(t-i.length):t,0,...i),this.extendedColumn.filter(p=>p.declarationIndex>=0).forEach((p,m)=>p.orderIndex=m),this.props.onColumnReorder){const p={target:this,columns:this.columns,nativeEvent:o};this.props.onColumnReorder.call(void 0,p)}},this.onResize=(e,t,o,s,r)=>{if(this.props.onColumnResize){const i=this.extendedColumn.filter(m=>m.children.length===0).reduce((m,C)=>m+=parseFloat(String(C.width)),0),p={columns:this.columns,totalWidth:i,index:e,nativeEvent:s,newWidth:t,oldWidth:o,end:r,target:this};this.props.onColumnResize.call(void 0,p)}},this.handleOnScroll=e=>{const t=e.currentTarget.scrollLeft,o=e.currentTarget.scrollTop,{columnVirtualization:s,scrollable:r,rowHeight:i=0}=this.props,p=i,m=0;let C=!1;s&&Math.abs(this.wrapperScrollLeft-t)>m&&(this.wrapperScrollLeft=t,C=!0),r==="virtual"&&Math.abs(this.wrapperScrollTop-o)>p&&(this.wrapperScrollTop=o,C=!0),C&&(this.updateOnScroll=!0,this.forceUpdate())},this.calculateSizes=e=>{if(!e||this.props.scrollable==="none")return;const t=Array.from(e.childNodes),o=t.find(i=>i.nodeName==="TABLE"),s=this.props.toolbar&&t.find(i=>i.nodeType===1&&i.classList.contains("k-grid-toolbar"));let r=0;if(s){const i=s.style.boxSizing;s.style.boxSizing="border-box",r=parseFloat(String(window.getComputedStyle(s).height))||s.offsetHeight,s.style.boxSizing=i,s.getAttribute("style")||s.removeAttribute("style")}this.tbodyOffsetTop=o.tBodies[0].offsetTop,H.setHeaderRowsTop(o,r)},this.itemChange=e=>{const t=this.props.onItemChange;if(e.field===this.props.expandField){const o=this.props.onExpandChange;if(o){const s={...this.getArguments(e.syntheticEvent),dataItem:e.dataItem,level:e.level,value:e.value};o.call(void 0,s)}return}if(t){const o={...this.getArguments(e.syntheticEvent),dataItem:e.dataItem,level:e.level,field:e.field,value:e.value};t.call(void 0,o)}},this.onHeaderSelectionChange=e=>{if(this.props.onHeaderSelectionChange){const t={field:e.field,nativeEvent:e.syntheticEvent&&e.syntheticEvent.nativeEvent,syntheticEvent:e.syntheticEvent,target:this,dataItems:this.getLeafDataItems()};this.props.onHeaderSelectionChange.call(void 0,t)}},this.selectionRelease=e=>{if(this.props.onSelectionChange){const t={syntheticEvent:void 0,target:this,selectedField:this.props.selectedField||"",componentId:this._treeListId,dataItems:this.getLeafDataItems(),dataItem:null,level:[],...e};this.props.onSelectionChange.call(void 0,t)}},this.sortChange=(e,t,o)=>{this.raiseDataEvent(this.props.onSortChange,{sort:t,field:o},e)},this.headerFilterChange=(e,t,o)=>{this.raiseDataEvent(this.props.onFilterChange,{filter:t,field:o},e)},this.filterChange=e=>{const{filter:t,field:o}=e;this.raiseDataEvent(this.props.onFilterChange,{filter:t,field:o},e.syntheticEvent)},this.columnMenuFilterChange=(e,t,o)=>{const{onColumnMenuFilterChange:s}=this.props;if(!s)return;const r={syntheticEvent:e,filter:t,field:o,target:this,nativeEvent:e.nativeEvent};s.call(void 0,r)},this.expandChange=(e,t,o)=>{const{expandField:s,onExpandChange:r}=this.props;if(s&&r){const i={...this.getArguments(e),dataItem:t,level:o,value:this.expanded(t)};r.call(void 0,i)}},this.rowClick=(e,t)=>{if(this.props.onRowClick&&e.target.nodeName==="TD"){const o={dataItem:t.dataItem,level:t.level,...this.getArguments(e)};this.props.onRowClick.call(void 0,o)}},this.rowDoubleClick=(e,t)=>{if(this.props.onRowDoubleClick&&e.target.nodeName==="TD"){const o={dataItem:t.dataItem,level:t.level,...this.getArguments(e)};this.props.onRowDoubleClick.call(void 0,o)}},this.rowContextMenu=(e,t)=>{if(this.props.onRowContextMenu&&e.target.nodeName==="TD"){const o={dataItem:t.dataItem,level:t.level,...this.getArguments(e)};this.props.onRowContextMenu.call(void 0,o)}},this.onPageChange=e=>{if(this.props.onPageChange){const t={...this.getArguments(e.syntheticEvent),skip:e.skip,take:e.take};this.props.onPageChange.call(void 0,t)}},this.expandedSubItems=e=>{const t=[];return this.expanded(e)&&this.hasChildren(e)&&t.push(...g.getNestedValue(this.props.subItemsField,e)),t},this.getLeafDataItems=()=>this.flatData.map(e=>e.dataItem),this.expanded=e=>!!g.getNestedValue(this.props.expandField,e),this.hasChildren=e=>!!g.getNestedValue(this.props.subItemsField,e),this.showLicenseWatermark=!g.validatePackage(P.packageMetadata,{component:"TreeList"}),this.licenseMessage=g.getLicenseMessage(P.packageMetadata),this.dragLogic=new h.CommonDragLogic(this.columnReorder,g.noop,g.noop),this.columnResize=new h.ColumnResize(this.onResize.bind(this)),h.tableKeyboardNavigation.onConstructor({navigatable:!!l.navigatable,contextStateRef:this.contextStateRef,navigationStateRef:this.navigationStateRef})}get _treeListId(){return this.props.id+"-treelist"}get document(){if(g.canUseDOM)return this.element&&this.element.ownerDocument||document}componentDidMount(){this.calculateSizes(this.element),h.tableKeyboardNavigation.onComponentDidMount({scope:this.element||void 0,contextStateRef:this.contextStateRef,navigationStateRef:this.navigationStateRef})}getSnapshotBeforeUpdate(){return h.tableKeyboardNavigation.onGetSnapshotBeforeUpdate({document:this.document,contextStateRef:this.contextStateRef,navigationStateRef:this.navigationStateRef}),null}componentDidUpdate(l){l.columns!==this.props.columns&&this.calculateSizes(this.element),h.tableKeyboardNavigation.onComponentDidUpdate({scope:this.element||void 0,contextStateRef:this.contextStateRef,navigationStateRef:this.navigationStateRef})}componentWillUnmount(){this.columnsMap=[],this.prevData=[],this.flattedData=[],this.updateOnScroll=!1,this.getExtendedColumn.clear(),this.getColumnsMap.clear()}render(){const{columns:l=[],filterRow:e,scrollable:t="scrollable",resizable:o=!1,reorderable:s=!1,skip:r,take:i}=this.props,p=l.some(n=>!!n.filter||!!n.filterCell)||e!==void 0,m=e||h.FilterRow,C=h.tableKeyboardNavigationTools.getIdPrefix(this.navigationStateRef),T=this.getExtendedColumn(l,C),z=T.length!==this.extendedColumn.length;this.extendedColumn=T,this.columnsMap=this.getColumnsMap(this.extendedColumn,z);const b=this.extendedColumn.filter(n=>n.children.length===0);this.columnResize.columns=this.extendedColumn,this.columnResize.resizable=o,this.dragLogic.columns=this.extendedColumn,this.dragLogic.reorderable=s,this.dragLogic.groupable=!1;const D=c.createElement(h.Header,{headerRow:c.createElement(h.HeaderRow,{sort:this.props.sort,sortable:this.props.sortable,sortChange:this.sortChange,selectionChange:this.onHeaderSelectionChange,columns:this.extendedColumn,columnsMap:this.columnsMap,cellRender:this.props.headerCellRender,columnResize:this.columnResize,columnMenu:this.props.columnMenu,columnMenuFilter:this.props.columnMenuFilter,columnMenuFilterChange:this.columnMenuFilterChange,pressHandler:this.dragLogic.pressHandler,dragHandler:this.dragLogic.dragHandler,releaseHandler:this.dragLogic.releaseHandler,filterChange:this.headerFilterChange}),reorderable:this.props.reorderable,filterRow:p&&c.createElement(m,{columns:b,filter:this.props.filter,filterChange:this.filterChange,sort:this.props.sort,ariaRowIndex:this.columnsMap.length+1})||void 0,columnResize:this.columnResize}),M=this.props.style||{},{colSpans:A,hiddenColumns:V}=h.tableColumnsVirtualization({enabled:this.props.columnVirtualization,columns:b,scrollLeft:this.wrapperScrollLeft,tableViewPortWidth:parseFloat((M.width||"").toString())}),B=(n,f,I,E,k,x)=>b.map((d,u)=>{if(V[u])return null;const R=d.id?d.id:u,L=`${d.className?d.className+" ":""}${d.locked?"k-grid-content-sticky":""}`,w={id:h.tableKeyboardNavigationTools.generateNavigatableId(`${I}-${String(u)}`,C),colSpan:A[u],dataItem:n.dataItem,field:d.field,format:d.format,className:L||void 0,render:this.props.cellRender,onChange:this.itemChange,selectionChange:this.props.onSelectionChange?S=>{this.selectionChange({event:S,item:n,columnIndex:u,dataIndex:k})}:void 0,level:n.level,expandable:d.expandable,expanded:E,hasChildren:this.hasChildren(n.dataItem),onExpandChange:this.expandChange,colIndex:u,ariaColumnIndex:d.ariaColumnIndex,style:d.left!==void 0&&{left:d.left,right:d.right,borderRightWidth:d.rightBorder?"1px":""}||{},isSelected:Array.isArray(x)&&x.indexOf(u)>-1};return f&&d.editCell?c.createElement(d.editCell,{key:R,...w,onChange:this.itemChange}):d.cell?c.createElement(d.cell,{key:R,...w}):c.createElement(Q.TreeListCell,{key:R,...w})});let v=this.flatData;const O=v.length;r!==void 0&&i!==void 0&&(v=v.slice(r,r+i)),t==="virtual"&&(v=H.tableRowsVirtualization({rows:v,tableViewPortHeight:parseFloat((M.height||M.maxHeight||"").toString()),scrollTop:this.wrapperScrollTop}),this.updateOnScroll=!1);const U=v.map(n=>n.level),j=this.columnsMap.length+(p?1:0)+1,q=v.length>0&&v.map((n,f)=>{const I=g.getNestedValue(this.props.editField,n.dataItem),E=this.props.dataItemKey&&g.getter(this.props.dataItemKey)(n.dataItem),k=String(E||n.level.join(".")),x=this.expanded(n.dataItem),d=this.props.selectedField?g.getNestedValue(this.props.selectedField,n.dataItem):void 0,u={key:k,level:n.level,levels:U,dataItem:n.dataItem,selectedField:this.props.selectedField,rowHeight:t==="virtual"?n.height:this.props.rowHeight,render:this.props.rowRender,onDrop:this.onRowDrop,onDrag:this.onRowDrag,onClick:S=>this.rowClick(S,n),onDoubleClick:S=>this.rowDoubleClick(S,n),onContextMenu:S=>this.rowContextMenu(S,n),isAltRow:f%2!==0,expanded:x,rowIndex:f,ariaRowIndex:j+f,ariaSetSize:n.levelCount,ariaPosInSet:n.level[n.level.length-1]+1,isSelected:typeof d=="boolean"&&d},R=this.props.editRow,L=this.props.row||Y.TreeListRow,w=B(n,I,k,x,f,d);return I&&R?c.createElement(R,{...u,key:u.key},w):c.createElement(L,{...u,key:u.key},w)})||c.createElement("tr",{className:"k-table-row k-grid-norecords"},c.createElement("td",{colSpan:b.length},this.props.noRecords||c.createElement(X.TreeListNoRecords,null))),W=n=>this.props.sort&&this.props.sort.some(f=>f.field===n),_=c.createElement("colgroup",{ref:n=>{this.columnResize.colGroupMain=n}},b.map((n,f)=>c.createElement("col",{key:f.toString(),className:W(n.field)?"k-sorted":void 0,style:n.width!==void 0?{width:n.width}:void 0}))),$=this.props.columnVirtualization||this.props.scrollable==="virtual",G=this.props.selectable&&this.props.selectable.drag?"none":void 0,K=this.props.tableProps||{};return c.createElement(h.TableKeyboardNavigationContext.Provider,{value:this.contextStateRef.current},c.createElement("div",{id:this.props.id,style:this.props.style,className:g.classNames("k-grid k-grid-md","k-treelist",this.props.className,{"k-treelist-scrollable":t!=="none"}),ref:n=>{this.element=n},onScroll:$?this.handleOnScroll:void 0,onKeyDown:this.onKeyDown,onFocus:this.onFocus,"aria-rowcount":O,"aria-colcount":b.length,role:"treegrid",...h.tableKeyboardNavigationScopeAttributes},this.props.toolbar,c.createElement(h.TableSelection,{selectable:this.props.selectable,onRelease:this.selectionRelease},c.createElement("table",{className:"k-table k-table-md k-grid-table",...K,style:{...K.style||{},userSelect:G},role:"presentation"},_,D,c.createElement("tbody",{className:"k-table-tbody",...h.tableKeyboardNavigationBodyAttributes,role:"presentation"},q))),this.props.pager&&c.createElement(this.props.pager,{className:"k-grid-pager",total:O,skip:r,take:i,onPageChange:this.onPageChange}),s&&c.createElement(c.Fragment,null,c.createElement(h.DropClue,{ref:this.dragLogic.refDropElementClue}),c.createElement(h.DragClue,{ref:this.dragLogic.refDragElementClue})),this.showLicenseWatermark&&c.createElement(g.WatermarkOverlay,{message:this.licenseMessage})))}get columns(){const l=this.extendedColumn.filter(t=>t.declarationIndex>=0&&t.parentIndex===-1),e=t=>(t.sort((o,s)=>o.declarationIndex-s.declarationIndex),t.map(o=>{const{declarationIndex:s,parentIndex:r,depth:i,colSpan:p,rowSpan:m,index:C,kFirst:T,groupable:z,children:b,...D}=o;return b.length?{children:e(b),...D}:D}));return e(l)}get flatData(){const{data:l=[],rowHeight:e=0}=this.props;let t=0;const o=r=>{const i={height:e,offsetTop:t};return t+=i.height,i},s=this.updateOnScroll&&this.prevData===l&&this.tbodyOffsetTop>0&&this.flattedData.length?this.flattedData:h.flatData(l,this.expandedSubItems,o);return this.prevData=l,this.flattedData=s,s}selectionChange(l){if(this.props.onSelectionChange){const{event:e,item:t,dataIndex:o,columnIndex:s}=l,{mode:r,cell:i}=h.getSelectionOptions(this.props.selectable),p={...this.getArguments(e.syntheticEvent),dataItem:t.dataItem,level:t.level,startColIndex:s,endColIndex:s,startRowIndex:o,endRowIndex:o,dataItems:this.getLeafDataItems(),altKey:!1,ctrlKey:!1,shiftKey:!1,metaKey:!1,mode:r,cell:i,isDrag:!1,componentId:this._treeListId,selectedField:this.props.selectedField||""};this.props.onSelectionChange.call(void 0,p)}}raiseDataEvent(l,e,t){const o=this.props.onDataStateChange;if(l)l.call(void 0,{...this.getArguments(t),...e});else if(o){const s={...this.getArguments(t),dataState:{...this.getDataState(),...e}};o.call(void 0,s)}}getDataState(){return{filter:this.props.filter,sort:this.props.sort}}getArguments(l){return{nativeEvent:l&&l.nativeEvent,syntheticEvent:l,target:this}}};F.propTypes={data:a.array,resizable:a.bool,reorderable:a.bool,sortable:a.oneOfType([a.bool,a.shape({mode:a.oneOf(["single","multiple"]),allowUnsort:a.bool})]),onSortChange:a.func,sort:a.array,columns:a.arrayOf(a.object),columnVirtualization:a.bool,filter:a.array,onFilterChange:a.func,filterRow:a.any,toolbar:a.any,noRecords:a.any,onExpandChange:a.func,expandField:a.string,subItemsField:a.string,selectedField:a.string,onSelectionChange:a.func,onHeaderSelectionChange:a.func,onRowClick:a.func,onItemChange:a.func,editField:a.string,scrollable:a.oneOf(["none","scrollable","virtual"]),rowHeight:a.number,style:a.object,tableProps:a.object,pager:a.any,skip:a.number,take:a.number,onPageChange:a.func,onDataStateChange:a.func,onColumnResize:a.func,onColumnReorder:a.func,dataItemKey:a.string,navigatable:a.bool},F.contextType=h.TableKeyboardNavigationContext;let N=F;exports.TreeList=N;