import React from 'react' import { noop } from 'rxjs' import { BaseTable } from '../../base-table' import type { BaseTableProps } from '../../base-table' import type { CellProps } from '../../interfaces' import { ROW_KEY } from '../cross-table' import type { CrossTableLeftMetaColumn, LeftCrossTreeNode, TopCrossTreeNode } from '../cross-table' import buildCrossTreeTable from './buildCrossTreeTable' export interface CrossTreeTableProps extends Omit { BaseTableComponent?: any baseTableRef?: React.Ref primaryColumn: CrossTableLeftMetaColumn leftTree: LeftCrossTreeNode[] topTree: TopCrossTreeNode[] defaultOpenKeys?: string[] openKeys?: string[] onChangeOpenKeys?(nextOpenKeys: string[]): void indentSize?: number isLeafNode?(node: any, nodeMeta: { depth: number; expanded: boolean; rowKey: string }): boolean getValue?(leftNode: LeftCrossTreeNode, topNode: TopCrossTreeNode, leftDepth: number, topDepth: number): any render?( value: any, leftNode: LeftCrossTreeNode, topNode: TopCrossTreeNode, leftDepth: number, topDepth: number, ): React.ReactNode getCellProps?( value: any, leftNode: LeftCrossTreeNode, topNode: TopCrossTreeNode, leftDepth: number, topDepth: number, ): CellProps } export default class CrossTreeTable extends React.Component { static defaultProps = { defaultOpenKeys: [] as string[], onChangeOpenKeys: noop, } static getDerivedStateFromProps(nextProps: Readonly) { if ('openKeys' in nextProps) { return { openKeys: nextProps.openKeys } } return null } constructor(props: Readonly) { super(props) this.state = { openKeys: props.defaultOpenKeys, } } onChangeOpenKeys = (nextOpenKeys: string[]) => { this.props.onChangeOpenKeys(nextOpenKeys) if (!('openKeys' in this.props)) { this.setState({ openKeys: nextOpenKeys }) } } render() { const { BaseTableComponent = BaseTable, leftTree, topTree, getValue, getCellProps, primaryColumn, render, openKeys: openKeysProp, defaultOpenKeys, onChangeOpenKeys, indentSize, isLeafNode, baseTableRef, ...others // 透传其他 BaseTable 的 props } = this.props const openKeys = openKeysProp ?? this.state.openKeys const { dataSource, columns } = buildCrossTreeTable({ leftTree, topTree, getValue, getCellProps, render, primaryColumn, openKeys, onChangeOpenKeys: this.onChangeOpenKeys, indentSize, isLeafNode, }) return ( ) } }