import React, { useState } from 'react'; import { Table } from 'antd'; import type { TableColumnsType } from 'antd'; import type { ResizeCallbackData } from 'react-resizable'; import { Resizable } from 'react-resizable'; interface DataType { key: React.Key; date: string; amount: number; type: string; note: string; } interface TitlePropsType { width: number; onResize: (e: React.SyntheticEvent<Element>, data: ResizeCallbackData) => void; } const ResizableTitle: React.FC<Readonly<React.HTMLAttributes<any> & TitlePropsType>> = (props) => { const { onResize, width, ...restProps } = props; if (!width) { return <th {...restProps} />; } return ( <Resizable width={width} height={0} handle={<span className="react-resizable-handle" onClick={(e) => e.stopPropagation()} />} onResize={onResize} draggableOpts={{ enableUserSelectHack: false }} > <th {...restProps} /> </Resizable> ); }; const data: DataType[] = [ { key: 0, date: '2018-02-11', amount: 120, type: 'income', note: 'transfer', }, { key: 1, date: '2018-03-11', amount: 243, type: 'income', note: 'transfer', }, { key: 2, date: '2018-04-11', amount: 98, type: 'income', note: 'transfer', }, ]; const App: React.FC = () => { const [columns, setColumns] = useState<TableColumnsType<DataType>>([ { title: 'Date', dataIndex: 'date', width: 200, }, { title: 'Amount', dataIndex: 'amount', width: 100, sorter: (a, b) => a.amount - b.amount, }, { title: 'Type', dataIndex: 'type', width: 100, }, { title: 'Note', dataIndex: 'note', width: 100, }, { title: 'Action', key: 'action', render: () => <a>Delete</a>, }, ]); const handleResize = (index: number) => (_: React.SyntheticEvent<Element>, { size }: ResizeCallbackData) => { const newColumns = [...columns]; newColumns[index] = { ...newColumns[index], width: size.width, }; setColumns(newColumns); }; const mergedColumns = columns.map<TableColumnsType<DataType>[number]>((col, index) => ({ ...col, onHeaderCell: (column: TableColumnsType<DataType>[number]) => ({ width: column.width, onResize: handleResize(index) as React.ReactEventHandler<any>, }), })); return ( <Table<DataType> bordered components={{ header: { cell: ResizableTitle } }} columns={mergedColumns} dataSource={data} /> ); }; export default App;