index.jsx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. import React, { useState, useMemo, useCallback } from 'react';
  2. import { DndProvider, DragSource, DropTarget } from 'react-dnd';
  3. import HTML5Backend from 'react-dnd-html5-backend';
  4. import { Table, Tooltip, Tag } from '@douyinfe/semi-ui';
  5. import './index.scss';
  6. let draggingIndex = -1;
  7. const PAGE_SIZE = 5;
  8. function BodyRow(props) {
  9. const { isOver, connectDragSource, connectDropTarget, moveRow, currentPage, ...restProps } = props;
  10. const style = { ...restProps.style, cursor: 'move' };
  11. let { className } = restProps;
  12. if (isOver) {
  13. console.log('true');
  14. if (restProps.index > draggingIndex) {
  15. className += ' drop-over-downward';
  16. }
  17. if (restProps.index < draggingIndex) {
  18. className += ' drop-over-upward';
  19. }
  20. }
  21. return connectDragSource(connectDropTarget(<tr {...restProps} className={className} style={style} />));
  22. }
  23. const rowSource = {
  24. beginDrag(props) {
  25. draggingIndex = props.index;
  26. return {
  27. index: props.index,
  28. };
  29. },
  30. };
  31. const rowTarget = {
  32. drop(props, monitor) {
  33. const dragIndex = monitor.getItem().index;
  34. const hoverIndex = props.index;
  35. if (dragIndex === hoverIndex) {
  36. return;
  37. }
  38. props.moveRow(dragIndex, hoverIndex);
  39. monitor.getItem().index = hoverIndex;
  40. },
  41. };
  42. const DraggableBodyRow = DropTarget('row', rowTarget, (connect, monitor) => ({
  43. connectDropTarget: connect.dropTarget(),
  44. isOver: monitor.isOver(),
  45. }))(
  46. DragSource('row', rowSource, connect => ({
  47. connectDragSource: connect.dragSource(),
  48. }))(BodyRow)
  49. );
  50. const columns = [
  51. {
  52. title: 'Name',
  53. dataIndex: 'name',
  54. width: 150,
  55. filters: [
  56. {
  57. text: 'King 3',
  58. value: 'King 3',
  59. },
  60. {
  61. text: 'King 4',
  62. value: 'King 4',
  63. },
  64. ],
  65. onFilter: (value, record) => record.name.includes(value),
  66. },
  67. {
  68. title: 'Age',
  69. dataIndex: 'age',
  70. width: 150,
  71. sorter: (a, b) => a.age - b.age > 0 ? 1 : -1,
  72. },
  73. {
  74. title: 'Address',
  75. width: 200,
  76. dataIndex: 'address',
  77. },
  78. {
  79. render: (text, record) => <Tooltip content={record.description}><Tag color='green'>Show Info</Tag></Tooltip>
  80. }
  81. ];
  82. const initData = [];
  83. for (let i = 0; i < 46; i++) {
  84. let age = 40 + (Math.random() > 0.5 ? 1 : -1) * Math.ceil(i/3);
  85. let name = `Edward King ${i}`;
  86. initData.push({
  87. key: '' + i,
  88. name,
  89. age,
  90. address: `London, Park Lane no. ${i}`,
  91. description: `My name is ${name}, I am ${age} years old, living in New York No. ${i+1} Lake Park.`,
  92. });
  93. }
  94. export default function DragSortingTableDemo(props) {
  95. const [data, setData] = useState([...initData]);
  96. const [currentPage, setCurrentPage] = useState(1);
  97. const [pageData, setPageData] = useState(data.slice(0, PAGE_SIZE));
  98. const components = useMemo(() => ({
  99. body: {
  100. row: DraggableBodyRow,
  101. },
  102. }), []);
  103. const moveRow = (dragIndex, hoverIndex) => {
  104. const totalDragIndex = (currentPage - 1) * PAGE_SIZE + dragIndex;
  105. const totalHoverIndex = (currentPage - 1) * PAGE_SIZE + hoverIndex;
  106. const dragRow = data[totalDragIndex];
  107. const newData = [...data];
  108. newData.splice(totalDragIndex, 1);
  109. newData.splice(totalHoverIndex, 0, dragRow);
  110. setData(newData);
  111. setPageData(newData.slice((currentPage - 1) * PAGE_SIZE, currentPage * PAGE_SIZE));
  112. };
  113. const handlePageChange = (pageNum) => {
  114. console.log(pageNum);
  115. setCurrentPage(pageNum);
  116. setPageData(data.slice((pageNum - 1) * PAGE_SIZE, pageNum * PAGE_SIZE));
  117. };
  118. return (
  119. <div id="components-table-demo-drag-sorting">
  120. <DndProvider backend={HTML5Backend}>
  121. <Table
  122. columns={columns}
  123. dataSource={pageData}
  124. pagination={{
  125. pageSize: PAGE_SIZE,
  126. total: data.length,
  127. currentPage,
  128. onPageChange: handlePageChange
  129. }}
  130. components={components}
  131. onRow={(record, index) => ({
  132. index,
  133. moveRow,
  134. })}
  135. />
  136. </DndProvider>
  137. </div>
  138. );
  139. }