Skip to content

Commit 54f9f28

Browse files
committed
feat: sync v5
2 parents 5d0f833 + 5246767 commit 54f9f28

File tree

8 files changed

+180
-37
lines changed

8 files changed

+180
-37
lines changed

docs/examples/stickyHeader.tsx

Lines changed: 110 additions & 6 deletions
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;
@@ -79,6 +79,41 @@ const columns: ColumnType<RecordType>[] = [
7979
},
8080
];
8181

82+
const columnsWithWidth: ColumnType<RecordType>[] = [
83+
{ title: 'title1', dataIndex: 'a', key: 'a', width: 100 },
84+
{ title: 'title2', dataIndex: 'b', key: 'b', width: 100 },
85+
{ title: 'title3', dataIndex: 'c', key: 'c', width: 200 },
86+
{ title: 'title4', dataIndex: 'd', key: 'd', width: 100 },
87+
];
88+
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+
82117
const data = [
83118
{ a: '123', key: '1' },
84119
{ a: 'cdd', b: 'edd', key: '2' },
@@ -105,11 +140,7 @@ const data = [
105140
const Demo = () => {
106141
const container = useRef();
107142
return (
108-
<div
109-
style={{
110-
height: 10000,
111-
}}
112-
>
143+
<div>
113144
<h2>Sticky</h2>
114145
<Table<RecordType>
115146
columns={columns}
@@ -212,6 +243,79 @@ const Demo = () => {
212243
suscipit asperiores, id ullam in iste soluta dignissimos vero incidunt, rem ex consectetur
213244
beatae totam aperiam. Sunt, laudantium?
214245
</div>
246+
247+
<h2>Sticky header with empty data</h2>
248+
<Table
249+
columns={fixedColumns}
250+
data={[]}
251+
scroll={{
252+
x: 'max-content',
253+
}}
254+
sticky
255+
/>
256+
<br />
257+
<Table
258+
columns={fixedColumns}
259+
data={[]}
260+
scroll={{
261+
x: 1200,
262+
}}
263+
sticky
264+
/>
265+
<br />
266+
<Table
267+
columns={columnsWithWidth}
268+
data={[]}
269+
scroll={{
270+
x: 'max-content',
271+
}}
272+
sticky
273+
/>
274+
<br />
275+
<Table
276+
columns={fixedColumns}
277+
data={[{}]}
278+
scroll={{
279+
x: 'max-content',
280+
}}
281+
sticky
282+
/>
283+
<br />
284+
<Table
285+
columns={columnsWithWidth}
286+
data={[{}]}
287+
scroll={{
288+
x: 1200,
289+
}}
290+
sticky
291+
/>
292+
<br />
293+
<Table
294+
columns={fixedColumns.map(column => ({ ...column, width: undefined }))}
295+
data={[]}
296+
scroll={{
297+
x: 'max-content',
298+
}}
299+
sticky
300+
/>
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+
/>
215319
</div>
216320
);
217321
};

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@rc-component/table",
3-
"version": "1.5.2",
3+
"version": "1.5.3",
44
"description": "table ui component for react",
55
"engines": {
66
"node": ">=8.x"

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-component/resize-observer';
33
import useLayoutEffect from '@rc-component/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-component/resize-observer';
33
import MeasureCell from './MeasureCell';
44
import isVisible from '@rc-component/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
@@ -146,6 +146,7 @@ function Body<RecordType>(props: BodyProps<RecordType>) {
146146
prefixCls={prefixCls}
147147
columnsKey={columnsKey}
148148
onColumnResize={onColumnResize}
149+
columns={flattenColumns}
149150
/>
150151
)}
151152

src/ColGroup.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ function ColGroup<RecordType>({ colWidths, columns, columCount }: ColGroupProps<
2222
for (let i = len - 1; i >= 0; i -= 1) {
2323
const width = colWidths[i];
2424
const column = columns && columns[i];
25-
let additionalProps;
25+
let additionalProps: Record<string, unknown>;
2626
let minWidth: number;
2727
if (column) {
2828
additionalProps = column[INTERNAL_COL_DEFINE];

src/FixedHolder/index.tsx

Lines changed: 34 additions & 15 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(() => {
@@ -36,6 +36,8 @@ export interface FixedHeaderProps<RecordType> extends HeaderProps<RecordType> {
3636
stickyTopOffset?: number;
3737
stickyBottomOffset?: number;
3838
stickyClassName?: string;
39+
scrollTableStyle?: React.CSSProperties;
40+
tableLayout?: TableLayout;
3941
onScroll: (info: { currentTarget: HTMLDivElement; scrollLeft?: number }) => void;
4042
children: (info: HeaderProps<RecordType>) => React.ReactNode;
4143
}
@@ -59,6 +61,8 @@ const FixedHolder = React.forwardRef<HTMLDivElement, FixedHeaderProps<any>>((pro
5961
stickyTopOffset,
6062
stickyBottomOffset,
6163
stickyClassName,
64+
scrollTableStyle,
65+
tableLayout = 'fixed',
6266
onScroll,
6367
maxContentScroll,
6468
children,
@@ -115,12 +119,6 @@ const FixedHolder = React.forwardRef<HTMLDivElement, FixedHeaderProps<any>>((pro
115119
};
116120
}, []);
117121

118-
// Check if all flattenColumns has width
119-
const allFlattenColumnsWithWidth = React.useMemo(
120-
() => flattenColumns.every(column => column.width),
121-
[flattenColumns],
122-
);
123-
124122
// Add scrollbar column
125123
const lastColumn = flattenColumns[flattenColumns.length - 1];
126124
const ScrollBarColumn: ColumnType<unknown> & { scrollbar: true } = {
@@ -158,6 +156,32 @@ const FixedHolder = React.forwardRef<HTMLDivElement, FixedHeaderProps<any>>((pro
158156

159157
const mergedColumnWidth = useColumnWidth(colWidths, columCount);
160158

159+
const colGroupNode = useMemo(() => {
160+
// use original ColGroup if no data or no calculated column width, otherwise use calculated column width
161+
// Return original colGroup if no data, or mergedColumnWidth is empty, or all widths are falsy
162+
if (
163+
noData ||
164+
!mergedColumnWidth ||
165+
mergedColumnWidth.length === 0 ||
166+
mergedColumnWidth.every(width => !width)
167+
) {
168+
return ColGroup;
169+
}
170+
return (
171+
<ColGroup
172+
colWidths={[...mergedColumnWidth, combinationScrollBarSize]}
173+
columCount={columCount + 1}
174+
columns={flattenColumnsWithScrollbar}
175+
/>
176+
);
177+
}, [
178+
noData,
179+
mergedColumnWidth,
180+
combinationScrollBarSize,
181+
columCount,
182+
flattenColumnsWithScrollbar,
183+
]);
184+
161185
return (
162186
<div
163187
style={{
@@ -172,17 +196,12 @@ const FixedHolder = React.forwardRef<HTMLDivElement, FixedHeaderProps<any>>((pro
172196
>
173197
<TableComponent
174198
style={{
175-
tableLayout: 'fixed',
199+
tableLayout,
176200
visibility: noData || mergedColumnWidth ? null : 'hidden',
201+
...scrollTableStyle,
177202
}}
178203
>
179-
{(!noData || !maxContentScroll || allFlattenColumnsWithWidth) && (
180-
<ColGroup
181-
colWidths={mergedColumnWidth ? [...mergedColumnWidth, combinationScrollBarSize] : []}
182-
columCount={columCount + 1}
183-
columns={flattenColumnsWithScrollbar}
184-
/>
185-
)}
204+
{colGroupNode}
186205
{children({
187206
...restProps,
188207
stickyOffsets: headerStickyOffsets,

src/Table.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,8 @@ function Table<RecordType extends DefaultRecordType>(
719719
...columnContext,
720720
direction,
721721
stickyClassName,
722+
scrollTableStyle,
723+
tableLayout: mergedTableLayout,
722724
onScroll: onInternalScroll,
723725
};
724726

0 commit comments

Comments
 (0)