import React, { isValidElement } from "react"; import { TreeNode, TreeNodeInnerProps } from "./TreeNode"; import { TreeData, TreeProps } from "./TreeProps"; import { CheckTreeRelation } from "../checktree"; import { isChildOfType } from "../_util/is-child-of-type"; type InnerTreeData = TreeData & TreeNodeInnerProps; export function getNodeShowState( id: string, relations: CheckTreeRelation, expandedIds: string[], isFiltered?: boolean ) { // 留存源id const originId = id; let show = true; const nodeSet = new Set(); while (relations[id] && !nodeSet.has(relations[id])) { nodeSet.add(relations[id]); if (!expandedIds.includes(relations[id])) { show = false; break; } // eslint-disable-next-line no-param-reassign id = relations[id]; } // 兼容过滤操作 if (!expandedIds.includes(originId) && !isFiltered) { show = false; } return show; } export function getDefaultExpandedIds({ relations, expandedIds, defaultExpandedIds, defaultExpandAll, defaultExpandParent = true, forceExpandParent, }: Partial & { relations: CheckTreeRelation }) { // 受控 if (Array.isArray(expandedIds)) { return expandedIds; } if (defaultExpandAll) { const ids = []; Object.values(relations).forEach(parent => { ids.push(parent); }); return ids; } const expandParent = forceExpandParent ?? defaultExpandParent; if (expandParent) { const idSet = new Set(defaultExpandedIds); defaultExpandedIds.forEach(id => { let child = id; while (child in relations && !idSet.has(relations[child])) { idSet.add(relations[child]); child = relations[child]; } }); return [...idSet]; } return defaultExpandedIds; } /** * 获取被过滤后需展开的节点集合 * @param nodes 树节点集合 * @param relations 父子节点对应关系 * @returns */ export function getFilteredExpandedIds( nodes: InnerTreeData[], relations: CheckTreeRelation ): string[] { if (!nodes.length) return []; const idSet = new Set(); [...nodes].reverse().forEach(node => { // 获取父节点 const parent = relations[node.id]; if (node.isFiltered || idSet.has(node.id)) { if (parent) { idSet.add(parent); } else { idSet.add(node.id); } } }); return [...idSet]; } /** * 新的平级结构无法适配原有自定义 Node 组件嵌套 * 判断如果包含自定义组件则使用老版本组件渲染 */ export function checkTreeNode(children): boolean { let isValid = true; if (!children) { return isValid; } React.Children.forEach(children, child => { if (isValidElement(child)) { if (isValid) { if (!isChildOfType(child, TreeNode)) { isValid = false; } else { isValid = checkTreeNode(child.props.children); } } } }); return isValid; }