diff --git a/README.md b/README.md index 6c0dd12..7369991 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,123 @@ # react-widget-tree-basic -`npm install --save react-widget-tree-basic` +Tree基础组件 + + +## 安装 + +``` +npm install --save react-widget-tree-basic +``` + +## 使用 + +[![Edit react-widget-tree-basic](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-widget-tree-basic-bsqjd?fontsize=14&hidenavigation=1&theme=dark) + +```js + +import TreeBasic from 'react-widget-tree-basic'; + +export default () => + +``` + +### Interfaces + +```ts +export interface TreeProps { + /** 样式前缀 */ + prefixCls: string; + /** 样式名称 */ + className?: string; + /** 样式属性 */ + style?: React.CSSProperties; + /** 树根节点ID */ + rootId: string | number | null; + /** tree 数据结构 id 属性名称 */ + idField: string; + /** tree 数据结构 leaf 属性名称 */ + leafField: string; + /** tree 数据结构 parent 属性名称 */ + pidField: string; + /** 最大展开层级限制没,默认:99 */ + maxDepth: number; + /** 异步检测耗时机制,超过该时长即认定为异步加载,默认:16 ms */ + asyncTestDelay: number; + /** 已展开的节点ID */ + expandedIds: (string | number)[]; + /** Tree数据加载器,必填 */ + loadData: (data: T, node: Node) => T[] | Promise; + /** 自定义TreeNode的render返回 */ + nodeRender?: (props: nodeRenderProps, item: React.ReactNode, children: React.ReactNode) => React.ReactNode; + /** 自定义TreeItem的render返回,必填 */ + itemRender: (props: itemRenderProps) => React.ReactNode; + /** 自定义TreeNode的子节点渲染,一般动画需要使用。*/ + childrenRender: (props: childrenRenderProps) => React.ReactNode; + /** 异步加载时的加载内容返回,默认为:null */ + loadRender?: (props: LoadRenderProps) => React.ReactNode; + /** 自定义Tree容器组件*/ + rootComponent: React.ElementType; +} + +export declare type renderProps = Omit, "render" | "childrenRender">; +export interface TreeNodeProps { + node: Node; + isRoot: boolean; + render?: (props: renderProps, nodeItem: React.ReactNode, children: React.ReactNode) => React.ReactNode; +} + +export interface TreeNodeProps { + node: Node; + isRoot: boolean; + render?: ( + props: renderProps, + nodeItem: React.ReactNode, + children: React.ReactNode + ) => React.ReactNode; +} +export interface childrenRenderProps { + getChildren: () => React.ReactNode; + expanded: boolean; + loading: boolean; + root: boolean; + node: Node; + data: T; +} +export interface itemRenderProps { + expanded: boolean; + loading: boolean; + leaf: boolean; + node: Node; + data: T; +} +export declare function toMarked(array: any[]): any; +export declare type DataType = Record; +export declare type IdType = string | number; +export declare type nodeRenderProps = renderProps; +export interface LoadRenderProps { + root: boolean; + node: Node; + data: T; +} + +``` + +### defaultProps + +```js +{ + prefixCls: "rw-tree", + rootId: null, + idField: "id", + leafField: "leaf", + pidField: "pid", + maxDepth: 99, + asyncTestDelay: 16, + expandedIds: [], + childrenRender(props) { + if (!props.expanded) return null; + return props.getChildren(); + }, + rootComponent: "div", +} +``` diff --git a/docs/asset-manifest.json b/docs/asset-manifest.json index 2df6efc..422fdc9 100644 --- a/docs/asset-manifest.json +++ b/docs/asset-manifest.json @@ -1,6 +1,6 @@ { - "index.css": "static/css/index.a0a710ab.chunk.css", - "index.js": "static/js/index.a0a710ab.chunk.js", + "index.css": "static/css/index.387855a9.chunk.css", + "index.js": "static/js/index.387855a9.chunk.js", "runtime-index.js": "static/js/runtime-index.92eae014.js", "static/js/2.e9b6bfc8.chunk.js": "static/js/2.e9b6bfc8.chunk.js", "index.html": "index.html" diff --git a/docs/index.html b/docs/index.html index 6a5eff8..d596933 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1 +1 @@ -Tree Basic
\ No newline at end of file +Tree Basic
\ No newline at end of file diff --git a/docs/static/css/index.a0a710ab.chunk.css b/docs/static/css/index.387855a9.chunk.css similarity index 100% rename from docs/static/css/index.a0a710ab.chunk.css rename to docs/static/css/index.387855a9.chunk.css diff --git a/docs/static/js/index.387855a9.chunk.js b/docs/static/js/index.387855a9.chunk.js new file mode 100644 index 0000000..d425af4 --- /dev/null +++ b/docs/static/js/index.387855a9.chunk.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[0],{118:function(e,d,l){},119:function(e,d,l){},126:function(e,d,l){"use strict";l.r(d);var a=l(0),i=l.n(a),t=l(80),p=l.n(t),u=(l(118),l(119),l(43),l(26),l(4)),r=l.n(u),f=l(7),h=l.n(f),v=l(1),n=l.n(v),b=(l(76),l(78),l(22)),o=(l(120),l(121),l(81)),s=l.n(o),c=i.a.createContext({tree:{}}),m=1,g=function(){function e(e,d,l,a){void 0===l&&(l={}),void 0===a&&(a={}),n()(this,"id",void 0),n()(this,"pid",void 0),n()(this,"leaf",void 0),n()(this,"data",void 0),n()(this,"loading",void 0),n()(this,"root",void 0),n()(this,"expanded",void 0),n()(this,"depth",void 0);var i=l,t=i.rootId,p=void 0===t?null:t,u=i.idField,r=void 0===u?"id":u,f=i.pidField,h=void 0===f?"pid":f,v=i.leafField,b=void 0===v?"leaf":v,o=a.expandedMap,s=void 0===o?{}:o;this.id=e[r],this.pid=e[h],this.leaf=e[b],this.data=e,null==this.id&&this.id!==p&&(this.id="node_"+m++),this.loading=!1,this.root=!d,this.expanded=!!this.root||!!s[this.id],this.depth=d?d.depth+1:0}var d=e.prototype;return d.getId=function(){return this.id},d.getDepth=function(){return this.depth},d.setDepth=function(e){this.depth=e},d.getData=function(){return this.data},d.isRoot=function(){return this.root},d.isLeaf=function(){return this.leaf},d.setExpanded=function(e){this.expanded=e},d.isExpanded=function(){return this.expanded},d.setLoading=function(e){this.loading=e},d.isLoading=function(){return this.loading},e}(),x=(l(123),l(82)),C=l.n(x),D=function(e){function d(d,l){var a;return a=e.call(this,d,l)||this,n()(r()(a),"context",void 0),a.state={isLoading:!1},a}h()(d,e);var l=d.prototype;return l.getTree=function(){return this.context.tree},l.getTreeProps=function(){return this.getTree().props},l.getNodeList=function(e){var l=this.getTree(),a=this.props.node,t=this.getTreeProps(),p=l.state;return e.map((function(e,l){var u=new g(e,a,t,p);return i.a.createElement(d,{render:t.nodeRender,node:u,key:u.getId()})}))},l.loadNodeChildren=function(){var e=this,d=this.props,l=d.node,a=d.isRoot,i=this.state.isLoading,t=this.getTreeProps(),p=t.loadData,u=t.asyncTestDelay,r=t.loadRender;if(i)return r?r({root:a,node:l,data:l.data}):null;var f=null,h=function(){f&&(clearTimeout(f),f=null),l.setLoading(!1),e.setState({isLoading:!1})},v=h,n=p(l.data,l);return C()(n)?(f=setTimeout((function(){f=null,l.setLoading(!0),e.setState({isLoading:!0})}),u),n.then(h,v),null):this.getNodeList(n)},l.renderNodeChildren=function(){var e=this,d=this.getTreeProps(),l=d.maxDepth,a=d.childrenRender,i=this.props,t=i.node,p=i.isRoot,u=t.isLeaf(),r=!u&&t.isExpanded();return r&&t.getDepth()>=l||u?null:a({getChildren:function(){return e.loadNodeChildren()},loading:t.isLoading(),root:p,expanded:r,node:t,data:t.data})},l.render=function(){var e=this,d=this.props,l=d.node,a=d.isRoot,t=d.render,p=this.getTreeProps(),u=p.itemRender,r=p.childrenRender;if(a)return r({getChildren:function(){return e.loadNodeChildren()},loading:l.isLoading(),root:!0,expanded:!0,node:l,data:l.data});var f=u({node:l,loading:l.isLoading(),leaf:l.isLeaf(),data:l.getData(),expanded:l.isExpanded()});return t?t(this.props,f,this.renderNodeChildren()):i.a.createElement(i.a.Fragment,null,f,this.renderNodeChildren())},d}(i.a.Component);n()(D,"defaultProps",{node:{},isRoot:!1}),n()(D,"contextType",c);var I=D;function y(e){var d=Object.create(null);return e.forEach((function(e){d[e]=!0})),d}var E=function(e){function d(d){var l;return(l=e.call(this,d)||this).state={expandedIds:[],expandedMap:{}},l}h()(d,e),d.getDerivedStateFromProps=function(e){return{expandedIds:e.expandedIds,expandedMap:y(e.expandedIds||[])}};var l=d.prototype;return l.getRootNode=function(){var e,d=this.props,l=d.rootId,a=d.idField,i=d.pidField,t=d.leafField;return new g(((e={})[a]=l,e[i]=null,e[t]=!1,e),null,this.props,this.state)},l.getContext=function(){return{tree:this}},l.render=function(){var e,d=this.props,l=d.prefixCls,a=d.className,t=d.style,p=d.rootComponent,u=d.itemRender,r=d.loadData;if(!u)throw new Error("react-widget-tree-basic: itemRender cannot be empty.");if(!r)throw new Error("react-widget-tree-basic: loadData cannot be empty.");var f=s()(((e={})[l]=!0,e[a]=a,e));return i.a.createElement(c.Provider,{value:this.getContext()},i.a.createElement(p,{className:f,style:t},i.a.createElement(I,{node:this.getRootNode(),isRoot:!0})))},d}(i.a.Component);n()(E,"defaultProps",{prefixCls:"rw-tree",rootId:null,idField:"id",leafField:"leaf",pidField:"pid",maxDepth:99,asyncTestDelay:16,expandedIds:[],childrenRender:function(e){return e.expanded?e.getChildren():null},rootComponent:"div"});var w=E,N=l(21),L=function(e){function d(d){var l;return l=e.call(this,d)||this,n()(r()(l),"state",{expandedIds:[1]}),n()(r()(l),"loadData",(function(e){return console.log("loadData",e),l.store.getChildren(e.id).map((function(e){return e.data}))})),n()(r()(l),"renderItem",(function(e){var d=e.data,a=e.node;return console.log("renderItem",e),i.a.createElement("div",{className:"rw-tree-item",style:{paddingLeft:16*(a.getDepth()-1)},onClick:l.handleNodeClick.bind(r()(l),d)},i.a.createElement("span",{style:{display:"inline-block",width:20,textAlign:"center"}},e.leaf?"":e.expanded?" [-] ":" [+] "),d.label,"(id:",d.id,")")})),l.store=new b.a(N,{simpleData:!0}),l}h()(d,e);var l=d.prototype;return l.handleNodeClick=function(e){if(!e.leaf){var d=this.state.expandedIds;if(-1===d.indexOf(e.id))this.setState({expandedIds:[].concat(d,[e.id])});else{var l=d.indexOf(e.id);d.splice(l,1),this.setState({expandedIds:[].concat(d)})}}},l.render=function(){var e=this.state.expandedIds;return i.a.createElement(w,{expandedIds:e,loadData:this.loadData,itemRender:this.renderItem})},d}(a.Component),R=(l(124),l(63),new b.a(N,{simpleData:!0})),T=[{label:"\u57fa\u672c\u529f\u80fd",component:L},{label:"\u5f02\u6b65\u52a0\u8f7d",component:function(e){function d(d){var l;return l=e.call(this,d)||this,n()(r()(l),"state",{expandedIds:[1,3,8]}),n()(r()(l),"localData",Object.create(null)),n()(r()(l),"loadData",(function(e){console.log("loadData",e);var d=e.id;return l.localData[d]?l.localData[d]:new Promise((function(a){setTimeout((function(){l.localData[d]=R.getChildren(e.id).map((function(e){return e.data})),a()}),500)}))})),n()(r()(l),"renderItem",(function(e){var d=e.data,a=e.node;return console.log("renderItem",e),i.a.createElement("div",{className:"rw-tree-item",style:{paddingLeft:16*(a.getDepth()-1)},onClick:l.handleNodeClick.bind(r()(l),d)},i.a.createElement("span",{style:{display:"inline-block",width:20,textAlign:"center"}},e.leaf?"":e.expanded?" [-] ":" [+] "),d.label,"(id:",d.id,")",e.loading?i.a.createElement("span",{style:{marginLeft:8,fontSize:12,color:"#ccc"}},"\u52a0\u8f7d\u4e2d..."):null)})),l.store=new b.a(N,{simpleData:!0}),l}h()(d,e);var l=d.prototype;return l.handleNodeClick=function(e){if(!e.leaf){var d=this.state.expandedIds;if(-1===d.indexOf(e.id))this.setState({expandedIds:[].concat(d,[e.id])});else{var l=d.indexOf(e.id);d.splice(l,1),this.setState({expandedIds:[].concat(d)})}}},l.render=function(){var e=this.state.expandedIds;return i.a.createElement(w,{loadRender:function(e){return e.root?"\u52a0\u8f7d\u4e2d...":null},expandedIds:e,loadData:this.loadData,itemRender:this.renderItem})},d}(a.Component)}],k=function(e){function d(){for(var d,l=arguments.length,a=new Array(l),i=0;i=l||u?null:a({getChildren:function(){return e.loadNodeChildren()},loading:t.isLoading(),root:p,expanded:r,node:t,data:t.data})},l.render=function(){var e=this,d=this.props,l=d.node,a=d.isRoot,t=d.render,p=this.getTreeProps(),u=p.itemRender,r=p.childrenRender;if(a)return r({getChildren:function(){return e.loadNodeChildren()},loading:l.isLoading(),root:!0,expanded:!0,node:l,data:l.data});var f=u({node:l,loading:l.isLoading(),leaf:l.isLeaf(),data:l.getData(),expanded:l.isExpanded()});return t?t(this.props,f,this.renderNodeChildren()):i.a.createElement(i.a.Fragment,null,f,this.renderNodeChildren())},d}(i.a.Component);n()(D,"defaultProps",{node:{},isRoot:!1}),n()(D,"contextType",c);var I=D;function y(e){void 0===e&&(e=[]);var d=Object.create(null);return e.forEach((function(e){d[e]=!0})),d}var E=function(e){function d(d){var l;return(l=e.call(this,d)||this).state={expandedIds:[],expandedMap:{}},l}h()(d,e),d.getDerivedStateFromProps=function(e){return{expandedIds:e.expandedIds,expandedMap:y(e.expandedIds)}};var l=d.prototype;return l.getRootNode=function(){var e,d=this.props,l=d.rootId,a=d.idField,i=d.pidField,t=d.leafField;return new g(((e={})[a]=l,e[i]=null,e[t]=!1,e),null,this.props,this.state)},l.getContext=function(){return{tree:this}},l.render=function(){var e,d=this.props,l=d.prefixCls,a=d.className,t=d.style,p=d.rootComponent;if(!d.itemRender)throw new Error("react-widget-tree-basic: itemRender cannot be empty.");var u=s()(((e={})[l]=!0,e[a]=a,e));return i.a.createElement(c.Provider,{value:this.getContext()},i.a.createElement(p,{className:u,style:t},i.a.createElement(I,{node:this.getRootNode(),isRoot:!0})))},d}(i.a.Component);n()(E,"defaultProps",{prefixCls:"rw-tree",rootId:null,idField:"id",leafField:"leaf",pidField:"pid",maxDepth:99,asyncTestDelay:16,expandedIds:[],childrenRender:function(e){return e.expanded?e.getChildren():null},rootComponent:"div"});var N=E,w=l(21),L=function(e){function d(d){var l;return l=e.call(this,d)||this,n()(r()(l),"state",{expandedIds:[1]}),n()(r()(l),"loadData",(function(e){return console.log("loadData",e),l.store.getChildren(e.id).map((function(e){return e.data}))})),n()(r()(l),"renderItem",(function(e){var d=e.data,a=e.node;return console.log("renderItem",e),i.a.createElement("div",{className:"rw-tree-item",style:{paddingLeft:16*(a.getDepth()-1)},onClick:l.handleNodeClick.bind(r()(l),d)},i.a.createElement("span",{style:{display:"inline-block",width:20,textAlign:"center"}},e.leaf?"":e.expanded?" [-] ":" [+] "),d.label,"(id:",d.id,")")})),l.store=new b.a(w,{simpleData:!0}),l}h()(d,e);var l=d.prototype;return l.handleNodeClick=function(e){if(!e.leaf){var d=this.state.expandedIds;if(-1===d.indexOf(e.id))this.setState({expandedIds:[].concat(d,[e.id])});else{var l=d.indexOf(e.id);d.splice(l,1),this.setState({expandedIds:[].concat(d)})}}},l.render=function(){var e=this.state.expandedIds;return i.a.createElement(N,{expandedIds:e,loadData:this.loadData,itemRender:this.renderItem})},d}(a.Component),R=(l(124),l(63),new b.a(w,{simpleData:!0})),T=[{label:"\u57fa\u672c\u529f\u80fd",component:L},{label:"\u5f02\u6b65\u52a0\u8f7d",component:function(e){function d(d){var l;return l=e.call(this,d)||this,n()(r()(l),"state",{expandedIds:[1,3,8]}),n()(r()(l),"localData",Object.create(null)),n()(r()(l),"loadData",(function(e){console.log("loadData",e);var d=e.id;return l.localData[d]?l.localData[d]:new Promise((function(a){setTimeout((function(){l.localData[d]=R.getChildren(e.id).map((function(e){return e.data})),a()}),500)}))})),n()(r()(l),"renderItem",(function(e){var d=e.data,a=e.node;return console.log("renderItem",e),i.a.createElement("div",{className:"rw-tree-item",style:{paddingLeft:16*(a.getDepth()-1)},onClick:l.handleNodeClick.bind(r()(l),d)},i.a.createElement("span",{style:{display:"inline-block",width:20,textAlign:"center"}},e.leaf?"":e.expanded?" [-] ":" [+] "),d.label,"(id:",d.id,")",e.loading?i.a.createElement("span",{style:{marginLeft:8,fontSize:12,color:"#ccc"}},"\u52a0\u8f7d\u4e2d..."):null)})),l.store=new b.a(w,{simpleData:!0}),l}h()(d,e);var l=d.prototype;return l.handleNodeClick=function(e){if(!e.leaf){var d=this.state.expandedIds;if(-1===d.indexOf(e.id))this.setState({expandedIds:[].concat(d,[e.id])});else{var l=d.indexOf(e.id);d.splice(l,1),this.setState({expandedIds:[].concat(d)})}}},l.render=function(){var e=this.state.expandedIds;return i.a.createElement(N,{loadRender:function(e){return e.root?"\u52a0\u8f7d\u4e2d...":null},expandedIds:e,loadData:this.loadData,itemRender:this.renderItem})},d}(a.Component)}],k=function(e){function d(){for(var d,l=arguments.length,a=new Array(l),i=0;i; } -export default class Node { +export default class Node> { id: string | number; pid: string | number; leaf: boolean; - data: Record; + data: T; loading: boolean; root: boolean; expanded: boolean; depth: number; constructor( - data: Record, + data: T, parentNode: Node | null, options: NodeOptions = {}, state: NodeState = {} diff --git a/src/TreeContext.ts b/src/TreeContext.ts index b695f7c..e505d9f 100644 --- a/src/TreeContext.ts +++ b/src/TreeContext.ts @@ -1,7 +1,7 @@ import React from "react"; import Tree from "./index"; -export interface ContextValue { - tree: Tree; +export interface ContextValue { + tree: Tree; } export default React.createContext({ tree: {} as Tree }); diff --git a/src/TreeNode.tsx b/src/TreeNode.tsx index 4081677..d5e779f 100644 --- a/src/TreeNode.tsx +++ b/src/TreeNode.tsx @@ -4,17 +4,14 @@ import isPromise from "is-promise"; import TreeContext, { ContextValue } from "./TreeContext"; import Node from "./Node"; -export interface NodeItemRenderProps { - node: Node; -} - -export type renderProps = Omit; +export type DataType = Record; +export type renderProps = Omit, "render" | "childrenRender">; -export interface TreeNodeProps { - node: Node; +export interface TreeNodeProps { + node: Node; isRoot: boolean; render?: ( - props: renderProps, + props: renderProps, nodeItem: React.ReactNode, children: React.ReactNode ) => React.ReactNode; @@ -24,16 +21,16 @@ export interface TreeNodeState { isLoading: boolean; } -class TreeNode extends React.Component { +class TreeNode extends React.Component, TreeNodeState> { static defaultProps = { node: {}, isRoot: false, }; static contextType = TreeContext; - context: ContextValue; + context: ContextValue; - constructor(props: TreeNodeProps, context: React.ContextType) { + constructor(props: TreeNodeProps, context: React.ContextType) { super(props, context); this.state = { @@ -49,7 +46,7 @@ class TreeNode extends React.Component { return tree.props; } - getNodeList(list: Record[]) { + getNodeList(list: T[]) { const tree = this.getTree(); const { node: pNode } = this.props; const options = this.getTreeProps(); @@ -119,7 +116,7 @@ class TreeNode extends React.Component { const expanded = !leaf && node.isExpanded(); if (expanded && node.getDepth() >= maxDepth) { - warning(false, `maximum depth: ${maxDepth}`); + warning(false, `react-widget-tree-basic: maximum depth: ${maxDepth}`); return null; } diff --git a/src/index.tsx b/src/index.tsx index 6987a1c..e93c192 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -6,24 +6,24 @@ import TreeNode, { renderProps } from "./TreeNode"; export const version = "%VERSION%"; -export interface childrenRenderProps { +export interface childrenRenderProps { getChildren: () => React.ReactNode; expanded: boolean; loading: boolean; root: boolean; - node: Node; - data: Record; + node: Node; + data: T; } -export interface itemRenderProps { +export interface itemRenderProps { expanded: boolean; loading: boolean; leaf: boolean; - node: Node; - data: Record; + node: Node; + data: T; } -export function toMarked(array: any[] = []) { +export function toMarked(array: any[]) { const marked = Object.create(null); array.forEach((value) => { @@ -35,35 +35,50 @@ export function toMarked(array: any[] = []) { export type DataType = Record; export type IdType = string | number; -export type nodeRenderProps = renderProps; +export type nodeRenderProps = renderProps; -export interface LoadRenderProps { +export interface LoadRenderProps { root: boolean; node: Node; - data: Record; + data: T; } -export interface TreeProps { +export interface TreeProps { + /** 样式前缀 */ prefixCls: string; + /** 样式名称 */ className?: string; + /** 样式属性 */ style?: React.CSSProperties; + /** 树根节点ID */ rootId: string | number | null; + /** tree 数据结构 id 属性名称 */ idField: string; + /** tree 数据结构 leaf 属性名称 */ leafField: string; + /** tree 数据结构 parent 属性名称 */ pidField: string; - // labelField: string; - loadData: (data: DataType, node: Node) => DataType[] | Promise; + /** 最大展开层级限制没,默认:99 */ maxDepth: number; + /** 异步检测耗时机制,超过该时长即认定为异步加载,默认:16 ms */ asyncTestDelay: number; + /** 已展开的节点ID */ expandedIds: (string | number)[]; + /** Tree数据加载器,必填 */ + loadData: (data: T, node: Node) => T[] | Promise; + /** 自定义TreeNode的render返回 */ nodeRender?: ( - props: nodeRenderProps, + props: nodeRenderProps, item: React.ReactNode, children: React.ReactNode ) => React.ReactNode; - itemRender: (props: itemRenderProps) => React.ReactNode; - childrenRender: (props: childrenRenderProps) => React.ReactNode; - loadRender?: (props: LoadRenderProps) => React.ReactNode; + /** 自定义TreeItem的render返回,必填 */ + itemRender: (props: itemRenderProps) => React.ReactNode; + /** 自定义TreeNode的子节点渲染,一般动画需要使用。*/ + childrenRender: (props: childrenRenderProps) => React.ReactNode; + /** 异步加载时的加载内容返回,默认为:null */ + loadRender?: (props: LoadRenderProps) => React.ReactNode; + /** 自定义Tree容器组件*/ rootComponent: React.ElementType; } @@ -72,14 +87,13 @@ export interface TreeState { expandedMap: Record; } -export class TreeBasic extends React.Component { +export class TreeBasic extends React.Component, TreeState> { static defaultProps = { prefixCls: "rw-tree", rootId: null, idField: "id", leafField: "leaf", pidField: "pid", - // labelField: "label", maxDepth: 99, //最大层级99 Number.MAX_VALUE asyncTestDelay: 16, expandedIds: [], @@ -90,14 +104,14 @@ export class TreeBasic extends React.Component { rootComponent: "div", }; - static getDerivedStateFromProps(nextProps: TreeProps) { + static getDerivedStateFromProps(nextProps: TreeProps) { return { expandedIds: nextProps.expandedIds, - expandedMap: toMarked(nextProps.expandedIds), + expandedMap: toMarked(nextProps.expandedIds || []), }; } - constructor(props: TreeProps) { + constructor(props: TreeProps) { super(props); this.state = { @@ -123,18 +137,28 @@ export class TreeBasic extends React.Component { return node; } - getContext(this: TreeBasic) { + getContext(this: TreeBasic) { return { tree: this, }; } render() { - const { prefixCls, className, style, rootComponent: Component, itemRender } = this.props; + const { + prefixCls, + className, + style, + rootComponent: Component, + itemRender, + loadData, + } = this.props; if (!itemRender) { throw new Error("react-widget-tree-basic: itemRender cannot be empty."); } + if (!loadData) { + throw new Error("react-widget-tree-basic: loadData cannot be empty."); + } let classes = classNames({ [prefixCls]: true,