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