Skip to content

Commit 39c323a

Browse files
fix: insert header content into body measure rows for column width calculation (#1331)
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
1 parent 8a7dac0 commit 39c323a

File tree

9 files changed

+390
-323
lines changed

9 files changed

+390
-323
lines changed

docs/examples/stickyHeader.tsx

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import React, { useRef } from 'react';
33
import Table from 'rc-table';
44
import '../../assets/index.less';
5-
import type { ColumnType } from '@/interface';
5+
import type { ColumnType, ColumnsType } from '@/interface';
66

77
interface RecordType {
88
a?: string;
@@ -86,6 +86,34 @@ const columnsWithWidth: ColumnType<RecordType>[] = [
8686
{ title: 'title4', dataIndex: 'd', key: 'd', width: 100 },
8787
];
8888

89+
const columnsGrouped: ColumnsType<any> = [
90+
{
91+
title: '',
92+
dataIndex: 'productType',
93+
key: 'productType',
94+
rowSpan: 2,
95+
rowScope: 'row',
96+
},
97+
{
98+
title: 'Mars',
99+
dataIndex: 'mars',
100+
key: 'mars',
101+
children: [
102+
{ title: 'ProducedProducedProduced', dataIndex: 'producedMars', key: 'producedMars' },
103+
{ title: 'Sold', dataIndex: 'soldMars', key: 'soldMars' },
104+
],
105+
},
106+
{
107+
title: 'Venus',
108+
dataIndex: 'venus',
109+
key: 'venus',
110+
children: [
111+
{ title: 'Produced Produced', dataIndex: 'producedVenus', key: 'producedVenus' },
112+
{ title: 'Sold Sold Sold Sold', dataIndex: 'soldVenus', key: 'soldVenus' },
113+
],
114+
},
115+
];
116+
89117
const data = [
90118
{ a: '123', key: '1' },
91119
{ a: 'cdd', b: 'edd', key: '2' },
@@ -270,6 +298,24 @@ const Demo = () => {
270298
}}
271299
sticky
272300
/>
301+
<br />
302+
<Table
303+
columns={fixedColumns.map(column => ({ ...column, width: undefined }))}
304+
data={[{}]}
305+
scroll={{
306+
x: 'max-content',
307+
}}
308+
sticky
309+
/>
310+
<br />
311+
<Table
312+
columns={columnsGrouped}
313+
data={[{}, {}]}
314+
scroll={{
315+
x: 'max-content',
316+
}}
317+
sticky
318+
/>
273319
</div>
274320
);
275321
};

src/Body/MeasureCell.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import * as React from 'react';
22
import ResizeObserver from 'rc-resize-observer';
33
import useLayoutEffect from 'rc-util/lib/hooks/useLayoutEffect';
4+
import type { ColumnType } from '../interface';
45

56
export interface MeasureCellProps {
67
columnKey: React.Key;
78
onColumnResize: (key: React.Key, width: number) => void;
9+
column?: ColumnType<any>;
810
}
911

