import React, { useState, useEffect, useMemo, useCallback } from 'react';
import type { ColumnType } from 'antd/lib/table/interface';
import { Resizable } from 'react-resizable';
import classnames from 'classnames';
import './index.less';
const ResizeableTitle = (props: {
[x: string]: any;
onResize: any;
width: number;
}) => {
const { onResize, width, ...restProps } = props;
// 添加偏移量
const [offset, setOffset] = useState(0);
// 设置了列宽就改为可拖拽状态,可以增加其他属性配置
if (!width) {
return <th {...restProps} />;
}
return (
<Resizable
width={width + offset}
height={0}
handle={
<span
// 有偏移量显示竖线
className={classnames(['react-resizable-handle', offset && 'active'])}
// 拖拽层偏移
style={{ transform: `translateX(${offset}px)` }}
onClick={(e) => {
e.stopPropagation();
e.preventDefault();
}}
/>
}
// 拖拽事件实时更新
onResize={(e: Event, { size }: {size: {width: number}}) => {
// 只更新偏移量,数据列表其实并没有伸缩
setOffset(size.width - width);
}}
// 拖拽结束更新
onResizeStop={(...argu: any) => {
// 拖拽结束以后偏移量归零
setOffset(0);
onResize(...argu);
}}
draggableOpts={{ enableUserSelectHack: false }}
>
<th {...restProps} />
</Resizable>
);
};
const components = {
header: {
cell: ResizeableTitle,
},
};
const useResizeCell = (initColumn: any, func: ({ dataIndex, width }: {dataIndex: string; width: number}) => void) => {
const [columns, setColumns] = useState<ColumnType<Record<string, any>>[]>(initColumn);
useEffect(() => {
setColumns(initColumn);
}, [initColumn]);
const handleResize = useCallback(
(index: number, dataIndex) => (e: Event, { size }: {size: {width: number}}) => {
setColumns((prev) => {
const nextColumns = [...prev];
nextColumns[index] = {
...nextColumns[index],
width: size.width,
};
if (func) {
func({ dataIndex, width: size.width });
}
return nextColumns;
});
},
[func],
);
const changeColumns = useMemo(() => {
return columns.map((col, index: number) => ({
...col,
onHeaderCell: (column: {
width: number;
canResize: boolean;
dataIndex: 'string';
}) => ({
width: column.width,
canResize: column.canResize,
onResize: handleResize(index, column.dataIndex),
}),
}));
}, [columns, handleResize]);
return [components, changeColumns];
};
export default useResizeCell;
.react-resizable { position: relative; background-clip: padding-box;}.react-resizable-handle { position: absolute; width: 10px; height: 100%; bottom: 0; right: -5px; cursor: col-resize; z-index: 1;}.react-resizable-handle.active::before { content: ''; position: absolute; left: 50%; top: 0; bottom: 0; border-right: 3px solid #1885f2 !important;}