Skip to content

Commit 04f1afc

Browse files
committed
feat: Table components support paging
1 parent 8e4a2eb commit 04f1afc

11 files changed

Lines changed: 492 additions & 86 deletions

File tree

.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,6 @@ module.exports = {
2929
'react/no-array-index-key': 'off',
3030
'no-param-reassign': 'off',
3131
'@typescript-eslint/no-loop-func': 'off',
32+
'@typescript-eslint/no-unused-expressions': 'off',
3233
},
3334
};

docs/demo/Mock.tsx

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
import React, { useState, useEffect } from 'react';
2+
import type { ColumnsType, FilterInfoType, SortInfoType } from 'react-data-table';
3+
import { Table } from 'react-data-table';
4+
5+
interface DataType {
6+
key: React.Key;
7+
name: string;
8+
age: number;
9+
address: string;
10+
}
11+
12+
const columns: ColumnsType<DataType> = [
13+
{
14+
title: 'Name',
15+
dataIndex: 'name',
16+
filters: [
17+
{ label: 'Edward King 2', value: '2' },
18+
{ label: 'Jim', value: 'Jim' },
19+
],
20+
filterMethod: (value: string, record: DataType) => record.name.includes(value),
21+
},
22+
{
23+
title: 'Age',
24+
dataIndex: 'age',
25+
sorter: (a: DataType, b: DataType) => a.age - b.age,
26+
},
27+
{
28+
title: 'Address',
29+
dataIndex: 'address',
30+
},
31+
];
32+
33+
const App = () => {
34+
const [current, setCurrent] = useState<number>(1);
35+
const [pageSize, setPageSize] = useState<number>(10);
36+
const [list, setList] = useState<DataType[]>([]);
37+
const [sorts, setSorts] = useState<SortInfoType[]>([]);
38+
const [filters, setFilters] = useState<FilterInfoType>({});
39+
40+
useEffect(() => {
41+
let data: DataType[] = [];
42+
for (let i = 0; i < 46; i++) {
43+
data.push({
44+
key: i,
45+
name: `Edward King ${i}`,
46+
age: 32 + i,
47+
address: `London, Park Lane no. ${i}`,
48+
});
49+
}
50+
data.push({
51+
key: 46,
52+
name: `Jim`,
53+
age: 78,
54+
address: `London, Park Lane no. ${78}`,
55+
});
56+
57+
Object.keys(filters).forEach((key: string) => {
58+
const value: string[] = filters[key];
59+
data = data.filter((d) => {
60+
if (value && value.length) {
61+
const res = value.some((v) => {
62+
return (d as any)[key].includes(v);
63+
});
64+
return res;
65+
}
66+
return true;
67+
});
68+
});
69+
70+
sorts.forEach((s) => {
71+
const sortFn = (a: DataType, b: DataType) => {
72+
const a1 = (a as any)[s.field].toString();
73+
const b1 = (b as any)[s.field].toString();
74+
return a1.localeCompare(b1);
75+
};
76+
data.sort((a, b) => {
77+
const compareResult = sortFn(a, b);
78+
if (compareResult !== 0) {
79+
return s.order === 'asc' ? compareResult : -compareResult;
80+
}
81+
return compareResult;
82+
});
83+
});
84+
85+
const start = (current - 1) * pageSize;
86+
data.slice(start, start + pageSize);
87+
setList(data);
88+
}, [current, pageSize, sorts, filters]);
89+
90+
const handleChange = (page: number, size: number) => {
91+
setCurrent(page);
92+
setPageSize(size);
93+
};
94+
95+
const handleSort = (sortInfo: SortInfoType) => {
96+
setSorts(sortInfo);
97+
};
98+
99+
const handleFilter = (info: FilterInfoType) => {
100+
setFilters(info);
101+
};
102+
103+
const renderInfo = ({ total }: { current: number; total: number; pageSize: number }) => {
104+
return `Total ${total} items`;
105+
};
106+
107+
const rowSelection = {
108+
onSelectAll: (selected: boolean, selectedRows: DataType[], changeRows: DataType[]) => {
109+
console.log(`selected: ${selected}`);
110+
console.log('selectedRows:', selectedRows);
111+
console.log('changeRows:', changeRows);
112+
},
113+
onChange: (selectedRowKeys: (string | number)[], selectedRows: DataType[]) => {
114+
console.log('selectedRowKeys:', selectedRowKeys, 'selectedRows: ', selectedRows);
115+
},
116+
onSelect: (
117+
record: DataType,
118+
selected: boolean,
119+
selectedRows: DataType[],
120+
nativeEvent: Event,
121+
) => {
122+
console.log(
123+
'record: ',
124+
record,
125+
`selected: ${selected}`,
126+
'selectedRows: ',
127+
selectedRows,
128+
'nativeEvent:',
129+
nativeEvent,
130+
);
131+
},
132+
};
133+
134+
return (
135+
<Table
136+
bordered
137+
columns={columns}
138+
dataSource={list}
139+
rowSelection={rowSelection}
140+
pagination={{
141+
align: 'right',
142+
total: list.length,
143+
current,
144+
pageSize,
145+
layout: ['prev', 'pager', 'next', 'sizes', 'jumper', renderInfo],
146+
onChange: handleChange,
147+
}}
148+
onSort={handleSort}
149+
onFilter={handleFilter}
150+
/>
151+
);
152+
};
153+
154+
export default App;

