2020-05-21 15:56:09 +08:00
|
|
|
---
|
|
|
|
order: 27
|
|
|
|
title:
|
|
|
|
en-US: Drag sorting with handler
|
|
|
|
zh-CN: 拖拽手柄列
|
|
|
|
---
|
|
|
|
|
|
|
|
## zh-CN
|
|
|
|
|
|
|
|
也可以使用 [react-sortable-hoc](https://github.com/clauderic/react-sortable-hoc) 来实现一个拖拽操作列。
|
|
|
|
|
|
|
|
## en-US
|
|
|
|
|
|
|
|
Alternatively you can implement drag sorting with handler using [react-sortable-hoc](https://github.com/clauderic/react-sortable-hoc).
|
|
|
|
|
2022-05-19 09:46:26 +08:00
|
|
|
```tsx
|
2020-05-21 15:56:09 +08:00
|
|
|
import { MenuOutlined } from '@ant-design/icons';
|
2022-05-23 14:37:16 +08:00
|
|
|
import { Table } from 'antd';
|
2022-05-19 09:46:26 +08:00
|
|
|
import type { ColumnsType } from 'antd/lib/table';
|
2021-08-13 17:33:09 +08:00
|
|
|
import { arrayMoveImmutable } from 'array-move';
|
2022-05-23 14:37:16 +08:00
|
|
|
import React, { useState } from 'react';
|
2022-05-19 09:46:26 +08:00
|
|
|
import type { SortableContainerProps, SortEnd } from 'react-sortable-hoc';
|
2022-05-23 14:37:16 +08:00
|
|
|
import { SortableContainer, SortableElement, SortableHandle } from 'react-sortable-hoc';
|
2022-05-19 09:46:26 +08:00
|
|
|
|
|
|
|
interface DataType {
|
|
|
|
key: string;
|
|
|
|
name: string;
|
|
|
|
age: number;
|
|
|
|
address: string;
|
|
|
|
index: number;
|
|
|
|
}
|
2020-05-21 15:56:09 +08:00
|
|
|
|
2022-01-14 18:50:02 +08:00
|
|
|
const DragHandle = SortableHandle(() => <MenuOutlined style={{ cursor: 'grab', color: '#999' }} />);
|
2020-05-21 15:56:09 +08:00
|
|
|
|
2022-05-19 09:46:26 +08:00
|
|
|
const columns: ColumnsType<DataType> = [
|
2020-05-21 15:56:09 +08:00
|
|
|
{
|
|
|
|
title: 'Sort',
|
|
|
|
dataIndex: 'sort',
|
|
|
|
width: 30,
|
|
|
|
className: 'drag-visible',
|
|
|
|
render: () => <DragHandle />,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: 'Name',
|
|
|
|
dataIndex: 'name',
|
|
|
|
className: 'drag-visible',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: 'Age',
|
|
|
|
dataIndex: 'age',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: 'Address',
|
|
|
|
dataIndex: 'address',
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
2022-05-19 09:46:26 +08:00
|
|
|
const data: DataType[] = [
|
2020-05-21 15:56:09 +08:00
|
|
|
{
|
|
|
|
key: '1',
|
|
|
|
name: 'John Brown',
|
|
|
|
age: 32,
|
|
|
|
address: 'New York No. 1 Lake Park',
|
|
|
|
index: 0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: '2',
|
|
|
|
name: 'Jim Green',
|
|
|
|
age: 42,
|
|
|
|
address: 'London No. 1 Lake Park',
|
|
|
|
index: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: '3',
|
|
|
|
name: 'Joe Black',
|
|
|
|
age: 32,
|
|
|
|
address: 'Sidney No. 1 Lake Park',
|
|
|
|
index: 2,
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
2022-05-19 09:46:26 +08:00
|
|
|
const SortableItem = SortableElement((props: React.HTMLAttributes<HTMLTableRowElement>) => (
|
|
|
|
<tr {...props} />
|
|
|
|
));
|
|
|
|
const SortableBody = SortableContainer((props: React.HTMLAttributes<HTMLTableSectionElement>) => (
|
|
|
|
<tbody {...props} />
|
|
|
|
));
|
2020-05-21 15:56:09 +08:00
|
|
|
|
2022-05-19 09:46:26 +08:00
|
|
|
const App: React.FC = () => {
|
|
|
|
const [dataSource, setDataSource] = useState(data);
|
2020-05-21 15:56:09 +08:00
|
|
|
|
2022-05-19 09:46:26 +08:00
|
|
|
const onSortEnd = ({ oldIndex, newIndex }: SortEnd) => {
|
2020-05-21 15:56:09 +08:00
|
|
|
if (oldIndex !== newIndex) {
|
2022-05-19 09:46:26 +08:00
|
|
|
const newData = arrayMoveImmutable(dataSource.slice(), oldIndex, newIndex).filter(
|
|
|
|
(el: DataType) => !!el,
|
2022-01-14 18:50:02 +08:00
|
|
|
);
|
2020-05-21 15:56:09 +08:00
|
|
|
console.log('Sorted items: ', newData);
|
2022-05-19 09:46:26 +08:00
|
|
|
setDataSource(newData);
|
2020-05-21 15:56:09 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-05-19 09:46:26 +08:00
|
|
|
const DraggableContainer = (props: SortableContainerProps) => (
|
2022-01-14 18:50:02 +08:00
|
|
|
<SortableBody
|
2020-12-22 16:46:52 +08:00
|
|
|
useDragHandle
|
2021-01-08 10:14:01 +08:00
|
|
|
disableAutoscroll
|
2020-12-22 16:46:52 +08:00
|
|
|
helperClass="row-dragging"
|
2022-05-19 09:46:26 +08:00
|
|
|
onSortEnd={onSortEnd}
|
2020-12-22 16:46:52 +08:00
|
|
|
{...props}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
|
2022-05-19 09:46:26 +08:00
|
|
|
const DraggableBodyRow: React.FC<any> = ({ className, style, ...restProps }) => {
|
2020-07-12 14:47:59 +08:00
|
|
|
// function findIndex base on Table rowKey props and should always be a right array index
|
|
|
|
const index = dataSource.findIndex(x => x.index === restProps['data-row-key']);
|
|
|
|
return <SortableItem index={index} {...restProps} />;
|
|
|
|
};
|
|
|
|
|
2022-05-19 09:46:26 +08:00
|
|
|
return (
|
|
|
|
<Table
|
|
|
|
pagination={false}
|
|
|
|
dataSource={dataSource}
|
|
|
|
columns={columns}
|
|
|
|
rowKey="index"
|
|
|
|
components={{
|
|
|
|
body: {
|
|
|
|
wrapper: DraggableContainer,
|
|
|
|
row: DraggableBodyRow,
|
|
|
|
},
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
};
|
2020-05-21 15:56:09 +08:00
|
|
|
|
2022-05-19 09:46:26 +08:00
|
|
|
export default App;
|
2020-05-21 15:56:09 +08:00
|
|
|
```
|
|
|
|
|
|
|
|
```css
|
|
|
|
.row-dragging {
|
|
|
|
background: #fafafa;
|
|
|
|
border: 1px solid #ccc;
|
|
|
|
}
|
|
|
|
|
|
|
|
.row-dragging td {
|
|
|
|
padding: 16px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.row-dragging .drag-visible {
|
|
|
|
visibility: visible;
|
|
|
|
}
|
|
|
|
```
|