Browse Source

demo: add table drag sorting handler demo (#40346)

* demo: add table drag sorting handler demo

* update snapshot
pull/40506/head
linxianxi 2 years ago
committed by GitHub
parent
commit
590b084565
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 308
      components/table/__tests__/__snapshots__/demo-extend.test.ts.snap
  2. 308
      components/table/__tests__/__snapshots__/demo.test.ts.snap
  3. 7
      components/table/demo/drag-sorting-handler.md
  4. 139
      components/table/demo/drag-sorting-handler.tsx
  5. 14
      components/table/demo/drag-sorting.md
  6. 153
      components/table/demo/drag-sorting.tsx
  7. 1
      components/table/index.en-US.md
  8. 1
      components/table/index.zh-CN.md
  9. 3
      package.json

308
components/table/__tests__/__snapshots__/demo-extend.test.ts.snap

@ -2000,9 +2000,14 @@ exports[`renders ./components/table/demo/drag-sorting.tsx extend context correct
class="ant-table-tbody"
>
<tr
aria-describedby="DndDescribedBy-1"
aria-disabled="false"
aria-roledescription="sortable"
class="ant-table-row ant-table-row-level-0"
data-row-key="1"
role="button"
style="cursor:move"
tabindex="0"
>
<td
class="ant-table-cell"
@ -2017,13 +2022,18 @@ exports[`renders ./components/table/demo/drag-sorting.tsx extend context correct
<td
class="ant-table-cell"
>
New York No. 1 Lake Park
Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text
</td>
</tr>
<tr
aria-describedby="DndDescribedBy-1"
aria-disabled="false"
aria-roledescription="sortable"
class="ant-table-row ant-table-row-level-0"
data-row-key="2"
role="button"
style="cursor:move"
tabindex="0"
>
<td
class="ant-table-cell"
@ -2042,9 +2052,14 @@ exports[`renders ./components/table/demo/drag-sorting.tsx extend context correct
</td>
</tr>
<tr
aria-describedby="DndDescribedBy-1"
aria-disabled="false"
aria-roledescription="sortable"
class="ant-table-row ant-table-row-level-0"
data-row-key="3"
role="button"
style="cursor:move"
tabindex="0"
>
<td
class="ant-table-cell"
@ -2059,7 +2074,296 @@ exports[`renders ./components/table/demo/drag-sorting.tsx extend context correct
<td
class="ant-table-cell"
>
Sydney No. 1 Lake Park
Sidney No. 1 Lake Park
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<ul
class="ant-pagination ant-table-pagination ant-table-pagination-right"
>
<li
aria-disabled="true"
class="ant-pagination-prev ant-pagination-disabled"
title="Previous Page"
>
<button
class="ant-pagination-item-link"
disabled=""
tabindex="-1"
type="button"
>
<span
aria-label="left"
class="anticon anticon-left"
role="img"
>
<svg
aria-hidden="true"
data-icon="left"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 000 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"
/>
</svg>
</span>
</button>
</li>
<li
class="ant-pagination-item ant-pagination-item-1 ant-pagination-item-active"
tabindex="0"
title="1"
>
<a
rel="nofollow"
>
1
</a>
</li>
<li
aria-disabled="true"
class="ant-pagination-next ant-pagination-disabled"
title="Next Page"
>
<button
class="ant-pagination-item-link"
disabled=""
tabindex="-1"
type="button"
>
<span
aria-label="right"
class="anticon anticon-right"
role="img"
>
<svg
aria-hidden="true"
data-icon="right"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"
/>
</svg>
</span>
</button>
</li>
</ul>
</div>
</div>
</div>
`;
exports[`renders ./components/table/demo/drag-sorting-handler.tsx extend context correctly 1`] = `
<div
class="ant-table-wrapper"
>
<div
class="ant-spin-nested-loading"
>
<div
class="ant-spin-container"
>
<div
class="ant-table"
>
<div
class="ant-table-container"
>
<div
class="ant-table-content"
>
<table
style="table-layout:auto"
>
<colgroup />
<thead
class="ant-table-thead"
>
<tr>
<td
class="ant-table-cell"
/>
<th
class="ant-table-cell"
scope="col"
>
Name
</th>
<th
class="ant-table-cell"
scope="col"
>
Age
</th>
<th
class="ant-table-cell"
scope="col"
>
Address
</th>
</tr>
</thead>
<tbody
class="ant-table-tbody"
>
<tr
aria-describedby="DndDescribedBy-0"
aria-disabled="false"
aria-roledescription="sortable"
class="ant-table-row ant-table-row-level-0"
data-row-key="1"
role="button"
tabindex="0"
>
<td
class="ant-table-cell"
>
<span
aria-label="menu"
class="anticon anticon-menu"
role="img"
style="touch-action:none;cursor:move"
>
<svg
aria-hidden="true"
data-icon="menu"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M904 160H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0 624H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0-312H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8z"
/>
</svg>
</span>
</td>
<td
class="ant-table-cell"
>
John Brown
</td>
<td
class="ant-table-cell"
>
32
</td>
<td
class="ant-table-cell"
>
Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text
</td>
</tr>
<tr
aria-describedby="DndDescribedBy-0"
aria-disabled="false"
aria-roledescription="sortable"
class="ant-table-row ant-table-row-level-0"
data-row-key="2"
role="button"
tabindex="0"
>
<td
class="ant-table-cell"
>
<span
aria-label="menu"
class="anticon anticon-menu"
role="img"
style="touch-action:none;cursor:move"
>
<svg
aria-hidden="true"
data-icon="menu"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M904 160H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0 624H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0-312H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8z"
/>
</svg>
</span>
</td>
<td
class="ant-table-cell"
>
Jim Green
</td>
<td
class="ant-table-cell"
>
42
</td>
<td
class="ant-table-cell"
>
London No. 1 Lake Park
</td>
</tr>
<tr
aria-describedby="DndDescribedBy-0"
aria-disabled="false"
aria-roledescription="sortable"
class="ant-table-row ant-table-row-level-0"
data-row-key="3"
role="button"
tabindex="0"
>
<td
class="ant-table-cell"
>
<span
aria-label="menu"
class="anticon anticon-menu"
role="img"
style="touch-action:none;cursor:move"
>
<svg
aria-hidden="true"
data-icon="menu"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M904 160H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0 624H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0-312H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8z"
/>
</svg>
</span>
</td>
<td
class="ant-table-cell"
>
Joe Black
</td>
<td
class="ant-table-cell"
>
32
</td>
<td
class="ant-table-cell"
>
Sidney No. 1 Lake Park
</td>
</tr>
</tbody>

308
components/table/__tests__/__snapshots__/demo.test.ts.snap

@ -1470,9 +1470,14 @@ exports[`renders ./components/table/demo/drag-sorting.tsx correctly 1`] = `
class="ant-table-tbody"
>
<tr
aria-describedby="DndDescribedBy-1"
aria-disabled="false"
aria-roledescription="sortable"
class="ant-table-row ant-table-row-level-0"
data-row-key="1"
role="button"
style="cursor:move"
tabindex="0"
>
<td
class="ant-table-cell"
@ -1487,13 +1492,18 @@ exports[`renders ./components/table/demo/drag-sorting.tsx correctly 1`] = `
<td
class="ant-table-cell"
>
New York No. 1 Lake Park
Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text
</td>
</tr>
<tr
aria-describedby="DndDescribedBy-1"
aria-disabled="false"
aria-roledescription="sortable"
class="ant-table-row ant-table-row-level-0"
data-row-key="2"
role="button"
style="cursor:move"
tabindex="0"
>
<td
class="ant-table-cell"
@ -1512,9 +1522,14 @@ exports[`renders ./components/table/demo/drag-sorting.tsx correctly 1`] = `
</td>
</tr>
<tr
aria-describedby="DndDescribedBy-1"
aria-disabled="false"
aria-roledescription="sortable"
class="ant-table-row ant-table-row-level-0"
data-row-key="3"
role="button"
style="cursor:move"
tabindex="0"
>
<td
class="ant-table-cell"
@ -1529,7 +1544,296 @@ exports[`renders ./components/table/demo/drag-sorting.tsx correctly 1`] = `
<td
class="ant-table-cell"
>
Sydney No. 1 Lake Park
Sidney No. 1 Lake Park
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<ul
class="ant-pagination ant-table-pagination ant-table-pagination-right"
>
<li
aria-disabled="true"
class="ant-pagination-prev ant-pagination-disabled"
title="Previous Page"
>
<button
class="ant-pagination-item-link"
disabled=""
tabindex="-1"
type="button"
>
<span
aria-label="left"
class="anticon anticon-left"
role="img"
>
<svg
aria-hidden="true"
data-icon="left"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 000 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"
/>
</svg>
</span>
</button>
</li>
<li
class="ant-pagination-item ant-pagination-item-1 ant-pagination-item-active"
tabindex="0"
title="1"
>
<a
rel="nofollow"
>
1
</a>
</li>
<li
aria-disabled="true"
class="ant-pagination-next ant-pagination-disabled"
title="Next Page"
>
<button
class="ant-pagination-item-link"
disabled=""
tabindex="-1"
type="button"
>
<span
aria-label="right"
class="anticon anticon-right"
role="img"
>
<svg
aria-hidden="true"
data-icon="right"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"
/>
</svg>
</span>
</button>
</li>
</ul>
</div>
</div>
</div>
`;
exports[`renders ./components/table/demo/drag-sorting-handler.tsx correctly 1`] = `
<div
class="ant-table-wrapper"
>
<div
class="ant-spin-nested-loading"
>
<div
class="ant-spin-container"
>
<div
class="ant-table"
>
<div
class="ant-table-container"
>
<div
class="ant-table-content"
>
<table
style="table-layout:auto"
>
<colgroup />
<thead
class="ant-table-thead"
>
<tr>
<td
class="ant-table-cell"
/>
<th
class="ant-table-cell"
scope="col"
>
Name
</th>
<th
class="ant-table-cell"
scope="col"
>
Age
</th>
<th
class="ant-table-cell"
scope="col"
>
Address
</th>
</tr>
</thead>
<tbody
class="ant-table-tbody"
>
<tr
aria-describedby="DndDescribedBy-0"
aria-disabled="false"
aria-roledescription="sortable"
class="ant-table-row ant-table-row-level-0"
data-row-key="1"
role="button"
tabindex="0"
>
<td
class="ant-table-cell"
>
<span
aria-label="menu"
class="anticon anticon-menu"
role="img"
style="touch-action:none;cursor:move"
>
<svg
aria-hidden="true"
data-icon="menu"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M904 160H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0 624H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0-312H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8z"
/>
</svg>
</span>
</td>
<td
class="ant-table-cell"
>
John Brown
</td>
<td
class="ant-table-cell"
>
32
</td>
<td
class="ant-table-cell"
>
Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text
</td>
</tr>
<tr
aria-describedby="DndDescribedBy-0"
aria-disabled="false"
aria-roledescription="sortable"
class="ant-table-row ant-table-row-level-0"
data-row-key="2"
role="button"
tabindex="0"
>
<td
class="ant-table-cell"
>
<span
aria-label="menu"
class="anticon anticon-menu"
role="img"
style="touch-action:none;cursor:move"
>
<svg
aria-hidden="true"
data-icon="menu"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M904 160H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0 624H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0-312H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8z"
/>
</svg>
</span>
</td>
<td
class="ant-table-cell"
>
Jim Green
</td>
<td
class="ant-table-cell"
>
42
</td>
<td
class="ant-table-cell"
>
London No. 1 Lake Park
</td>
</tr>
<tr
aria-describedby="DndDescribedBy-0"
aria-disabled="false"
aria-roledescription="sortable"
class="ant-table-row ant-table-row-level-0"
data-row-key="3"
role="button"
tabindex="0"
>
<td
class="ant-table-cell"
>
<span
aria-label="menu"
class="anticon anticon-menu"
role="img"
style="touch-action:none;cursor:move"
>
<svg
aria-hidden="true"
data-icon="menu"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M904 160H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0 624H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0-312H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8z"
/>
</svg>
</span>
</td>
<td
class="ant-table-cell"
>
Joe Black
</td>
<td
class="ant-table-cell"
>
32
</td>
<td
class="ant-table-cell"
>
Sidney No. 1 Lake Park
</td>
</tr>
</tbody>

7
components/table/demo/drag-sorting-handler.md

@ -0,0 +1,7 @@
## zh-CN
使用 [dnd-kit](https://github.com/clauderic/dnd-kit) 来实现一个拖拽操作列。
## en-US
Alternatively you can implement drag sorting with handler using [dnd-kit](https://github.com/clauderic/dnd-kit).

139
components/table/demo/drag-sorting-handler.tsx

@ -0,0 +1,139 @@
import { MenuOutlined } from '@ant-design/icons';
import type { DragEndEvent } from '@dnd-kit/core';
import { DndContext } from '@dnd-kit/core';
import {
arrayMove,
SortableContext,
useSortable,
verticalListSortingStrategy,
} from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { Table } from 'antd';
import type { ColumnsType } from 'antd/es/table';
import React, { useState } from 'react';
interface DataType {
key: string;
name: string;
age: number;
address: string;
}
const columns: ColumnsType<DataType> = [
{
key: 'sort',
},
{
title: 'Name',
dataIndex: 'name',
},
{
title: 'Age',
dataIndex: 'age',
},
{
title: 'Address',
dataIndex: 'address',
},
];
interface RowProps extends React.HTMLAttributes<HTMLTableRowElement> {
'data-row-key': string;
}
const Row = ({ children, ...props }: RowProps) => {
const {
attributes,
listeners,
setNodeRef,
setActivatorNodeRef,
transform,
transition,
isDragging,
} = useSortable({
id: props['data-row-key'],
});
const style: React.CSSProperties = {
...props.style,
transform: CSS.Transform.toString(transform && { ...transform, scaleY: 1 }),
transition,
...(isDragging ? { position: 'relative', zIndex: 9999 } : {}),
};
return (
<tr {...props} ref={setNodeRef} style={style} {...attributes}>
{React.Children.map(children, (child) => {
if ((child as React.ReactElement).key === 'sort') {
return React.cloneElement(child as React.ReactElement, {
children: (
<MenuOutlined
ref={setActivatorNodeRef}
style={{ touchAction: 'none', cursor: 'move' }}
{...listeners}
/>
),
});
}
return child;
})}
</tr>
);
};
const App: React.FC = () => {
const [dataSource, setDataSource] = useState([
{
key: '1',
name: 'John Brown',
age: 32,
address:
'Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text',
},
{
key: '2',
name: 'Jim Green',
age: 42,
address: 'London No. 1 Lake Park',
},
{
key: '3',
name: 'Joe Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
},
]);
const onDragEnd = ({ active, over }: DragEndEvent) => {
if (active.id !== over?.id) {
setDataSource((previous) => {
const activeIndex = previous.findIndex((i) => i.key === active.id);
const overIndex = previous.findIndex((i) => i.key === over?.id);
return arrayMove(previous, activeIndex, overIndex);
});
}
};
return (
<DndContext onDragEnd={onDragEnd}>
<SortableContext
// rowKey array
items={dataSource.map((i) => i.key)}
strategy={verticalListSortingStrategy}
>
<Table
components={{
body: {
row: Row,
},
}}
rowKey="key"
columns={columns}
dataSource={dataSource}
/>
</SortableContext>
</DndContext>
);
};
export default App;

14
components/table/demo/drag-sorting.md

@ -1,17 +1,7 @@
## zh-CN
使用自定义元素,我们可以集成 [react-dnd](https://github.com/react-dnd/react-dnd) 来实现拖拽排序。
使用自定义元素,我们可以集成 [dnd-kit](https://github.com/clauderic/dnd-kit) 来实现拖拽排序。
## en-US
By using `components`, we can integrate table with [react-dnd](https://github.com/react-dnd/react-dnd) to implement drag sorting function.
```css
#components-table-demo-drag-sorting tr.drop-over-downward td {
border-bottom: 2px dashed #1677ff !important;
}
#components-table-demo-drag-sorting tr.drop-over-upward td {
border-top: 2px dashed #1677ff !important;
}
```
By using `components`, we can integrate table with [dnd-kit](https://github.com/clauderic/dnd-kit) to implement drag sorting function.

153
components/table/demo/drag-sorting.tsx

@ -1,9 +1,15 @@
import React, { useCallback, useRef, useState } from 'react';
import type { DragEndEvent } from '@dnd-kit/core';
import { DndContext } from '@dnd-kit/core';
import {
arrayMove,
SortableContext,
useSortable,
verticalListSortingStrategy,
} from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { Table } from 'antd';
import type { ColumnsType } from 'antd/es/table';
import update from 'immutability-helper';
import { DndProvider, useDrag, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import React, { useState } from 'react';
interface DataType {
key: string;
@ -12,81 +18,49 @@ interface DataType {
address: string;
}
interface DraggableBodyRowProps extends React.HTMLAttributes<HTMLTableRowElement> {
index: number;
moveRow: (dragIndex: number, hoverIndex: number) => void;
}
const type = 'DraggableBodyRow';
const DraggableBodyRow = ({
index,
moveRow,
className,
style,
...restProps
}: DraggableBodyRowProps) => {
const ref = useRef<HTMLTableRowElement>(null);
const [{ isOver, dropClassName }, drop] = useDrop({
accept: type,
collect: (monitor) => {
const { index: dragIndex } = monitor.getItem() || {};
if (dragIndex === index) {
return {};
}
return {
isOver: monitor.isOver(),
dropClassName: dragIndex < index ? ' drop-over-downward' : ' drop-over-upward',
};
},
drop: (item: { index: number }) => {
moveRow(item.index, index);
},
});
const [, drag] = useDrag({
type,
item: { index },
collect: (monitor) => ({
isDragging: monitor.isDragging(),
}),
});
drop(drag(ref));
return (
<tr
ref={ref}
className={`${className}${isOver ? dropClassName : ''}`}
style={{ cursor: 'move', ...style }}
{...restProps}
/>
);
};
const columns: ColumnsType<DataType> = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
},
{
title: 'Address',
dataIndex: 'address',
key: 'address',
},
];
interface RowProps extends React.HTMLAttributes<HTMLTableRowElement> {
'data-row-key': string;
}
const Row = (props: RowProps) => {
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
id: props['data-row-key'],
});
const style: React.CSSProperties = {
...props.style,
transform: CSS.Transform.toString(transform && { ...transform, scaleY: 1 }),
transition,
cursor: 'move',
...(isDragging ? { position: 'relative', zIndex: 9999 } : {}),
};
return <tr {...props} ref={setNodeRef} style={style} {...attributes} {...listeners} />;
};
const App: React.FC = () => {
const [data, setData] = useState([
const [dataSource, setDataSource] = useState([
{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
address:
'Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text',
},
{
key: '2',
@ -98,46 +72,39 @@ const App: React.FC = () => {
key: '3',
name: 'Joe Black',
age: 32,
address: 'Sydney No. 1 Lake Park',
address: 'Sidney No. 1 Lake Park',
},
]);
const components = {
body: {
row: DraggableBodyRow,
},
const onDragEnd = ({ active, over }: DragEndEvent) => {
if (active.id !== over?.id) {
setDataSource((prev) => {
const activeIndex = prev.findIndex((i) => i.key === active.id);
const overIndex = prev.findIndex((i) => i.key === over?.id);
return arrayMove(prev, activeIndex, overIndex);
});
}
};
const moveRow = useCallback(
(dragIndex: number, hoverIndex: number) => {
const dragRow = data[dragIndex];
setData(
update(data, {
$splice: [
[dragIndex, 1],
[hoverIndex, 0, dragRow],
],
}),
);
},
[data],
);
return (
<DndProvider backend={HTML5Backend}>
<Table
columns={columns}
dataSource={data}
components={components}
onRow={(_, index) => {
const attr = {
index,
moveRow,
};
return attr as React.HTMLAttributes<any>;
}}
/>
</DndProvider>
<DndContext onDragEnd={onDragEnd}>
<SortableContext
// rowKey array
items={dataSource.map((i) => i.key)}
strategy={verticalListSortingStrategy}
>
<Table
components={{
body: {
row: Row,
},
}}
rowKey="key"
columns={columns}
dataSource={dataSource}
/>
</SortableContext>
</DndContext>
);
};

1
components/table/index.en-US.md

@ -91,6 +91,7 @@ const columns = [
<code src="./demo/edit-row.tsx">Editable Rows</code>
<code src="./demo/nested-table.tsx">Nested tables</code>
<code src="./demo/drag-sorting.tsx">Drag sorting</code>
<code src="./demo/drag-sorting-handler.tsx">Drag sorting with handler</code>
<code src="./demo/resizable-column.tsx" debug>Resizable column</code>
<code src="./demo/ellipsis.tsx">ellipsis column</code>
<code src="./demo/ellipsis-custom-tooltip.tsx">ellipsis column custom tooltip</code>

1
components/table/index.zh-CN.md

@ -92,6 +92,7 @@ const columns = [
<code src="./demo/edit-row.tsx">可编辑行</code>
<code src="./demo/nested-table.tsx">嵌套子表格</code>
<code src="./demo/drag-sorting.tsx">拖拽排序</code>
<code src="./demo/drag-sorting-handler.tsx">拖拽手柄列</code>
<code src="./demo/resizable-column.tsx" debug>可伸缩列</code>
<code src="./demo/ellipsis.tsx">单元格自动省略</code>
<code src="./demo/ellipsis-custom-tooltip.tsx">自定义单元格省略提示</code>

3
package.json

@ -158,6 +158,9 @@
"devDependencies": {
"@ant-design/tools": "^17.0.0",
"@babel/eslint-plugin": "^7.19.1",
"@dnd-kit/core": "^6.0.7",
"@dnd-kit/sortable": "^7.0.2",
"@dnd-kit/utilities": "^3.2.1",
"@emotion/babel-preset-css-prop": "^11.10.0",
"@emotion/css": "^11.10.5",
"@emotion/react": "^11.10.4",

Loading…
Cancel
Save