TocTree.tsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. import { Tree } from "antd";
  2. import type { DataNode, TreeProps } from "antd/es/tree";
  3. import { useEffect, useState } from "react";
  4. import type { ListNodeData } from "./EditableTree";
  5. import PaliText from "../template/Wbw/PaliText";
  6. type TreeNodeData = {
  7. key: string;
  8. title: string;
  9. children?: TreeNodeData[];
  10. level: number;
  11. };
  12. function tocGetTreeData(
  13. listData: ListNodeData[],
  14. active = ""
  15. ): TreeNodeData[] | undefined {
  16. let treeData: TreeNodeData[] = [];
  17. let tocActivePath: TreeNodeData[] = [];
  18. let treeParents = [];
  19. let rootNode: TreeNodeData = {
  20. key: "0",
  21. title: "root",
  22. level: 0,
  23. children: [],
  24. };
  25. treeData.push(rootNode);
  26. let lastInsNode: TreeNodeData = rootNode;
  27. let iCurrLevel = 0;
  28. for (let index = 0; index < listData.length; index++) {
  29. const element = listData[index];
  30. let newNode: TreeNodeData = {
  31. key: element.key,
  32. title: element.title,
  33. level: element.level,
  34. };
  35. if (newNode.level > iCurrLevel) {
  36. //新的层级比较大,为上一个的子目录
  37. treeParents.push(lastInsNode);
  38. if (typeof lastInsNode.children === "undefined") {
  39. lastInsNode.children = [];
  40. }
  41. lastInsNode.children.push(newNode);
  42. } else if (newNode.level === iCurrLevel) {
  43. //目录层级相同,为平级
  44. const parentNode = treeParents[treeParents.length - 1];
  45. if (typeof parentNode !== "undefined") {
  46. if (typeof parentNode.children === "undefined") {
  47. parentNode.children = [];
  48. }
  49. parentNode.children.push(newNode);
  50. }
  51. } else {
  52. // 小于 挂在上一个层级
  53. while (treeParents.length > 1) {
  54. treeParents.pop();
  55. if (treeParents[treeParents.length - 1].level < newNode.level) {
  56. break;
  57. }
  58. }
  59. const parentNode = treeParents[treeParents.length - 1];
  60. if (typeof parentNode !== "undefined") {
  61. if (typeof parentNode.children === "undefined") {
  62. parentNode.children = [];
  63. }
  64. parentNode.children.push(newNode);
  65. }
  66. }
  67. lastInsNode = newNode;
  68. iCurrLevel = newNode.level;
  69. if (active === element.key) {
  70. tocActivePath = [];
  71. for (let index = 1; index < treeParents.length; index++) {
  72. //treeParents[index]["expanded"] = true;
  73. tocActivePath.push(treeParents[index]);
  74. }
  75. }
  76. }
  77. return treeData[0].children;
  78. }
  79. interface IWidgetTocTree {
  80. treeData?: ListNodeData[];
  81. expandedKey?: string[];
  82. onSelect?: Function;
  83. }
  84. const Widget = ({ treeData, expandedKey, onSelect }: IWidgetTocTree) => {
  85. const [tree, setTree] = useState<TreeNodeData[]>();
  86. const [expanded, setExpanded] = useState(expandedKey);
  87. useEffect(() => {
  88. if (treeData && treeData.length > 0) {
  89. const data = tocGetTreeData(treeData);
  90. setTree(data);
  91. setExpanded(expandedKey);
  92. console.log("create tree", treeData.length, expandedKey);
  93. }
  94. }, [treeData, expandedKey]);
  95. const onNodeSelect: TreeProps["onSelect"] = (selectedKeys, info) => {
  96. console.log("selected", selectedKeys);
  97. if (typeof onSelect !== "undefined") {
  98. onSelect(selectedKeys);
  99. }
  100. };
  101. return (
  102. <Tree
  103. onSelect={onNodeSelect}
  104. treeData={tree}
  105. defaultExpandedKeys={expanded}
  106. defaultSelectedKeys={expanded}
  107. blockNode
  108. titleRender={(node: DataNode) => {
  109. if (typeof node.title === "string") {
  110. return <PaliText text={node.title} />;
  111. } else {
  112. return <></>;
  113. }
  114. }}
  115. />
  116. );
  117. };
  118. export default Widget;