10-
export default function MeasureCell({ columnKey, onColumnResize }: MeasureCellProps) {
12+
export default function MeasureCell({ columnKey, onColumnResize, column }: MeasureCellProps) {
1113
const cellRef = React.useRef<HTMLTableCellElement>();
1214

1315
useLayoutEffect(() => {
@@ -18,8 +20,13 @@ export default function MeasureCell({ columnKey, onColumnResize }: MeasureCellPr
1820

1921
return (
2022
<ResizeObserver data={columnKey}>
21-
<td ref={cellRef} style={{ padding: 0, border: 0, height: 0 }}>
22-
<div style={{ height: 0, overflow: 'hidden' }}>&nbsp;</div>
23+
<td
24+
ref={cellRef}
25+
style={{ paddingTop: 0, paddingBottom: 0, borderTop: 0, borderBottom: 0, height: 0 }}
26+
>
27+
<div style={{ height: 0, overflow: 'hidden', fontWeight: 'bold' }}>
28+
{column?.title || '\xa0'}
29+
</div>
2330
</td>
2431
</ResizeObserver>
2532
);

src/Body/MeasureRow.tsx

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,25 @@ import * as React from 'react';
22
import ResizeObserver from 'rc-resize-observer';
33
import MeasureCell from './MeasureCell';
44
import isVisible from 'rc-util/lib/Dom/isVisible';
5+
import type { ColumnType } from '../interface';
56

6-
export interface MeasureCellProps {
7+
export interface MeasureRowProps {
78
prefixCls: string;
89
onColumnResize: (key: React.Key, width: number) => void;
910
columnsKey: React.Key[];
11+
columns: readonly ColumnType<any>[];
1012
}
1113

12-
export default function MeasureRow({ prefixCls, columnsKey, onColumnResize }: MeasureCellProps) {
14+
export default function MeasureRow({
15+
prefixCls,
16+
columnsKey,
17+
onColumnResize,
18+
columns,
19+
}: MeasureRowProps) {
1320
const ref = React.useRef<HTMLTableRowElement>(null);
1421

1522
return (
16-
<tr
17-
aria-hidden="true"
18-
className={`${prefixCls}-measure-row`}
19-
style={{ height: 0, fontSize: 0 }}
20-
ref={ref}
21-
>
23+
<tr aria-hidden="true" className={`${prefixCls}-measure-row`} style={{ height: 0 }} ref={ref}>
2224
<ResizeObserver.Collection
2325
onBatchResize={infoList => {
2426
if (isVisible(ref.current)) {
@@ -28,9 +30,17 @@ export default function MeasureRow({ prefixCls, columnsKey, onColumnResize }: Me
2830
}
2931
}}
3032
>
31-
{columnsKey.map(columnKey => (
32-
<MeasureCell key={columnKey} columnKey={columnKey} onColumnResize={onColumnResize} />
33-
))}
33+
{columnsKey.map(columnKey => {
34+
const column = columns.find(col => col.key === columnKey);
35+
return (
36+
<MeasureCell
37+
key={columnKey}
38+
columnKey={columnKey}
39+
onColumnResize={onColumnResize}
40+
column={column}
41+
/>
42+
);
43+
})}
3444
</ResizeObserver.Collection>
3545
</tr>
3646
);

src/Body/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ function Body<RecordType>(props: BodyProps<RecordType>) {
133133
prefixCls={prefixCls}
134134
columnsKey={columnsKey}
135135
onColumnResize={onColumnResize}
136+
columns={flattenColumns}
136137
/>
137138
)}
138139

src/FixedHolder/index.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import ColGroup from '../ColGroup';
77
import TableContext from '../context/TableContext';
88
import type { HeaderProps } from '../Header/Header';
99
import devRenderTimes from '../hooks/useRenderTimes';
10-
import type { ColumnsType, ColumnType, Direction } from '../interface';
10+
import type { ColumnsType, ColumnType, Direction, TableLayout } from '../interface';
1111

1212
function useColumnWidth(colWidths: readonly number[], columCount: number) {
1313
return useMemo(() => {
@@ -35,6 +35,7 @@ export interface FixedHeaderProps<RecordType> extends HeaderProps<RecordType> {
3535
stickyBottomOffset?: number;
3636
stickyClassName?: string;
3737
scrollTableStyle?: React.CSSProperties;
38+
tableLayout?: TableLayout;
3839
onScroll: (info: { currentTarget: HTMLDivElement; scrollLeft?: number }) => void;
3940
children: (info: HeaderProps<RecordType>) => React.ReactNode;
4041
colGroup?: React.ReactNode;
@@ -60,6 +61,7 @@ const FixedHolder = React.forwardRef<HTMLDivElement, FixedHeaderProps<any>>((pro
6061
stickyBottomOffset,
6162
stickyClassName,
6263
scrollTableStyle,
64+
tableLayout = 'fixed',
6365
onScroll,
6466
children,
6567
...restProps
@@ -148,7 +150,7 @@ const FixedHolder = React.forwardRef<HTMLDivElement, FixedHeaderProps<any>>((pro
148150
>
149151
<TableComponent
150152
style={{
151-
tableLayout: 'fixed',
153+
tableLayout,
152154
visibility: noData || mergedColumnWidth ? null : 'hidden',
153155
...scrollTableStyle,
154156
}}

src/Table.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,7 @@ function Table<RecordType extends DefaultRecordType>(
685685
direction,
686686
stickyClassName,
687687
scrollTableStyle,
688+
tableLayout: mergedTableLayout,
688689
onScroll: onInternalScroll,
689690
};
690691

0 commit comments

Comments
 (0)