Browse Source

docs(table): update drag sorting demo (#191)

走鹃 4 years ago
parent
commit
4e61800731

+ 78 - 78
content/show/table/index-en-US.md

@@ -2066,35 +2066,35 @@ The CSS style definition used in this example:
 With custom elements, we can integrate `react-dnd` To implement drag and drop sorting.
 With custom elements, we can integrate `react-dnd` To implement drag and drop sorting.
 
 
 ```jsx live=true dir="column" noInline=true
 ```jsx live=true dir="column" noInline=true
-import React from 'react';
+import React, { useState, useMemo, useCallback } from 'react';
 import { Table, Tooltip, Tag } from '@douyinfe/semi-ui';
 import { Table, Tooltip, Tag } from '@douyinfe/semi-ui';
 import { DndProvider, DragSource, DropTarget } from 'react-dnd';
 import { DndProvider, DragSource, DropTarget } from 'react-dnd';
 import HTML5Backend from 'react-dnd-html5-backend';
 import HTML5Backend from 'react-dnd-html5-backend';
 
 
-let dragingIndex = -1;
+let draggingIndex = -1;
+const PAGE_SIZE = 5;
 
 
-class BodyRow extends React.Component {
-    render() {
-        const { isOver, connectDragSource, connectDropTarget, moveRow, ...restProps } = this.props;
-        const style = { ...restProps.style, cursor: 'move' };
+function BodyRow(props) {
+    const { isOver, connectDragSource, connectDropTarget, moveRow, currentPage, ...restProps } = props;
+    const style = { ...restProps.style, cursor: 'move' };
 
 
-        let { className } = restProps;
-        if (isOver) {
-            if (restProps.index > dragingIndex) {
-                className += ' drop-over-downward';
-            }
-            if (restProps.index < dragingIndex) {
-                className += ' drop-over-upward';
-            }
+    let { className } = restProps;
+    if (isOver) {
+        console.log('true');
+        if (restProps.index > draggingIndex) {
+            className += ' drop-over-downward';
+        }
+        if (restProps.index < draggingIndex) {
+            className += ' drop-over-upward';
         }
         }
-
-        return connectDragSource(connectDropTarget(<tr {...restProps} className={className} style={style} />));
     }
     }
+
+    return connectDragSource(connectDropTarget(<tr {...restProps} className={className} style={style} />));
 }
 }
 
 
 const rowSource = {
 const rowSource = {
     beginDrag(props) {
     beginDrag(props) {
-        dragingIndex = props.index;
+        draggingIndex = props.index;
         return {
         return {
             index: props.index,
             index: props.index,
         };
         };
@@ -2116,7 +2116,7 @@ const rowTarget = {
     },
     },
 };
 };
 
 
-const DragableBodyRow = DropTarget('row', rowTarget, (connect, monitor) => ({
+const DraggableBodyRow = DropTarget('row', rowTarget, (connect, monitor) => ({
     connectDropTarget: connect.dropTarget(),
     connectDropTarget: connect.dropTarget(),
     isOver: monitor.isOver(),
     isOver: monitor.isOver(),
 }))(
 }))(
@@ -2146,7 +2146,7 @@ const columns = [
         title: 'Age',
         title: 'Age',
         dataIndex: 'age',
         dataIndex: 'age',
         width: 150,
         width: 150,
-        sorter: (a, b) => (a.age - b.age > 0 ? 1 : -1),
+        sorter: (a, b) => a.age - b.age > 0 ? 1 : -1,
     },
     },
     {
     {
         title: 'Address',
         title: 'Address',
@@ -2154,72 +2154,72 @@ const columns = [
         dataIndex: 'address',
         dataIndex: 'address',
     },
     },
     {
     {
-        render: (text, record) => (
-            <Tooltip content={record.description}>
-                <Tag color="green">Show Info</Tag>
-            </Tooltip>
-        ),
-    },
+        render: (text, record) => <Tooltip content={record.description}><Tag color='green'>Show Info</Tag></Tooltip>
+    }
 ];
 ];
 
 
-class DragSortingTableDemo extends React.Component {
-    constructor() {
-        this.data = [];
-        for (let i = 0; i < 46; i++) {
-            let age = 40 + (Math.random() > 0.5 ? 1 : -1) * Math.ceil(i / 3);
-            let name = `Edward King ${i}`;
-            this.data.push({
-                key: '' + i,
-                name,
-                age,
-                address: `London, Park Lane no. ${i}`,
-                description: `My name is ${name}, I am ${age} years old, living in New York No. ${i + 1} Lake Park.`,
-            });
-        }
-
-        this.state = {
-            data: [...this.data],
-        };
+const initData = [];
+for (let i = 0; i < 46; i++) {
+    let age = 40 + (Math.random() > 0.5 ? 1 : -1) * Math.ceil(i/3);
+    let name = `Edward King ${i}`;
+    initData.push({
+        key: '' + i,
+        name,
+        age,
+        address: `London, Park Lane no. ${i}`,
+        description: `My name is ${name}, I am ${age} years old, living in New York No. ${i+1} Lake Park.`,
+    });
+}
 
 
-        this.components = {
-            body: {
-                row: DragableBodyRow,
-            },
-        };
+function DragSortingTableDemo(props) {
+    const [data, setData] = useState([...initData]);
+    const [currentPage, setCurrentPage] = useState(1);
+    const [pageData, setPageData] = useState(data.slice(0, PAGE_SIZE));
 
 
-        this.pagination = {
-            pageSize: 5,
-        };
+    const components = useMemo(() => ({
+        body: {
+            row: DraggableBodyRow,
+        },
+    }), []);
 
 
-        this.moveRow = (dragIndex, hoverIndex) => {
-            const { data } = this.state;
-            const dragRow = data[dragIndex];
+    const moveRow = (dragIndex, hoverIndex) => {
+        const totalDragIndex = (currentPage - 1) * PAGE_SIZE + dragIndex;
+        const totalHoverIndex = (currentPage - 1) * PAGE_SIZE + hoverIndex;
+        const dragRow = data[totalDragIndex];
+        const newData = [...data];
+        newData.splice(totalDragIndex, 1);
+        newData.splice(totalHoverIndex, 0, dragRow);
+        setData(newData);
+        setPageData(newData.slice((currentPage - 1) * PAGE_SIZE, currentPage * PAGE_SIZE));
+    };
 
 
-            const newData = [...data];
-            newData.splice(dragIndex, 1);
-            newData.splice(hoverIndex, 0, dragRow);
-            this.setState({ data: newData });
-        };
-    }
+    const handlePageChange = (pageNum) => {
+        console.log(pageNum);
+        setCurrentPage(pageNum);
+        setPageData(data.slice((pageNum - 1) * PAGE_SIZE, pageNum * PAGE_SIZE));
+    };
 
 
-    render() {
-        return (
-            <div id="components-table-demo-drag-sorting">
-                <DndProvider backend={HTML5Backend}>
-                    <Table
-                        pagination={this.pagination}
-                        columns={columns}
-                        dataSource={this.state.data}
-                        components={this.components}
-                        onRow={(record, index) => ({
-                            index,
-                            moveRow: this.moveRow,
-                        })}
-                    />
-                </DndProvider>
-            </div>
-        );
-    }
+    return (
+        <div id="components-table-demo-drag-sorting">
+            <DndProvider backend={HTML5Backend}>
+                <Table
+                    columns={columns}
+                    dataSource={pageData}
+                    pagination={{
+                        pageSize: PAGE_SIZE,
+                        total: data.length,
+                        currentPage,
+                        onPageChange: handlePageChange
+                    }}
+                    components={components}
+                    onRow={(record, index) => ({
+                        index,
+                        moveRow,
+                    })}
+                />
+            </DndProvider>
+        </div>
+    );
 }
 }
 
 
 render(DragSortingTableDemo);
 render(DragSortingTableDemo);

+ 75 - 71
content/show/table/index.md

@@ -2028,35 +2028,35 @@ render(ResizableDemo);
 使用自定义元素,我们可以集成 `react-dnd` 来实现拖拽排序。
 使用自定义元素,我们可以集成 `react-dnd` 来实现拖拽排序。
 
 
 ```jsx live=true dir="column" noInline=true hideInDSM
 ```jsx live=true dir="column" noInline=true hideInDSM
-import React from 'react';
+import React, { useState, useMemo, useCallback } from 'react';
 import { Table, Tooltip, Tag } from '@douyinfe/semi-ui';
 import { Table, Tooltip, Tag } from '@douyinfe/semi-ui';
 import { DndProvider, DragSource, DropTarget } from 'react-dnd';
 import { DndProvider, DragSource, DropTarget } from 'react-dnd';
 import HTML5Backend from 'react-dnd-html5-backend';
 import HTML5Backend from 'react-dnd-html5-backend';
 
 
-let dragingIndex = -1;
+let draggingIndex = -1;
+const PAGE_SIZE = 5;
 
 
-class BodyRow extends React.Component {
-    render() {
-        const { isOver, connectDragSource, connectDropTarget, moveRow, ...restProps } = this.props;
-        const style = { ...restProps.style, cursor: 'move' };
+function BodyRow(props) {
+    const { isOver, connectDragSource, connectDropTarget, moveRow, currentPage, ...restProps } = props;
+    const style = { ...restProps.style, cursor: 'move' };
 
 
-        let { className } = restProps;
-        if (isOver) {
-            if (restProps.index > dragingIndex) {
-                className += ' drop-over-downward';
-            }
-            if (restProps.index < dragingIndex) {
-                className += ' drop-over-upward';
-            }
+    let { className } = restProps;
+    if (isOver) {
+        console.log('true');
+        if (restProps.index > draggingIndex) {
+            className += ' drop-over-downward';
+        }
+        if (restProps.index < draggingIndex) {
+            className += ' drop-over-upward';
         }
         }
-
-        return connectDragSource(connectDropTarget(<tr {...restProps} className={className} style={style} />));
     }
     }
+
+    return connectDragSource(connectDropTarget(<tr {...restProps} className={className} style={style} />));
 }
 }
 
 
 const rowSource = {
 const rowSource = {
     beginDrag(props) {
     beginDrag(props) {
-        dragingIndex = props.index;
+        draggingIndex = props.index;
         return {
         return {
             index: props.index,
             index: props.index,
         };
         };
@@ -2078,7 +2078,7 @@ const rowTarget = {
     },
     },
 };
 };
 
 
-const DragableBodyRow = DropTarget('row', rowTarget, (connect, monitor) => ({
+const DraggableBodyRow = DropTarget('row', rowTarget, (connect, monitor) => ({
     connectDropTarget: connect.dropTarget(),
     connectDropTarget: connect.dropTarget(),
     isOver: monitor.isOver(),
     isOver: monitor.isOver(),
 }))(
 }))(
@@ -2120,64 +2120,68 @@ const columns = [
     }
     }
 ];
 ];
 
 
-class DragSortingTableDemo extends React.Component {
-    constructor() {
-        this.data = [];
-        for (let i = 0; i < 46; i++) {
-            let age = 40 + (Math.random() > 0.5 ? 1 : -1) * Math.ceil(i/3);
-            let name = `Edward King ${i}`;
-            this.data.push({
-                key: '' + i,
-                name,
-                age,
-                address: `London, Park Lane no. ${i}`,
-                description: `My name is ${name}, I am ${age} years old, living in New York No. ${i+1} Lake Park.`,
-            });
-        }
+const initData = [];
+for (let i = 0; i < 46; i++) {
+    let age = 40 + (Math.random() > 0.5 ? 1 : -1) * Math.ceil(i/3);
+    let name = `Edward King ${i}`;
+    initData.push({
+        key: '' + i,
+        name,
+        age,
+        address: `London, Park Lane no. ${i}`,
+        description: `My name is ${name}, I am ${age} years old, living in New York No. ${i+1} Lake Park.`,
+    });
+}
 
 
-        this.state = {
-            data: [...this.data],
-        };
+function DragSortingTableDemo(props) {
+    const [data, setData] = useState([...initData]);
+    const [currentPage, setCurrentPage] = useState(1);
+    const [pageData, setPageData] = useState(data.slice(0, PAGE_SIZE));
 
 
-        this.components = {
-            body: {
-                row: DragableBodyRow,
-            },
-        };
+    const components = useMemo(() => ({
+        body: {
+            row: DraggableBodyRow,
+        },
+    }), []);
 
 
-        this.pagination = {
-            pageSize: 5
-        };
+    const moveRow = (dragIndex, hoverIndex) => {
+        const totalDragIndex = (currentPage - 1) * PAGE_SIZE + dragIndex;
+        const totalHoverIndex = (currentPage - 1) * PAGE_SIZE + hoverIndex;
+        const dragRow = data[totalDragIndex];
+        const newData = [...data];
+        newData.splice(totalDragIndex, 1);
+        newData.splice(totalHoverIndex, 0, dragRow);
+        setData(newData);
+        setPageData(newData.slice((currentPage - 1) * PAGE_SIZE, currentPage * PAGE_SIZE));
+    };
 
 
-        this.moveRow = (dragIndex, hoverIndex) => {
-            const { data } = this.state;
-            const dragRow = data[dragIndex];
-            
-            const newData = [...data];
-            newData.splice(dragIndex, 1);
-            newData.splice(hoverIndex, 0, dragRow);
-            this.setState({ data: newData });
-        };
-    }
+    const handlePageChange = (pageNum) => {
+        console.log(pageNum);
+        setCurrentPage(pageNum);
+        setPageData(data.slice((pageNum - 1) * PAGE_SIZE, pageNum * PAGE_SIZE));
+    };
 
 
-    render() {
-        return (
-            <div id="components-table-demo-drag-sorting">
-                <DndProvider backend={HTML5Backend}>
-                    <Table
-                        pagination={this.pagination}
-                        columns={columns}
-                        dataSource={this.state.data}
-                        components={this.components}
-                        onRow={(record, index) => ({
-                            index,
-                            moveRow: this.moveRow,
-                        })}
-                    />
-                </DndProvider>
-            </div>
-        );
-    }
+    return (
+        <div id="components-table-demo-drag-sorting">
+            <DndProvider backend={HTML5Backend}>
+                <Table
+                    columns={columns}
+                    dataSource={pageData}
+                    pagination={{
+                        pageSize: PAGE_SIZE,
+                        total: data.length,
+                        currentPage,
+                        onPageChange: handlePageChange
+                    }}
+                    components={components}
+                    onRow={(record, index) => ({
+                        index,
+                        moveRow,
+                    })}
+                />
+            </DndProvider>
+        </div>
+    );
 }
 }
 
 
 render(DragSortingTableDemo);
 render(DragSortingTableDemo);

+ 96 - 85
packages/semi-ui/table/_story/DragableTable/index.jsx

@@ -1,33 +1,33 @@
-import Table from '../..';
+import React, { useState, useMemo, useCallback } from 'react';
 import { DndProvider, DragSource, DropTarget } from 'react-dnd';
 import { DndProvider, DragSource, DropTarget } from 'react-dnd';
 import HTML5Backend from 'react-dnd-html5-backend';
 import HTML5Backend from 'react-dnd-html5-backend';
-import update from 'immutability-helper';
-import React from 'react';
-import '@douyinfe/semi-foundation/table/table.scss';
-
-let dragingIndex = -1;
-class BodyRow extends React.Component {
-    render() {
-        const { isOver, connectDragSource, connectDropTarget, moveRow, ...restProps } = this.props;
-        const style = { ...restProps.style, cursor: 'move' };
-
-        let { className } = restProps;
-        if (isOver) {
-            if (restProps.index > dragingIndex) {
-                className += ' drop-over-downward';
-            }
-            if (restProps.index < dragingIndex) {
-                className += ' drop-over-upward';
-            }
-        }
+import { Table, Tooltip, Tag } from '@douyinfe/semi-ui';
+import './index.scss';
+
+let draggingIndex = -1;
+const PAGE_SIZE = 5;
 
 
-        return connectDragSource(connectDropTarget(<tr {...restProps} className={className} style={style} />));
+function BodyRow(props) {
+    const { isOver, connectDragSource, connectDropTarget, moveRow, currentPage, ...restProps } = props;
+    const style = { ...restProps.style, cursor: 'move' };
+
+    let { className } = restProps;
+    if (isOver) {
+        console.log('true');
+        if (restProps.index > draggingIndex) {
+            className += ' drop-over-downward';
+        }
+        if (restProps.index < draggingIndex) {
+            className += ' drop-over-upward';
+        }
     }
     }
+
+    return connectDragSource(connectDropTarget(<tr {...restProps} className={className} style={style} />));
 }
 }
 
 
 const rowSource = {
 const rowSource = {
     beginDrag(props) {
     beginDrag(props) {
-        dragingIndex = props.index;
+        draggingIndex = props.index;
         return {
         return {
             index: props.index,
             index: props.index,
         };
         };
@@ -39,23 +39,17 @@ const rowTarget = {
         const dragIndex = monitor.getItem().index;
         const dragIndex = monitor.getItem().index;
         const hoverIndex = props.index;
         const hoverIndex = props.index;
 
 
-        // Don't replace items with themselves
         if (dragIndex === hoverIndex) {
         if (dragIndex === hoverIndex) {
             return;
             return;
         }
         }
 
 
-        // Time to actually perform the action
         props.moveRow(dragIndex, hoverIndex);
         props.moveRow(dragIndex, hoverIndex);
 
 
-        // Note: we're mutating the monitor item here!
-        // Generally it's better to avoid mutations,
-        // but it's good here for the sake of performance
-        // to avoid expensive index searches.
         monitor.getItem().index = hoverIndex;
         monitor.getItem().index = hoverIndex;
     },
     },
 };
 };
 
 
-const DragableBodyRow = DropTarget('row', rowTarget, (connect, monitor) => ({
+const DraggableBodyRow = DropTarget('row', rowTarget, (connect, monitor) => ({
     connectDropTarget: connect.dropTarget(),
     connectDropTarget: connect.dropTarget(),
     isOver: monitor.isOver(),
     isOver: monitor.isOver(),
 }))(
 }))(
@@ -68,78 +62,95 @@ const columns = [
     {
     {
         title: 'Name',
         title: 'Name',
         dataIndex: 'name',
         dataIndex: 'name',
-        key: 'name',
+        width: 150,
+        filters: [
+            {
+                text: 'King 3',
+                value: 'King 3',
+            },
+            {
+                text: 'King 4',
+                value: 'King 4',
+            },
+        ],
+        onFilter: (value, record) => record.name.includes(value),
     },
     },
     {
     {
         title: 'Age',
         title: 'Age',
         dataIndex: 'age',
         dataIndex: 'age',
-        key: 'age',
+        width: 150,
+        sorter: (a, b) => a.age - b.age > 0 ? 1 : -1,
     },
     },
     {
     {
         title: 'Address',
         title: 'Address',
+        width: 200,
         dataIndex: 'address',
         dataIndex: 'address',
-        key: 'address',
     },
     },
+    {
+        render: (text, record) => <Tooltip content={record.description}><Tag color='green'>Show Info</Tag></Tooltip>
+    }
 ];
 ];
 
 
-export default class DragSortingTable extends React.Component {
-    state = {
-        data: [
-            {
-                key: '1',
-                name: 'John Brown',
-                age: 32,
-                address: 'New York No. 1 Lake Park',
-            },
-            {
-                key: '2',
-                name: 'Jim Green',
-                age: 42,
-                address: 'London No. 1 Lake Park',
-            },
-            {
-                key: '3',
-                name: 'Joe Black',
-                age: 39,
-                address: 'Sidney No. 1 Lake Park',
-            },
-        ],
-    };
+const initData = [];
+for (let i = 0; i < 46; i++) {
+    let age = 40 + (Math.random() > 0.5 ? 1 : -1) * Math.ceil(i/3);
+    let name = `Edward King ${i}`;
+    initData.push({
+        key: '' + i,
+        name,
+        age,
+        address: `London, Park Lane no. ${i}`,
+        description: `My name is ${name}, I am ${age} years old, living in New York No. ${i+1} Lake Park.`,
+    });
+}
 
 
-    components = {
+export default function DragSortingTableDemo(props) {
+    const [data, setData] = useState([...initData]);
+    const [currentPage, setCurrentPage] = useState(1);
+    const [pageData, setPageData] = useState(data.slice(0, PAGE_SIZE));
+
+    const components = useMemo(() => ({
         body: {
         body: {
-            row: DragableBodyRow,
+            row: DraggableBodyRow,
         },
         },
+    }), []);
+
+    const moveRow = (dragIndex, hoverIndex) => {
+        const totalDragIndex = (currentPage - 1) * PAGE_SIZE + dragIndex;
+        const totalHoverIndex = (currentPage - 1) * PAGE_SIZE + hoverIndex;
+        const dragRow = data[totalDragIndex];
+        const newData = [...data];
+        newData.splice(totalDragIndex, 1);
+        newData.splice(totalHoverIndex, 0, dragRow);
+        setData(newData);
+        setPageData(newData.slice((currentPage - 1) * PAGE_SIZE, currentPage * PAGE_SIZE));
     };
     };
 
 
-    moveRow = (dragIndex, hoverIndex) => {
-        const { data } = this.state;
-        const dragRow = data[dragIndex];
-
-        this.setState(
-            update(this.state, {
-                data: {
-                    $splice: [[dragIndex, 1], [hoverIndex, 0, dragRow]],
-                },
-            })
-        );
+    const handlePageChange = (pageNum) => {
+        console.log(pageNum);
+        setCurrentPage(pageNum);
+        setPageData(data.slice((pageNum - 1) * PAGE_SIZE, pageNum * PAGE_SIZE));
     };
     };
 
 
-    render() {
-        return (
-            <div id="components-table-demo-drag-sorting">
-                <DndProvider backend={HTML5Backend}>
-                    <Table
-                        columns={columns}
-                        dataSource={this.state.data}
-                        components={this.components}
-                        onRow={(record, index) => ({
-                            index,
-                            moveRow: this.moveRow,
-                        })}
-                    />
-                </DndProvider>
-            </div>
-        );
-    }
+    return (
+        <div id="components-table-demo-drag-sorting">
+            <DndProvider backend={HTML5Backend}>
+                <Table
+                    columns={columns}
+                    dataSource={pageData}
+                    pagination={{
+                        pageSize: PAGE_SIZE,
+                        total: data.length,
+                        currentPage,
+                        onPageChange: handlePageChange
+                    }}
+                    components={components}
+                    onRow={(record, index) => ({
+                        index,
+                        moveRow,
+                    })}
+                />
+            </DndProvider>
+        </div>
+    );
 }
 }

+ 1 - 1
packages/semi-ui/table/_story/DragableTable/index.scss

@@ -4,4 +4,4 @@
 
 
 #components-table-demo-drag-sorting tr.drop-over-upward td {
 #components-table-demo-drag-sorting tr.drop-over-upward td {
     border-top: 2px dashed #1890ff;
     border-top: 2px dashed #1890ff;
-}
+}