diff --git a/components/table/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/table/__tests__/__snapshots__/demo-extend.test.ts.snap index 0b568b4e11..0b09cc8033 100644 --- a/components/table/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/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" > - 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 - Sydney No. 1 Lake Park + Sidney No. 1 Lake Park + + + + + + + + + + + +`; + +exports[`renders ./components/table/demo/drag-sorting-handler.tsx extend context correctly 1`] = ` +
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/table/__tests__/__snapshots__/demo.test.ts.snap b/components/table/__tests__/__snapshots__/demo.test.ts.snap index 84bfb58ced..a022e7fc1e 100644 --- a/components/table/__tests__/__snapshots__/demo.test.ts.snap +++ b/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" > + + +
+ + Name + + Age + + Address +
+ + + + + John Brown + + 32 + + 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 +
+ + + + + Jim Green + + 42 + + London No. 1 Lake Park +
+ + + + + Joe Black + + 32 + + Sidney No. 1 Lake Park
- 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
- Sydney No. 1 Lake Park + Sidney No. 1 Lake Park +
+
+
+
+
    +
  • + +
  • +
  • + + 1 + +
  • +
  • + +
  • +
+
+
+
+`; + +exports[`renders ./components/table/demo/drag-sorting-handler.tsx correctly 1`] = ` +
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/table/demo/drag-sorting-handler.md b/components/table/demo/drag-sorting-handler.md new file mode 100644 index 0000000000..0da9ebe896 --- /dev/null +++ b/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). diff --git a/components/table/demo/drag-sorting-handler.tsx b/components/table/demo/drag-sorting-handler.tsx new file mode 100644 index 0000000000..1f3754cb99 --- /dev/null +++ b/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 = [ + { + key: 'sort', + }, + { + title: 'Name', + dataIndex: 'name', + }, + { + title: 'Age', + dataIndex: 'age', + }, + { + title: 'Address', + dataIndex: 'address', + }, +]; + +interface RowProps extends React.HTMLAttributes { + '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 ( + + {React.Children.map(children, (child) => { + if ((child as React.ReactElement).key === 'sort') { + return React.cloneElement(child as React.ReactElement, { + children: ( + + ), + }); + } + return child; + })} + + ); +}; + +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 ( + + i.key)} + strategy={verticalListSortingStrategy} + > +
+ + Name + + Age + + Address +
+ + + + + John Brown + + 32 + + 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 +
+ + + + + Jim Green + + 42 + + London No. 1 Lake Park +
+ + + + + Joe Black + + 32 + + Sidney No. 1 Lake Park
+ + + ); +}; + +export default App; diff --git a/components/table/demo/drag-sorting.md b/components/table/demo/drag-sorting.md index 2af0c3218e..ba6467b27a 100644 --- a/components/table/demo/drag-sorting.md +++ b/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. diff --git a/components/table/demo/drag-sorting.tsx b/components/table/demo/drag-sorting.tsx index fe82b1e4e1..3a0e852988 100644 --- a/components/table/demo/drag-sorting.tsx +++ b/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 { - index: number; - moveRow: (dragIndex: number, hoverIndex: number) => void; -} - -const type = 'DraggableBodyRow'; - -const DraggableBodyRow = ({ - index, - moveRow, - className, - style, - ...restProps -}: DraggableBodyRowProps) => { - const ref = useRef(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 ( - - ); -}; - const columns: ColumnsType = [ { title: 'Name', dataIndex: 'name', - key: 'name', }, { title: 'Age', dataIndex: 'age', - key: 'age', }, { title: 'Address', dataIndex: 'address', - key: 'address', }, ]; +interface RowProps extends React.HTMLAttributes { + '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 ; +}; + 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 ( - -
{ - const attr = { - index, - moveRow, - }; - return attr as React.HTMLAttributes; - }} - /> - + + i.key)} + strategy={verticalListSortingStrategy} + > +
+ + ); }; diff --git a/components/table/index.en-US.md b/components/table/index.en-US.md index abcb943226..5cf1ef4173 100644 --- a/components/table/index.en-US.md +++ b/components/table/index.en-US.md @@ -91,6 +91,7 @@ const columns = [ Editable RowsNested tablesDrag sorting +Drag sorting with handlerResizable columnellipsis columnellipsis column custom tooltip diff --git a/components/table/index.zh-CN.md b/components/table/index.zh-CN.md index b50d7b9f8f..7b08e46e2a 100644 --- a/components/table/index.zh-CN.md +++ b/components/table/index.zh-CN.md @@ -92,6 +92,7 @@ const columns = [ 可编辑行嵌套子表格拖拽排序 +拖拽手柄列可伸缩列单元格自动省略自定义单元格省略提示 diff --git a/package.json b/package.json index d7e580f5fd..6ceb8558e3 100644 --- a/package.json +++ b/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",