From 1085c400a3612d95f0876c351b8b885c99db7297 Mon Sep 17 00:00:00 2001 From: * <8> Date: Tue, 22 Mar 2022 19:54:31 +0800 Subject: [PATCH] Match-id-f9eaf1cfccee2ac7b3b2f5b071385d1356d11320 --- libs/extension/src/components/VTree.tsx | 103 ++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 libs/extension/src/components/VTree.tsx diff --git a/libs/extension/src/components/VTree.tsx b/libs/extension/src/components/VTree.tsx new file mode 100644 index 00000000..040ea892 --- /dev/null +++ b/libs/extension/src/components/VTree.tsx @@ -0,0 +1,103 @@ +import { useState } from 'horizon'; + +export interface IData { + id: string; + name: string; + indentation: number; + userKey: string; +} + +type IItem = { + style: any, + hasChild: boolean, + onExpand: (id: string) => void, +} & IData + +// TODO: 计算可以展示的最多数量,并且监听显示器高度变化修改数值 +const showNum = 50; +const divHeight = 21; + +function Item({ name, style, userKey, hasChild, onExpand, id, indentation }: IItem) { + const key = userKey === '' ? '' : ` key = '${userKey}'`; + const showIcon = hasChild ? '△' : ''; + const onClickExpand = () => { + onExpand(id); + } + return ( +
+
{showIcon}
+ {name + key} +
+ ) +} + +function VTree({ data }: { data: IData[] }) { + const [scrollTop, setScrollTop] = useState(0); + const [collapseNode, setCollapseNode] = useState(new Set()); + const changeExpandNode = (id: string) => { + const nodes = new Set(); + collapseNode.forEach(value => { + nodes.add(value); + }); + if (nodes.has(id)) { + nodes.delete(id); + } else { + nodes.add(id); + } + setCollapseNode(nodes); + }; + const showList: any[] = []; + + let totalHeight = 0; + let currentCollapseIndentation: null| number = null; + data.forEach((item, index) => { + // 存在未处理完的收起节点 + if (currentCollapseIndentation !== null) { + const indentation = item.indentation; + // 缩进更大,不显示 + if (indentation > currentCollapseIndentation) { + return; + } else { + // 缩进小,说明完成了该收起节点的子节点处理。 + currentCollapseIndentation = null; + } + } + if (totalHeight >= scrollTop && showList.length <= showNum) { + const nextItem = data[index + 1]; + const hasChild = nextItem ? nextItem.indentation > item.indentation : false; + showList.push( + + ) + } + totalHeight = totalHeight + divHeight; + let id = item.id; + if (collapseNode.has(id)) { + // 该节点需要收起子节点 + currentCollapseIndentation = item.indentation; + } + }); + + const scroll = (event: any) => { + const scrollTop = event.target.scrollTop; + setScrollTop(Math.max(scrollTop - 100, 0)); + } + + return ( +
+ {showList} + {/* 确保有足够的高度 */} +
+
+ ) +} + +export default VTree;