import React , { Component , Children } from 'react' ; import Column , { ColumnProps } from './Column' ; import TreeTableHeader from './TreeTableHeader' ; import VirtualList from './VirtualList' ; import TreeState from '../model/tree-state' ; import { createRefPolyfill } from '../util/ref-polyfill' ; export type TreeTableProps = { value : Readonly < TreeState > ; onChange ? : ( value : Readonly < TreeState > ) => void ; children ? : Array < React . ReactElement < Column > > ; onScroll ? : ( scrollTop : number ) => void ; height ? : number ; headerHeight ? : number ; className ? : string ; } ; const TABLE_DEFAULT_HEIGHT = 260 ; const noopOnChange = ( value ) => { } ; const noopOnScroll = ( scrollTop ) => { } ; export default class TreeTable extends Component < TreeTableProps , { } > { static Column = Column ; private vListRef = createRefPolyfill < VirtualList > ( ) ; render ( ) { const { value , children , onChange , onScroll , height , headerHeight , className } = this . props ; const columnsDef = [ ] ; Children . toArray ( children ) . forEach ( ( node ) => { if ( isColumnElement ( node ) ) { columnsDef . push ( node . props ) ; } } ) ; return ( < div className = { `cp_tree-table ${ className != null && className }` } > < TreeTableHeader columns = { columnsDef } height = { headerHeight } / > { value . hasData && < VirtualList data = { value } columns = { columnsDef } height = { Number ( height ) || TABLE_DEFAULT_HEIGHT } onChange = { onChange || noopOnChange } ref = { this . vListRef } onScroll = { onScroll || noopOnScroll } />} < /div>); } private handleChange = ( value ) : void => { const { onChange } = this . props ; ( onChange || noopOnChange ) ( value ) ; } ; scrollTo ( posY ) { if ( this . vListRef . current != null ) { this . vListRef . current . scrollTo ( posY ) ; } } } const isColumnElement = ( elem ) : elem is React . ReactElement < ColumnProps > => { return checkElementType ( elem , Column ) ; } ; const checkElementType = < T extends { } > ( elem , cmpType ) : elem is React . ReactElement < T > => { return ( elem != null && elem . type != null && elem . type . displayName != null && elem . type . displayName === cmpType . displayName ) ; } ;