docs/demo/Pagination.tsx

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import React, { useState } from 'react';
2+
import type { ColumnsType } from 'react-data-table';
3+
import { Table } from 'react-data-table';
4+
5+
interface DataType {
6+
key: React.Key;
7+
name: string;
8+
age: number;
9+
address: string;
10+
// description: string;
11+
children?: DataType[];
12+
}
13+
14+
const columns: ColumnsType<DataType> = [
15+
{
16+
title: 'Name',
17+
dataIndex: 'name',
18+
filters: [
19+
{ label: 'Edward King 2', value: '2' },
20+
{ label: 'Jim', value: 'Jim' },
21+
],
22+
filterMethod: (value: string, record: DataType) => record.name.includes(value),
23+
},
24+
{
25+
title: 'Age',
26+
dataIndex: 'age',
27+
sorter: (a: DataType, b: DataType) => a.age - b.age,
28+
},
29+
{
30+
title: 'Address',
31+
dataIndex: 'address',
32+
},
33+
];
34+
35+
const data: DataType[] = [];
36+
for (let i = 0; i < 46; i++) {
37+
data.push({
38+
key: i,
39+
name: `Edward King ${i}`,
40+
age: 32 + i,
41+
address: `London, Park Lane no. ${i}`,
42+
// description: 'test description',
43+
children: [
44+
{
45+
key: `${i}_1`,
46+
name: 'Jim Green jr.',
47+
age: 25 + i,
48+
address: 'London No. 3 Lake Park',
49+
},
50+
],
51+
});
52+
}
53+
54+
const App = () => {
55+
const [current, setCurrent] = useState<number>(1);
56+
const [pageSize, setPageSize] = useState<number>(10);
57+
// const [expandedRowKeys, setExpandedRowKeys] = useState<number[]>([]);
58+
59+
const handleChange = (page: number, size: number) => {
60+
setCurrent(page);
61+
setPageSize(size);
62+
};
63+
64+
const renderInfo = ({ total }: { current: number; total: number; pageSize: number }) => {
65+
return `Total ${total} items`;
66+
};
67+
68+
const rowSelection = {
69+
onSelectAll: (selected: boolean, selectedRows: DataType[], changeRows: DataType[]) => {
70+
console.log(`selected: ${selected}`);
71+
console.log('selectedRows:', selectedRows);
72+
console.log('changeRows:', changeRows);
73+
},
74+
onChange: (selectedRowKeys: (string | number)[], selectedRows: DataType[]) => {
75+
console.log('selectedRowKeys:', selectedRowKeys, 'selectedRows: ', selectedRows);
76+
},
77+
onSelect: (
78+
record: DataType,
79+
selected: boolean,
80+
selectedRows: DataType[],
81+
nativeEvent: Event,
82+
) => {
83+
console.log(
84+
'record: ',
85+
record,
86+
`selected: ${selected}`,
87+
'selectedRows: ',
88+
selectedRows,
89+
'nativeEvent:',
90+
nativeEvent,
91+
);
92+
},
93+
};
94+
95+
return (
96+
<Table
97+
bordered
98+
columns={columns}
99+
dataSource={data}
100+
rowSelection={rowSelection}
101+
pagination={{
102+
align: 'right',
103+
current,
104+
pageSize,
105+
layout: ['sizes', 'prev', 'pager', 'next', 'jumper', renderInfo],
106+
onChange: handleChange,
107+
}}
108+
treeProps={
109+
{
110+
// expandedRowKeys,
111+
// onExpand: (expanded: boolean, record: DataType) => {
112+
// setExpandedRowKeys((prev) => {
113+
// return expanded ? [...prev, record.key] : prev.filter((p) => p !== record.key);
114+
// });
115+
// },
116+
// defaultExpandAllRows: true,
117+
// expandedRowRender: (record: DataType) => <p style={{ margin: 0 }}>{record.description}</p>,
118+
// onExpand: (expanded: boolean, record: DataType) => {
119+
// console.log(`expanded: ${expanded}`, 'record: ', record);
120+
// },
121+
}
122+
}
123+
/>
124+
);
125+
};
126+
127+
export default App;

docs/demo/Sort.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import type { ColumnsType } from 'react-data-table';
2+
import type { ColumnsType, SortInfoType } from 'react-data-table';
33
import { Table } from 'react-data-table';
44

55
interface DataType {
@@ -64,10 +64,9 @@ const data: DataType[] = [
6464
];
6565

6666
const App = () => {
67-
const handleSortCancel = (cancelName: ColumnsType<DataType>, order: 'asc' | 'desc') => {
68-
console.log(`取消排序字段: ${cancelName}`);
69-
console.log(order);
67+
const handleSort = (sortInfo: SortInfoType) => {
68+
console.log(sortInfo);
7069
};
71-
return <Table columns={columns} dataSource={data} bordered onSortCancel={handleSortCancel} />;
70+
return <Table columns={columns} dataSource={data} bordered onSort={handleSort} />;
7271
};
7372
export default App;

docs/demo/pagination.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
### 分页
2+
3+
<code src='./Pagination.tsx' desc='设置pagination实现分页'></code>
4+
5+
### 模拟服务端分页
6+
7+
<code src='./Mock.tsx' desc='通过onSort和onFilter拿到排序和过滤参数然后发送到服务端请求数据'></code>

src/Pagination/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { ReactComponent as LeftDoubleArrow } from '@/assets/left-double-arrow.sv
99
import { ReactComponent as RightDoubleArrow } from '@/assets/right-double-arrow.svg';
1010
import './index.less';
1111

12-
interface PaginationProps {
12+
export interface PaginationProps {
1313
className?: string;
1414
style?: React.CSSProperties;
1515
align?: 'center' | 'left' | 'right';

0 commit comments

Comments
 (0)