Comments (5)
- 复杂分组表头
- 复杂分组表头下 colStart 与 colEnd 不正确的问题
- 复杂分组表头下,且数据为空时 body colspan 不正确的问题
- 测试
(匿了
from table.
实现复杂分组表头最小侵入方案:
已有单元测试测试通过
新增 src/utils/convertUtil.ts
interface Column {
[key: string | symbol]: any;
};
interface Options {
children: string;
colSpan: string;
rowSpan: string;
hidden: string;
}
export function convertColumns<Columns extends readonly any[] = Column[]>(
columns: Columns,
options: Partial<Options> = {},
) {
if (!Array.isArray(columns) || columns.length === 0) {
return [] as unknown as Columns;
}
const defaultOptions = {
children: 'children',
colSpan: 'colSpan',
rowSpan: 'rowSpan',
hidden: 'hidden',
};
const {
children: childrenProp,
colSpan: colSpanProp,
rowSpan: rowSpanProp,
hidden: hiddenProp,
} = Object.assign({}, defaultOptions, options);
let specified = false;
let tree = columns.map((item) => ({ ...item } as Column));
let depthCurr = 0;
let depthNext = 0;
const nodePos: {
index: number;
total: number;
} = [{
index: tree.length,
total: tree.length,
}];
const rowSpans: number[] = [];
const columnsMap = new Map<number, Column[]>();
const treeMap = new Map<Column, Column[]>();
const branchLastSet = new Set<Column>();
while (tree.length > 0) {
depthCurr = depthNext;
nodePos.splice(depthCurr + 1);
rowSpans.splice(depthCurr);
nodePos[depthCurr].index--;
if (nodePos[depthCurr].index <= 0) {
depthNext = 0;
for (let i = nodePos.length - 1; i >= 0; i--) {
if (nodePos[i].index > 0) {
depthNext = i;
break;
}
}
}
const node = tree.shift();
if (!node || typeof node !== 'object' || node[hiddenProp]) {
continue;
}
// const pathKey = nodePos.reduce((acc, { index, total }) => {
// return `${acc}-${total - 1 - index}`;
// }, 'key');
const colSpanSpecified = node[colSpanProp];
const rowSpanSpecified = node[rowSpanProp];
const colSpan = node[colSpanProp] ?? 1;
const rowSpan = node[rowSpanProp] ?? 1;
node[colSpanProp] = colSpan;
node[rowSpanProp] = rowSpan;
if (!specified && (colSpan > 1 || rowSpan > 1)) {
specified = true;
}
const parentsRowCount = rowSpans.reduce((acc, num) => acc + num, 0);
if (!columnsMap.has(parentsRowCount)) {
columnsMap.set(parentsRowCount, []);
}
columnsMap.get(parentsRowCount).push(node);
let leaf = node[childrenProp];
delete node[childrenProp];
if (Array.isArray(leaf) && leaf.length > 0) {
depthNext = depthCurr + 1;
nodePos[depthNext] = { index: leaf.length, total: leaf.length };
rowSpans[depthCurr] = rowSpan;
leaf = leaf.map((item) => ({ ...item } as Column));
node.colSpanSpecified = colSpanSpecified;
if (!treeMap.has(node)) {
treeMap.set(node, []);
}
treeMap.get(node).push(...leaf);
tree = [...leaf, ...tree];
} else {
node.rowSpanSpecified = rowSpanSpecified;
node.parentsRowCount = parentsRowCount;
branchLastSet.add(node);
}
}
if (!specified) {
return columns;
}
// correct colSpan of parent column in default state
[...treeMap.keys()].reverse().forEach((column) => {
const { colSpanSpecified } = column;
delete column.colSpanSpecified;
if (column[hiddenProp] || Number.isInteger(colSpanSpecified)) {
return;
}
const children = treeMap.get(column);
column[colSpanProp] = children.reduce((acc, item) => {
return item[hiddenProp] ? acc : acc + item[colSpanProp];
}, 0);
});
let rowCountMax = 0;
branchLastSet.forEach((column) => {
const rowCount = column[rowSpanProp] + column.parentsRowCount;
if (rowCount > rowCountMax) {
rowCountMax = rowCount;
}
});
// correct rowSpan of column in default state
branchLastSet.forEach((column) => {
const { rowSpanSpecified, parentsRowCount } = column;
if (!Number.isInteger(rowSpanSpecified)) {
column[rowSpanProp] = rowCountMax - parentsRowCount;
}
delete column.rowSpanSpecified;
delete column.parentsRowCount;
});
const keys = [...columnsMap.keys()].sort();
for (let i = keys.length - 1; i >= 1; i--) {
const parent = columnsMap.get(keys[i - 1]);
parent[0][childrenProp] = columnsMap.get(keys[i]);
}
return columnsMap.get(0) as unknown as Columns;
}
在 src/Header/Header.tsx
的 fillRowCells
之前转换 rootColumns
:
diff --git a/src/Header/Header.tsx b/src/Header/Header.tsx
index f21b817b..07162562 100644
--- a/src/Header/Header.tsx
+++ b/src/Header/Header.tsx
@@ -2,6 +2,7 @@ import { useContext } from '@rc-component/context';
import * as React from 'react';
import TableContext, { responseImmutable } from '../context/TableContext';
import devRenderTimes from '../hooks/useRenderTimes';
+import { convertColumns } from '../utils/convertUtil';
import type {
CellType,
ColumnGroupType,
@@ -67,7 +68,7 @@ function parseHeaderRows<RecordType>(
}
// Generate `rows` cell data
- fillRowCells(rootColumns, 0);
+ fillRowCells(convertColumns<ColumnsType<RecordType>>(rootColumns), 0);
// Handle `rowSpan`
const rowCount = rows.length;
from table.
来个 PR?
from table.
from table.
新增复杂分组表头后会造成以下影响
-
复杂分组表头下的
colStart
colEnd
计算不正确在显式指定的
colSpan
或rowSpan
大于或者等于 2 时 -
table 数据为空时
.rc-table-placeholder .rc-table-cell
的colspan
值不正确在
flattenColumns.length
与实际表头列数
不一致时
改动的文件可能较多,继续在 #1118 追加完善,还是等待 merge 后再提交新的 PR 呢
from table.
Related Issues (20)
- antd table,已经设置了 scroll={{x:true}} ,但是有的时候表格显示正常,有的时候内容会撑出去,把整个页面给撑开 HOT 1
- 没有设置 `title` 的列,展示时表头变成了 `td`,应该是 `th` HOT 5
- 【咨询】请问rc-table 虚拟列表支持row动态高度吗
- flex布局时,resize窗口,表格无法自动适应
- Feature Request: Add Hierarchical Lines to Expandable Row RC Table
- 能否提供一个类似elementui table 树形数据与懒加载 的API
- npm run compile error !!! How to build component? HOT 1
- 虚拟滚动时,table getRowKey 索引index 为undefined
- 虚拟滚动时,固定列阴影消失 HOT 2
- VirtualTable 虚拟列表如何处理 load more?
- SSR with Nextjs14+
- Tailwind customization table
- Option to scroll smooth to row in scrollTo function HOT 1
- 虚拟滚动时,当数据源发生变更时,横向滚动被重置
- rc-table show fixed column shadown as expected when viewport zoom in/out with some width
- scroll更新时不能滚动 HOT 1
- fixFooter 判断不准确,导致 Summary 组件的 fixed 为 'top' 不符合预期
- expandedRowRender and colspan
- onScroll 事件的属性 firefox 和 chrome 表现不一致 HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from table.