1+ import React , { useCallback , useMemo , useState } from "react" ;
2+ import { default as Table , TableProps , ColumnType } from "antd/es/table" ;
3+ import ResizeableTitle from "./ResizeableTitle" ;
4+ import TableCellView from "./TableCellView" ;
5+ import { COL_MIN_WIDTH , CustomColumnType } from "../tableUtils" ;
6+ import { TableColumnStyleType } from "comps/controls/styleControlConstants" ;
7+ import { RowColorViewType , RowHeightViewType } from "../tableTypes" ;
8+
9+ export type ResizeableTableProps < RecordType > = Omit < TableProps < RecordType > , "components" | "columns" > & {
10+ columns : CustomColumnType < RecordType > [ ] ;
11+ viewModeResizable : boolean ;
12+ rowColorFn : RowColorViewType ;
13+ rowHeightFn : RowHeightViewType ;
14+ columnsStyle : TableColumnStyleType ;
15+ size ?: string ;
16+ rowAutoHeight ?: boolean ;
17+ customLoading ?: boolean ;
18+ onCellClick : ( columnName : string , dataIndex : string ) => void ;
19+ } ;
20+
21+ /**
22+ * A table with adjustable column width, width less than 0 means auto column width
23+ */
24+ function ResizeableTableComp < RecordType extends object > ( props : ResizeableTableProps < RecordType > ) {
25+ const {
26+ columns,
27+ viewModeResizable,
28+ rowColorFn,
29+ rowHeightFn,
30+ columnsStyle,
31+ size,
32+ rowAutoHeight,
33+ customLoading,
34+ onCellClick,
35+ ...restProps
36+ } = props ;
37+ const [ resizeData , setResizeData ] = useState ( { index : - 1 , width : - 1 } ) ;
38+
39+ const handleResize = useCallback ( ( width : number , index : number ) => {
40+ setResizeData ( { index, width } ) ;
41+ } , [ ] ) ;
42+
43+ const handleResizeStop = useCallback (
44+ ( width : number , index : number , onWidthResize ?: ( width : number ) => void ) => {
45+ setResizeData ( { index : - 1 , width : - 1 } ) ;
46+ if ( onWidthResize ) {
47+ onWidthResize ( width ) ;
48+ }
49+ } ,
50+ [ ]
51+ ) ;
52+
53+ const createCellHandler = useCallback (
54+ ( col : CustomColumnType < RecordType > ) => {
55+ return ( record : RecordType , index : number ) => ( {
56+ record,
57+ title : String ( col . dataIndex ) ,
58+ rowColorFn,
59+ rowHeightFn,
60+ cellColorFn : col . cellColorFn ,
61+ rowIndex : index ,
62+ columnsStyle,
63+ columnStyle : col . style ,
64+ linkStyle : col . linkStyle ,
65+ tableSize : size ,
66+ autoHeight : rowAutoHeight ,
67+ onClick : ( ) => onCellClick ( col . titleText , String ( col . dataIndex ) ) ,
68+ loading : customLoading ,
69+ customAlign : col . align ,
70+ } ) ;
71+ } ,
72+ [ rowColorFn , rowHeightFn , columnsStyle , size , rowAutoHeight , onCellClick , customLoading ]
73+ ) ;
74+
75+ const createHeaderCellHandler = useCallback (
76+ ( col : CustomColumnType < RecordType > , index : number , resizeWidth : number ) => {
77+ return ( ) => ( {
78+ width : resizeWidth ,
79+ title : col . titleText ,
80+ viewModeResizable,
81+ onResize : ( width : React . SyntheticEvent ) => {
82+ if ( width ) {
83+ handleResize ( Number ( width ) , index ) ;
84+ }
85+ } ,
86+ onResizeStop : ( e : React . SyntheticEvent , { size } : { size : { width : number } } ) => {
87+ handleResizeStop ( size . width , index , col . onWidthResize ) ;
88+ } ,
89+ } ) ;
90+ } ,
91+ [ viewModeResizable , handleResize , handleResizeStop ]
92+ ) ;
93+
94+ const memoizedColumns = useMemo ( ( ) => {
95+ return columns . map ( ( col : CustomColumnType < RecordType > , index : number ) => {
96+ const { width, style, linkStyle, cellColorFn, onWidthResize, ...restCol } = col ;
97+ const resizeWidth = ( resizeData . index === index ? resizeData . width : col . width ) ?? 0 ;
98+
99+ const column : ColumnType < RecordType > = {
100+ ...restCol ,
101+ width : typeof resizeWidth === "number" && resizeWidth > 0 ? resizeWidth : undefined ,
102+ minWidth : typeof resizeWidth === "number" && resizeWidth > 0 ? undefined : COL_MIN_WIDTH ,
103+ onCell : ( record : RecordType , index ?: number ) => createCellHandler ( col ) ( record , index ?? 0 ) ,
104+ onHeaderCell : ( ) => createHeaderCellHandler ( col , index , Number ( resizeWidth ) ) ( ) ,
105+ } ;
106+ return column ;
107+ } ) ;
108+ } , [ columns , resizeData , createCellHandler , createHeaderCellHandler ] ) ;
109+
110+ return (
111+ < Table < RecordType >
112+ components = { {
113+ header : {
114+ cell : ResizeableTitle ,
115+ } ,
116+ body : {
117+ cell : TableCellView ,
118+ } ,
119+ } }
120+ { ...restProps }
121+ pagination = { false }
122+ columns = { memoizedColumns }
123+ scroll = { {
124+ x : COL_MIN_WIDTH * columns . length ,
125+ } }
126+ />
127+ ) ;
128+ }
129+
130+ const ResizeableTable = React . memo ( ResizeableTableComp ) as typeof ResizeableTableComp ;
131+ export default ResizeableTable ;
0 commit comments