@rainbow-oh/yee-c 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/Table/demo/components-override.d.ts +3 -0
- package/dist/cjs/Table/demo/components-override.js +54 -0
- package/dist/cjs/Table/demo/grouping.d.ts +3 -0
- package/dist/cjs/Table/demo/grouping.js +129 -0
- package/dist/cjs/Table/hooks/useColumns.d.ts +2 -2
- package/dist/cjs/Table/hooks/useColumns.js +15 -37
- package/dist/cjs/Table/index.d.ts +1 -1
- package/dist/cjs/Table/interface.d.ts +59 -8
- package/dist/cjs/Table/style/index.less +19 -1
- package/dist/cjs/Table/table.js +5 -7
- package/dist/cjs/Table/tbody/cell.d.ts +0 -1
- package/dist/cjs/Table/tbody/cell.js +0 -4
- package/dist/cjs/Table/tbody/index.js +19 -2
- package/dist/cjs/Table/tbody/row.js +15 -11
- package/dist/cjs/Table/theader/cell.js +7 -1
- package/dist/cjs/Table/theader/index.d.ts +5 -5
- package/dist/cjs/Table/theader/index.js +41 -27
- package/dist/cjs/Table/util/header.d.ts +23 -0
- package/dist/cjs/Table/util/header.js +109 -0
- package/dist/cjs/style/themes.css +1 -1
- package/dist/cjs/style/variables.css +1 -1
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/Table/demo/components-override.d.ts +3 -0
- package/dist/esm/Table/demo/components-override.js +86 -0
- package/dist/esm/Table/demo/grouping.d.ts +3 -0
- package/dist/esm/Table/demo/grouping.js +102 -0
- package/dist/esm/Table/hooks/useColumns.d.ts +2 -2
- package/dist/esm/Table/hooks/useColumns.js +24 -50
- package/dist/esm/Table/index.d.ts +1 -1
- package/dist/esm/Table/interface.d.ts +59 -8
- package/dist/esm/Table/style/index.less +19 -1
- package/dist/esm/Table/table.js +5 -7
- package/dist/esm/Table/tbody/cell.d.ts +0 -1
- package/dist/esm/Table/tbody/cell.js +0 -5
- package/dist/esm/Table/tbody/index.js +21 -2
- package/dist/esm/Table/tbody/row.js +19 -15
- package/dist/esm/Table/theader/cell.js +6 -2
- package/dist/esm/Table/theader/index.d.ts +5 -5
- package/dist/esm/Table/theader/index.js +48 -35
- package/dist/esm/Table/util/header.d.ts +23 -0
- package/dist/esm/Table/util/header.js +107 -0
- package/dist/esm/style/themes.css +1 -1
- package/dist/esm/style/variables.css +1 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/umd/yee-c.min.css +1 -1
- package/dist/umd/yee-c.min.js +1 -1
- package/package.json +1 -1
- package/src/Table/demo/components-override.tsx +49 -0
- package/src/Table/demo/grouping.tsx +104 -0
- package/src/Table/hooks/useColumns.ts +29 -46
- package/src/Table/index.en-US.md +31 -3
- package/src/Table/index.ts +4 -0
- package/src/Table/index.zh-CN.md +30 -2
- package/src/Table/interface.ts +66 -8
- package/src/Table/style/index.less +19 -1
- package/src/Table/table.tsx +5 -7
- package/src/Table/tbody/cell.tsx +0 -6
- package/src/Table/tbody/index.tsx +21 -2
- package/src/Table/tbody/row.tsx +25 -14
- package/src/Table/theader/cell.tsx +4 -0
- package/src/Table/theader/index.tsx +61 -42
- package/src/Table/util/header.ts +111 -0
- package/src/version.ts +1 -1
package/package.json
CHANGED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 自定义表格元素(可被外部接管)
|
|
3
|
+
*
|
|
4
|
+
* Table 暴露两个接缝供外部库(如 dnd-kit)接管行/体渲染:
|
|
5
|
+
* - components.body.tbody —— 替换 <tbody>,外部可在此包 SortableContext 等 Provider;
|
|
6
|
+
* - components.body.row —— 整行接管,消费方自行渲染 <tr> + 单元格,可在任意单元格里放拖拽手柄。
|
|
7
|
+
*
|
|
8
|
+
* Table 本身不依赖任何拖拽库;本 demo 不引入 dnd,仅证明替换点生效。
|
|
9
|
+
*/
|
|
10
|
+
import { Table } from '@rainbow-oh/yee-c';
|
|
11
|
+
import type { TableComponents, TableRowRendererProps } from '@rainbow-oh/yee-c';
|
|
12
|
+
import React from 'react';
|
|
13
|
+
|
|
14
|
+
// 替换 <tbody>:保持渲染 <tbody>,外部库可在此包 SortableContext。
|
|
15
|
+
const CustomTbody = (props: { className?: string; children?: React.ReactNode }) => (
|
|
16
|
+
<tbody className={props.className} data-custom-tbody>
|
|
17
|
+
{props.children}
|
|
18
|
+
</tbody>
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
// 整行接管:消费方渲染整 <tr> + 单元格,可在此放拖拽手柄等任意内容。
|
|
22
|
+
const CustomRow = ({ record, index, columns, rowKey }: TableRowRendererProps) => (
|
|
23
|
+
<tr data-row-key={rowKey} style={{ background: index % 2 === 0 ? '#f8fafc' : undefined }}>
|
|
24
|
+
<td style={{ width: 40, textAlign: 'center', color: '#2563eb', fontWeight: 700 }}>{index + 1}</td>
|
|
25
|
+
{columns.map((col) => (
|
|
26
|
+
<td key={String(col.key)}>{record[col.dataIndex || '']}</td>
|
|
27
|
+
))}
|
|
28
|
+
</tr>
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
export default () => {
|
|
32
|
+
const columns = [
|
|
33
|
+
{ title: 'Name', dataIndex: 'name', key: 'name' },
|
|
34
|
+
{ title: 'Age', dataIndex: 'age', key: 'age' },
|
|
35
|
+
{ title: 'Address', dataIndex: 'address', key: 'address' },
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
const dataSource = [
|
|
39
|
+
{ key: '1', name: 'John Brown', age: 32, address: 'New York No. 1 Lake Park' },
|
|
40
|
+
{ key: '2', name: 'Jim Green', age: 42, address: 'London No. 1 Lake Park' },
|
|
41
|
+
{ key: '3', name: 'Joe Black', age: 32, address: 'Sidney No. 1 Lake Park' },
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
const components: TableComponents = {
|
|
45
|
+
body: { tbody: CustomTbody, row: CustomRow },
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
return <Table columns={columns} dataSource={dataSource} components={components} />;
|
|
49
|
+
};
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type { ColumnProps, RowSelectionType } from '@rainbow-oh/yee-c';
|
|
2
|
+
import { Table } from '@rainbow-oh/yee-c';
|
|
3
|
+
import React, { useState } from 'react';
|
|
4
|
+
|
|
5
|
+
export default () => {
|
|
6
|
+
const [selectedRowKeys, setSelectedRowKeys] = useState<
|
|
7
|
+
Array<string | number>
|
|
8
|
+
>([]);
|
|
9
|
+
|
|
10
|
+
const columns: ColumnProps[] = [
|
|
11
|
+
{
|
|
12
|
+
title: 'Name',
|
|
13
|
+
dataIndex: 'name',
|
|
14
|
+
key: 'name',
|
|
15
|
+
fixed: 'left',
|
|
16
|
+
width: 120,
|
|
17
|
+
sorter: true,
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
title: 'Info',
|
|
21
|
+
key: 'info',
|
|
22
|
+
children: [
|
|
23
|
+
{ title: 'Age', dataIndex: 'age', key: 'age', width: 100, sorter: true },
|
|
24
|
+
{
|
|
25
|
+
title: 'Address',
|
|
26
|
+
dataIndex: 'address',
|
|
27
|
+
key: 'address',
|
|
28
|
+
width: 200,
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
title: 'Company',
|
|
34
|
+
key: 'company',
|
|
35
|
+
children: [
|
|
36
|
+
{
|
|
37
|
+
title: 'Name',
|
|
38
|
+
dataIndex: 'companyName',
|
|
39
|
+
key: 'companyName',
|
|
40
|
+
width: 180,
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
title: 'Address',
|
|
44
|
+
dataIndex: 'companyAddress',
|
|
45
|
+
key: 'companyAddress',
|
|
46
|
+
width: 220,
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
title: 'Action',
|
|
52
|
+
key: 'action',
|
|
53
|
+
fixed: 'right',
|
|
54
|
+
width: 100,
|
|
55
|
+
render: (record) => (
|
|
56
|
+
<a onClick={() => console.log(record)}>Edit</a>
|
|
57
|
+
),
|
|
58
|
+
},
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
const dataSource = [
|
|
62
|
+
{
|
|
63
|
+
key: '1',
|
|
64
|
+
name: 'John Brown',
|
|
65
|
+
age: 32,
|
|
66
|
+
address: 'New York No. 1 Lake Park',
|
|
67
|
+
companyName: 'Acme Inc.',
|
|
68
|
+
companyAddress: 'NY Office',
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
key: '2',
|
|
72
|
+
name: 'Jim Green',
|
|
73
|
+
age: 42,
|
|
74
|
+
address: 'London No. 1 Lake Park',
|
|
75
|
+
companyName: 'Globex',
|
|
76
|
+
companyAddress: 'London Office',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
key: '3',
|
|
80
|
+
name: 'Joe Black',
|
|
81
|
+
age: 28,
|
|
82
|
+
address: 'Sidney No. 1 Lake Park',
|
|
83
|
+
companyName: 'Initech',
|
|
84
|
+
companyAddress: 'Sidney Office',
|
|
85
|
+
},
|
|
86
|
+
];
|
|
87
|
+
|
|
88
|
+
const rowSelection = {
|
|
89
|
+
type: 'checkbox',
|
|
90
|
+
selectedRowKeys,
|
|
91
|
+
onChange: (keys: string[] | number[]) => setSelectedRowKeys(keys),
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
return (
|
|
95
|
+
<Table
|
|
96
|
+
columns={columns}
|
|
97
|
+
dataSource={dataSource}
|
|
98
|
+
rowKey="key"
|
|
99
|
+
rowSelection={rowSelection as RowSelectionType}
|
|
100
|
+
bordered
|
|
101
|
+
scroll={{ x: 1200 }}
|
|
102
|
+
/>
|
|
103
|
+
);
|
|
104
|
+
};
|
|
@@ -2,8 +2,18 @@ import React, { useMemo } from 'react';
|
|
|
2
2
|
import useDeepCompareMemo from '../../hooks/useDeepCompareMemo';
|
|
3
3
|
import deepClone from '../../utils/deepClone';
|
|
4
4
|
import { handleColumns } from '../util';
|
|
5
|
+
import {
|
|
6
|
+
flattenLeafColumns,
|
|
7
|
+
injectSelectionExpand,
|
|
8
|
+
parseHeaderRows,
|
|
9
|
+
} from '../util/header';
|
|
5
10
|
|
|
6
|
-
import {
|
|
11
|
+
import type {
|
|
12
|
+
ColumnProps,
|
|
13
|
+
ExpandableType,
|
|
14
|
+
RowSelectionType,
|
|
15
|
+
WrapedColumnProps,
|
|
16
|
+
} from '../interface';
|
|
7
17
|
|
|
8
18
|
export default function useColumns({
|
|
9
19
|
children,
|
|
@@ -22,15 +32,15 @@ export default function useColumns({
|
|
|
22
32
|
const shouldRenderExpand = !!expandable;
|
|
23
33
|
|
|
24
34
|
const getColumnsFromChild = (
|
|
25
|
-
|
|
35
|
+
childs: React.ReactElement<ColumnProps>[],
|
|
26
36
|
): Array<ColumnProps> | null => {
|
|
27
|
-
const
|
|
28
|
-
React.Children.forEach(
|
|
37
|
+
const cols: ColumnProps[] = [];
|
|
38
|
+
React.Children.forEach(childs, (child) => {
|
|
29
39
|
if (child) {
|
|
30
|
-
|
|
40
|
+
cols.push({ ...(child.props as ColumnProps) });
|
|
31
41
|
}
|
|
32
42
|
});
|
|
33
|
-
return
|
|
43
|
+
return cols.length ? cols : null;
|
|
34
44
|
};
|
|
35
45
|
|
|
36
46
|
const childColumns: Array<ColumnProps> | null = useMemo(() => {
|
|
@@ -39,48 +49,21 @@ export default function useColumns({
|
|
|
39
49
|
: null;
|
|
40
50
|
}, [children]);
|
|
41
51
|
|
|
42
|
-
//
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
if (expandable) {
|
|
55
|
-
const { index = 1, visible = true } = expandable;
|
|
56
|
-
const loc = index ? index - 1 : rowSelection ? 1 : 0;
|
|
57
|
-
if (visible !== false) {
|
|
58
|
-
result.splice(loc, 0, {
|
|
59
|
-
width: 50,
|
|
60
|
-
...expandable,
|
|
61
|
-
key: 'YEE_EXPAND_COL',
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
result = handleColumns(result);
|
|
66
|
-
return result;
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
// const [mergedColumns, setMergedColumns] = React.useState(
|
|
70
|
-
// wrapColumns(childColumns || columns || []),
|
|
71
|
-
// );
|
|
72
|
-
|
|
73
|
-
// useDeepCompareEffect(() => {
|
|
74
|
-
// const merged = wrapColumns(childColumns || columns || []);
|
|
75
|
-
// setMergedColumns(merged);
|
|
76
|
-
// }, [childColumns, columns, shouldRenderSelection, shouldRenderExpand]);
|
|
77
|
-
|
|
78
|
-
const mergedColumns = useDeepCompareMemo(() => {
|
|
79
|
-
return wrapColumns(childColumns || columns || []);
|
|
52
|
+
// Build the column tree (with selection/expand injected at the top level),
|
|
53
|
+
// then derive both the flat leaf columns (body/colgroup/summary/sorter) and
|
|
54
|
+
// the 2D header rows (thead multi-level rendering).
|
|
55
|
+
const { wrapedColumns, headerRows } = useDeepCompareMemo(() => {
|
|
56
|
+
const base = (deepClone(childColumns || columns || []) ||
|
|
57
|
+
[]) as WrapedColumnProps[];
|
|
58
|
+
const tree = injectSelectionExpand(base, rowSelection, expandable);
|
|
59
|
+
const leaves = flattenLeafColumns(tree);
|
|
60
|
+
const wraped = handleColumns(leaves);
|
|
61
|
+
const rows = parseHeaderRows(tree);
|
|
62
|
+
return { wrapedColumns: wraped, headerRows: rows };
|
|
80
63
|
}, [childColumns, columns, shouldRenderSelection, shouldRenderExpand]);
|
|
81
64
|
|
|
82
65
|
return {
|
|
83
|
-
wrapedColumns
|
|
84
|
-
|
|
66
|
+
wrapedColumns,
|
|
67
|
+
headerRows,
|
|
85
68
|
};
|
|
86
69
|
}
|
package/src/Table/index.en-US.md
CHANGED
|
@@ -22,6 +22,8 @@ A table displays rows of data.
|
|
|
22
22
|
<code src="./demo/expand.tsx" title="Expandable" description="Expandable rows"></code>
|
|
23
23
|
<code src="./demo/pagination.tsx" title="Pagination" description="Table with pagination"></code>
|
|
24
24
|
<code src="./demo/column-filter.tsx" title="column filter" description="Table column filter"></code>
|
|
25
|
+
<code src="./demo/grouping.tsx" title="Grouping" description="Multi-level header"></code>
|
|
26
|
+
<code src="./demo/components-override.tsx" title="components override" description="tbody / row rendering that can be taken over by external libs (e.g. dnd-kit)"></code>
|
|
25
27
|
## API
|
|
26
28
|
|
|
27
29
|
### TableProps
|
|
@@ -33,7 +35,7 @@ A table displays rows of data.
|
|
|
33
35
|
| style | `React.CSSProperties` | Custom root style | - |
|
|
34
36
|
| classNames | `Partial<Record<SemanticType, string>>` | Semantic class names | - |
|
|
35
37
|
| styles | `Partial<Record<SemanticType, React.CSSProperties>>` | Semantic styles | - |
|
|
36
|
-
| components | `
|
|
38
|
+
| components | [`TableComponents`](#tablecomponents) | Custom table elements, can be taken over by external libs (e.g. dnd-kit) | - |
|
|
37
39
|
| bordered | `boolean` | Show border | - |
|
|
38
40
|
| columns | `ColumnProps[]` | Table column configuration | - |
|
|
39
41
|
| children | `Array<React.ReactElement<ColumnProps>> | React.ReactElement<ColumnProps>` | Children elements | - |
|
|
@@ -77,7 +79,7 @@ A table displays rows of data.
|
|
|
77
79
|
| width | `number \| string` | Column width | - |
|
|
78
80
|
| title | `React.ReactNode` | Column title | - |
|
|
79
81
|
| helper | `string \| React.ReactNode` | Help icon for column header | - |
|
|
80
|
-
| children | `
|
|
82
|
+
| children | `ColumnProps[]` | Sub-columns for header grouping (multi-level header); use `render` for custom cell content | - |
|
|
81
83
|
| onCell | `(record: object, rowIndex: number) => object` | Cell props | - |
|
|
82
84
|
| onHeaderCell | `(column: ColumnProps) => object` | Header cell props | - |
|
|
83
85
|
| render | `(record: object, rowIndex: number) => React.ReactNode` | Custom render | - |
|
|
@@ -113,4 +115,30 @@ A table displays rows of data.
|
|
|
113
115
|
| rowExpandable | `(record: object) => boolean` | Whether row is expandable | - |
|
|
114
116
|
| onExpand | `(expanded: boolean, record: Record<string, any>) => void` | Expand callback | - |
|
|
115
117
|
| onExpandedRowsChange | `(expandedKeys?: Array<number \| string>) => void` | Expanded rows change callback | - |
|
|
116
|
-
| expandedRowRender | `(record, index, page) => React.ReactNode` | Expanded row render | - |
|
|
118
|
+
| expandedRowRender | `(record, index, page) => React.ReactNode` | Expanded row render | - |
|
|
119
|
+
|
|
120
|
+
### TableComponents
|
|
121
|
+
|
|
122
|
+
Seams exposed by Table so an external lib (e.g. dnd-kit) can take over rendering. **Table itself has no dependency on any drag library** — it only provides replacement points; drag logic is owned by the consumer.
|
|
123
|
+
|
|
124
|
+
| Property | Type | Description | Default |
|
|
125
|
+
| --- | --- | --- | --- |
|
|
126
|
+
| body | `TableBodyComponents` | Replaceable body elements | - |
|
|
127
|
+
|
|
128
|
+
#### TableBodyComponents
|
|
129
|
+
|
|
130
|
+
| Property | Type | Description | Default |
|
|
131
|
+
| --- | --- | --- | --- |
|
|
132
|
+
| tbody | `React.ElementType` | Replace `<tbody>`; commonly used to wrap a `SortableContext` provider | - |
|
|
133
|
+
| row | `React.ComponentType<TableRowRendererProps>` | Full-row takeover: consumer renders the whole `<tr>` + cells (can place a drag handle, etc.) | - |
|
|
134
|
+
|
|
135
|
+
> Under full-row takeover, the consumer-rendered row **does not** get Table's auto selection / expand / colSpan / stripe row-level features. Table's pagination / sorting / filtering still apply (they mutate `dataSource`).
|
|
136
|
+
|
|
137
|
+
#### TableRowRendererProps (received by components.body.row)
|
|
138
|
+
|
|
139
|
+
| Property | Type | Description |
|
|
140
|
+
| --- | --- | --- |
|
|
141
|
+
| record | `Record<string, any>` | Current row data |
|
|
142
|
+
| index | `number` | Current row index |
|
|
143
|
+
| columns | `WrapedColumnProps[]` | Table-resolved columns |
|
|
144
|
+
| rowKey | `string \| number` | Current row key value; usable as sortable id |
|
package/src/Table/index.ts
CHANGED
package/src/Table/index.zh-CN.md
CHANGED
|
@@ -23,9 +23,11 @@ toc: 'content'
|
|
|
23
23
|
<code src="./demo/expand.tsx" title="可展开" description="可展开行的表格"></code>
|
|
24
24
|
<code src="./demo/pagination.tsx" title="分页" description="带分页的表格"></code>
|
|
25
25
|
<code src="./demo/merge-cell.tsx" title="合并单元格" description="合并单元格的表格"></code>
|
|
26
|
+
<code src="./demo/grouping.tsx" title="表头分组" description="多级表头"></code>
|
|
26
27
|
<code src="./demo/summary.tsx" title="统计" description="表格的统计行"></code>
|
|
27
28
|
<code src="./demo/filter.tsx" title="筛选" description="表格的筛选功能"></code>
|
|
28
29
|
<code src="./demo/column-filter.tsx" title="列筛选" description="表格的列筛选功能"></code>
|
|
30
|
+
<code src="./demo/components-override.tsx" title="自定义表格元素" description="可被外部(如 dnd-kit)接管的 tbody / 行渲染"></code>
|
|
29
31
|
|
|
30
32
|
## API
|
|
31
33
|
|
|
@@ -38,7 +40,7 @@ toc: 'content'
|
|
|
38
40
|
| style | `React.CSSProperties` | 自定义根样式 | - |
|
|
39
41
|
| classNames | `Partial<Record<SemanticType, string>>` | 语义化类名 | - |
|
|
40
42
|
| styles | `Partial<Record<SemanticType, React.CSSProperties>>` | 语义化样式 | - |
|
|
41
|
-
| components | `
|
|
43
|
+
| components | [`TableComponents`](#tablecomponents) | 自定义表格元素,可被外部(如 dnd-kit)接管 | - |
|
|
42
44
|
| bordered | `boolean` | 是否展示外边框和列边框 | - |
|
|
43
45
|
| columns | `ColumnProps[]` | 表格列的配置信息 | - |
|
|
44
46
|
| children | `Array<React.ReactElement<ColumnProps>> \| React.ReactElement<ColumnProps>` | 子元素 | - |
|
|
@@ -82,7 +84,7 @@ toc: 'content'
|
|
|
82
84
|
| width | `number \| string` | 设置宽度 | - |
|
|
83
85
|
| title | `React.ReactNode` | 设置列头显示文本 | - |
|
|
84
86
|
| helper | `string \| React.ReactNode` | 设置表头help 帮助图标 | - |
|
|
85
|
-
| children | `
|
|
87
|
+
| children | `ColumnProps[]` | 子列,用于表头分组(多级表头);自定义单元格内容请用 `render` | - |
|
|
86
88
|
| onCell | `(record: object, rowIndex: number) => object` | 设置单元格属性 | - |
|
|
87
89
|
| onHeaderCell | `(column: ColumnProps) => object` | 设置表头单元格属性 | - |
|
|
88
90
|
| render | `(record: Record<string, any>, rowIndex: number) => React.ReactNode` | 自定义渲染函数 | - |
|
|
@@ -119,3 +121,29 @@ toc: 'content'
|
|
|
119
121
|
| onExpand | `(expanded: boolean, record: Record<string, any>) => void` | 点击展开图标时触发 | - |
|
|
120
122
|
| onExpandedRowsChange | `(expandedKeys?: Array<number \| string>) => void` | 展开的行变化时触发 | - |
|
|
121
123
|
| expandedRowRender | `(record, index, page) => React.ReactNode` | 额外的展开行 | - |
|
|
124
|
+
|
|
125
|
+
### TableComponents
|
|
126
|
+
|
|
127
|
+
Table 暴露的"可被外部接管"接缝。**Table 本身不依赖任何拖拽库**,仅提供替换点;dnd 等逻辑由消费方持有。
|
|
128
|
+
|
|
129
|
+
| 属性名 | 类型 | 描述 | 默认值 |
|
|
130
|
+
| ------ | --------------------- | ---------------- | ------ |
|
|
131
|
+
| body | `TableBodyComponents` | 可替换的表体元素 | - |
|
|
132
|
+
|
|
133
|
+
#### TableBodyComponents
|
|
134
|
+
|
|
135
|
+
| 属性名 | 类型 | 描述 | 默认值 |
|
|
136
|
+
| ------ | ------------------------------------------ | ------------------------------------------------------------- | ------ |
|
|
137
|
+
| tbody | `React.ElementType` | 替换 `<tbody>`,常用于在外部包 `SortableContext` 等 Provider | - |
|
|
138
|
+
| row | `React.ComponentType<TableRowRendererProps>` | 整行接管:消费方自行渲染 `<tr>` + 单元格(可放拖拽手柄等) | - |
|
|
139
|
+
|
|
140
|
+
> 整行接管时,消费方渲染的行**不享受** Table 的自动 selection / expand / colSpan / stripe 等行级特性;Table 的分页 / 排序 / 筛选仍生效(它们改变 `dataSource`)。
|
|
141
|
+
|
|
142
|
+
#### TableRowRendererProps(components.body.row 收到的 props)
|
|
143
|
+
|
|
144
|
+
| 属性名 | 类型 | 描述 |
|
|
145
|
+
| -------- | ----------------------- | --------------------------------- |
|
|
146
|
+
| record | `Record<string, any>` | 当前行数据 |
|
|
147
|
+
| index | `number` | 当前行索引 |
|
|
148
|
+
| columns | `WrapedColumnProps[]` | Table 解析后的列 |
|
|
149
|
+
| rowKey | `string \| number` | 当前行 key 值,可作 sortable id |
|
package/src/Table/interface.ts
CHANGED
|
@@ -70,6 +70,14 @@ export interface HeadCellProps extends Omit<WrapedColumnProps, 'title'> {
|
|
|
70
70
|
internalFilters?: { [dataIndex: string]: boolean }; // Whether this column is filtered
|
|
71
71
|
onSort?: (dataIndex: string, sorter: any) => void;
|
|
72
72
|
onInternalFilter?: (dataIndex: string, value: string) => void;
|
|
73
|
+
/**
|
|
74
|
+
* Horizontal span, used for grouped header cells
|
|
75
|
+
*/
|
|
76
|
+
colSpan?: number;
|
|
77
|
+
/**
|
|
78
|
+
* Vertical span, used for grouped header cells
|
|
79
|
+
*/
|
|
80
|
+
rowSpan?: number;
|
|
73
81
|
}
|
|
74
82
|
|
|
75
83
|
// Row selection config
|
|
@@ -252,9 +260,9 @@ export interface ColumnProps {
|
|
|
252
260
|
*/
|
|
253
261
|
helper?: string | React.ReactNode;
|
|
254
262
|
/**
|
|
255
|
-
*
|
|
263
|
+
* Sub-columns for header grouping (multi-level header). Use cell `render` for custom cell content.
|
|
256
264
|
*/
|
|
257
|
-
children?:
|
|
265
|
+
children?: ColumnProps[];
|
|
258
266
|
/**
|
|
259
267
|
* Set cell properties
|
|
260
268
|
*/
|
|
@@ -287,8 +295,55 @@ export interface WrapedColumnProps
|
|
|
287
295
|
*/
|
|
288
296
|
}
|
|
289
297
|
|
|
298
|
+
/**
|
|
299
|
+
* A header cell resolved from the column tree, with computed span info for multi-level headers.
|
|
300
|
+
*/
|
|
301
|
+
export interface HeaderCell {
|
|
302
|
+
/**
|
|
303
|
+
* The source wrapped column (leaf or group)
|
|
304
|
+
*/
|
|
305
|
+
column: WrapedColumnProps;
|
|
306
|
+
/**
|
|
307
|
+
* Horizontal span (number of leaf columns covered)
|
|
308
|
+
*/
|
|
309
|
+
colSpan: number;
|
|
310
|
+
/**
|
|
311
|
+
* Vertical span (number of header rows covered)
|
|
312
|
+
*/
|
|
313
|
+
rowSpan: number;
|
|
314
|
+
/**
|
|
315
|
+
* Whether this cell has sub-columns (group header)
|
|
316
|
+
*/
|
|
317
|
+
hasSubColumns?: boolean;
|
|
318
|
+
}
|
|
319
|
+
|
|
290
320
|
type DownloadType = ButtonProps;
|
|
291
321
|
|
|
322
|
+
/**
|
|
323
|
+
* 行接管渲染器收到的 props(components.body.row)
|
|
324
|
+
*/
|
|
325
|
+
export interface TableRowRendererProps {
|
|
326
|
+
record: Record<string, any>;
|
|
327
|
+
index: number;
|
|
328
|
+
columns: WrapedColumnProps[];
|
|
329
|
+
/** 当前行 key 值(= record[rowKey]),可作 sortable id */
|
|
330
|
+
rowKey: string | number;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* 可被外部接管的 <tbody> / 行渲染
|
|
335
|
+
*/
|
|
336
|
+
export interface TableBodyComponents {
|
|
337
|
+
/** 替换 <tbody>;常用于在外部包 SortableContext 等 Provider */
|
|
338
|
+
tbody?: React.ElementType;
|
|
339
|
+
/** 整行接管:消费方自行渲染 <tr> + 单元格(含拖拽手柄等) */
|
|
340
|
+
row?: React.ComponentType<TableRowRendererProps>;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
export interface TableComponents {
|
|
344
|
+
body?: TableBodyComponents;
|
|
345
|
+
}
|
|
346
|
+
|
|
292
347
|
export type SemanticProps = {
|
|
293
348
|
/**
|
|
294
349
|
* Semantic class names
|
|
@@ -301,7 +356,7 @@ export type SemanticProps = {
|
|
|
301
356
|
/**
|
|
302
357
|
* Custom table elements
|
|
303
358
|
*/
|
|
304
|
-
components?:
|
|
359
|
+
components?: TableComponents;
|
|
305
360
|
};
|
|
306
361
|
|
|
307
362
|
export interface HeaderProps extends SemanticProps {
|
|
@@ -358,11 +413,14 @@ export interface TableRowProps {
|
|
|
358
413
|
stripe?: boolean;
|
|
359
414
|
expandedKeyType?: string;
|
|
360
415
|
onRow?: (record: Record<string, any>, index: number) => Record<string, any>;
|
|
361
|
-
rowClassName?: (
|
|
416
|
+
rowClassName?: (
|
|
417
|
+
record: Record<string, any>,
|
|
418
|
+
index: number,
|
|
419
|
+
) => string | undefined;
|
|
362
420
|
rowStyle?: (
|
|
363
421
|
record: Record<string, any>,
|
|
364
422
|
index: number,
|
|
365
|
-
) => React.CSSProperties;
|
|
423
|
+
) => React.CSSProperties | undefined;
|
|
366
424
|
onDoubleClick?: (
|
|
367
425
|
record: Record<string, any>,
|
|
368
426
|
event: React.MouseEvent<HTMLTableRowElement>,
|
|
@@ -473,7 +531,7 @@ export interface TableProps
|
|
|
473
531
|
/**
|
|
474
532
|
* Custom table elements
|
|
475
533
|
*/
|
|
476
|
-
components?:
|
|
534
|
+
components?: TableComponents;
|
|
477
535
|
/**
|
|
478
536
|
* Whether to show outer and column borders
|
|
479
537
|
*/
|
|
@@ -519,11 +577,11 @@ export interface TableProps
|
|
|
519
577
|
/**
|
|
520
578
|
* Row class name, unlike classNames, this prop can be set dynamically via a function
|
|
521
579
|
*/
|
|
522
|
-
rowClassName?: (record: object) => string;
|
|
580
|
+
rowClassName?: (record: object) => string | undefined;
|
|
523
581
|
/**
|
|
524
582
|
* Row style, unlike styles, this prop can be set dynamically via a function
|
|
525
583
|
*/
|
|
526
|
-
rowStyle?: (record: object) => React.CSSProperties;
|
|
584
|
+
rowStyle?: (record: object) => React.CSSProperties | undefined;
|
|
527
585
|
/**
|
|
528
586
|
* Pagination config
|
|
529
587
|
*/
|
|
@@ -153,7 +153,25 @@
|
|
|
153
153
|
|
|
154
154
|
&-tbody {
|
|
155
155
|
@{pls}-cell {
|
|
156
|
-
background-color: var(--yee-table-cell-bg-color,
|
|
156
|
+
background-color: var(--yee-table-cell-bg-color, inherit);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
@{pls}-row {
|
|
160
|
+
&:hover {
|
|
161
|
+
background-color: var(--yee-table-tbody-tr-hover-bg-color);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
&-odd-row {
|
|
167
|
+
> @{pls}-cell {
|
|
168
|
+
background-color: var(--yee-table-odd-row-bg-color);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
&-even-row {
|
|
173
|
+
> @{pls}-cell {
|
|
174
|
+
background-color: var(--yee-table-even-row-bg-color);
|
|
157
175
|
}
|
|
158
176
|
}
|
|
159
177
|
|
package/src/Table/table.tsx
CHANGED
|
@@ -75,7 +75,7 @@ const Table = React.forwardRef<HTMLDivElement, TableProps>((baseprops, ref) => {
|
|
|
75
75
|
: [];
|
|
76
76
|
}, [dataSource, rowKey, getRowKey]);
|
|
77
77
|
|
|
78
|
-
const { wrapedColumns,
|
|
78
|
+
const { wrapedColumns, headerRows } = useColumns({
|
|
79
79
|
children,
|
|
80
80
|
columns: propColumns,
|
|
81
81
|
expandable,
|
|
@@ -92,7 +92,7 @@ const Table = React.forwardRef<HTMLDivElement, TableProps>((baseprops, ref) => {
|
|
|
92
92
|
data: sortedData,
|
|
93
93
|
sorters,
|
|
94
94
|
onSort,
|
|
95
|
-
} = useSorter({ data: filteredData, columns });
|
|
95
|
+
} = useSorter({ data: filteredData, columns: wrapedColumns });
|
|
96
96
|
// Pagination
|
|
97
97
|
const { pageData, current, pageSize, pagination } = usePagination({
|
|
98
98
|
data: sortedData,
|
|
@@ -120,7 +120,6 @@ const Table = React.forwardRef<HTMLDivElement, TableProps>((baseprops, ref) => {
|
|
|
120
120
|
const {
|
|
121
121
|
selectedRowKeys,
|
|
122
122
|
checkedAll,
|
|
123
|
-
pageDataRowKeys,
|
|
124
123
|
onCheckAll,
|
|
125
124
|
onChange: onSelectionChange,
|
|
126
125
|
} = useSelection({ pageData, dataSource, getRowKey, rowSelection, allKeys });
|
|
@@ -180,7 +179,7 @@ const Table = React.forwardRef<HTMLDivElement, TableProps>((baseprops, ref) => {
|
|
|
180
179
|
prefixCls={prefixCls}
|
|
181
180
|
header={header}
|
|
182
181
|
download={download}
|
|
183
|
-
columns={
|
|
182
|
+
columns={wrapedColumns}
|
|
184
183
|
pageData={pageData}
|
|
185
184
|
dataSource={dataSource}
|
|
186
185
|
/>
|
|
@@ -195,8 +194,7 @@ const Table = React.forwardRef<HTMLDivElement, TableProps>((baseprops, ref) => {
|
|
|
195
194
|
return (
|
|
196
195
|
<THeader
|
|
197
196
|
{...ths}
|
|
198
|
-
|
|
199
|
-
pageDataRowKeys={pageDataRowKeys}
|
|
197
|
+
headerRows={headerRows}
|
|
200
198
|
checkedAll={checkedAll}
|
|
201
199
|
sorters={sorters}
|
|
202
200
|
onSort={onSort}
|
|
@@ -243,7 +241,7 @@ const Table = React.forwardRef<HTMLDivElement, TableProps>((baseprops, ref) => {
|
|
|
243
241
|
<TableCtx.Provider
|
|
244
242
|
value={{
|
|
245
243
|
prefixCls,
|
|
246
|
-
columns,
|
|
244
|
+
columns: wrapedColumns,
|
|
247
245
|
classNames,
|
|
248
246
|
styles,
|
|
249
247
|
components,
|
package/src/Table/tbody/cell.tsx
CHANGED
|
@@ -11,7 +11,6 @@ export interface BodyCellProps {
|
|
|
11
11
|
fixedToLeft?: number;
|
|
12
12
|
current: number;
|
|
13
13
|
pageSize: number;
|
|
14
|
-
children?: (record: Record<string, any>, index: number) => React.ReactNode;
|
|
15
14
|
}
|
|
16
15
|
|
|
17
16
|
const TableCell: React.FC<BodyCellProps> = (props) => {
|
|
@@ -27,7 +26,6 @@ const TableCell: React.FC<BodyCellProps> = (props) => {
|
|
|
27
26
|
className,
|
|
28
27
|
styles,
|
|
29
28
|
classNames,
|
|
30
|
-
children,
|
|
31
29
|
onCell,
|
|
32
30
|
render,
|
|
33
31
|
} = column;
|
|
@@ -38,10 +36,6 @@ const TableCell: React.FC<BodyCellProps> = (props) => {
|
|
|
38
36
|
if (render) {
|
|
39
37
|
return typeof render === 'function' ? render(record, rowIndex) : render;
|
|
40
38
|
}
|
|
41
|
-
if (typeof children === 'function') {
|
|
42
|
-
// @ts-ignore
|
|
43
|
-
return children(record, rowIndex);
|
|
44
|
-
}
|
|
45
39
|
return (
|
|
46
40
|
<div
|
|
47
41
|
className={clsx(`${prefixCls}-cell-inner`, classNames?.inner)}
|