Skip to content

Commit 6178246

Browse files
authored
fix: VirtualTable should force align column width (#1018)
* fix: scroll width fit * test: add test case * fix: ts * adjust header ts
1 parent 86f5cab commit 6178246

File tree

11 files changed

+228
-185
lines changed

11 files changed

+228
-185
lines changed

docs/examples/virtual.tsx

Lines changed: 143 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22
import '../../assets/index.less';
3-
import type { ColumnsType } from '../../src/interface';
43
import { VirtualTable } from '../../src';
4+
import type { ColumnsType } from '../../src/interface';
55

66
interface RecordType {
77
a: string;
@@ -12,152 +12,154 @@ interface RecordType {
1212
}
1313

1414
const columns: ColumnsType = [
15-
{ title: 'title1', dataIndex: 'a', key: 'a', width: 100, fixed: 'left' },
16-
{ title: 'title2', dataIndex: 'b', key: 'b', width: 100, fixed: 'left', ellipsis: true },
17-
{
18-
title: 'title3',
19-
dataIndex: 'c',
20-
key: 'c',
21-
onCell: (_, index) => {
22-
if (index % 4 === 0) {
23-
return {
24-
rowSpan: 3,
25-
};
26-
}
15+
{ title: 'title1', dataIndex: 'a', key: 'a', width: 100 },
16+
{ title: 'title1', dataIndex: 'a', key: 'a', width: 800 },
17+
{ title: 'title1', dataIndex: 'a', key: 'a', width: 100 },
18+
// { title: 'title2', dataIndex: 'b', key: 'b', width: 100, fixed: 'left', ellipsis: true },
19+
// {
20+
// title: 'title3',
21+
// dataIndex: 'c',
22+
// key: 'c',
23+
// onCell: (_, index) => {
24+
// if (index % 4 === 0) {
25+
// return {
26+
// rowSpan: 3,
27+
// };
28+
// }
2729

28-
if (index % 4 === 3) {
29-
return {
30-
rowSpan: 1,
31-
colSpan: 3,
32-
};
33-
}
30+
// if (index % 4 === 3) {
31+
// return {
32+
// rowSpan: 1,
33+
// colSpan: 3,
34+
// };
35+
// }
3436

35-
return {
36-
rowSpan: 0,
37-
};
38-
},
39-
},
40-
{
41-
title: 'title4',
42-
key: 'd',
43-
children: [
44-
// Children columns
45-
{
46-
title: 'title4-1',
47-
dataIndex: 'b',
48-
onCell: (_, index) => {
49-
if (index % 4 === 0) {
50-
return {
51-
colSpan: 3,
52-
};
53-
}
37+
// return {
38+
// rowSpan: 0,
39+
// };
40+
// },
41+
// },
42+
// {
43+
// title: 'title4',
44+
// key: 'd',
45+
// children: [
46+
// // Children columns
47+
// {
48+
// title: 'title4-1',
49+
// dataIndex: 'b',
50+
// onCell: (_, index) => {
51+
// if (index % 4 === 0) {
52+
// return {
53+
// colSpan: 3,
54+
// };
55+
// }
5456

55-
if (index % 4 === 3) {
56-
return {
57-
colSpan: 0,
58-
};
59-
}
60-
},
61-
},
62-
{
63-
title: 'title4-2',
64-
dataIndex: 'b',
65-
onCell: (_, index) => {
66-
if (index % 4 === 0 || index % 4 === 3) {
67-
return {
68-
colSpan: 0,
69-
};
70-
}
71-
},
72-
},
73-
],
74-
},
75-
{
76-
title: 'title6',
77-
dataIndex: 'b',
78-
key: 'f',
79-
onCell: (_, index) => {
80-
if (index % 4 === 0) {
81-
return {
82-
rowSpan: 0,
83-
colSpan: 0,
84-
};
85-
}
57+
// if (index % 4 === 3) {
58+
// return {
59+
// colSpan: 0,
60+
// };
61+
// }
62+
// },
63+
// },
64+
// {
65+
// title: 'title4-2',
66+
// dataIndex: 'b',
67+
// onCell: (_, index) => {
68+
// if (index % 4 === 0 || index % 4 === 3) {
69+
// return {
70+
// colSpan: 0,
71+
// };
72+
// }
73+
// },
74+
// },
75+
// ],
76+
// },
77+
// {
78+
// title: 'title6',
79+
// dataIndex: 'b',
80+
// key: 'f',
81+
// onCell: (_, index) => {
82+
// if (index % 4 === 0) {
83+
// return {
84+
// rowSpan: 0,
85+
// colSpan: 0,
86+
// };
87+
// }
8688

87-
if (index % 4 === 1) {
88-
return {
89-
rowSpan: 3,
90-
};
91-
}
89+
// if (index % 4 === 1) {
90+
// return {
91+
// rowSpan: 3,
92+
// };
93+
// }
9294

93-
return {
94-
rowSpan: 0,
95-
};
96-
},
97-
},
98-
{
99-
title: (
100-
<div>
101-
title7
102-
<br />
103-
<br />
104-
<br />
105-
Hello world!
106-
</div>
107-
),
108-
dataIndex: 'bk',
109-
key: 'g',
110-
},
111-
{
112-
title: 'title8',
113-
dataIndex: 'b',
114-
onCell: (_, index) => {
115-
if (index % 2 === 0) {
116-
return {
117-
rowSpan: 2,
118-
colSpan: 2,
119-
};
120-
}
95+
// return {
96+
// rowSpan: 0,
97+
// };
98+
// },
99+
// },
100+
// {
101+
// title: (
102+
// <div>
103+
// title7
104+
// <br />
105+
// <br />
106+
// <br />
107+
// Hello world!
108+
// </div>
109+
// ),
110+
// dataIndex: 'bk',
111+
// key: 'g',
112+
// },
113+
// {
114+
// title: 'title8',
115+
// dataIndex: 'b',
116+
// onCell: (_, index) => {
117+
// if (index % 2 === 0) {
118+
// return {
119+
// rowSpan: 2,
120+
// colSpan: 2,
121+
// };
122+
// }
121123

122-
return {
123-
rowSpan: 0,
124-
};
125-
},
126-
},
127-
{
128-
title: 'title9 i',
129-
dataIndex: 'b',
130-
key: 'i',
131-
onCell: () => ({
132-
colSpan: 0,
133-
}),
134-
},
135-
{ title: 'title10', dataIndex: 'b', key: 'j' },
136-
{
137-
title: 'title11',
138-
dataIndex: 'b',
139-
key: 'k',
140-
width: 50,
141-
fixed: 'right',
142-
onCell: (_, index) => {
143-
return {
144-
rowSpan: index % 2 === 0 ? 2 : 0,
145-
// colSpan: 2,
146-
};
147-
},
148-
},
149-
{
150-
title: 'title12',
151-
dataIndex: 'b',
152-
key: 'l',
153-
width: 100,
154-
fixed: 'right',
155-
onCell: () => {
156-
return {
157-
// colSpan: 0,
158-
};
159-
},
160-
},
124+
// return {
125+
// rowSpan: 0,
126+
// };
127+
// },
128+
// },
129+
// {
130+
// title: 'title9 i',
131+
// dataIndex: 'b',
132+
// key: 'i',
133+
// onCell: () => ({
134+
// colSpan: 0,
135+
// }),
136+
// },
137+
// { title: 'title10', dataIndex: 'b', key: 'j' },
138+
// {
139+
// title: 'title11',
140+
// dataIndex: 'b',
141+
// key: 'k',
142+
// width: 50,
143+
// fixed: 'right',
144+
// onCell: (_, index) => {
145+
// return {
146+
// rowSpan: index % 2 === 0 ? 2 : 0,
147+
// // colSpan: 2,
148+
// };
149+
// },
150+
// },
151+
// {
152+
// title: 'title12',
153+
// dataIndex: 'b',
154+
// key: 'l',
155+
// width: 100,
156+
// fixed: 'right',
157+
// onCell: () => {
158+
// return {
159+
// // colSpan: 0,
160+
// };
161+
// },
162+
// },
161163
];
162164

163165
export function cleanOnCell(cols: any = []) {

src/FixedHolder/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ const FixedHolder = React.forwardRef<HTMLDivElement, FixedHeaderProps<unknown>>(
9696

9797
// Check if all flattenColumns has width
9898
const allFlattenColumnsWithWidth = React.useMemo(
99-
() => flattenColumns.every(column => column.width >= 0),
99+
() => flattenColumns.every(column => column.width),
100100
[flattenColumns],
101101
);
102102

src/Table.tsx

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -264,9 +264,10 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco
264264
] = useExpand(props, mergedData, getRowKey);
265265

266266
// ====================== Column ======================
267+
const scrollX = scroll?.x;
267268
const [componentWidth, setComponentWidth] = React.useState(0);
268269

269-
const [columns, flattenColumns] = useColumns(
270+
const [columns, flattenColumns, flattenScrollX] = useColumns(
270271
{
271272
...props,
272273
...expandableConfig,
@@ -279,10 +280,11 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco
279280
expandIcon: mergedExpandIcon,
280281
expandIconColumnIndex: expandableConfig.expandIconColumnIndex,
281282
direction,
282-
scrollWidth: useInternalHooks && tailor && typeof scroll?.x === 'number' ? scroll.x : null,
283+
scrollWidth: useInternalHooks && tailor && typeof scrollX === 'number' ? scrollX : null,
283284
},
284285
useInternalHooks ? transformColumns : null,
285286
);
287+
const mergedScrollX = flattenScrollX ?? scrollX;
286288

287289
const columnContext = React.useMemo(
288290
() => ({
@@ -308,7 +310,7 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco
308310
const colWidths = React.useMemo(() => pureColWidths, [pureColWidths.join('_')]);
309311
const stickyOffsets = useStickyOffsets(colWidths, flattenColumns.length, direction);
310312
const fixHeader = scroll && validateValue(scroll.y);
311-
const horizonScroll = (scroll && validateValue(scroll.x)) || Boolean(expandableConfig.fixed);
313+
const horizonScroll = (scroll && validateValue(mergedScrollX)) || Boolean(expandableConfig.fixed);
312314
const fixColumn = horizonScroll && flattenColumns.some(({ fixed }) => fixed);
313315

314316
// Sticky
@@ -345,7 +347,7 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco
345347
scrollYStyle = { overflowY: 'hidden' };
346348
}
347349
scrollTableStyle = {
348-
width: scroll?.x === true ? 'auto' : scroll?.x,
350+
width: mergedScrollX === true ? 'auto' : mergedScrollX,
349351
minWidth: '100%',
350352
};
351353
}
@@ -502,7 +504,7 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco
502504
// When scroll.x is max-content, no need to fix table layout
503505
// it's width should stretch out to fit content
504506
if (fixColumn) {
505-
return scroll?.x === 'max-content' ? 'auto' : 'fixed';
507+
return mergedScrollX === 'max-content' ? 'auto' : 'fixed';
506508
}
507509
if (fixHeader || isSticky || flattenColumns.some(({ ellipsis }) => ellipsis)) {
508510
return 'fixed';
@@ -615,7 +617,7 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco
615617
// Fixed holder share the props
616618
const fixedHolderProps = {
617619
noData: !mergedData.length,
618-
maxContentScroll: horizonScroll && scroll.x === 'max-content',
620+
maxContentScroll: horizonScroll && mergedScrollX === 'max-content',
619621
...headerProps,
620622
...columnContext,
621623
direction,
@@ -730,6 +732,9 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco
730732

731733
const TableContextValue = React.useMemo(
732734
() => ({
735+
// Scroll
736+
scrollX: mergedScrollX,
737+
733738
// Table
734739
prefixCls,
735740
getComponent,
@@ -775,6 +780,9 @@ function Table<RecordType extends DefaultRecordType>(tableProps: TableProps<Reco
775780
childrenColumnName: mergedChildrenColumnName,
776781
}),
777782
[
783+
// Scroll
784+
mergedScrollX,
785+
778786
// Table
779787
prefixCls,
780788
getComponent,

0 commit comments

Comments
 (0)